用于在不同的应用程序之间实现数据共享的功能
内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序中的数据,另一种是创建自己的内容提供器给我们程序的数据提供外部访问接口
ContentResolver的基本用法
ContentResolver 中提供了一系列的方法用于对数据进行CRUD操作,其中insert()方法用于添加数据, update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据。
解析内容URI最标准的格式写法 :
Uri uri = Uri.parse("content://com.example.app.provider/table1")
查询数据
可以使用这个Uri对象来查询tablet表中的数据
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
查询完成后返回的仍然是一个Cursor对象,这时我们就可以将数据从Cursor对象中逐个读取出来了。读取的思路仍然是通过移动游标的位置来遍历Cursor的所有行,然后再取出每一行中相应列的数据
if (cursor != null) {
while (cursor.moveToNext()) (
String columnl = cursor.getString(cursor.getColumnIndex("columnl")); int column2 = cursor.getInt(cursor.getColumnIndex("column?"));
}
cursor.close();
}
添加一条数据
Contentvalues values = new Contentvalues();
values.put("columnl", "text");
values.put("column?", 1);
getContentResolver().insert(uri, values);
Contentvalues values = new Contentvalues();
values.put("columnl","");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String!] {''text", "1"});
删除数据
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });
读取联系人
布局添加LisvView用于显示联系人信息
<ListView
android:id="@+id/seven_contacts_view"
android:layout_width="match_parent"
android:layout_height="300dp">
</ListView>
主代码:
public class SevenActivity extends BaseActivity {
ArrayAdapter<String> adapter;
List<String> contactsList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seven);
ListView contactsView = (ListView) findViewById(R.id.seven_contacts_view);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
contactsView.setAdapter(adapter);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1);
} else {
readContacts();
}
}
private void readContacts() {
Cursor cursor = null;
try {
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cursor != 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);
}
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readContacts();
} else {
Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
}
添加权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
创建自己的内容提供器
新建一个类去继承Contentprovider的方式来创建一个自己的内容提供器。 Contentprovider类中有6个抽象方法,我们在使用子类继承它的时候,需要将这6个方法全 部重写
public class MyProder extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
}
onCreate()
初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,返回true 表示内容提供器初始化成功,返回false则表示失败。注意,只有当存在ContentResolver尝试 访问我们程序中的数据时,内容提供器才会被初始化。
query()
从内容提供器中查询数据。使用uri参数来确定查询哪张表,projection参数用于确定查 询哪些列,selection和selectionArgs参数用于约束查询哪些行,sortOrder参数用于对结 果进行排序,查询的结果存放在Cursor对象中返回。
insert()
向内容提供器中添加一条数据。使用uri参数来确定要添加到的表,待添加的数据保存在 values参数中。添加完成后,返回一个用于表示这条新记录的URI。
update()
更新内容提供器中已有的数据。使用uri参数来确定更新哪一张表中的数据,新数据保存在 values参数中,selection和selectionArgs参数用于约束更新哪些行,受影响的行数将作 为返回值返回。
delete()
从内容提供器中删除数据。使用uri参数来确定删除哪一张表中的数据,selection和 selectionArgs参数用于约束删除哪些行,被删除的行数将作为返回值返回。
getType()
根据传入的内容URI来返回相应的MIME类型。
可以看到,几乎每一个方法都会带有Uri这个参数,这个参数也正是调用ContentResolver 的增删改查方法时传递过来的。而现在,我们需要对传入的Uri参数进行解析,从中分析出调用 方期望访问的表和数据。
在AS中新建:
Exported属性表示是否允许外部程序访问我们的内容提供器, Enabled属性表示是否启用这个内容提供器
它也会在AndroidManiFest.xml中注册:
<provider
android:name=".DatabaseProvider"
android:authorities="com.example.databasetest.provider"
android:enabled="true"
android:exported="true">
</provider>
修改主代码:
public class MyContentProvider 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.myapplication.provider";
private static UriMatcher uriMatcher;
private SixthMyDataHelper 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);
}
public MyContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int deleteRaws = 0;
switch (uriMatcher.match(uri))
{
case BOOK_DIR:
{
deleteRaws = db.delete("Book", selection, selectionArgs);
}break;
case BOOK_ITEM:
{
String bookId = uri.getPathSegments().get(1);
deleteRaws = db.delete("Book", "id = ?", new String[]{bookId});
}break;
case CATEGORY_DIR:
{
String categoryId = uri.getPathSegments().get(1);
deleteRaws = db.delete("Category", "id = ?", new String[]{categoryId});
}break;
case CATEGORY_ITEM:
{
deleteRaws = db.delete("Category", selection, selectionArgs);
}break;
default:
break;
}
return deleteRaws;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)){
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.com.example.myapplication.provider.book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd.com.example.myapplication.provider.book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd.com.example.myapplication.provider.category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd.com.example.myapplication.provider.category";
}
return null;
}
@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 boolean onCreate() {
dbHelper = new SixthMyDataHelper(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 bookItem = uri.getPathSegments().get(1);
cursor = db.query("Book", projection, "id = ?", new String[]{bookItem}, null, null, sortOrder);
}break;
case CATEGORY_DIR:
{
cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
}break;
case CATEGORY_ITEM:
{
String categoryItem = uri.getPathSegments().get(1);
cursor = db.query("Category", projection, "id = ?", new String[]{categoryItem}, null, null, sortOrder);
}break;
default:
break;
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
int updateRaws = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR: {
updateRaws = db.update("Book", values, selection, selectionArgs);
}
break;
case BOOK_ITEM: {
String bookItem = uri.getPathSegments().get(1);
updateRaws = db.update("Book", values, "id = ?", new String[]{bookItem});
}
break;
case CATEGORY_DIR: {
updateRaws = db.update("Category", values, selection, selectionArgs);
}
break;
case CATEGORY_ITEM: {
String categoryItem = uri.getPathSegments().get(1);
updateRaws = db.update("Category", values, "id = ?", new String[]{categoryItem});
}
break;
default:
break;
}
return updateRaws;
}
}
添加按钮
<Button
android:id="@+id/seven_add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="在Book表中添加数据"/>
<Button
android:id="@+id/seven_query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="在Book表中查询数据"/>
<Button
android:id="@+id/seven_updata_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="在Book表中更新数据"/>
<Button
android:id="@+id/seven_delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="在Book表中删除数据"/>
修改主活动:
public class SevenActivity extends BaseActivity {
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seven);
Button addData = (Button)findViewById(R.id.seven_add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.myapplication.provider/book");
ContentValues values = new ContentValues();
values.put("name","A Clash of Kings");
values.put("author","George Martin");
values.put("pages",1040);
values.put("price",55.55);
Uri newUri = getContentResolver().insert(uri,values);
newId = newUri.getPathSegments().get(1);
}
});
Button queryData = (Button)findViewById(R.id.seven_query_data);
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.myapplication.provider/book");
Cursor cursor = getContentResolver().query(uri,null,null,null,null);
if(cursor != null){
while (cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("MainActivity","书的名字是" + name);
Log.d("MainActivity","书的作者是" + author);
Log.d("MainActivity","书的页数是" + pages);
Log.d("MainActivity","书的价格是" + price);
}
cursor.close();
}
}
});
Button updateData = (Button)findViewById(R.id.seven_updata_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.myapplication.provider/book/" + newId);
ContentValues values = new ContentValues();
values.put("name","A Strom of Swords");
values.put("pages",1216);
values.put("price",24.05);
getContentResolver().update(uri,values,null,null);
}
});
Button deleteData = (Button)findViewById(R.id.seven_delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.myapplication.provider/book/" + newId);
getContentResolver().delete(uri,null,null);
}
});
}
}