概述
ContentProvider作用
为存储和获取数据提供了统一的接口
实现了不用应用间的数据共享
Android为常用数据(如声音、图片、视频和通讯录等)提供的默认的ContentProvider支持
相关概念介绍
ContentProvider简介
为了实现向其他应用共享数据,需要继承一个抽象类ContentProvider,并实现如下几个抽象方法。
public class MyProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
}
看到这些抽象方法的参数是不是和数据库的相关操作很像。因此一般情况下,我们都是用数据库来存储数据。
Uri简介
概念:通用资源标示符(Uniform Resource Identifier)
组成部分:
scheme 访问资源的命名机制
authority 存放资源的主机名
path 资源自身的名称
格式:scheme://authority/path,其中authority还包括host的port。例如:
content://com.cydia.test:200/login/username
- content为scheme
- com.cydia.test:200为authority(com.cydia.test为host,200为port)
- login/username为path。
Sqlite简介
参考文章《Android中的数据库应用小结》
本应用内的provider构建
众所周知,ContentProvider是用来向其他应用共享本应用内的数据,因此,我们首先需要确定数据在本应用内的存储方式。而考虑到继承ContentProvider需要实现的抽象方法(与sqlite的操作方法太相似),我们使用sqlite来存储数据。
创建数据库: MySqliteHelper
public class MySqliteHelper extends SQLiteOpenHelper {
public static final String DB_NAME = "cydia.db";
public static final int DB_VERSION = 3;
public static final String TABLE_NAME = "bookstore";
public static final String COLUMN_ID = "id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_AUTHOR = "author";
public static final String COLUMN_PRICE = "price";
public static final String COLUMN_PAGES = "pages";
public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
COLUMN_ID + " integer primary key autoincrement," +
COLUMN_NAME + " text NOT NULL," +
COLUMN_AUTHOR + " text," +
COLUMN_PRICE + " real," +
COLUMN_PAGES + " integer)";
public MySqliteHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
创建数据管理类: DBManager
public class DBManager {
private volatile static DBManager sInstance;
private SQLiteDatabase db;
private DBManager(Context context) {
MySqliteHelper helper = new MySqliteHelper(context);
db = helper.getWritableDatabase();
}
public static DBManager getInstance(Context context) {
if (sInstance == null) {
synchronized (DBManager.class) {
if (sInstance == null) {
sInstance = new DBManager(context);
}
}
}
return sInstance;
}
public long add(ContentValues contentValues) {
return db.insert(MySqliteHelper.TABLE_NAME, null, contentValues);
}
public int delete(String whereClause, String[] whereArgs) {
return db.delete(MySqliteHelper.TABLE_NAME, whereClause, whereArgs);
}
public int update(ContentValues contentValues, String whereClause, String[] whereArgs) {
return db.update(MySqliteHelper.TABLE_NAME, contentValues, whereClause, whereArgs);
}
public Cursor query(String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy) {
return db.query(MySqliteHelper.TABLE_NAME, columns, selection,
selectionArgs, groupBy, having,
orderBy);
}
public void closeDB() {
db.close();
}
}
继承ContentProvider类
public class MyProvider extends ContentProvider {
private Context context;
private ContentResolver contentResolver;
private static final String AUTHORITY = "com.pptv.test";
private static final int ALL_BOOKS = 1;
private static final int SINGLE_BOOK = 1;
//匹配Uri
private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
//匹配Uri为content://com.pptv.test/bookstore 返回整数1
uriMatcher.addURI(AUTHORITY, MySqliteHelper.TABLE_NAME, ALL_BOOKS);
//匹配Uri为content://com.pptv.test/bookstore/# 返回整数2,注#为通配符
//如content://com.pptv.test/bookstore/1 就返回2
uriMatcher.addURI(AUTHORITY, MySqliteHelper.TABLE_NAME + "/#", SINGLE_BOOK);
}
@Override
public boolean onCreate() {
context = getContext();
contentResolver = context.getContentResolver();
return true;
}
@Nullable
@Override
public String getType(Uri uri) {
if (uriMatcher.match(uri) == ALL_BOOKS) {
return "vnd.android.cursor.dir/" + MySqliteHelper.TABLE_NAME;
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
return "vnd.android.cursor.item/" + MySqliteHelper.TABLE_NAME;
}
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
Uri ret = null;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//uri为 content://com.pptv.test/bookstore 可以执行插入操作
long id = DBManager.getInstance(context).add(values);
ret = ContentUris.withAppendedId(uri, id);
contentResolver.notifyChange(ret, null);
}
//content://com.pptv.test/bookstore/4 没有插入权限
return ret;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int id = 0;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//content://com.pptv.test/bookstore 删除满足条件的所有记录
id = DBManager.getInstance(context).delete(selection, selectionArgs);
contentResolver.notifyChange(uri, null);
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
//content://com.pptv.test/bookstore/4 删除id=4的记录
long deleted_id = ContentUris.parseId(uri);
id = DBManager.getInstance(context).delete(MySqliteHelper.COLUMN_ID + "=?",
new String[]{deleted_id +""});
contentResolver.notifyChange(uri, null);
}
return id;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int id = 0;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//content://com.pptv.test/bookstore 更新满足条件的所有记录
id = DBManager.getInstance(context).update(values, selection, selectionArgs);
contentResolver.notifyChange(uri, null);
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
//content://com.pptv.test/bookstore/4 更新id=4的记录
long update_id = ContentUris.parseId(uri);
id = DBManager.getInstance(context).update(values, MySqliteHelper.COLUMN_ID + "=?",
new String[]{update_id +""});
contentResolver.notifyChange(uri, null);
}
return id;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor cursor = null;
if (uriMatcher.match(uri) == ALL_BOOKS) {
//content://com.pptv.test/bookstore 查找满足条件的所有记录
cursor = DBManager.getInstance(context).query(projection, selection, selectionArgs,
null, null, sortOrder);
cursor.setNotificationUri(contentResolver, uri);
} else if(uriMatcher.match(uri) == SINGLE_BOOK) {
//content://com.pptv.test/bookstore/4 查找id=4的记录
long select_id = ContentUris.parseId(uri);
cursor = DBManager.getInstance(context).query(projection, MySqliteHelper.COLUMN_ID + "=?",
new String[]{select_id +""},
null, null, sortOrder);
cursor.setNotificationUri(contentResolver, uri);
}
return cursor;
}
}
UriMatcher的作用在于,控制不同Uri的操作权限以及操作内容。
比如上述code所示:content://com.pptv.test/bookstore 执行查找其返回所有符合条件的记录,而content://com.pptv.test/bookstore/4 执行查找方法,其仅仅返回id为4的记录
在AndroidManifest中注册provider
<provider
android:name=".provider.MyProvider"
android:authorities="com.pptv.test"
android:enabled="true"
android:exported="true" />
- android:authorities 访问这个provider的权限,需要和MyProvider中定义的AUTHORITY保持一致。
- android:enabled 指定这个内容提供器是否能够被系统安装
- android:exported 指定该内容提供器是否能够被其他的应用程序组件使用
其他应用使用Provider来访问数据
获取一个ContentResolver类
直接使用Content类的getContentResolver()方法就能获取到。
通过ContentResolver执行增删改查操作
ContentResolver的主要方法:
返回值 | 函数声明 |
---|---|
final Uri | insert(Uri url, ContentValues values) |
final int | delete(Uri url, String where, String[] selectionArgs) |
final int | update(Uri uri, ContentValues values, String where, String[] selectionArgs) |
final Cursor | query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) |
例如:查询所有的数据
private String getData(){
StringBuilder sb =new StringBuilder();
ContentResolver cr = this.getContentResolver();
Uri uri = Uri.parse("content://com.pptv.test/bookstore");
Cursor cursor = cr.query(uri, null, null,null,null);
if(cursor != null){
Log.i(TAG, "cursor != null");
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
float price = cursor.getFloat(cursor.getColumnIndex("price"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
sb.append("name = " + name + ", ")
.append("author = " + author + ", ")
.append("price = " + price + " ,")
.append("pages = " + pages + "n");
}
cursor.close();
}
return sb.toString();
}
最后
以上就是懵懂皮皮虾为你收集整理的Android中的ContentProvider小结的全部内容,希望文章能够帮你解决Android中的ContentProvider小结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复