Android 它们的定义ContentProvider和ContentObserver充分利用

在他们的定义ContentProvider结合ContentObserver一起使用时,自己写的ContentProvider,在运行完insert、delete和update后,要手动地调用getContentResolver().notifyChange()这种方法来通知修改的产生。

直接上代码:

MainActivity

package com.jackie.contentobserver;

import java.util.ArrayList;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

	private ArrayList<Person> mList;
	private ListView mListView;
	private ContentResolver resolver;
	private MyBaseAdapter mBaseAdapter;
	private Handler mHandler;

	private AdapterContentObserver mAdapterContentObserver;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mListView = (ListView) findViewById(R.id.lv_person);
		initData();

		mBaseAdapter = new MyBaseAdapter(this, mList);
		mListView.setAdapter(mBaseAdapter);

		mHandler = new Handler();

		mAdapterContentObserver = new AdapterContentObserver(this, mHandler);
		resolver.registerContentObserver(Uri.parse("content://com.jackie.provider.person/person"), true, mAdapterContentObserver);
		//注冊短信变化监听
		//this.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content)
	}

	@Override
	protected void onDestroy() {
		resolver.unregisterContentObserver(mAdapterContentObserver);
		super.onDestroy();
	}

	private ArrayList<Person> initData() {
		mList = new ArrayList<Person>();
		resolver = getContentResolver();
		Cursor cursor = resolver.query(Uri.parse("content://com.jackie.provider.person/person"), null, null, null, null);
		while (cursor.moveToNext()) {
			Person person = new Person();
			person.set_id(cursor.getInt(cursor.getColumnIndex("_id")));
			person.setName(cursor.getString(cursor.getColumnIndex("name")));
			mList.add(person);
		}

		return mList;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_settings:
//			AlertDialog.Builder builder = new AlertDialog.Builder(this);
//			builder.setTitle("提示").setMessage("您确定要退出?");
//			builder.create().show();
			ContentValues values = new ContentValues();
			values.put("name", "Jackie");
			Uri mUri = resolver.insert(Uri.parse("content://com.jackie.provider.person/person"), values);

			//方法一: 又一次查询数据库实时刷新
//	        mBaseAdapter = new MyBaseAdapter(this, initData());
//	        mListView.setAdapter(mBaseAdapter);

			//方法二: 当adapter绑定的list变化时,调用adapter的notifyDataSetChanged方法实时刷新(不用反复查询数据库,效率更高)
//			long id = ContentUris.parseId(mUri);
//			mList.add(new Person(id, "chengjie"));
//			mBaseAdapter.notifyDataSetChanged();

			//方法三: 内容观察者ContentObserver
			//自己写的ContentProvider,在运行完insert、delete和update后,要手动地调用getContentResolver().notifyChange()这种方法来通知修改的产生(请參考MyProvider.java的方法)

			break;

		default:
			break;
		}
		return super.onMenuItemSelected(featureId, item);
	}

}

AdapterContentObserver.java

package com.jackie.contentobserver;

    import android.content.ContentResolver;
    import android.content.Context;
    import android.database.ContentObserver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Handler;
    import android.util.Log;
    import android.widget.Toast;

    public class AdapterContentObserver extends ContentObserver {
        private Context context;
        private Handler handler;

        private static final int PERSON_UPDATE = 0;

        public AdapterContentObserver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }

        public AdapterContentObserver(Context context, Handler handler) {
            super(handler);
            this.context = context;
            this.handler = handler;
        }

        //当监听的Uri发生变化。便会运行这种方法
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);

            ContentResolver resolver = context.getContentResolver();
            // 获取最新的一条数据
            Cursor cursor = resolver.query(uri, null, null, null, "_id desc limit 1");
            while (cursor.moveToNext()) {
                int _id = cursor.getInt(cursor.getColumnIndex("_id"));
                Toast.makeText(context, "数据库更新了, _id 为: " + _id, Toast.LENGTH_SHORT).show();
            }
            cursor.close();
        }
    }

DBHelper.java

package com.jackie.contentobserver;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {

	public DBHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table if not exists person(_id integer primary key autoincrement, name text)");
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

	}

}

MyBaseAdapter.java

