Content Provider

1、ContentProvider是什么?

ContentProvider在android中的作用是对外共享数据,你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对你应用中的数据进行添删改查。

 2、ContentResolver是什么?

当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,来操作数据。

3、Uri是什么?

Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,2.对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:
       1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://。
       2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
       3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
•         要操作contact表中id为10的记录,可以构建这样的路径:/contact/10
•         要操作contact表中id为10的记录的name字段, contact/10/name
•         要操作contact表中的所有记录,可以构建这样的路径:/contact

A : 是一个前缀,表示是由ContentProvider提供,固定不变

B : authority, 标识是哪个Provider,不同的Provider此部分必须不同。

C : 对应于哪张表 student

D : id对应表中的哪条记录

------------------------小案例开始————————————————

1、AndroidManifest.xml(在该文件中填入provider组件,主要是看红色部分)

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.l09_contentprovider.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>

        <provider
            android:name="com.example.l09_contentprovider.MyContentProvider"
            android:authorities="com.example.l09_contentprovider.mycontentprovider"
            android:exported="true" >
        </provider>
    </application>

</manifest>

接下来是案例的布局文件(很简单就4个button)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="insert"
        android:text="insert" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="deleteById"
        android:text="deleteById" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="deleteByColumn"
        android:text="deleteByColumn" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="updateById"
        android:text="updateById" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="updateByColumn"
        android:text="updateByColumn" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="queryAll"
        android:text="queryAll" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="queryById"
        android:text="queryById" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="queryByColumn"
        android:text="queryByColumn" />

</LinearLayout>


接下来是DBHelper.java(这个类是创建数据库,数据表,并且初始化一些数据的准备工作的)

package com.example.contentprovider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {
	public DBHelper(Context context) {
		//初始化创建数据库
		super(context, "atguigu.db", null, 1);
	}
	/*
	 * 第一次链接数据库,如果数据库文件未创建,系统自动创建数据库文件, 
	 * onCreate方法就会自动调用,并且只调用一次
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		//创建数据表,并且添加三条数据
		 db.execSQL("create table student(_id integer primary key autoincrement,name,sex)");
		 db.execSQL("insert into student(name,sex)values('Tom1','nan')");
		 db.execSQL("insert into student(name,sex)values('Tom2','nv')");
		 db.execSQL("insert into student(name,sex)values('Tom3','nan')");
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}
}


MyContentProvider.java

package com.example.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;
import android.util.Log;

public class MyContentProvider extends ContentProvider {
	private static final String AUTHORITY = "com.example.contentprovider.MyContentProvider";
	private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

	static {
		// content://com.example.l09_contentprovider.mycontentprovider/student
		// 不带记录
		uriMatcher.addURI(AUTHORITY, "student", 2);
		// content://com.example.l09_contentprovider.mycontentprovider/student/3
		// 带记录的
		uriMatcher.addURI(AUTHORITY, "student/#", 3);
	}

	public MyContentProvider() {
		Log.e("TAG", "provider MyContentProvider() ");
	}

	private DBHelper dbHelper;

	@Override
	public boolean onCreate() {
		dbHelper = new DBHelper(getContext());
		return true;
	}

	// insert方法中发送插入改变的通知,通知所有监听在此URL上
	private static final Uri URI = Uri
			.parse("content://com.example.contentprovider.MyContentProvider/student");

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// 获取标示
		int code = uriMatcher.match(uri);
		// 获取数据库链接
		SQLiteDatabase database = null;
		if (code == 2) {
			database = dbHelper.getReadableDatabase();
			// 指定列为空
			long id = database.insert("student", null, values);
			/*
			 * 解析uri的工具类--添加id到指定的uri中 生成当前记录的uri---重新赋值
			 */
			uri = ContentUris.withAppendedId(uri, id);
			database.close();

			getContext().getContentResolver().notifyChange(URI, null);// 通知所有监视在URI上
		} else {
			database.close();
			throw new RuntimeException("uri格式不对");
		}
		// 返回传递过来的uri
		return uri;
	}

	@Override
	public String getType(Uri uri) {
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// 标示
		int code = uriMatcher.match(uri);
		int deleteCount = -1;
		// 获取链接
		SQLiteDatabase database = dbHelper.getReadableDatabase();
		// 不是根据id删除
		if (code == 2) {
			deleteCount = database.delete("student", selection, selectionArgs);
			
			// 根据id删除
		} else if (code == 3) {
			long id = ContentUris.parseId(uri);

			deleteCount = database.delete("student", "_id=" + id, null);
		} else {
			throw new RuntimeException("uri格式不正确");
		}
		return deleteCount;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// 匹配uri, 得到标识code
		int code = uriMatcher.match(uri);
		SQLiteDatabase database = dbHelper.getReadableDatabase();
		Cursor cursor = null;
		if (code == 2) {
			// 不是根据id查询
			cursor = database.query("student", projection, selection,
					selectionArgs, null, null, sortOrder);
		} else if (code == 3) {
			// 是根据id查询
			long id = ContentUris.parseId(uri);

			cursor = database.query("student", projection, "_id=" + id, null,
					null, null, null);
		} else {
			throw new RuntimeException("uri格式不正确");
		}
		// 如果数据库链接关闭不能获取数据
		// database.close();
		return cursor;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int updateCount = -1;
		// 匹配uri, 得到标识code
		int code = uriMatcher.match(uri);
		// 得到数据库连接
		SQLiteDatabase database = dbHelper.getReadableDatabase();
		if (code == 2) {
			// 不是根据id更新
			updateCount = database.update("student", values, selection,
					selectionArgs);
		} else if (code == 3) {
			// 是根据id更新
			long id = ContentUris.parseId(uri);
			updateCount = database.update("student", values, "_id=" + id, null);
		} else {// 其它的都不是
			throw new RuntimeException("uri格式不正确");
		}
		database.close();
		return updateCount;
	}
}


