ContentProvider学习例程

ContentProvider总是需要与ContentResolver结合使用,它们之间的关系是:

Context提供了getContentResolver()方法,这个表示Activity、Service等组件都可通过getContentResolver()方法获取ContentResolver对象。

获取了ContentResolver对象之后,接下来就可以调用ContentResolver的query()、insert()、update()和delete()方法

——实际上指定Uri对应的ContentProvider的query()、insert()、update()和delete()

从mars视频学习的例程,主要是在数据库中增加和查询数据

CPActivity.java

public class CPActivity extends Activity {

	public Button queryButton = null;
	public Button insertButton = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		queryButton = (Button)findViewById(R.id.query);
		insertButton = (Button)findViewById(R.id.insert);
		queryButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Cursor c = getContentResolver().query(
						FirstProviderMetaData.UserTableMetaData.CONTENT_URI, null,
						null, null, null);
				while(c.moveToNext()){
					System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
				}

			}
		});
		insertButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				ContentValues values = new ContentValues();
				values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "zhangsan");
				Uri uri = getContentResolver().insert(FirstProviderMetaData.UserTableMetaData.CONTENT_URI, values);
				System.out.println("uri-->"+uri.toString());
			}
		});
		System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
	}
}

FirstContentProvider.java 重写ContentProvider类的query()、insert()方法

public class FirstContentProvider extends ContentProvider {

	public static final UriMatcher uriMatcher;//对URI的参数进行判断,是否符合标准,确定该ContentProvider实际能处理的URI
	public static final int INCOMING_USER_COLLECTION = 1;
	public static final int INCOMING_USER_SINGLE = 2;

	private DatabaseHelper dh;

	static {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(FirstProviderMetaData.AUTHORITY,"/users",INCOMING_USER_COLLECTION);
		uriMatcher.addURI(FirstProviderMetaData.AUTHORITY, "/users/#", INCOMING_USER_SINGLE);

	}

	public static HashMap<String,String> userProjectionMap;
	static{
		userProjectionMap = new HashMap<String,String>();
		userProjectionMap.put(UserTableMetaData._ID, UserTableMetaData._ID);
		userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
	}

	//是一个回调函数,在contentProvider创建的时候执行
	@Override
	public boolean onCreate() {
		//打开数据库
		dh = new DatabaseHelper(getContext(), FirstProviderMetaData.DATABASE_NAME);
		System.out.println("onCreate");
		return true;
	}

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

	//根据传入的URI,返回该URI所表示的数据类型
	@Override
	public String getType(Uri uri) {
		System.out.println("getType");
		switch(uriMatcher.match(uri)){
		case INCOMING_USER_COLLECTION:
			return UserTableMetaData.CONTENT_TYPE;
		case INCOMING_USER_SINGLE:
			return UserTableMetaData.CONTENT_TYPE_ITEM;
		default:
			throw new IllegalArgumentException("Unknown URI" + uri);
		}
	}

	/**
	 * 该函数的返回值是一个uri,这个uri表示的是刚刚使用这个函数所插入的数据
	 */
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		System.out.println("insert");
		SQLiteDatabase db = dh.getWritableDatabase();
		long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
		if(rowId > 0){
			Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
			//通知监听器,数据已经改变
			getContext().getContentResolver().notifyChange(insertedUserUri, null);
			return insertedUserUri;
		}
		throw new SQLException("Failed to insert row into" + uri);
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		switch(uriMatcher.match(uri)){
		case INCOMING_USER_COLLECTION:
			qb.setTables(UserTableMetaData.TABLE_NAME);
			qb.setProjectionMap(userProjectionMap);
			break;
		case INCOMING_USER_SINGLE:
			qb.setTables(UserTableMetaData.TABLE_NAME);
			qb.setProjectionMap(userProjectionMap);
			qb.appendWhere(UserTableMetaData._ID+"=" + uri.getPathSegments().get(1));
			break;
		}
		String orderBy;
		if(TextUtils.isEmpty(sortOrder)){
			orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
		}else{
			orderBy = sortOrder;
		}
		SQLiteDatabase db = dh.getWritableDatabase();
		Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
		c.setNotificationUri(getContext().getContentResolver(), uri);
		System.out.println("query");
			return c;
	}

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

}

FirstProviderMetaData.java  定义该ContentProvider的常量

public class FirstProviderMetaData {
	public static final String AUTHORITY = "com.mars.testcp.FirstContentProvider";
	public static final String DATABASE_NAME = "FirstProvider.db";
	public static final int DATABASE_VERSION = 1;
	public static final String USERS_TABLE_NAME = "users";

	//定义一个静态内部类 定义该ContentProvider所包含的数据列的列名
	public static final class UserTableMetaData implements BaseColumns{
		//表名
		public static final String TABLE_NAME = "users";
		//访问该ContentProvider的URI
		public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/users");
		//该ContentProvider所返回的数据类型的定义,参考帮助文档
		//整张表的数据
		public static final String CONTENT_TYPE = "vnd.android.cursor.dir/nvd.firstprovider.user";
		//表中的一条数据
		public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/nvd.firstprovider.user";
		//列名
		public static final String USER_NAME = "name";
		//默认的排序方法
		public static final String DEFAULT_SORT_ORDER = "_id desc";

	}

}

DatabaseHelper.java  创建数据库文件

