天天看點

Android内容提供者源碼

Android内容提供者源碼,我不想說多,隻講一些實用的代碼,增删改查。通過contentProvider向資料進行操作。大家可以下載下傳,通過日志與LogCat列印出來的資訊作為參考!  

package com.smart;  

import android.app.Activity;  

import android.content.ContentResolver;  

import android.content.ContentValues;  

import android.database.Cursor;  

import android.net.Uri;  

import android.os.Bundle;  

import android.provider.ContactsContract;  

import android.util.Log;  

public class ContentProvider extends Activity {  

  private static final String TAG = "ContentProvider";  

    @Override 

    public void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.main);  

//      通過這個類,方問DB項目  

      ContentResolver contentResolver = this.getContentResolver();  

      Uri alluri = Uri.parse("content://com.smart.provider.personprovider/person");  

//      Uri uri = Uri.parse("content://com.smart.provider.personprovider/person");  

      ContentValues values = new ContentValues();  

      values.put("name", "smart99"); // 這裡更改就可以了。/  

      values.put("age", (short)44);  

//      contentResolver.insert(uri, values); //增加  

      Uri uri = Uri.parse("content://com.smart.provider.personprovider/person/5");  

//      contentResolver.update(uri, values, null, null);//更新  

//      contentResolver.delete(uri, null, null);//删除  

      //查詢  

//      Cursor cursor = contentResolver.query(uri, new String[] {  

//        "personid", "name", "age" }, null, null, "personid desc");  

//      while (cursor.moveToNext()) {  

//       Log.i(TAG,  

//         "personid=" + cursor.getInt(0) + ",name="  

//           + cursor.getString(1) + ",age="  

//           + cursor.getShort(2));  

//      }  

//      cursor.close();  

//      記得要關掉資料  

      //01:19  

      contactMethod();  

    }  

    //讀取通迅裡的人員。  

 public void contactMethod(){  

 //聯系人,/媒體庫/  

 ContentResolver contentResolver = this.getContentResolver();  

 Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);  

 while (cursor.moveToNext()) {  

  int contactId=cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));  

  String name=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));  

  Log.i(TAG,"contactId=" + contactId + ",name=" 

      + name);  

  Cursor phones=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,  

    null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contactId, null, null);  

  StringBuffer sb=new StringBuffer();  

  while(phones.moveToNext()){  

   String phoneNumber=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));  

  sb.append(phoneNumber).append(",");  

 }  

  //電話号碼可以得到  

  Log.i(TAG, sb.toString());  

 cursor.close();  

}  

package com.smart.dh;  

import android.content.ContentProvider;  

import android.content.ContentUris;  

import android.content.UriMatcher;  

import android.database.sqlite.SQLiteDatabase;  

import android.text.TextUtils;  

import com.smart.service.DataBaseOpenHelper;  

/**  

 * 使用内容提供者  

ContentProvider共享資料  

當應用繼承ContentProvider類,并重寫該類用于提供資料和存儲資料的方法  

就可以向其它應用共享其資料。雖然使用其它方法對外共享資料,但是資料通路  

方式 會因資料存儲的方式而不同。,而采用檔案操作讀寫資料,采用sharedoreferences共享資料的需要使用sharedpreferences API讀寫資料,而使用ContentProvider共享資料的好處  

好處是統一了資料通路方式,當應用需要通過ContentProvider對外共享 資料時,第一步需要繼承ContentProvider并重寫下面的方法。  

Public class PersonContentProvider extends ContentProvider{  

Public boolean onCreate();  

Public Uri insert(Uri uri,ContentValues values);  

Public int delete(Uri uri,String selection,String[] selectionArgs);  

Public int update(Uri uri,ContentValues values,String selection,String selectionArgs);  

Pullic Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String softOrder);  

Public String getType(Uri uri);  

第二步需要在AndroidMandifest.xml使用<provider>對該ContentProvider進行配置,為了能讓其它應用找到該ContentProvider,ContentProvider采用了authorites(主機名、域名)對它進行唯一辨別,你可以把ContentProvider看作是一個網站(想想,網站也是提供資料者),authorites就是他的域名:  

下面是在要注冊資訊  

<appli…>  

<provider android:name=”.類名” android:authorities=”con.smart.provider.包名”>  

</appli>  

注意:一旦應用繼承了ContentProvider類,後面我們就會把這個應用稱為ContentProvider内容提供者  

 * ContentProvider來自于檔案與資料庫都可以  

 *   

 * Uri介紹  

 * Uri代表了要操作的資料,Uri主要包含了兩部資訊:1》  

 * 需要操作的ContentProvider,2>  

 * 對ContentProvider中的,什麼資料進行操作, 一個Uri由以下幾個部分組成。  

 * content:// com.smart.provider.personperovider/person/988  

 *  content://  指 scheme    

 *  om.smart.provider.personperovider指 主機名或authority  

 *  person  指路徑  

 *  988  指ID  

 * */ 

