欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

安卓学习 之 ContentResolver内容提供者(七)

程序员文章站 2024-02-09 18:02:10
...

简介

Android持久化技术一章中所保存的数据都只能在当前应用程序中访问,但跨程序数据共享是由Content Provider提供的,譬如说:电话薄、短信、媒体库中的信息。

一、基本用法

  1. 构建内容URI对象,com.example.app是包名,table是表名,将内容URI字符串解析成URI对象.
Uri uri = Uri.parse("content://com.example.app.provider/table1")
  1. 利用如下的方法进行查询,查询完之后为cursor对象.
Cursor cursor = getContentResolver().query( uri,
projection, selection, selectionArgs, sortOrder);
query()方法参数 对应SQL 部分 描述
uri from table_name 指定查询某个应用程序下的某一张表
projection select column1, column2 指定查询的列名
selection where column = value 指定 where 的约束条件
selectionArgs - 为 where 中的占位符提供具体的值
orderBy order by column1, column2 指定查询结果的排序方式
  1. 利用如下代码将cursor对象的值一条条读出来。
if (cursor != null) {
    while (cursor.moveToNext()) {
        String column1 = cursor.getString(cursor.getColumnIndex("column1")); 
        int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
    }
    cursor.close();
}
  1. 增删改(本质一样,就是用法稍微有点区别)
//添加一条("text",1)的数据
ContentValues values = new ContentValues(); 
values.put("column1", "text"); 
values.put("column2", 1); 
getContentResolver().insert(uri, values);

//将("text",1)数据的第一列设置为
ContentValues values = new ContentValues(); 
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[] {"text", "1"});

//将第二列为1的数据删除
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });

应用(读取系统联系人)

private void readContacts() { 
    Cursor cursor = null;
    try {
        // 查询联系人数据
        cursor = getContentResolver().query( 
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
        while (cursor.moveToNext()) {
            // 获取联系人姓名
            String displayName = cursor.getString(cursor.getColumnIndex( ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            // 获取联系人手机号
            String number = cursor.getString(cursor.getColumnIndex(
            ContactsContract.CommonDataKinds.Phone.NUMBER));
            contactsList.add(displayName + "\n" + number);
        }
    } catch (Exception e) { 
        e.printStackTrace();
    } finally {
    if (cursor != null) { cursor.close();
    }
}

然后设置ArrayAdapter把数据渲染到ListView中,这里就不展示了。

二、创建内容提供者

1.新建类继承自ContentProvider类,该类中有6个抽象方法,复写六个方法。

  • OnCreate():初始化内容提供器、完成数据库创建和升级等,存在Content Resolver时调用;
  • query():在内容提供器中查询数据,使用uri参数来确定是那张表,每个参数代表不同意思;
  • insert()项内容提供器添加一条数据,根据uri和values来完成添加;
  • update()更新数据;
  • delete()删除数据;
  • getType()根据传入URI来返回相应的MIME类型。

URI具体可以这样写:

  1. *:表示匹配任意长度的任意字符
  2. #:表示匹配任意长度的数字

2.借助URIMatcher来实现匹配内容URI的功能,而且URIMatcher提供了一个addURI方法,并将authority、path和自定义代码传入。

static {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR); 
    uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM); 
    uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM); 
    uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM);
}

3.复写query方法,利用UriMathcer的match()方法对传入URI进行匹配,得到相应的数据。UriMathcer的match()的输出是2步的自定义代码,代表的是表中的哪一列。

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
   switch (uriMatcher.match(uri)) { 
       case TABLE1_DIR:
           // 查询table1表中的所有数据
           break;
       case TABLE1_ITEM:
           // 查询table1表中的单条数据
           break;
       case TABLE2_DIR:
           // 查询table2表中的所有数据
           break;
       case TABLE2_ITEM:
           // 查询table2表中的单条数据
           break; 
       default:
           break;
   }
}

4.getType()方法用于获取Uri对象所对应的MIME类型。它是所有的内容提供器都必须提供的一个方法,用于获取 Uri 对象所对应的 MIME 类型。MIME格式如下:

  1. 必须以 vnd 开头。
  2. 如果内容 URI 以路径结尾,则后接 android.cursor.dir/,如果内容 URI 以 id 结尾, 则后接 android.cursor.item/。
  3. 最后接上 vnd..
