ContentProvider是Android实现跨程序共享数据的标准方式。
主要用于,一个程序访问另一个程序中允许共享的数据,同时还能保证被访问数据的安全性。
ContentProvider基本用法
1. ContentResolver
如果想访问ContentProvider中共享的数据,就需要借助ContentResolver类。
通过Context提供的getContentResolver()获取,ContentResolver提供了一系列的CRUD操作。
内容Uri
ContentResolver的CRUD不接收表名参数,而是用一个Uri代替。
组成:
authority:用于区分不同的应用程序,一般用程序包名命名。
path:用于对同一程序不同表做区分,通常添加到authority后。
程序A定义ContentProvider,共享数据。
1. 定义数据库
public class UserDb extends SQLiteOpenHelper {
public UserDb(Context context) {
super(context, "user.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table if not exists " +
"t_user(_id integer primary key autoincrement," +
"name text," +
"code integer)");
sqLiteDatabase.execSQL("insert into t_user(name,code)" +
"values('Demo1',1),('Demo2',2) ");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
2. 定义Provider共享数据
public class MyProviderDemo extends ContentProvider {
private static final String TAG = "MyProviderDemo";
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static int URI_MATCHER_SUCCESS = 0;
private UserDb mUserDb;
static {
/**
* 参数注意
* authority 要和配置清单中一致
* path 内容解析者调用的路径 com.w.review/query
* code 匹配成功的返回码
*/
URI_MATCHER.addURI("com.w.review", "query", URI_MATCHER_SUCCESS);
}
@Override
public boolean onCreate() {
mUserDb = new UserDb(getContext());
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri,
@Nullable String[] projection,
@Nullable String selection,
@Nullable String[] selectionArgs,
@Nullable String sortOrder) {
int code = URI_MATCHER.match(uri); //别的程序调用,匹配时查询成功时返回
if (code == URI_MATCHER_SUCCESS) {
SQLiteDatabase database = mUserDb.getReadableDatabase();
Cursor cursor = database.query("t_user", projection,
selection, selectionArgs,
null, null, sortOrder);
return cursor;
} else {
Log.i(TAG, "参数异常" + code);
throw new IllegalArgumentException("参数异常");
}
}
@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;
}
}
3. mainfests内声明
<application>
<provider
android:name=".provider.MyProviderDemo"
android:authorities="com.w.review"
android:enabled="true"
android:exported="true">
</provider>
</application>
程序B查询A的共享数据
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getProviderData();
}
private void getProviderData() {
//注意:规定一定要跟头路径content://
Uri uri = Uri.parse("content://com.w.review/query");
Cursor cursor = getContentResolver().query(uri, new String[]{"name"},
null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String value = cursor.getString(0);
Log.i(TAG, value);
}
cursor.close();
} else {
Log.i(TAG, "fail");
}
}
}
获取手机联系人
权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getPermission();
}
//6.0后需要动态申请权限
private void getPermission() {
int checkPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS);
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_CONTACTS}, 0);
} else {
getLinkMan();
}
}
private void getLinkMan() {
Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("TAG", name + "\r\n" + number);
}
cursor.close();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 0:
if (grantResults.length > 0 && grantResults[0] == PackageManager.GET_RECEIVERS) {
getLinkMan();
} else {
Toast.makeText(MainActivity.this, "没有读取权限", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
}