Create your own content provider for Android

Create a new class to inherit ContentProvider to create your own content provider.
There are six abstract methods in the ContentProvider class. When we use subclasses to inherit it, we need to rewrite all these six methods.

  1. The new MyProvider inherits from ContentProvider. Copy several methods.

```handlebars
 public class MyProvider extends ContentProvider {
    
    
    @Override
    public boolean onCreate() {
    
    
    return false;
    }
    
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
    String[] selectionArgs, String sortOrder) {
    
    
    return null;
    }
    
    @Override
    public Uri insert(Uri uri, ContentValues values) {
    
    
    return null;
    }
    
    @Override
    public int update(Uri uri, ContentValues values, String selection,
    String[] selectionArgs) {
    
    
    return 0;
    }
    
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
    
    
    return 0;
    }
    
    @Override
    public String getType(Uri uri) {
    
    
    return null;
    }
    }

1. onCreate()

It is called when the content provider is initialized, and it will usually complete operations such as database creation and upgrade.
Returning true means that the content provider is initialized successfully, and false means that it failed.
Note that the content provider will only be initialized when there is a ContentResolver trying to access the data in our program.

2. query()

Query data from the content provider.
Use the uri parameter to determine which table to query, the projection parameter to determine which columns to query, the selection and selectionArgs parameters to constrain which rows to query, and the sortOrder parameter to sort the results.
The result of the query is stored in the Cursor object and returned.

3. insert()

Add a piece of data to the content provider.
Use the uri parameter to determine the table to be added, and the data to be added is stored in the values ​​parameter.
After the addition is complete, return a URI to represent this new record.

4. update()

Update the existing data in the content provider.
Use the uri parameter to determine the data in which table to update. The new data is stored in the values ​​parameter. The selection and selectionArgs parameters are used to constrain which rows to update.
The number of affected rows will be returned as the return value.

5. delete()

Delete data from the content provider.
Use the uri parameter to determine the data in which table to delete, and the selection and selectionArgs parameters are used to restrict which rows to delete.
The number of deleted rows will be returned as the return value.

6. getType()

According to the incoming content URI to return the corresponding MIME type.
The MIME string corresponding to a content URI is mainly composed of three parts: it
must start with vnd.
If the content URI ends with a path, then android.cursor.dir/ is followed. If the content URI ends with an id, then android.cursor.item/ is followed.
Finally, connect vnd..

For content://com.example.app.provider/table1, the corresponding MIME type is:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
For content://com.example.app .provider/table1/1, the corresponding MIME type is:
vnd.android.cursor.item/vnd.com.example.app.provider.table1

Implement getType() logic:

public class MyProvider extends ContentProvider {
    
    
......
  @Override
  public String getType(Uri uri) {
    
    
      switch (uriMatcher.match(uri)) {
    
    
          case TABLE1_DIR:
              return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
          case TABLE1_ITEM:
              return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
          case TABLE2_DIR:
              return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2";
          case TABLE2_ITEM:
              return "vnd.android.cursor.item/vnd.com.example.app.provider.table2";
          default:
              break;
      }
      return null;
  }
}
  1. With the help of UriMatcher to match the content URI, we know which data in which table the incoming Uri object wants to access.

Content URI that can match any table:
content://com.example.app.provider/ * Content URI that
can match any row of data in table1:
content://com.example.app.provider/table1/#

UriMatcher provides an addURI() method, which receives three parameters, and can pass in the permission, path and a custom code respectively.
When the match() method of UriMatcher is called, a Uri object can be passed in, and the return
value is a custom code that can match this Uri object.
Using this code, we can determine which table or row of data the caller expects to access.

public static final int TABLE1_DIR = 0;
public static final int TABLE1_ITEM = 1;
public static final int TABLE2_DIR = 2;
public static final int TABLE2_ITEM = 3;

private static UriMatcher uriMatcher;

static {
    
    
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
    uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM);
    uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM);
    uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM);
}
  1. Use switch to judge uriMatcher.match(uri) in several methods of MyProvider, and locate the purpose to the corresponding table or row according to the purpose of different Uri.
public class MyProvider extends ContentProvider {
    
    
    public static final int TABLE1_DIR = 0;
    public static final int TABLE1_ITEM = 1;
    public static final int TABLE2_DIR = 2;
    public static final int TABLE2_ITEM = 3;

    private static UriMatcher uriMatcher;

    static {
    
    
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
        uriMatcher.addURI("com.example.app.provider ", "table1/#", TABLE1_ITEM);
        uriMatcher.addURI("com.example.app.provider ", "table2", TABLE2_ITEM);
        uriMatcher.addURI("com.example.app.provider ", "table2/#", TABLE2_ITEM);
    }
......
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {
    
    
        switch (uriMatcher.match(uri)) {
    
    
            case TABLE1_DIR:
                // 查询table1表中的所有数据
                break;
            case TABLE1_ITEM:
                // 查询table1表中的单条数据
                break;
            case TABLE2_DIR:
                // 查询table2表中的所有数据
                break;
            case TABLE2_ITEM:
                // 查询table2表中的单条数据
                break;
            default:
                break;
        }
......
    }
......
}
  1. After the purpose is clarified, the specific operations are performed on SQLiteDatabase to complete the addition, deletion, and modification check.
public class DatabaseProvider extends ContentProvider {
    
    
    public static final int BOOK_DIR = 0;
    public static final int BOOK_ITEM = 1;
    public static final int CATEGORY_DIR = 2;
    public static final int CATEGORY_ITEM = 3;
    public static final String AUTHORITY = "com.example.databasetest.provider";
    private static UriMatcher uriMatcher;
    private MyDatabaseHelper dbHelper;

    static {
    
    
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
        uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
        uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);
        uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);
    }

    @Override
    public boolean onCreate() {
    
    dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2);
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {
    
    
        // 查询数据
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
    
    
            case BOOK_DIR:
                cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                cursor = db.query("Book", projection, "id = ?", new String[]{
    
     bookId }, null, null, sortOrder);
                break;
            case CATEGORY_DIR:
                cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                cursor = db.query("Category", projection, "id = ?", new String[] {
    
     categoryId }, null, null, sortOrder);
                break;
            default:
                break;
        }
        return cursor;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
    
    
        // 添加数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uriReturn = null;
        switch (uriMatcher.match(uri)) {
    
    
            case BOOK_DIR:
            case BOOK_ITEM:
                long newBookId = db.insert("Book", null, values);
                uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
                break;
            case CATEGORY_DIR:
            case CATEGORY_ITEM:
                long newCategoryId = db.insert("Category", null, values);
                uriReturn = Uri.parse("content://" + AUTHORITY + "/category/" + newCategoryId);
                break;
            default:
                break;
        }
        return uriReturn;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    
    
        // 更新数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updatedRows = 0;
        switch (uriMatcher.match(uri)) {
    
    
            case BOOK_DIR:
                updatedRows = db.update("Book", values, selection, selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1); 
                updatedRows = db.update("Book", values, "id = ?", new String[] {
    
     bookId });
                break;
            case CATEGORY_DIR:
                updatedRows = db.update("Category", values, selection, selectionArgs);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                updatedRows = db.update("Category", values, "id = ?", new String[] {
    
     categoryId });
                break;
            default:
                break;
        }
        return updatedRows;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
    
    
        // 删除数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deletedRows = 0;
        switch (uriMatcher.match(uri)) {
    
    
            case BOOK_DIR:
                deletedRows = db.delete("Book", selection, selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                deletedRows = db.delete("Book", "id = ?", new String[] {
    
     bookId });
                break;
            case CATEGORY_DIR:
                deletedRows = db.delete("Category", selection, selectionArgs);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                deletedRows = db.delete("Category", "id = ?", new String[] {
    
     categoryId });
                break;
            default:
                break;
        }
        return deletedRows;
    }

    @Override
    public String getType(Uri uri) {
    
    
        switch (uriMatcher.match(uri)) {
    
    
            case BOOK_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.book";
            case BOOK_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.book";
            case CATEGORY_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest. provider.category";
            case CATEGORY_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest. provider.category";
        }
        return null;
    }
}

The getPathSegments() method divides
the part after the content URI authority with the "/" symbol, and puts the result of the division into a string list. The 0th position of this list is the path, the 1st This location stores id.

  1. To register in AndroidManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.databasetest"
    android:versionCode="1"
    android:versionName="1.0" >
......
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
......
        <provider
            android:name="com.example.databasetest.DatabaseProvider"
            android:authorities="com.example.databasetest.provider" >
        </provider>

    </application>
</manifest>

Guess you like

Origin blog.csdn.net/i_nclude/article/details/77683771