#对于content://com.example.app.provider/table1 
vnd.android.cursor.dir/vnd.com.example.app.provider.table1

#对于 content://com.example.app.provider/table1/1 
vnd.android.cursor.item/vnd. com.example.app.provider.table1

应用(创建Book和Category的内容提供者)

public class DatabaseProvider extends ContentProvider {
		public static final int BOOK_DIR = 0;
		public static final int BOOK_ITEM = 1;
		public static final int CATEGORY_DIR = 2;
		public static final int CATEGORY_ITEM = 3;
		public static final String AUTHORITY = "com.example.databasetest.provider";
		private static UriMatcher uriMatcher;
		private MyDatabaseHelper dbHelper;

		static {
			uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
			uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
			uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
			uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);
			uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);
		}

		@Override
		public boolean onCreate() {
			dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
			return true;
		}

		@Override
		public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
			// 查询数据
			SQLiteDatabase db = dbHelper.getReadableDatabase();
			Cursor cursor = null;
			switch (uriMatcher.match(uri)) {
			case BOOK_DIR:
				cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
				break;
			case BOOK_ITEM:
				String bookId = uri.getPathSegments().get(1);
				cursor = db.query("Book", projection, "id = ?", new String[] { bookId }, null, null, sortOrder);
				break;
			case CATEGORY_DIR:
				cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
				break;
			case CATEGORY_ITEM:
				String categoryId = uri.getPathSegments().get(1);
				cursor = db.query("Category", projection, "id = ?", new String[] { categoryId }, null, null, sortOrder);
				break;
			default:
				break;
			}
			return cursor;
		}

		@Override
		public Uri insert(Uri uri, ContentValues values) {

			// 添加数据
			SQLiteDatabase db = dbHelper.getWritableDatabase();
			Uri uriReturn = null;
			switch (uriMatcher.match(uri)) {
			case BOOK_DIR:
			case BOOK_ITEM:
				long newBookId = db.insert("Book", null, values);
				uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
				break;
			case CATEGORY_DIR:
			case CATEGORY_ITEM:
				long newCategoryId = db.insert("Category", null, values);
				uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId);
				break;
			default:
				break;
			}
			return uriReturn;
		}

		@Override
		public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
			// 更新数据
			SQLiteDatabase db = dbHelper.getWritableDatabase();
			int updatedRows = 0;
			switch (uriMatcher.match(uri)) {
			case BOOK_DIR:
				updatedRows = db.update("Book", values, selection, selectionArgs);
				break;
			case BOOK_ITEM:
				String bookId = uri.getPathSegments().get(1);
				updatedRows = db.update("Book", values, "id = ?", new String[] { bookId });
				break;
			case CATEGORY_DIR:
				updatedRows = db.update("Category", values, selection, selectionArgs);

				break;
			case CATEGORY_ITEM:
				String categoryId = uri.getPathSegments().get(1);
				updatedRows = db.update("Category", values, "id = ?", new String[] { categoryId });
				break;
			default:
				break;
			}
			return updatedRows;
		}

		@Override
		public int delete(Uri uri, String selection, String[] selectionArgs) {
			// 删除数据
			SQLiteDatabase db = dbHelper.getWritableDatabase();
			int deletedRows = 0;
			switch (uriMatcher.match(uri)) {
			case BOOK_DIR:
				deletedRows = db.delete("Book", selection, selectionArgs);
				break;
			case BOOK_ITEM:
				String bookId = uri.getPathSegments().get(1);
				deletedRows = db.delete("Book", "id = ?", new String[] { bookId });
				break;
			case CATEGORY_DIR:
				deletedRows = db.delete("Category", selection, selectionArgs);
				break;
			case CATEGORY_ITEM:
				String categoryId = uri.getPathSegments().get(1);
				deletedRows = db.delete("Category", "id = ?", new String[] { categoryId });
				break;
			default:
				break;
			}
			return deletedRows;
		}

		@Override
		public String getType(Uri uri) {
			switch (uriMatcher.match(uri)) {
			case BOOK_DIR:
				return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.book";
			case BOOK_ITEM:
				return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.book";
			case CATEGORY_DIR:
				return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.category";
			case CATEGORY_ITEM:
				return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.category";
			}
			return null;
		}

	}