天天看點

android ContentProvider的使用

  contentprovider是android四大元件之一,他可以使另外一個應用通路本應用中的資料,例如通過内容提供者我們可以在自己的應用中通路通訊錄中的資料。下面就通過代碼說明如何使用内容提供者。

1.建立一個資料庫。

package com.example.android_asynctask.database;

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 {

	private static String name = "mydb.db";
	private static int version = 1;

	public DBHelper(Context context) {
		super(context, name, null, version);
		// TODO Auto-generated constructor stub
	}
	@Override
	public void onCreate(SQLiteDatabase database) {
		// TODO Auto-generated method stub
		String sql = "create table user (id integer primary key autoincrement ,name varchar(64) ,address varchar(64))";
		database.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
	}

}
           

2.建立一個内容提供者類UserProvider繼承ContentProvider

這裡需注意的是提供者類必須要寫在AndroidMainfest.xml中package節點中那個包名下面,否則會出錯。這裡坑了我好久。

UserProvider需要重寫父類的幾個方法

public boolean onCreate();

public String getType(Uri uri);

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);

public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder);

package com.example.iweibo;

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 com.lql.database.DBHelper;

public class UserProvider extends ContentProvider {

	private DBHelper helper;
	private static final UriMatcher URI_MATCHER = new UriMatcher(
			UriMatcher.NO_MATCH);
	private static final int USER = 1;// 操作單條記錄
	private static final int USERS = 2;// 操作多條記錄
	
	static {// 添加比對的URI,分别是單條記錄和多條記錄
		URI_MATCHER.addURI("com.example.iweibo.UserProvider", "user/#", USER);
		URI_MATCHER.addURI("com.example.iweibo.UserProvider", "user", USERS);
	}

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		helper = new DBHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		Cursor cursor = null;
		SQLiteDatabase database = helper.getReadableDatabase();
		int flag = URI_MATCHER.match(uri);
		try {
			switch (flag) {
			case USER:
				long id = ContentUris.parseId(uri);
				String where_value = " id = " + id;
				if (selection != null && !"".equals(selection)) {
					where_value += " and " + selection;
				}
				cursor = database.query("user", null, where_value,
						selectionArgs, null, null, null);
				break;
			case USERS:
				cursor = database.query("user", null, selection, selectionArgs,
						null, null, null);
			default:
				break;
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		int match = URI_MATCHER.match(uri);
		switch (match) {
		case USER:// 如果比對的是單條記錄
			return "vnd.android.cursor.item/user";

		case USERS:// 如果比對的是多條記錄
			return "vnd.android.cursor.dir/users";
		}
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		Uri resultUri = null;
		SQLiteDatabase database = helper.getWritableDatabase();
		int flag = URI_MATCHER.match(uri);
		long id = 0;
		switch (flag) {
		case USERS:
			id = database.insert("user", null, values);
			resultUri = ContentUris.withAppendedId(uri, id);
			break;
		case USER:
			id = database.insert("user", null, values);
			String path = uri.toString();
			resultUri = Uri
					.parse(path.substring(0, path.lastIndexOf("/")) + id);
		default:
			break;
		}
		return resultUri;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		SQLiteDatabase database = helper.getWritableDatabase();
		int flag = URI_MATCHER.match(uri);
		long id = -1;
		int count = 0;
		switch (flag) {
		case USER:
			id = ContentUris.parseId(uri);
			String where_value = " id = " + id;
			if (selection != null && !selection.equals("")) {
				where_value += " and ";
			}
			count = database.delete("user", where_value, selectionArgs);
			break;
		case USERS:
			count = database.delete("user", selection, selectionArgs);
			break;
		default:
			break;
		}
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		SQLiteDatabase database = helper.getWritableDatabase();
		int flag = URI_MATCHER.match(uri);
		long id;
		int count = 0;
		switch (flag) {
		case USER:
			id = ContentUris.parseId(uri);
			String where_value = " id = " + id;
			if (selection != null && !selection.equals("")) {
				where_value += " and ";
			}
			count = database.update("user", values, where_value, selectionArgs);
			break;
		case USERS:
			count = database.update("user", values, selection, selectionArgs);
		default:
			break;
		}
		return count;
	}

}
           

3.在AndroidMainfest.xml中進行配置provider

在Application節點中添加<provider></provider>節點

<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android_asynctask"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.example.android_asynctask" >
    </instrumentation>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="android.test.runner" >
        </uses-library>

        <provider
            android:name=".UserProvider"
            android:authorities="com.example.iweibo.UserProvider" >
        </provider>

        <activity
            android:name=".MainActivity"
            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>

</manifest>
           

provider節點中android:name即是内容提供者的類名,android:authorities我用的是包名+類名,這裡很重要,因為内容通路者比對Uri尋找内容提供者時就是通過這個節點。

4.用單元測試測試是否成功

package com.example.android_asynctask.database;


import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

public class Test extends AndroidTestCase {

	private final static String TAG = "TestAsyncTask";
	public void create(){
		DBHelper helper = new DBHelper(getContext());
		helper.getWritableDatabase();
		Log.i(TAG, "success");
	}
	
	public void insert(){
		ContentResolver contentResolver = getContext().getContentResolver();
		Uri uri = Uri.parse("content://com.example.android_asynctask.UserProvider/user");
		ContentValues values = new ContentValues();
		values.put("name", "mark");
		values.put("address","上海");
		Uri uri2 = contentResolver.insert(uri, values);
		Log.i(TAG, uri2.toString());
	}
	
	public void query(){
		ContentResolver contentResolver = getContext().getContentResolver();
		Uri uri = Uri.parse("content://com.example.android_asynctask.UserProvider/user");
		Cursor cursor = contentResolver.query(uri, null, null, null, null);
		int columns = cursor.getColumnCount();
		while(cursor.moveToNext()){
			for(int i = 0 ; i < columns ; i++){
				String col_name = cursor.getColumnName(i);
				String col_value = cursor.getString(cursor.getColumnIndex(col_name));
				Log.i(TAG, "--------------->" + col_name);
				Log.i(TAG, "--------------->" + col_value);
			}
		}
	}
	public void updata(){
		ContentResolver contentResolver = getContext().getContentResolver();
		Uri uri = Uri.parse("content://com.example.android_asynctask.UserProvider/user/1");
		ContentValues values = new ContentValues();
		values.put("name", "lucy");
		int row = contentResolver.update(uri, values, null, null);
		Log.i(TAG, "**********************************"+row);
	}
	
	public void delete(){
		ContentResolver contentResolver = getContext().getContentResolver();
		Uri uri = Uri.parse("content://com.example.android_asynctask.UserProvider/user/2");
		int row = contentResolver.delete(uri, null,null);
		Log.i(TAG, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + row);
	}
}