最近正好用到,写个小Demo记录下:
清单文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gyz.mycontentprovidertest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name="com.gyz.MainActivity">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider android:name="com.gyz.MyProvider" android:authorities="com.gyz.myprovidertest" android:exported="true"></provider><!--exported=true 供外部使用 -->
</application>
</manifest>
DBlite:
package com.gyz;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBlite extends SQLiteOpenHelper {
public DBlite(Context context) {
super(context, MyProvider.DBNAME, null, MyProvider.VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table "+MyProvider.TNAME+"(" +
MyProvider.TID+" integer primary key autoincrement not null,"+
MyProvider.EMAIL+" text not null," +
MyProvider.USERNAME+" text not null," +
MyProvider.DATE+" interger not null,"+
MyProvider.SEX+" text not null);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(newVersion){
case 1:
break;
case 2://为2的时候测试升级
db.execSQL("DROP TABLE IF EXISTS " + MyProvider.TNAME);
onCreate(db);
break;
}
}
}
MyProvider:
package com.gyz;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
/**
*
* @ClassName: MyProvider
* @Description: 内容提供者
* @author guoyizhe
* @email [email protected]
* @date 2015-6-29 上午10:56:56
*
*/
public class MyProvider extends ContentProvider {
public static final String DBNAME = "myprovidertest.db";
public static final String TNAME = "myprovidertest";
public static final int VERSION = 1;
public static String TID = "tid";
public static final String EMAIL = "email";
public static final String USERNAME = "username";
public static final String DATE = "date";
public static final String SEX = "sex";
public static final String AUTOHORITY = "com.gyz.myprovidertest";// 访问此provider的标示
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/myprovidertest";// 如果是集合,必须以vnd.android.cursor.dir开头
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/myprovidertest";// 如果是单条记录,必须以vnd.android.cursor.item开头
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTOHORITY + "/myprovidertest");
private static final UriMatcher sMatcher;
DBlite dBlite;
SQLiteDatabase db;
static {
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI(MyProvider.AUTOHORITY, MyProvider.TNAME, MyProvider.ITEM);// 匹配成功返回1
sMatcher.addURI(MyProvider.AUTOHORITY, MyProvider.TNAME + "/#", MyProvider.ITEM_ID);// 匹配成功返回2
}
//避免在第一次初始化的时候使用db.getReadableDatabase打开数据库,应该复写SQLiteOpenHelper.onOpen方法处理当数据库打开时的操作
@Override
public boolean onCreate() {
this.dBlite = new DBlite(this.getContext());
return true;//provider加载成功返回true,否则返回false
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
db = dBlite.getWritableDatabase();
Cursor c;
switch (sMatcher.match(uri)) {
case ITEM:
c = db.query(TNAME, projection, selection, selectionArgs, null, null, null);
break;
case ITEM_ID:
// String id = uri.getPathSegments().get(1);
String id = uri.getLastPathSegment();//获得最后的id
c = db.query(TNAME, projection, TID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""),selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
// c.setNotificationUri(getContext().getContentResolver(), uri);//注册观察该URI上数据的变化
// getContext().getContentResolver().notifyChange(uri, null);//直接通知数据改变
return c;
}
//根据匹配的uri确定返回的是集合还是单条记录
@Override
public String getType(Uri uri) {
switch (sMatcher.match(uri)) {
case ITEM:
return CONTENT_TYPE;
case ITEM_ID:
return CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
db = dBlite.getWritableDatabase();
long rowId;
if(sMatcher.match(uri)!=ITEM){
throw new IllegalArgumentException("Unknown URI"+uri);
}
rowId = db.insert(TNAME,TID,values);
if(rowId>0){
Uri noteUri=ContentUris.withAppendedId(CONTENT_URI, rowId);//用于为路径加上ID部分
getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
}
throw new IllegalArgumentException("Unknown URI"+uri);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
db = dBlite.getWritableDatabase();
int match = sMatcher.match(uri);
switch (match) {
case ITEM:
//doesn't need any code in my provider.
break;
case ITEM_ID:
long _id = ContentUris.parseId(uri);
selection = "id = ?";
selectionArgs = new String[]{String.valueOf(_id)};
}
int count = db.delete(TNAME, selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
db = dBlite.getWritableDatabase();
int match = sMatcher.match(uri);
switch (match) {
case ITEM:
//doesn't need any code in my provider.
break;
case ITEM_ID:
long _id = ContentUris.parseId(uri); //获取到ID
selection = "id = ?";
selectionArgs = new String[]{String.valueOf(_id)};
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
int count = db.update(TNAME, values, selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
}
//利用事务批量插入数据
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
int numValues = 0;
db = dBlite.getWritableDatabase();
db.beginTransaction();
try {
//数据库操作
numValues = values.length;
for (int i = 0; i < numValues; i++) {
insert(uri, values[i]);
}
db.setTransactionSuccessful();
}catch(Exception e){
e.printStackTrace();
} finally {
db.endTransaction();
getContext().getContentResolver().notifyChange(uri, null);
}
return numValues;
}
}
MyObserver:
package com.gyz;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.os.Handler;
public class MyObserver extends ContentObserver {
private Handler mHandler;
private Context mContext;
private String msg;
public MyObserver(Handler handler,Context context) {
super(handler);
this.mHandler = handler;
this.mContext = context;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Cursor cursor = mContext.getContentResolver().query(MyProvider.CONTENT_URI, new String[] { MyProvider.EMAIL, MyProvider.USERNAME, MyProvider.DATE, MyProvider.SEX }, null, null, null);
while (cursor.moveToNext()) {
msg = cursor.getString(cursor.getColumnIndex(MyProvider.EMAIL)) + " " + cursor.getString(cursor.getColumnIndex(MyProvider.USERNAME)) + " "
+ cursor.getString(cursor.getColumnIndex(MyProvider.DATE)) + " " + cursor.getString(cursor.getColumnIndex(MyProvider.SEX));
}
mHandler.obtainMessage(0,msg).sendToTarget();
cursor.close();// 查找后关闭游标
}
}
MainActivity:
package com.gyz;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.gyz.mycontentprovidertest.R;
public class MainActivity extends Activity {
private ContentResolver contentResolver;
private MyObserver ob;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
Toast.makeText(MainActivity.this, (String) msg.obj, Toast.LENGTH_SHORT).show();
};
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 通过contentResolver进行查找
Button button = (Button) findViewById(R.id.button);
contentResolver = MainActivity.this.getContentResolver();
ob = new MyObserver(handler, MainActivity.this);
getContentResolver().registerContentObserver(MyProvider.CONTENT_URI, true, ob);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put(MyProvider.EMAIL, "[email protected]");
values.put(MyProvider.USERNAME, "gyzboy");
values.put(MyProvider.DATE, "20160629");
values.put(MyProvider.SEX, "man");
contentResolver.insert(MyProvider.CONTENT_URI, values);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
getContentResolver().unregisterContentObserver(ob);
}
}
如果另一个应用想要访问这个数据库,如下:
package com.gyz.mycontentproviderttest;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private Uri contentUrl;
private String email = "email";
private String username = "username";
private String date = "date";
private String sex = "sex";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text = (TextView) findViewById(R.id.text);
contentUrl = Uri.parse("content://com.gyz.myprovidertest/myprovidertest");//在另一个应用中定义的url
Cursor cursor = getContentResolver().query(contentUrl, new String[] { email, username, date, sex }, null, null, null);
cursor.moveToFirst();
text.setText(cursor.getString(cursor.getColumnIndex("email")) + " " + cursor.getString(cursor.getColumnIndex("username")) + " "
+ cursor.getString(cursor.getColumnIndex("date")) + " " + cursor.getString(cursor.getColumnIndex("sex")));
cursor.close();
}
}