Content provider of four Android application components

Posted by xxxxxx on Sat, 21 Dec 2019 22:30:36 +0100

understand

  1. 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"	/>
  1. What is ContentResolver?

ContentResolver, also known as content provider resolution class, is used to resolve ContentProvider exposed by visitors.

  1. 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

  1. 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;
    }
}
  1. 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();
    }
}

Topics: Database Android SQLite SQL