package com.jackie.contentobserver;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyBaseAdapter extends BaseAdapter {

	private ViewHolder holder;
	private Context context;
	private ArrayList<Person> mList;

	public MyBaseAdapter(Context context, ArrayList<Person> mList) {
		this.context = context;
		this.mList = mList;
	}

	@Override
	public int getCount() {
		return mList.size();
	}

	@Override
	public Object getItem(int position) {
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		LayoutInflater mInflater = LayoutInflater.from(context);
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = mInflater.inflate(R.layout.listview_item, null);
			holder.idTexitView = (TextView) convertView.findViewById(R.id.tv_id);
			holder.nameTextView = (TextView) convertView.findViewById(R.id.tv_name);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		holder.idTexitView.setText(mList.get(position).get_id() + "");
		holder.nameTextView.setText(mList.get(position).getName());
		return convertView;
	}

	class ViewHolder {
		TextView idTexitView;
		TextView nameTextView;
	}
}

MyProvider.java

package com.jackie.contentobserver;

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;

public class MyProvider extends ContentProvider {
	private final static String AUTHORITH = "com.jackie.provider.person";

	private final static String PERSONS_PATH = "person";

	private final static String PERSON_PATH = "person/#";

	private final static int PERSON = 1;

	private final static int PERSONS = 2;

	private final static String DATABASE_NAME = "person_db";

	private final static String TABLE_NAME = "person";

	private final static String TABLE_COLUMN_ID = "_id";

	private final static String TABLE_COLUMN_NAME = "name";

	private final static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

	static {
		mUriMatcher.addURI(AUTHORITH, PERSONS_PATH, PERSONS);
		mUriMatcher.addURI(AUTHORITH, PERSON_PATH, PERSON);
	}

	private DBHelper helper = null;

	@Override
	public boolean onCreate() {
		helper  = new DBHelper(getContext(), DATABASE_NAME, null, 1);
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase database = helper.getWritableDatabase();
		switch (mUriMatcher.match(uri)) {
		case PERSON:
			long id = ContentUris.parseId(uri);
			String where = TABLE_COLUMN_ID + "=" + id;
			if (selection != null && !"".equals(selection)) {
				selection = where + "and" + selection;
			}
			return database.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);

		case PERSONS:
			return database.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);

