Android ContentProviderの説明

14133 ワード

ContentProviderの説明
アプリケーションAがcontentProviderでデータを共有する必要がある場合は、次の手順に従います.
一.MyProviderextends androidを定義します.content.ContentProviderでは、onCreate、getType、insert、delete、query、updateの6つの方法を書き換えます.定義されたMyProviderはmanifestにあります.xmlで宣言登録を行います.
 
1.MyProviderでは、UriMatcherオブジェクトを定義し、その上にProviderから提供されたUriを登録し、対応する一致コードを返し、一致がなければ-1を返す.具体的には以下の通りです.
public static UriMatcher uriMatcher;
static{
    uriMatcher= new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI(AUTHORITY,"user", MATCH_DIR);//       uri,           ,     ,  -1
    uriMatcher.addURI(AUTHORITY,"user/#", MATCH_ITEM);//   match()    content://com.unj.myprovider/user/230  ,      2
}

 2.書き換えの添削修正の4つの方法について、sql文に対応する対応する方法のパラメータは以下のように参照される.
/**
* select id, name from user where age = ? order by name          
* projection = new String{"id","name"}; 
* selection = "age = ?"; 
* selectionArgs = new String{"23"}; 
* sortOrder = "name";
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder)

3.Uriに基づいてクエリー条件を追加できます.
switch (uriMatcher.match(uri)) {
		case MATCH_DIR:
			break;
		case MATCH_ITEM:
			long id = ContentUris.parseId(uri);
			if (selection != null && !"".equals(selection)) {
				selection += " and ";
			}
			selection += " id = " + id;
			break;
		default:
			throw new IllegalArgumentException("Unkonw URI" + uri);
		}

4.エクストラクション変更操作によってデータが変化した場合、このContentProviderを呼び出すContentResolverに、データが変化したことを通知する方法を呼び出すことができます.
getContext().getContentResolver().notifyChange(uri, null);//  ,   uri resolver,        ,    ContentObserver   onChange  。

5.以下は私がカスタマイズした操作データベースのProviderです:MyDBUserProvider.java
package com.androidstudydemo.contentprovider;

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;

/**
 *        ContentProvider       ,       ContentProvider         
 *       AndroidManifest.xml  <provider>  ContentProvider    
 *     :http://www.cnblogs.com/linjiqin/archive/2011/05/28/2061396.html
 * 
 * @author zkx016
 * 
 */
