欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ContentProvider+ContentObserver实例

程序员文章站 2024-02-09 16:50:10
...

最近正好用到,写个小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();
	}
}