		default:
			throw new IllegalArgumentException("UnKnown uri: " + uri);
		}
	}

	@Override
	public String getType(Uri uri) {
		switch (mUriMatcher.match(uri)) {
		case PERSON:
			return "vnd.android.cursor.item";

		case PERSONS:
			return "vnd.android.cursor.dir";

		default:
			throw new IllegalArgumentException("UnKnown uri: " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase database = helper.getWritableDatabase();
		long id = database.insert(TABLE_NAME, TABLE_COLUMN_NAME, values);
		//向外界通知该ContentProvider里的数据发生了变化 ,以便ContentObserver作出对应
                getContext().getContentResolver().notifyChange(uri, null);
		return ContentUris.withAppendedId(uri, id);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase database = helper.getWritableDatabase();
		switch (mUriMatcher.match(uri)) {
		case PERSON:
			long id = ContentUris.parseId(uri);
			String where = TABLE_COLUMN_ID + "=" + id;
			if (selection != null && !"".equals(selection)) {
				selection = where + "and" + selection;
			}
			return database.delete(TABLE_NAME, selection, selectionArgs);

		case PERSONS:
			return database.delete(TABLE_NAME, selection, selectionArgs);

		default:
			throw new IllegalArgumentException("UnKnown uri: " + uri);
		}
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

}

Person.java

package com.jackie.contentobserver;

public class Person {

	private long _id;
	private String name;
	public Person(long _id, String name) {
		super();
		this._id = _id;
		this.name = name;
	}

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public long get_id() {
		return _id;
	}

	public void set_id(long _id) {
		this._id = _id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

版权声明:本文博主原创文章。博客,未经同意不得转载。

时间: 2024-11-06 11:07:36

Android 它们的定义ContentProvider和ContentObserver充分利用的相关文章

Android 自定义ContentProvider和ContentObserver的完整使用

在自定义ContentProvider结合ContentObserver一起使用时,自己写的ContentProvider,在执行完insert.delete和update后,要手动地调用getContentResolver().notifyChange()这个方法来通知改动的产生. 直接上代码: MainActivity <span style="font-family:SimSun;font-size:14px;"><span style="font-f

android菜鸟学习笔记22----ContentProvider(二)ContentObserver的简单使用

现在有这样一个应用A通过ContentProvider提供自己的数据给其他应用,应用B通过ContentResolver获取应用A中提供的数据,并将其展示在ListView中,而应用C通过ContentResolver修改应用A中的数据,或者添加新的数据.现在的问题是应用C修改A中数据后,应用B的ListView中显示的还是历史数据…… 具体程序如下: ContentProvider和插入数据的应用分别复用上一篇中的两个应用,然后新建一个应用,用于获取ContentProvider中的数据,并在

Android 这 13 道 ContentProvider 面试题,你都会了吗?

前言 作为 Android 的四大组件之一,ContentProvider 可以说是无处不在了. 但是对于我而言,开发过程中看似 ContentProvider 用得很娴熟,却一直没能形成一个完整的体系. 也许大家也有着和我类似的烦恼,于是我特地花了几天的时间,总结了我所知道的知识点,以及面试中可能遇到的问题.将本文分享给大家,希望能帮助大家重新梳理下我们的这个老朋友 ContentProvider . 最后,希望大家阅读愉快! 文章目录 ContentProvider 应用程序间非常通用的共享

android四大组件之ContentProvider(一)

ContentProvider学习笔记 1. ContentProvider基本概念 ContentProvider向我们提供了我们在应用程序之前共享数据的一种机制,而我们知道每一个应用程序都是运行在不同的应用程序的,数据和文件在不同应用程序之间达到数据的共享不是没有可能,而是显得比较复杂,而正好Android中的ContentProvider则达到了这一需求,比如有时候我们需要操作手机里的联系人,手机里的多媒体等一些信息,我们都可以用到这个ContentProvider来达到我们所需. (1)

【Android】19.3 ContentProvider及安卓进一步封装后的相关类

分类:C#.Android.VS2015: 创建日期:2016-03-08 一.简介 ContentProvider:内容提供程序. Android的ContentProvider与.NET框架的EF(Entity Framework)非常类似.在EF中,每个类表示数据库中的一个表,类中的每个属性对应表的字段,类的每个实例表示数据库表的一行记录.同样,在Android中,每个ContentProvider类的实例表示数据表的一行记录,ContentProvider实例集合中的每一项表示数据表中的

Android中内容观察者的使用---- ContentObserver类详解

  转载请注明出处:http://blog.csdn.net/qinjuning 前言: 工作中,需要开启一个线程大量的查询某个数据库值发送了变化,导致的开销很大,后来在老大的指点下,利用了 ContentObserver完美的解决了该问题,感到很兴奋,做完之后自己也对ContentObserver做下总结. ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于 数据库技术中的触发器(Trigger),当ContentObs

[Android Pro] 内容提供者ContentProvider的基本使用

一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.ContentProvider为存储和获取数据提供了统一的接口.虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如采用文件方式对外共享数据,需要进行文件操作读写数据:采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据.而使用ContentProvider共享数据的

Android 内容提供者(ContentProvider)的简单实用

Android 中的数据库是对应用私有的,自己是无法使用别的应用的数据库的.但是往往有需求要我们使用另外一个应用或者系统应用的数据,这时候就彰显了内容提供者,ContentPrivider的作用,他就是两个应用数据的桥梁,通过内容提供者和内容接受者我们可以在不同应用间传递数据. ContentPrivider也可以视为一种数据存储.它存储数据的方式和使用它的应用程序无关,重要的是应用如何以一致的编程接口,来访问存储其中的数据.内容提供者与数据库的使用差不多,也可以增删改查.而且数据可以存储于数据

自定义ContentProvider以及ContentObserver的使用完整详细示例

示例说明: 该示例中一共包含两个工程.其中一个工程完成了自定义ContentProvider,另外一个工程用于测试该自定义ContentProvider且在该工程中使用了ContentObserver监听自定义ContentProvider的数据变化 以下代码为工程TestContentProvider ContentProviderTest如下: package cn.testcontentprovider; import android.content.ContentProvider; im