public class MyDBUserProvider extends ContentProvider {
	public static final String AUTHORITY = "com.unj.myprovider";
	public static final String TABLE_NAME = "user";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
	+ "/user");

	public static final int MATCH_DIR = 1;
	public static final int MATCH_ITEM = 2;
	MyDBHelper myDBHelper;
	/**
	 *  ContentProvider          
	 */
	public static final String CONTENT_TYPE_DIR = "vnd.android.cursor.dir/user";//          
	public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/user";//           

	/**
	 * UriMatcher     Uri,           Uri        ,
	 */
	public static UriMatcher uriMatcher;
	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(AUTHORITY, "user", MATCH_DIR);//       uri,           
		uriMatcher.addURI(AUTHORITY, "user/#", MATCH_ITEM);//   match()    content://com.unj.myprovider/person/230  ,      2
	}

	/**
	 *     ContentProvider        ,Android   ,ContentProvider                 。
	 */
	@Override
	public boolean onCreate() {
		myDBHelper = new MyDBHelper(getContext());//      ,      Sqlite   。
		return true;
	}

	/**
	 *          Url      MIME  。
	 *              ,  MIME        vnd.android.cursor.dir/  ,
	 *   :     person   Uri content://com.ljq.provider.personprovider/person,
	 *                    MIME        :"vnd.android.cursor.dir/person"。
	 *                  ,  MIME        vnd.android.cursor.item/  ,
	 */
	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {//     
		case MATCH_DIR:
			return CONTENT_TYPE_DIR;
		case MATCH_ITEM:
			return CONTENT_TYPE_ITEM;
		default:
			throw new IllegalArgumentException("Unknown URI" + uri);
		}

	}

	/**
	 *            ContentProvider    。
	 */
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int type = uriMatcher.match(uri);
		if (type != MATCH_DIR) {
			throw new IllegalArgumentException("Unknown URI:" + uri);
		}

		SQLiteDatabase db = myDBHelper.getWritableDatabase();
		long rowId = db.insert(TABLE_NAME, null, values);//               ,     -1;
		if (rowId > 0) {
			/**
			 * withAppendedId(uri, id)       ID  ,
			 *     Uri :content://com.unj.myprovider/person/10
			 */
			Uri noteUri = ContentUris.withAppendedId(CONTENT_URI, rowId);
			/**
			 *   ContentProvider        ContentProvider        ,
			 *    ContentProvider         getContentResolver().notifyChange(uri,
			 * null)       URI     ,
			 */
			getContext().getContentResolver().notifyChange(uri, null);
			db.close();
			return noteUri;
		} else {
			db.close();
			throw new IllegalArgumentException("Failed to insert row into"
					+ uri);
		}
	}

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

		SQLiteDatabase db = myDBHelper.getWritableDatabase();

		switch (uriMatcher.match(uri)) {
		case MATCH_DIR:
			break;
		case MATCH_ITEM:
			long id = ContentUris.parseId(uri);
			if (selection != null && !"".equals(selection)) {
				selection += " and ";
			}
			selection += " id = " + id;
			break;
		default:
			throw new IllegalArgumentException("Unkonw URI" + uri);
		}

		int rows = db.delete(TABLE_NAME, selection, selectionArgs);
		if (rows > 0) {
			getContext().getContentResolver().notifyChange(uri, null);
			db.close();
			return rows;
		} else {
			db.close();
			throw new IllegalArgumentException("Failed to delete row in" + uri);
		}

	}

	/**
	 * select id, name from user where age = ? order by name          projection
	 * = new String{"id","name"}; selection = "age = ?"; selectionArgs = new
	 * String{"23"}; sortOrder = "name";
	 */
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		switch (uriMatcher.match(uri)) {
		case MATCH_DIR:
			// tableName = uri.getLastPathSegment();
			break;
		case MATCH_ITEM:
			long id = ContentUris.parseId(uri);
			if (selection != null && !"".equals(selection)) {
				selection += " and ";
			}
			selection += "id = " + id;
			break;

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

		SQLiteDatabase db = myDBHelper.getReadableDatabase();
		Cursor cursor = db.query(TABLE_NAME, projection, selection,
				selectionArgs, null, null, sortOrder);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);// @1
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		switch (uriMatcher.match(uri)) {
		case MATCH_DIR:
			break;
		case MATCH_ITEM:
			long id = ContentUris.parseId(uri);
			if (selection != null && !"".equals(selection)) {
				selection += " and ";
			}
			selection += "id = " + id;
			break;

		default:
			throw new IllegalArgumentException("Unkonw URI" + uri);
		}
		SQLiteDatabase db = myDBHelper.getWritableDatabase();
		int rowsAffected = db.update(TABLE_NAME, values, selection,
				selectionArgs);//        
		db.close();
		if (rowsAffected > 0) {
			getContext().getContentResolver().notifyChange(CONTENT_URI, null);// @2
			return rowsAffected;
		}
		

		return 0;
	}

}

6.MyProvider定義が完了したら、manifest.xmlでは、<アプリケーション>の内部でProviderの登録を行います.
<!--    contentProvider-->
       <provider
           android:name="com.androidstudydemo.contentprovider.MyDBUserProvider"
           android:authorities="com.unj.myprovider" >
       </provider>

 
二.他のアプリケーション(B)において対応可能なContextによりContentResolverを得ることができるが、ContentResolverにはContentProviderに対応した添削チェックの4つの方法があり、BアプリケーションではcontentResolverを直接呼び出す.Insert()などの方法でAアプリケーションで提供されるデータが得られ、Bは呼び出し時にAアプリケーションが同時に実行されることを保証しなければならない.
1.androidプロジェクトを新規作成し、データが必要なUriとauthorityを宣言します.
public static final String AUTHORITY = "com.unj.myprovider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
			+ "/user");

2.ContentObserverを定義し、中のonChange(boolean selfChange,Uri uri)メソッドを書き換えます.このメソッドは、Provider内の対応するUriデータが変化すると、コールバックされます.
private ContentObserver contentObserver = new ContentObserver(handler) {
		public void onChange(boolean selfChange, Uri uri) {
			Toast.makeText(MainActivity.this, "      , uri is:" + uri,
					Toast.LENGTH_SHORT).show();
			queryClick();
		};
	};