public class PersonContentProvider extends ContentProvider {  

 // 另一個工程,方問這一個類。  

 private DataBaseOpenHelper dbOpenHelper;  

 private static final int ALLPERSON = 1;  

 private static final int PERSON = 2;  

 private static UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);// 任何不比對的時候,傳回為-1  

 static {  

//    

  sMatcher.addURI("com.smart.provider.personprovider", "person",ALLPERSON);  

  sMatcher.addURI("com.smart.provider.personprovider", "person/#", PERSON);  

 //删除  

 @Override 

 public int delete(Uri uri, String selection, String[] selectionArgs) {  

  SQLiteDatabase db = dbOpenHelper.getWritableDatabase();  

  int count = 0;// 傳回的行數  

  switch (sMatcher.match(uri)) {  

  case ALLPERSON:  

   count = db.delete("person", selection, selectionArgs);  

   break;  

  case PERSON:  

   long personid = ContentUris.parseId(uri);  

   String where = TextUtils.isEmpty(selection) ? "personid=?" 

     : selection + " and personid=?";  

   String[] params = new String[] { String.valueOf(personid) };  

   if (!TextUtils.isEmpty(selection) && selectionArgs != null) {  

    params = new String[selectionArgs.length + 1];  

    for (int i = 0; i < selectionArgs.length; i++) {  

     params[i] = selectionArgs[i];  

    params[selectionArgs.length + 1] = String.valueOf(personid);  

   }  

   count = db.delete("person", where, params);  

  default:  

   throw new IllegalArgumentException("Unkow Uri:" + uri);  

  }  

  return count;  

 /**  

  * public String getType(Uri uri)  

  * 方法用于傳回URI所代表資料的MIME類型,如果操作的資料發球集合類型,哪麼MIME類型  

  * 字元串應該以vnd.android.cursor.dir/開頭,要得到所有的person記錄Uri為,  

  * ontent//com.smart.domain/person 哪麼傳回MIME類型字元串應該為,  

  * vnd.android.cursor.item/開頭,比如,得到的ID為1的person記錄,URI為  

  * ontent//com.smart.domain/person/10 ,哪麼傳回的MIME類型字元串應該為  

  * vnd.android.cursor.item/person  

  * */ 

// 操作資料類型  

 @Override   //這個方法,不實作也可以的。  

 public String getType(Uri uri) {  

   //多條  

   return "vnd.android.cursor.dir/personprovider.person";  

   //personprovider.person  内容提供表的  

   //單條  

   return "vnd.android.cursor.item/personprovider.person";  

  * UriMatcher類的使用介紹 因為URI代表了要操作的資料,是以我們很經常需要解析URI,并從URI中獲得取資料,ANDROID系統  

  * 提供了兩個用于操作URI的工具類,分别為URIMATCHER和CONTENTURIS。掌握它們的使用,會便于我們的開發工作,  

  * URIMATCHER類于比對URI。它的用法如下。 首先第一步把你需要比對路徑全部給注冊上,如下 常量  

  * UriMatcher.NO_MATCH表示不比對任何路徑的傳回碼 Urimatcher sMatcher=new  

  * UriMatcher(UriMatcher.NO_MATCH);  

  * 如果match()方法比對content//com.smart.domain/person 路徑,傳回比對為1  

  * sMatcher.addURI(content//com.smart.domain/person/1);  

  * 如果match()方法比對content//com.smart.domain/person/230 路徑,傳回比對為2  

  * sMatcher.addURI(content//com.smart.domain/person/#,2); /#為通配符  

  *   

  * 這裡講一下,parse方法為任何的一個字元串轉換為Uri位址  

  * switch(sMatcher.match(Uri.parse("content//com.smart.domain/person/10"))){  

  * }  

  * 注冊完需要比對的URI後,就可以使用sMatcher.match(Uri)方法對輸入進行比對 ,如果比對就傳回比對碼  

  * 比對碼是調用ADDRUI()方法傳入第三個參數,假設比對 content//com.smart.domain/person 路徑,傳回的比對碼為1  

  * **/ 

 //增加  

 public Uri insert(Uri uri, ContentValues values) {  

  // 傳回的類型為,傳回一路徑,  

  long id = 0;  

  // com.smart.domain/person/100  

   // com.smart.domain/person/  

   id = db.insert("person", "name", values);// 記是記錄的行号,主健INT類,就是主健,  

   return ContentUris.withAppendedId(uri, id);  

   // com.smart.domain/person/20  

   db.insert("person", "name", values);  

   String path = uri.toString();  

   // 從0個開始,取到,com.smart.domain/person/20 前面20的一個'/'  

   return Uri.parse(path.substring(0, path.lastIndexOf('/')) + id);  

   // 傳回一個參數  

 public boolean onCreate() {  

  dbOpenHelper = new DataBaseOpenHelper(this.getContext());  

  return true;  

//查詢  

 public Cursor query(Uri uri, String[] projection, String selection,  

 String[] selectionArgs, String sortOrder) {  

  return db.query("person", projection, selection, selectionArgs,null,null,sortOrder);  

   return db.query("person", projection, where, params,null,null,sortOrder);  

//更新  

 public int update(Uri uri, ContentValues values, String selection,  

   String[] selectionArgs) {  

   count = db.update("person", values, selection, selectionArgs);  

  case PERSON://com.smart.domain/100  

   long personid = ContentUris.parseId(uri);//得到100的記錄  

   //判斷是否為空,為條件  

   count = db.update("person", values, where, params);  

 /*****  

  * 增加 ContentUris類用于擷取Uri 路徑後面的ID部分,它有兩個實用的方法,  

  * withAppendedld(Uri,id)用于為路徑為上ID部分 Uri  

  * uri=Uri.parse("content://com.smart.domain/person"); Uri  

  * resultUri=ContentUris.withAppendedld(uri,10)  

  * 生成後Uri為:content://com.smart.domain/person/10  

  * 更新的方法 parseld(uri)方法用于從路徑中擷取ID部分 Uri  

  * uri=Uri.parse("com.smart.domain/person/10"); long  

  * personid=ContentUris.parseld(uri);//擷取的結果為10  

<?xml version="1.0" encoding="utf-8"?>  

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 

      package="com.smart.dh" 

      android:versionCode="1" 

      android:versionName="1.0">  

    <application android:icon="@drawable/icon" android:label="@string/app_name">  

        <uses-library android:name="android.test.runner"/>  

       <provider android:name=".PersonContentProvider" 

        android:authorities="com.smart.provider.personprovider"   

        android:permission="com.smart.provider.personprovider"/>   

        <activity android:name=".DBActivity" 

                  android:label="@string/app_name">  

            <intent-filter>  

                <action android:name="android.intent.action.MAIN" />  

                <category android:name="android.intent.category.LAUNCHER" />  

            </intent-filter>  

        </activity>  

    </application>  

    <uses-sdk android:minSdkVersion="8" />  

 <instrumentation android:name="android.test.InstrumentationTestRunner" 

 android:targetPackage="com.smart.dh" android:label="Tests for My App"/>  

</manifest>   

   <!--  android:permission="cn.itcast.provider.personprovider" 

        這行是指權限    android:permission="com.smart.domain" 

        com.smart.domain  

        -->  

大家記住了,兩個工程,一定都導進來,然後運作。

本文轉自 llb988 51CTO部落格,原文連結:http://blog.51cto.com/llb988/518956,如需轉載請自行聯系原作者