1. Understanding
ContentProvider database expose interfaces for the application B, A B interface access ContentResolver application, database data read by
Uri Format:
Content: // com.example.transupportprovider / Trains / 122
prefix: // unique identification / table / table ID
the ContentProvider prefix is: content
unique identifier: with the general package names
2. a realization of the application B application interface accessed through the exposed ContentResolver ContentResolver
A Application expose interfaces
2.1 DBHelper.java provide access to the internal database
package com.example.myapplication;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* 数据库操作的帮助类
* @author denganzhi
*
*/
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context,int version) {
super(context, "atguigu.db", null, version);
}
/**
* 什么时候才会创建数据库文件?
* 1). 数据库文件不存在
* 2). 连接数据库
*
* 什么时候调用?
* 当数据库文件创建时调用(1次)
* 在此方法中做什么?
* 建表
* 插入一些初始化数据
*/
@Override
public void onCreate(SQLiteDatabase db) {
Log.e("TAG", "DBHelper onCreate()");
//建表
String sql = "create table person(_id integer primary key autoincrement, name varchar,age int)";
db.execSQL(sql);
//插入一些初始化数据
db.execSQL("insert into person (name, age) values ('Tom1', 11)");
db.execSQL("insert into person (name, age) values ('Tom2', 12)");
db.execSQL("insert into person (name, age) values ('Tom3', 13)");
}
//当传入的版本号大于数据库的版本号时调用
// 用户版本升级
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e("TAG", "DBHelper onUpgrade()-->"+"oldVersion:"+oldVersion + "newVersion:"+newVersion);
}
// 还有版本下降的时候调用的方法onDowngrade
}
2.2 PersonProvider.java: ContentProvider interface exposes methods to achieve
package com.example.myapplication;
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.net.Uri;
import android.util.Log;
/**
* 操作person表的provider类
*
*/
public class PersonProvider extends ContentProvider {
//用来存放所有合法的Uri的容器,这里的参数是如果url不能匹配返回的值:-1一般返回
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//保存一些合法的uri
// 前缀:// provider的唯一标识/表明/id
// content://com.atguigu.l09_provider.personprovider/person 不根据id操作
// content://com.atguigu.l09_provider.personprovider/person/3 根据id操作
static {
matcher.addURI("com.example.myapplication.PersonProvider", "/person", 1);
matcher.addURI("com.example.myapplication.PersonProvider", "/person/#", 2); //#匹配任意数字
}
private DBHelper dbHelper;
public PersonProvider() {
Log.e("TAG", "PersonProvider()");
}
// 当内容提供者被创建的时候调用,适合做数据初始化操作
@Override
public boolean onCreate() {
Log.e("TAG", "PersonProvider onCreate()");
dbHelper = new DBHelper(getContext(),1);
return false;
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id查询
* content://com.atguigu.l09_provider.personprovider/person/3 根据id查询
* 查询表数据:
* URI:地址
* projection: 查询那些字段
* String selection,
String[] selectionArgs 查询条件,条件中可能有?
*/
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Log.e("TAG", "PersonProvider query()");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//1.匹配uri, 返回code
int code = matcher.match(uri);
//如果合法, 进行查询
if(code==1) {//不根据id查询,配合1
Cursor cursor = database.query("person", projection, selection, selectionArgs, null, null, null);
return cursor;
} else if(code==2) {//根据id查询,匹配2
//得到id
long id = ContentUris.parseId(uri);
//查询
Cursor cursor = database.query("person", projection, "_id=?", new String[]{id+""}, null, null, null);
return cursor;
} else {//如果不合法, 抛出异常
throw new RuntimeException("查询的uri不合法");
}
}
/**
* content://com.atguigu.l09_provider.personprovider/person 插入
* content://com.atguigu.l09_provider.personprovider/person/3 根据id插入(没有)
* values: map接口插入数据
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
Log.e("TAG", "PersonProvider insert()");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//匹配uri, 返回code
int code = matcher.match(uri);
//如果合法, 进行插入
if(code==1) {
long id = database.insert("person", null, values);
//将id添加到uri中
uri = ContentUris.withAppendedId(uri, id);
database.close();
return uri;
} else {
//如果不合法, 抛出异常
database.close();
throw new RuntimeException("插入的uri不合法");
}
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id删除
* content://com.atguigu.l09_provider.personprovider/person/3 根据id删除
*
* String selection, String[] selectionArgs: 删除条件
*/
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.e("TAG", "PersonProvider delete()");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//匹配uri, 返回code
int code = matcher.match(uri);
int deleteCount = -1;
//如果合法, 进行删除
if(code==1) {
deleteCount = database.delete("person", selection, selectionArgs);
} else if(code==2) {
long id = ContentUris.parseId(uri);
deleteCount = database.delete("person", "_id="+id, null);
} else {
//如果不合法, 抛出异常
database.close();
throw new RuntimeException("删除的uri不合法");
}
database.close();
return deleteCount;
}
/**
* content://com.atguigu.l09_provider.personprovider/person 不根据id更新
* content://com.atguigu.l09_provider.personprovider/person/3 根据id更新
*
* values: map更新数据
* String selection,
String[] selectionArgs 更新条件
*/
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
Log.e("TAG", "PersonProvider update()");
//得到连接对象
SQLiteDatabase database = dbHelper.getReadableDatabase();
//匹配uri, 返回code
int code = matcher.match(uri);
int updateCount = -1;
//如果合法, 进行更新
if(code==1) {
updateCount = database.update("person", values, selection, selectionArgs);
} else if(code==2) {
long id = ContentUris.parseId(uri);
updateCount = database.update("person", values, "_id="+id, null);
} else {
//如果不合法, 抛出异常
database.close();
throw new RuntimeException("更新的uri不合法");
}
database.close();
return updateCount;
}
// MIME:
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
}
B ContentResolver access application uses the exposed interface, protocol format Uri
By means of ContentResolver interface to access ContentProvider exposed
public static String prividerStr="content://com.example.myapplication.PersonProvider/person";
/*
* 通过ContentResolver调用ContentProvider查询所有记录
*/
public void selectProvier(View v) {
//1. 得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2. 调用其query, 得到cursor
Uri uri = Uri.parse("content://com.example.myapplication.personprovider/person/1");
uri = Uri.parse(prividerStr);
Cursor cusor = resolver.query(uri, null, null, null, null);
//3. 取出cursor中的数据, 并显示
if(cusor!=null){
while(cusor.moveToNext()) {
int id = cusor.getInt(0);
String name = cusor.getString(1);
Toast.makeText(this, id+" : "+name, 1).show();
}
cusor.close();
}
}
public void addFun(View view) {
//1. 得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2. 调用其insert
Uri uri = Uri.parse(prividerStr);
//uri = Uri.parse("content://com.atguigu.l09_provider.personprovider/person/3");
ContentValues values = new ContentValues();
values.put("name", "JACK");
uri = resolver.insert(uri, values);
Toast.makeText(this, uri.toString(), 1).show();
}
public void updateFun(View view) {
//1. 得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2. 执行update
Uri uri = Uri.parse("content://com.example.myapplication.PersonProvider/person/10");
ContentValues values = new ContentValues();
values.put("name", "JACK2");
// 返回更新成功个数
int updateCount = resolver.update(uri, values, null, null);
Toast.makeText(this, "updateCount="+updateCount, 1).show();
}
public void deleteFun(View view) {
//1. 得到ContentResolver对象
ContentResolver resolver = getContentResolver();
//2. 执行delete
Uri uri = Uri.parse("content://com.example.myapplication.PersonProvider/person/2");
int deleteCount = resolver.delete(uri, null, null);
Toast.makeText(this, "deleteCount="+deleteCount, 1).show();
}
Cases, access contacts: AndroidManifest.xml
<!-- 读取联系人记录的权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
Java code: The system has provided a ready-made CONTENT_URI, the database field packaged in a constant
private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE =10 ;
public void selectContacts(View view) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
} else
{
selectContacts();
}
}
public void selectContacts() {
ContentResolver resolver = getContentResolver();
//执行查询得到cursor
String[] projection = {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
//取出其中的数据保存到data
while(cursor.moveToNext()) {
String name = cursor.getString(0);
String number = cursor.getString(1);
Map<String, String> map = new HashMap<String, String>();
map.put("name", name);
map.put("number", number);
Log.e("denganzhi","name:"+name + "number:"+ number);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
selectContacts();
} else
{
// Permission Denied
Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
Source Path: https://download.csdn.net/download/dreams_deng/12233364