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,如需轉載請自行聯系原作者