android-关于ContentProvider的使用
来源:互联网 发布:六味地黄丸 知乎 编辑:程序博客网 时间:2024/06/07 12:10
ContentProvider是用于将数据共享给其他应用。例如在同一部手机里面,有两个APP,第一个APP要访问第二个APP的数据。此时,第二个APP就需要设置ContentProvider。这样,第一个APP就能通过Uri访问第二个APP的数据。
第二部手机的设置,首先需要一个类来继承ContentProvider这个类,继承后需要实现onCreate,query,getType,insert,delete,update这个几个方法,如其名,其作用是给第一个APP调用的,至于第一个APP是如何调用的,下面会提到。
给出一个继承ContentProvider的例子:
1.先是提供的数据类型等数据的类。
package org.juetion.cp;import android.net.Uri;import android.provider.BaseColumns;/** * 提供的数据类型等数据。 * Created by juetionke on 13-12-21. */public class MyProviderMetaData { public static final String AUTHORIY = "org.juetion.cp.MyContentProvider"; /** * 数据库名称 */ public static final String DATABASE_NAME = "MyProvider.db"; /** * 数据库版本 */ public static final int DATABASE_VERSION = 1; /** * 表名 */ public static final String USERS_TABLE_NAME = "users"; /** * 继承了BaseColumns,所以已经有了_ID */ 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://" + AUTHORIY + "/users"); /** * 该ContentProvider所返回的数据类型定义 */ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/org.juetion.user"; public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/org.juetion.user"; /** * 列名 */ public static final String USER_NAME = "name"; public static final String USER_AGE = "age"; /** * 默认的排序方法 */ public static final String DEFAULT_SORT_ORDER = "_id desc"; }}
2,继承ContentProvider的类:
package org.juetion.cp;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.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;import android.text.TextUtils;import android.util.Log;import org.juetion.sqlite3.DatabaseHelper;import java.util.HashMap;/** * Created by juetionke on 13-12-21. */public class MyContentProvider extends ContentProvider { /** * 定义规则 */ public static final UriMatcher uriMatcher; public static final int USERS_COLLECTION = 1;//用于标记 public static final int USERS_SINGLE = 2;//用于标记 private DatabaseHelper databaseHelper;//这里的数据共享是共享Sqlite里的数据,当然,可以试用其他,如文本数据共享。 static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);//试用一个没有规则的Uri。然后下面自己匹配。 uriMatcher.addURI(MyProviderMetaData.AUTHORIY,"/users",USERS_COLLECTION);//自己定义的规则,有点像路由器,是uri匹配的方案。 uriMatcher.addURI(MyProviderMetaData.AUTHORIY,"/users/#",USERS_SINGLE);//同上。 } /** * 为列定义别名 */ public static HashMap<String,String> usersMap; static { usersMap = new HashMap<String, String>(); usersMap.put(MyProviderMetaData.UserTableMetaData._ID, MyProviderMetaData.UserTableMetaData._ID); usersMap.put(MyProviderMetaData.UserTableMetaData.USER_NAME, MyProviderMetaData.UserTableMetaData.USER_NAME); usersMap.put(MyProviderMetaData.UserTableMetaData.USER_AGE, MyProviderMetaData.UserTableMetaData.USER_AGE); } @Override public boolean onCreate() { Log.i("juetion","onCreate"); databaseHelper = new DatabaseHelper(getContext(), MyProviderMetaData.DATABASE_NAME);//这里的实现,常见前篇关于Sqlite的文章。 return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.i("juetion","query"); SQLiteQueryBuilder sqLiteQueryBuilder = new SQLiteQueryBuilder();//写入查询条件,有点像Hibernate。 switch (uriMatcher.match(uri)) {//判断查询的是单个数据还是多个数据。 case USERS_SINGLE: sqLiteQueryBuilder.setTables(MyProviderMetaData.UserTableMetaData.TABLE_NAME);//需要查询的表 sqLiteQueryBuilder.setProjectionMap(usersMap);//列的别名定义 sqLiteQueryBuilder.appendWhere(MyProviderMetaData.UserTableMetaData._ID + "=" + uri.getPathSegments().get(1)); //查询条件,uri.getPathSegments().get(1),getPathSegments是将内容根据/划分成list。 break; case USERS_COLLECTION: sqLiteQueryBuilder.setTables(MyProviderMetaData.UserTableMetaData.TABLE_NAME); sqLiteQueryBuilder.setProjectionMap(usersMap); break; } String orderBy;//判断sortOrder是否为空,加入默认。 if (TextUtils.isEmpty(sortOrder)) { orderBy = MyProviderMetaData.UserTableMetaData.DEFAULT_SORT_ORDER; } else { orderBy = sortOrder; } SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase(); Cursor cursor = sqLiteQueryBuilder.query(sqLiteDatabase, projection, selection, selectionArgs, null, null, sortOrder);//可以使用下面的方法,不过此时sqLiteDatabase将会没有用。 //Cursor cursor = sqLiteDatabase.query(MyProviderMetaData.UserTableMetaData.TABLE_NAME, projection, selection, selectionArgs, null, null, orderBy); cursor.setNotificationUri(getContext().getContentResolver(),uri); return cursor; } /** * 根据传入的URI,返回URI说表示的数据类型 * @param uri * @return */ @Override public String getType(Uri uri) { Log.i("juetion","getType"); switch (uriMatcher.match(uri)) {//匹配uri的规则 case USERS_COLLECTION: return MyProviderMetaData.UserTableMetaData.CONTENT_TYPE; case USERS_SINGLE: return MyProviderMetaData.UserTableMetaData.CONTENT_TYPE_ITEM; default: throw new IllegalArgumentException("Unknown URI" + uri); } } @Override public Uri insert(Uri uri, ContentValues values) { Log.i("juetion","insert"); SQLiteDatabase sqLiteDatabase = databaseHelper.getWritableDatabase(); long rowId = sqLiteDatabase.insert(MyProviderMetaData.UserTableMetaData.TABLE_NAME, null, values); if (rowId > 0) { Uri insertUserUri = ContentUris.withAppendedId(MyProviderMetaData.UserTableMetaData.CONTENT_URI, rowId);//简单来说就是字符串拼凑一下。只不过是uri专用的。 //通知监听器 getContext().getContentResolver().notifyChange(insertUserUri,null); return insertUserUri; }else throw new IllegalArgumentException("Failed to insert row into" + uri); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { Log.i("juetion","delete"); return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.i("juetion","update"); return 0; }}
这两个类里面都有的对应的注释,都能看懂吧?
还有重要的一点,再第二个APP的AndroidManifest.xml里面需要添加
<!-- provider name填写ContentProvider那个类的全称,authorities填写MyProviderMetaData里的AUTHORIY --> <provider android:authorities="org.juetion.cp.MyContentProvider" android:name="org.juetion.cp.MyContentProvider"/>
以上代码都是在第二个APP里面的。
--------我是可爱的分界线------------
以下代码是在第一个APP里面的。
关于使用。只需要将uri的string提供给第一个APP。
例如在第一个APP的Activity调用数据插入:
ContentValues contentValues = new ContentValues(); contentValues.put("name","zhangsan"); contentValues.put("age",19); Uri uri = getContentResolver().insert(Uri.parse("content://org.juetion.cp.MyContentProvider/users"),contentValues); Log.i("juetion", "insert uri-->" + uri.toString());
例如在第一个APP的Activity调用数据的查询:
Cursor cursor = getContentResolver().query(Uri.parse("content://org.juetion.cp.MyContentProvider/users"), new String[]{"name", "age"}, null, null, null); while (cursor.moveToNext()) { Log.i("juetion", cursor.getString(cursor.getColumnIndex("name"))); }
正如上面的例子,使用的时候是在Activity里面调用getContentResolver()的。
代码下载链接:http://download.csdn.net/detail/juetion/6752125
今月今日的学习温故到此结束了,谢谢观看。
3 0
- android-关于ContentProvider的使用
- 关于android中自定义contentprovider的使用
- 关于android的contentProvider
- 关于ContentProvider的使用
- Android ContentProvider的使用
- 【Android】ContentProvider的使用
- Android ContentProvider的使用
- android ContentProvider的使用
- android ContentProvider的使用
- android--ContentProvider的使用
- Android ContentProvider的使用
- Android中ContentProvider的使用
- Android 总结:ContentProvider 的使用
- Android ContentProvider的基本使用
- Android 总结:ContentProvider 的使用
- Android ContentProvider 的简单使用
- android 关于ContentProvider的一些知识
- android学习 关于contentprovider
- ReadPwd读windows内存中明文密码
- 抽象类及其用法
- HQL: Hibernate查询语言
- 恒大竟然被绝杀了
- Mat::create
- android-关于ContentProvider的使用
- 上周软件大会
- 长这么大,还是第一次有人这么夸我
- poj 1258
- ReadPwd读windows内存中明文密码
- 如何进行高效记忆
- 你这个机智的家伙
- mysql常用的函数
- RHEL6系统rpm方式安装MySQL数据库