update time:2019-1-22 author:要你命三千又三千 type:复习笔记
不同于文件存储和 SharedPreferences 存储中的两种全局可读写操作模式,内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。
使用方法
一.使用现有的内容提供器来读取和操作相应的程序中的数据
当一个应用程序通过内容提供器对其数据提供了外部访问接口,任何其他的应用程序就可以对这部分数据进行访问。
内容 URI:由两部分组成,权限(authority)和路径(path)。
举例:内容 URI 就变成了 com.example.app.provider/table1
还需要在字符串的头部加上协议声明
内容 URI 最标准的格式写法如下:
content://com.example.app.provider/table1
(协议://权限/路径)
Uri.parse()用于将字符串解析成Uri 对象
查询语句:
返回一个Cursor 对象。通过移动游标的位置来遍历Cursor 的行
if (cursor != null) {
while (cursor.moveToNext()) {
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}
增加:插入一行
ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);
更新数据
ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new
String[] {"text", "1"});
删除 数据
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });
package com.example.administrator.contactstest;
import android.app.Activity;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
ListView contactsView;
ArrayAdapter<String> adapter;
List<String> contactsList=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactsView=findViewById(R.id.contacts_view);
readContacts();
adapter=new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,contactsList);
contactsView.setAdapter(adapter);
}
private void readContacts(){
Cursor cursor=null;
try{
/**
* 为 什 么 没 有 调 用 Uri.parse() 方 法 去 解 析 一 个 内 容 URI 字 符 串 呢 ? 这 是 因 为
* ContactsContract.CommonDataKinds.Phone类已经帮我们做好了封装,提供了一个CONTENT_URI
* 常量,而这个常量就是使用 Uri.parse()方法解析出来的结果
*/
cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,null,null,null);
while(cursor.moveToNext()){
/**
* 联系人姓名这一列对应的常量是
* ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,联系人手机号这一列对应的常
* 量是 ContactsContract.CommonDataKinds.Phone.NUMBER。
*/
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();
}
}
}
授权管理
<uses-permission android:name="android.permission.READ_CONTACTS" />
问题补充:在读取联系人时,系统在AndroidMainfest.xml添加了读取联系人的授权了
出现了授权拒绝。
这里在手机上需要打开对此软件的许可授权。才能读取联系人。
创建内容提供器的步骤
一:实现contentProvider 类
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匹配器来匹配进行uri 查找
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)) {
//match()匹配路径,进行值的返回
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;
}
}
在AndroidMainfest.xml 中注册
<provider
android:name="com.example.databasetest.DatabaseProvider"
android:authorities="com.example.databasetest.provider" >
provider>