3,アプリケーションでgetContext()を通過する.getContentResolver()ContentResolverを取得し、ContentObserverを登録する
<span style="white-space:pre">		</span>resolver = getContentResolver();
		/**
		 *   ContentProvider              ,    ContentObserver   (    uri  )    
		 * ,           ,      ContentObserver onChange()  
		 */
		resolver.registerContentObserver(CONTENT_URI, false, contentObserver);
4. 上のProviderをテストするためにカスタマイズしたBprojectを以下に示します.
package com.example.providertest;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {
	public static final String AUTHORITY = "com.unj.myprovider";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
			+ "/user");

	private ContentResolver resolver;
	private TextView textView;
	private Button query;
	private int id = 0;
	Handler handler = new Handler();
	private ContentObserver contentObserver = new ContentObserver(handler) {
		public void onChange(boolean selfChange, Uri uri) {
			Toast.makeText(MainActivity.this, "      , uri is:" + uri,
					Toast.LENGTH_SHORT).show();
			queryClick();
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		query = (Button) this.findViewById(R.id.button2);
		resolver = getContentResolver();
		/**
		 *   ContentProvider              ,    ContentObserver   (    uri  )    
		 * ,           ,      ContentObserver onChange()  
		 */
		resolver.registerContentObserver(CONTENT_URI, false, contentObserver);
		textView = (TextView) findViewById(R.id.textView1);
	}

	public Uri insertClick() {
		ContentValues values = new ContentValues();
		values.put("id", id);
		values.put("name", "   " + id);
		Uri uri = resolver.insert(CONTENT_URI, values);
		id++;
		return uri;
	}

	public void deleteClick() {
		Cursor cursor = resolver.query(CONTENT_URI, null, null, null, null);
		int count = cursor.getColumnCount();
		if (count > 0 && cursor.moveToLast()) {
			int id = resolver.delete(CONTENT_URI, "id = ?",
					new String[] { cursor.getInt(cursor.getColumnIndex("id"))
							+ "" });
		} else {
			Toast.makeText(MainActivity.this, "    ",
					Toast.LENGTH_SHORT).show();
		}

	}

	public void updateClick() {
		Cursor cursor = resolver.query(CONTENT_URI, null, null, null, null);
		if (cursor.moveToFirst()) {
			ContentValues values = new ContentValues();
			int id = cursor.getInt(cursor.getColumnIndex("id"));
			values.put("name", "   " + id);
			Uri uri = ContentUris.withAppendedId(CONTENT_URI, id);
			int result = resolver.update(uri, values, "", null);
		}
		if (!cursor.isClosed()) {
			cursor.close();
		}
	}

	public void queryClick() {
		textView.setText("");
		Cursor cursor = resolver.query(CONTENT_URI, null, null, null, null);
		while (cursor.moveToNext()) {
			textView.append("id : "
					+ cursor.getInt(cursor.getColumnIndex("id")) + "     ");
			textView.append("name : "
					+ cursor.getString(cursor.getColumnIndex("name")) + "
"); } if (!cursor.isClosed()) { cursor.close(); } textView.append("getAuthority:" + CONTENT_URI.getAuthority() + "
********
getEncodedAuthority:" + CONTENT_URI.getEncodedAuthority() + "
********
getEncodedFragment:" + CONTENT_URI.getEncodedFragment() + "
********
getEncodedPath: " + CONTENT_URI.getEncodedPath() + "
********
getHost: " + CONTENT_URI.getHost() + "
********
getLastPathSegment: " + CONTENT_URI.getLastPathSegment() + "
********
getPath: " + CONTENT_URI.getPath() + "
********
getPort: " + CONTENT_URI.getPort() + "
********
getQuery: " + CONTENT_URI.getQuery() + "
********
getScheme: " + CONTENT_URI.getScheme() + "
********
getUserInfo: " + CONTENT_URI.getUserInfo() + "
********
"); } @Override public void onClick(View arg0) { switch (arg0.getId()) { case R.id.button1:// insertClick(); break; case R.id.button3:// deleteClick(); break; case R.id.button2:// queryClick(); break; case R.id.button4:// updateClick(); break; default: break; } } }