public class DatabaseHelper extends SQLiteOpenHelper {

	private static final int VERSION  = 1;

	//在SQLiteOepnHelper的子类当中,必须有该构造函数
	public DatabaseHelper(Context context, String name, CursorFactory factory,
			int version) {
		//必须通过super调用父类当中的构造函数
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	public DatabaseHelper(Context context, String name) {
		this(context, name, VERSION);
		// TODO Auto-generated constructor stub
		}

	public DatabaseHelper(Context context,String name,int version){
		this(context,name,null,version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		System.out.println("create a Database");
		//execSQL函数用于执行SQL语句,创建一个表名为user,有两列数据id、name
		db.execSQL("create table "+ FirstProviderMetaData.USERS_TABLE_NAME
				+ "(" + FirstProviderMetaData.UserTableMetaData._ID
				+ " INTEGER PRIMARY KEY AUTOINCREMENT,"
				+ FirstProviderMetaData.UserTableMetaData.USER_NAME
				+ " varchar(20));");

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		System.out.println("update a Database");

	}

}

在AndroidManifest.xml文件注册该ContentProvider:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mars.testcp"
    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.mars.testcp.CPActivity"
            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.mars.testcp.FirstContentProvider"
           android:authorities="com.mars.testcp.FirstContentProvider" />
    </application>

</manifest>

结果示意图:

时间: 2024-10-05 23:51:54

ContentProvider学习例程的相关文章

ContentProvider学习小结

ContentProvider学习小结 对于Android的一个应用程序,数据存储操作是必不可少的.因此,Android系统提供了五种数据存储方式,分别是:SharedPreferences.SQLite.Content Provider.File和网络存储.由于Android系统中,数据基本都是私有的,一般存放在属于自己的“data/data/程序包名”目录下,要在不同的应用之间实现数据共享,常用的方式是使用Content Provider. SQLite: SQLite是一个轻量级的数据库,

ContentProvider学习笔记

一.什么ContentProvider 二.如何使用ContentProvider 三.沙场练兵-实例操练 四.深入理解ContentProvider原理 为什么使用ContentProvider可以实现跨进程的通讯,第一反应肯定是这货和binder有关,因为android中只有稍微跟跨进程搭上边的,必定想到binder. 下面就来分析ContentProvider是怎么一步一步利用binder实现跨进程通信的: 1.首先你得创建一个ContentProvider运行在进程A,如上篇博客 And

BroadcastReceive学习例程

BroadcastReceive是Android四大核心组件之一,本质上是一种全局的监听器,用于监听系统全局的广播消息. 它用于接收程序所发出的Broadcast Intent,程序启动它只需两步: (1)创建需要启动的ReceivecastReceiver的Intent (2)调用Context的sendBroadcast()或sendOrderedBroastcast()方法来启动指定的BroadcastReceiver 当应用程序发出一个Broadcast Intent之后,所有匹配该In

android ContentProvider学习

1.ContentProvider提供位存储或获取数据提供了统一的接口. 2.使用ContentProvider可以在不同的应用程序之间共享数据. 3.Android为常见的一些数据提供了ContentProvider(包括音频.视频.图片和通讯录等等). ContentProvider所提供的函数 1.query():查询 2.insert():插入 3.update():更新 4.delete():删除 5.getType():得到数据的类型 6.onCreate();创建时的回调函数 实现

android四大组件之ContentProvider(一)

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

步步为营_Android开发课[6]_ContentProvider学习

Focus on technology, enjoy life!-- QQ:804212028 浏览链接:http://blog.csdn.net/y18334702058/article/details/44624305 主题:ContentProvider学习 ContentProvider是什么 ContentProvider(内容提供者)是Android中的四大组件之一.主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过Con

tensorflow实现迁移学习

此例程出自<TensorFlow实战Google深度学习框架>6.5.2小节 卷积神经网络迁移学习. 数据集来自http://download.tensorflow.org/example_images/flower_photos.tgz ,及谷歌提供的Inception-v3模型https://storage.googleapis.com/download.tensorflow.org/models/inception_dec_2015.zip . 自行下载和解压. 解压后的文件夹包含5个子

Service-黑名单来电自动挂断

这只是一个学习例程,很多功能有待完善 允许用户动态加载手机通讯录中的电话号码,勾选某些号码作为黑名单,一旦将某些号码设为黑名单,当该号码自动挂断该号码 Android没有对外公开挂断电话的API,如果需要挂断电话,必须使用AIDL与电话管理Service进行通信,并调用服务中的API实现结束通话 为了调用远程的AIDL Service,需要上图所示的两个aidl文件 BlockMain.java  界面提供一个按钮让用户打开对话框来勾选黑名单. public class BlockMain ex

[读书笔记]了不起的node.js(三)

这周的nodejs学习内容为几个依赖包的使用,把书上的例子都敲了一遍.这篇就以例程为线索,复习一下一周的工作. 1.connect 这个例程主要是使用connect依赖包,connect提供一个中间件(由函数组成,与请求.响应对象交互)的功能.书中也介绍了connect内置其他的中间件,这些中间件起到组织代码完成web功能的作用. 2.session 使用connect进行用户会话,进行基本的登录系统.通过中间件实现了检查登录.展示表单.用户匹配.处理登出的功能.展示了中间件的强大和组织方式.