内容提供者
用途:主要用于不同应用程序之间实现数据共享。比如,读取联系人,两个应用程序之间共享数据等。
类型:分为现有的内容提供器(系统自带的)和自定义的内容提供器。
实例:
一、现有的内容提供器。(读取联系人)
public class MainActivity extends AppCompatActivity {
private Context mContext;
private ListView lvContactList;
private List<Tb_Contact> contactList;
private Tb_Contact tb_contact;
private LViewUniversalBaseAdapter<Tb_Contact> contactListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
baseDataInit();
bindViews();
viewsAddListener();
viewsDataInit();
}
private void baseDataInit() {
mContext = this;
contactList = new ArrayList<>();
}
private void bindViews() {
lvContactList = findViewById(R.id.Main_lvContactList);
}
private void viewsAddListener() {
}
private void viewsDataInit() {
contactListSetAdapter();
checkPermission();
}
/**
* 联系人列表添加数据适配器
*/
private void contactListSetAdapter() {
contactListAdapter = new LViewUniversalBaseAdapter<Tb_Contact>((ArrayList<Tb_Contact>) contactList, R.layout.layout_item_contact) {
@Override
public void bindView(ViewHolder holder, int position) {
if (contactList.size() != 0) {
tb_contact = contactList.get(position);
holder.setText(R.id.Layout_Item_Contact_tvName, tb_contact.getName());
holder.setText(R.id.Layout_Item_Contact_tvTel, tb_contact.getTel());
}
}
};
lvContactList.setAdapter(contactListAdapter);
}
/**
* 读取联系人
*/
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 name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
tb_contact = new Tb_Contact(name, number);
contactList.add(tb_contact);
}
contactListAdapter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 检查权限
*/
private void checkPermission() {
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_CONTACTS}, 1001);
} else {
readContacts();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1001: {
if (grantResults.length >= 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
readContacts();
} else {
Toast.makeText(mContext, "您还未开启权限!", Toast.LENGTH_SHORT).show();
}
break;
}
default:break;
}
}
}
二、自定义内容提供者,同时让其他应用程序访问并操作共享数据。
(1)创建一个自定义的MyDatabaseHelper数据库管理器。
public class MyDatabaseHelper extends SQLiteOpenHelper {
private Context mContext;
public static final String CREATE_BOOK = "create table Book(id integer primary key autoincrement, author text, price real, pages integer, name text)";
public MyDatabaseHelper(Context mContext, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(mContext, name, factory, version);
this.mContext = mContext;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_BOOK);
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("drop table if exists Book");
onCreate(sqLiteDatabase);
}
}
(2)创建一个自定义的内容提供者
/**
* 自定义的内容提供者
*/
public class MyContentProvider extends ContentProvider {
public static final int BOOK_DIR = 1;
public static final int BOOK_ITEM = 2;
public static final String AUTHORITY = "com.crazyboy.contentproviderdemo.provider";
private MyDatabaseHelper myDatabaseHelper;
private static UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
}
public MyContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
SQLiteDatabase sqLiteDatabase = myDatabaseHelper.getWritableDatabase();
int deleteRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR: {
deleteRows = sqLiteDatabase.delete("Book", selection, selectionArgs);
break;
}
case BOOK_ITEM: {
String bookId = uri.getPathSegments().get(1);
deleteRows = sqLiteDatabase.delete("Book", "id = ?", new String[] { bookId });
break;
}
default:break;
}
return deleteRows;
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
String result = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR: {
result = "vnd.android.cursor.dir/vnd.com.crazyboy.contentproviderdemo.provider.book";
break;
}
case BOOK_ITEM: {
result = "vnd.android.cursor.item/vnd.com.crazyboy.contentproviderdemo.provider.book";
break;
}
default:break;
}
return result;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
SQLiteDatabase sqLiteDatabase = myDatabaseHelper.getWritableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR:
case BOOK_ITEM: {
long newBookId = sqLiteDatabase.insert("Book", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
break;
}
default:break;
}
return uriReturn;
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
myDatabaseHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
SQLiteDatabase sqLiteDatabase = myDatabaseHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case BOOK_DIR: {
cursor = sqLiteDatabase.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
break;
}
case BOOK_ITEM: {
String bookId = uri.getPathSegments().get(1);
cursor = sqLiteDatabase.query("Book", projection, "id = ?", new String[] {bookId}, null, null, sortOrder);
break;
}
default:break;
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
SQLiteDatabase sqLiteDatabase = myDatabaseHelper.getWritableDatabase();
int updateRows = 0;
switch (uriMatcher.match(uri)) {
case BOOK_DIR: {
updateRows = sqLiteDatabase.update("Book", values, selection, selectionArgs);
break;
}
case BOOK_ITEM: {
String bookId = uri.getPathSegments().get(1);
updateRows = sqLiteDatabase.update("Book", values, "id = ?", new String[] {bookId});
break;
}
default:break;
}
return updateRows;
}
}
(3)在AndroidManifest.xml清单文件里注册ContentProvider。
<provider
android:name=".MyContentProvider"
android:authorities="com.crazyboy.contentproviderdemo.provider"
android:enabled="true"
android:exported="true"></provider>
(4)再创建一个应用程序获取并操作内容提供者的数据。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Context mContext;
private Button btnAdd, btnSelect, btnUpdate, btnDelete;
private String newBookId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
baseDataInit();
bindViews();
viewsAddListener();
viewsDataInit();
}
private void baseDataInit() {
mContext = this;
}
private void bindViews() {
btnAdd = findViewById(R.id.Main_btnAdd);
btnSelect = findViewById(R.id.Main_btnSelect);
btnUpdate = findViewById(R.id.Main_btnUpdate);
btnDelete = findViewById(R.id.Main_btnDelete);
}
private void viewsAddListener() {
btnAdd.setOnClickListener(this);
btnSelect.setOnClickListener(this);
btnUpdate.setOnClickListener(this);
btnDelete.setOnClickListener(this);
}
private void viewsDataInit() {
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.Main_btnAdd: {
addData();
break;
}
case R.id.Main_btnSelect: {
selectData();
break;
}
case R.id.Main_btnUpdate: {
updateData();
break;
}
case R.id.Main_btnDelete: {
deleteData();
break;
}
default:break;
}
}
/**
* 添加数据
*/
private void addData() {
Uri uri = Uri.parse("content://com.crazyboy.contentproviderdemo.provider/book");
ContentValues values = new ContentValues();
values.put("name", "A Clash of Kings");
values.put("author", "Linux");
values.put("pages", 1050);
values.put("price", 22.50);
Uri newUri = getContentResolver().insert(uri, values);
newBookId = newUri.getPathSegments().get(1);
Toast.makeText(mContext, "添加成功!", Toast.LENGTH_SHORT).show();
}
/**
* 查询数据
*/
private void selectData() {
Uri uri = Uri.parse("content://com.crazyboy.contentproviderdemo.provider/book");
Cursor cursor = getContentResolver().query(uri, null, 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.e("name", name);
Log.e("author", author);
Log.e("pages", pages + "");
Log.e("price", price + "");
}
cursor.close();
}
Toast.makeText(mContext, "查询成功!", Toast.LENGTH_SHORT).show();
}
/**
* 更新数据
*/
private void updateData() {
Uri uri = Uri.parse("content://com.crazyboy.contentproviderdemo.provider/book/" + newBookId);
ContentValues values = new ContentValues();
values.put("name", "Lion of The Forest");
values.put("author", "Divide");
values.put("pages", 890);
values.put("price", 22.50);
getContentResolver().update(uri, values, null, null);
Toast.makeText(mContext, "更新成功!", Toast.LENGTH_SHORT).show();
}
/**
* 删除数据
*/
private void deleteData() {
Uri uri = Uri.parse("content://com.crazyboy.contentproviderdemo.provider/book/" + newBookId);
getContentResolver().delete(uri, null, null);
Toast.makeText(mContext, "删除成功!", Toast.LENGTH_SHORT).show();
}