MainActivity.java

package com.example.contentprovider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {

	//定义一个内容监听者,用来监听数据改变
	private ContentObserver observer = new ContentObserver(null) {
		public void onChange(boolean selfChange) {
			// 说明数据有改变,重新查询一直所有记录
			Uri uri = Uri
					.parse("content://com.example.contentprovider.MyContentProvider/student");
			Cursor cursor = contentResolver.query(uri, null, null, null, null);
			Log.e("TAG", "onChange()  count=" + cursor.getCount());
		};

	};

	//ContentResolver是通过URI来查询ContentProvider中提供的数据
	private ContentResolver contentResolver;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//加载布局文件
		setContentView(R.layout.activity_main);
		//创建ContentResolver
		contentResolver = this.getContentResolver();

		// 注册内容观察者
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider");

		// notifyForDescendents 是否模糊匹配, true: 不精确, 匹配当前路径级其子路径
		contentResolver.registerContentObserver(uri, true, observer);
	}

	/**
	 * 通过contentResover 调用contentProvider来执行方法
	 */
	public void insert(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student");
		// 准备要插入的数据
		ContentValues values = new ContentValues();
		values.put("name", "Tom4");
		values.put("sex", "nv");
		// 指定向表插入数据
		Uri uri2 = contentResolver.insert(uri, values);
		// 插入完毕进行土司提示
		Log.e("TAG", uri2.toString());
	}

	/**09-15 13:40:22.980: E/AndroidRuntime(10824): Caused by: java.lang.IllegalArgumentException: Too many bind arguments.  1 arguments were provided but the statement needs 0 arguments.

	 * 通过contentResover 调用contentProvider来执行删除方法 通过id来进行删除
	 */
	public void deleteById(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student/1");
		int deleteCount = contentResolver.delete(uri, null, null);
		Log.e("TAG", "deleteCount" + deleteCount);
		
	}
	public void deleteByColumn(View view) {
		Uri uri = Uri  
				.parse("content://com.example.contentprovider.MyContentProvider/student");
		int deleteCount1 = contentResolver.delete(uri, "name=?", new String[]{"Tom2"});
		Log.e("TAG", "deleteCount" + deleteCount1);
	}

	/**
	 * 通过contentResover 调用contentProvider来执行查询方法
	 */
	public void queryAll(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student");
		Cursor cursor = contentResolver.query(uri, null, null, null, null);
		while (cursor.moveToNext()) {
			int id = cursor.getInt(cursor.getColumnIndex("_id"));
			String name = cursor.getString(cursor.getColumnIndex("name"));
			Log.e("TAG", ""+(cursor.getColumnIndex("name")));//1
			Log.e("TAG", ""+(cursor.getColumnIndex("_id")));//0
			Log.e("TAG", ""+(cursor.getColumnIndex("sex")));//0
		}
		Log.e("TAG", "count:" + cursor.getCount());
		cursor.close();
	}

	public void queryById(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student/3");
		Cursor cursor = contentResolver.query(uri, new String[]{"_id","name","sex"}, null, null, null);
		while (cursor.moveToNext()) {
			int id = cursor.getInt(cursor.getColumnIndex("_id"));//???
			String name = cursor.getString(cursor.getColumnIndex("name"));
			String sex = cursor.getString(cursor.getColumnIndex("sex"));
			Log.e("TAG", id + "" + name+""+sex);
		}
		Log.e("TAG", "count:" + cursor.getCount());
		cursor.close();
	}
	
	public void queryByColumn(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student");
		Cursor cursor = contentResolver.query(uri, null, "name=?", new String[]{"Tom3"}, null);
		while (cursor.moveToNext()) {
			int id = cursor.getInt(cursor.getColumnIndex("_id"));//???
			String name = cursor.getString(cursor.getColumnIndex("name"));
			String sex = cursor.getString(cursor.getColumnIndex("sex"));
			Log.e("TAG", "" + name);
			Log.e("TAG", ""+id);
			Log.e("TAG", ""+sex);
		}
		Log.e("TAG", "count:" + cursor.getCount());
		cursor.close();
	}
	
	
	
	
	/**
	 * 通过contentResover 调用contentProvider来执行更新方法 通过id来进行更新
	 */
	public void updateById(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student/3");
		ContentValues values = new ContentValues();
		values.put("name", "wyf");
		int updateCount = contentResolver.update(uri, values, null, null);
		Log.e("TAG", "updateCount=" + updateCount);
	}

	/**
	 * 通过contentResover 调用contentProvider来执行更新方法 不通过id来进行更新
	 * 或者下面的方法
	 */
	public void updateByColumn(View view) {
		Uri uri = Uri
				.parse("content://com.example.contentprovider.MyContentProvider/student");
		ContentValues values = new ContentValues();
		values.put("name", "zrj");
		int updateCount = contentResolver.update(uri, values, "name=?",
				new String[] { "wyf" });
		Log.e("TAG", "updateCount=" + updateCount);
	}
}




你可能感兴趣的:(Content Provider)