understand
- First, let's talk about why there is a ContentProvider?
When an application wants to access the database of another application, because each application's database file is private and cannot be accessed directly, the accessed application needs an external database content provider, that is, content provider.
<provider <!--custom ContentProvider Need to inherit from ContentProvider,And register in the function list file--> android:authorities="com.sank.ar_8_contentprovider_1_bi.personprovider" android:name=".PersonProvider" android:exported="true" />
- What is ContentResolver?
ContentResolver, also known as content provider resolution class, is used to resolve ContentProvider exposed by visitors.
- The relationship between the two
The URI is used to communicate between ContentProvider and ContentResolver.
URI:
URI contains URL and URN, which is a class containing request address.
Two main tool classes are used:
UriMatcher : For matching Uri Container for
//Add a legal URI
void addURI(String authority,String path, int code) ;
//Match the specified uri and return the matching code
int match(Uri uri);
ContentUris : analysis uri Tool class of
//Parse the uri to get the id
long parseId(Uri contentUri)
//Add id to the specified uri
Uri withAppendedId(Uri contentUri, long id)
Demo
- ContentProvider:
- SQLite database part:
public class DBHelper extends SQLiteOpenHelper { public DBHelper(Context context) { super(context, "sank.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table person(" + "_id integer primary key autoincrement," + "name varchar(20))"); db.execSQL("insert into person " + "(name) values ('TOM')"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
- Custom Provider class:
public class PersonProvider extends ContentProvider { //A container for all legal URIs private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //Save some legal URIs //Content://com.sank.ar'8'contentprovider'1'bi.personprovider/person does not operate according to id //Content://com.sank.ar'8'contentprovider'1'bi.personprovider/person/3 operate according to id static { matcher.addURI("com.sank.ar_8_contentprovider_1_bi.personprovider" ,"/person",1); matcher.addURI("com.sank.ar_8_contentprovider_1_bi.personprovider" ,"/person/#",2); } private DBHelper dbHelper; @Override public boolean onCreate() { dbHelper = new DBHelper(getContext()); return false; } @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { //Get Sql link object SQLiteDatabase database = dbHelper.getReadableDatabase(); //Match uri, return code int code = matcher.match(uri); if(code==1){//How to query legally //Do not query based on id Cursor cursor = database.query("person", projection, selection, selectionArgs, null, null, null); return cursor; }else if(code==2){ //Query by id long id = ContentUris.parseId(uri); Cursor cursor = database.query("person", projection, "_id=?", new String[]{id + ""}, null, null, null); return cursor; }else{ //How to illegal throw an exception throw new RuntimeException("uri wrongful"); } } @Nullable @Override public String getType(@NonNull Uri uri) { return null; } @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { //Establish a link SQLiteDatabase database = dbHelper.getReadableDatabase(); //Match uri, return code int code = matcher.match(uri); //Check if uri is legal if(code==1){ long id = database.insert("person", null, values); //Add id to uri uri = ContentUris.withAppendedId(uri,id); database.close(); return uri; }else{ database.close(); throw new RuntimeException("uri wrongful"); } } @Override public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { //Establish a link SQLiteDatabase database = dbHelper.getReadableDatabase(); //Match uri, return code int code = matcher.match(uri); //Number of deletions int deleteCount = -1; //Check if uri is legal if(code==1){ deleteCount = database.delete("person", selection, selectionArgs); }else if(code ==2){ long id = ContentUris.parseId(uri); database.delete("person", "_id=" + id, null); } else{ database.close(); throw new RuntimeException("uri wrongful"); } database.close(); return deleteCount; } @Override public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { //Establish database link SQLiteDatabase database = dbHelper.getReadableDatabase(); //Match uri int code = matcher.match(uri); //Number of rows updated int updateCount; //Check if it is legal 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 wrongful"); } database.close(); return updateCount; } }
- ContentResolver:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /* CRUD */ public void insert(View view) { //Get ContentResolver object ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/"); ContentValues values = new ContentValues(); values.put("name","mary"); uri = resolver.insert(uri,values); Toast.makeText(this,uri.toString(),Toast.LENGTH_SHORT).show(); } public void delete(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/2"); int deleteCount = resolver.delete(uri,null, null); Toast.makeText(this,"deleteCount="+deleteCount,Toast.LENGTH_SHORT).show(); } public void update(View view) { ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person/1"); ContentValues values = new ContentValues(); values.put("name","Tom2"); int updateCount = resolver.update(uri, values, null, null); Toast.makeText(this,"updateCount="+updateCount,Toast.LENGTH_SHORT).show(); } public void query(View view) { //Get ContentResolver object ContentResolver resolver = getContentResolver(); //Call query to get the cursor object Uri uri = Uri.parse("content://com.sank.ar_8_contentprovider_1_bi.personprovider/person"); Cursor cursor = resolver.query(uri, null, null, null, null); //Fetching data from cursor assert cursor != null; while(cursor.moveToNext()){ int id = cursor.getInt(0); String name = cursor.getString(1); Toast.makeText(this,id+" : "+name,Toast.LENGTH_SHORT).show(); } cursor.close(); } }