SoFunction
Updated on 2025-03-11

Android Development Tutorials ContentProvider Data Storage

1. Introduction to ContentProvider Save Data

A program can completely expose its own data by implementing an abstract interface of ContentProvider, and ContentProvider exposes data in a similar way to tables in a database. Then the outside world obtains the data it provides should be basically the same as the operation of obtaining data from the database, except that the URL is used to represent the "database" that the outside world needs to access.

ContentProvider provides a way to share data between multiple applications.

ContentProvider is a class that implements a set of standard methods for providing other applications to access data. The application can perform the following operations in the ContentProvider: query data, modify data, add data, and delete data.

Standard ContentProvider: Android provides some standard ContentProviders that have been implemented in the system, such as contact information, picture libraries, etc. You can use these ContentProviders to access contact information, pictures, etc. stored on the device.

The query string used in ContentProvider is different from standard SQL queries. Many operations such as select, add, delete, modify, etc. use a special URL. This URL consists of 3 parts, "content://", which represents the path of the data and an optional ID that represents the data.

content://media/internal/images This URL will return all images stored on the device

content://contacts/people/ This URL will return all contact information on the device

content://contacts/people/45 This URL returns a single result (contact record with ID 45 in the contact information)

If you want to store byte-type data, such as a bitmap file, the data column that saves the data is actually a URL string representing the actual saving file. The client uses it to read the corresponding file data. The ContentProvider for processing this data type needs to implement a field named _data. The _data field lists the exact path of the file on the Android file system. This field is not only for the client, but also for ContentResolver. The client can call the () method to process the file resources pointed to by the URL. If it is the ContentResolver itself, since it holds higher permissions than the client, it can directly access the data file.

2. How to use

Most ContentProviders use an Android file system or SQLite database to hold data, but can also be stored in any way. This example uses SQLite database to maintain data.

1. Create an interface that defines a class variable of type Uri named CONTENT_URL and is a public static final. It must be specified with a unique string value. The best solution is the full name of the class and the name of the data column.

public interface IProivderMetaData {
  public static final String AUTHORITY = "";
  public static final String DB_NAME = "";
  public static final int VERSION = 1;
  public interface BookTableMetaData extends BaseColumns {
    public static final String TABLE_NAME = "book";
    public static final Uri CONTENT_URI = ("content://"
            + AUTHORITY + "/" + TABLE_NAME);
    public static final String BOOK_ID = "_id";
    public static final String BOOK_NAME = "name";
    public static final String BOOK_PUBLISHER = "publisher";
    public static final String SORT_ORDER = "_id desc";
    public static final String CONTENT_LIST = "/";
    public static final String CONTENT_ITEM = "/";
  }
}

2. Implement SQLiteOpenHelper

public class ContentProviderDBHelper extends SQLiteOpenHelper implements IProivderMetaData {
  private static final String TAG = "ContentProviderDBHelper";
  public ContentProviderDBHelper(Context context) {
    super(context, DB_NAME, null, VERSION);
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
    ...
  }
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    ...
  }
}

3. Create a class that inherits the parent class of ContentProvider

public class ContentProviderDBHelper extends SQLiteOpenHelper implements IProivderMetaData {
  public ContentProviderDBHelper(Context context) {
    super(context, DB_NAME, null, VERSION);
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
    ...
  }
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    ...
  }
}

4. Use tags in the settings to call ContentProvider.

<provider
   android:authorities=""
   android:name=".BookContentProvider"/>

5. Add data

mContentResolver = getContentResolver();
String[] bookNames = new String[]{"Chinese", "Math", "English", "Sports"};
String[] bookPublishers = new String[]{"XinHua", "GongXin", "DianZi", "YouDian"};
for (int i = 0; i < ; i++) {
  ContentValues values = new ContentValues();
  (.BOOK_NAME, bookNames[i]);
  (.BOOK_PUBLISHER, bookPublishers[i]);
  (.CONTENT_URI, values);
}

6. Delete data

String bookId = "1";
if (!"".equals(bookId)) {
   ContentValues values1 = new ContentValues();
   (.BOOK_ID,bookId);
   ((
                  .CONTENT_URI,
                  bookId), 
      "_id = ?",
              new String[]{bookId}
   );
} else {
  (
       .CONTENT_URI,
       null,
       null
  );
}

7. Query data

Cursor cursor = (.CONTENT_URI,
            null, null, null, null);
String text = "";
if (cursor != null) {
  while (()) {
    String bookIdText =
((.BOOK_ID));
    String bookNameText =
((.BOOK_NAME));
    String bookPublisherText =
((.BOOK_PUBLISHER));
    text += "id = " + bookIdText + ",name = " + bookNameText + 
          ",publisher = " + bookPublisherText + "\n";
  }
  ();
  (text);
}

8. Update data

String bookId1 = "2";
String bookName = "Art";
String bookPublisher = "TieDao";
ContentValues values2 = new ContentValues();
(.BOOK_NAME,bookName);
(.BOOK_PUBLISHER,bookPublisher);
if ("".equals(bookId1)) {
   (.CONTENT_URI,
              values2, null, null);
} else {
   ((.CONTENT_URI, bookId1),
              values2, "_id = ? ", new String[]{bookId1}
   );
}

3. Small cases

1. Add a file

  &lt;string name="content_provider"&gt;ContentProvider&lt;/string&gt;
  &lt;string name="add_data"&gt;Add data&lt;/string&gt;
  &lt;string name="delete_data"&gt;Delete data&lt;/string&gt;
  &lt;string name="update_data"&gt;Change the data&lt;/string&gt;
  &lt;string name="query_data"&gt;Query data&lt;/string&gt;

2. Modify the activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
< xmlns:andro
  xmlns:tools="/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:fitsSystemWindows="true"
  tools:context="">
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal"
      android:text="@string/content_provider" />
    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_marginBottom="@dimen/fab_margin"
      android:layout_marginTop="@dimen/fab_margin"
      android:orientation="horizontal">
      <Button
        android:
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/add_data" />
      <Button
        android:
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/delete_data" />
      <Button
        android:
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/update_data" />
      <Button
        android:
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/query_data" />
    </LinearLayout>
    <TextView
      android:
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:text="@string/app_name" />
  </LinearLayout>
</>

3. Add IProviderMetaData interface

package ;
import ;
import ;
/**
 * Created by zhangmiao on 2016/12/20.
 */
public interface IProviderMetaData {
  public static final String AUTHORITY = "";
  public static final String DB_NAME = "";
  public static final int VERSION = 1;
  public interface BookTableMetaData extends BaseColumns {
    public static final String TABLE_NAME = "book";
    public static final Uri CONTENT_URI = ("content://"
            + AUTHORITY + "/" + TABLE_NAME);
    public static final String BOOK_ID = "_id";
    public static final String BOOK_NAME = "name";
    public static final String BOOK_PUBLISHER = "publisher";
    public static final String SORT_ORDER = "_id desc";
    public static final String CONTENT_LIST = "/";
    public static final String CONTENT_ITEM = "/";
  }
}

4. Add ContentProviderDBHelper class

package ;
import ;
import ;
import ;
import ;
/**
 * Created by zhangmiao on 2016/12/20.
 */
public class ContentProviderDBHelper extends SQLiteOpenHelper implements IProviderMetaData {
  private static final String TAG = "ContentProviderDBHelper";
  public ContentProviderDBHelper(Context context) {
    super(context, DB_NAME, null, VERSION);
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
    String TABLESQL = "CREATE TABLE IF NOT EXISTS "
        + BookTableMetaData.TABLE_NAME + " ("
        + BookTableMetaData.BOOK_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
        + BookTableMetaData.BOOK_NAME + " VARCHAR,"
        + BookTableMetaData.BOOK_PUBLISHER + " VARCHAR)";
    (TABLESQL);
  }
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    (TAG, "Upgrading database from version " + oldVersion + "to"
        + newVersion + ", which will destroy all old data");
    ("DROP TABLE IF EXISTS " + DB_NAME);
    onCreate(db);
  }
}

5. Add BookContentProvider class

package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
 * Created by zhangmiao on 2016/12/21.
 */
public class BookContentProvider extends ContentProvider {
  private static final String TAG = "BookContentProvider";
  private static UriMatcher uriMatcher = null;
  private static final int BOOKS = 1;
  private static final int BOOK = 2;
  private ContentProviderDBHelper dbHelper;
  private SQLiteDatabase db;
  static {
    uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    (,
        .TABLE_NAME, BOOKS);
    (,
        .TABLE_NAME + "/#",
        BOOK);
  }
  @Override
  public boolean onCreate() {
    dbHelper = new ContentProviderDBHelper(getContext());
    return (dbHelper == null) ? false : true;
  }
  @Nullable
  @Override
  public String getType(Uri uri) {
    switch ((uri)) {
      case BOOKS:
        return .CONTENT_LIST;
      case BOOK:
        return .CONTENT_ITEM;
      default:
        throw new IllegalArgumentException("This is a unKnow Uri"
            + ());
    }
  }
  @Nullable
  @Override
  public Uri insert(Uri uri, ContentValues values) {
    switch ((uri)) {
      case BOOKS:
        db = ();
        long rowId = (
            .TABLE_NAME,
            .BOOK_ID,
            values);
        Uri insertUri = (uri, "/" + rowId);
        (TAG, "insertUri:" + ());
        getContext().getContentResolver().notifyChange(uri, null);
        return insertUri;
      case BOOK:
      default:
        throw new IllegalArgumentException("This is a unKnow Uri"
            + ());
    }
  }
  @Nullable
  @Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    db = ();
    switch ((uri)) {
      case BOOKS:
        return (.TABLE_NAME,
            projection, selection, selectionArgs, null, null,
            sortOrder);
      case BOOK:
        long id = (uri);
        String where = "_".equals(selection)) {
          where = selection + " and " + where;
        }
        return (.TABLE_NAME,
            projection, where, selectionArgs, null, null, sortOrder);
      default:
        throw new IllegalArgumentException("This is a unKnow Uri"
            + ());
    }
  }
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    db = ();
    switch ((uri)) {
      case BOOKS:
        return (.TABLE_NAME,
            selection, selectionArgs);
      case BOOK:
        long id = (uri);
        String where = "_".equals(selection)) {
          where = selection + " and " + where;
        }
        return (.TABLE_NAME,
            selection, selectionArgs);
      default:
        throw new IllegalArgumentException("This is a unKnow Uri"
            + ());
    }
  }
  @Override
  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    db = ();
    switch ((uri)) {
      case BOOKS:
        return (.TABLE_NAME,
            values, null, null);
      case BOOK:
        long id = (uri);
        String where = "_".equals(selection)) {
          where = selection + " and " + where;
        }
        return (.TABLE_NAME,
            values, selection, selectionArgs);
      default:
        throw new IllegalArgumentException("This is a unKnow Uri"
            + ());
    }
  }
}

6. Modify the file

<provider
      android:authorities=""
      android:name=".BookContentProvider"/>

7. Modify MainActivity

package ;
import ;
import ;
import ;
import .*;
import ;
import .;
import ;
import ;
import ;
import ;import ;
import ;
public class MainActivity extends AppCompatActivity implements  {private ContentResolver mContentResolver;
  private BookContentProvider mBookContentProvider;private TextView mTableInfo;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    ("MainActivity", "onCreate");
    (savedInstanceState);
    setContentView(.activity_main);
    Button cpAdd = (Button) findViewById(.provider_add);
    Button cpDelete = (Button) findViewById(.provider_delete);
    Button cpUpdate = (Button) findViewById(.provider_update);
    Button cpQuery = (Button) findViewById(.provider_query);
    mTableInfo = (TextView) findViewById(.table_info);
    (this);
    (this);
    (this);
    (this);
  }
  @Override
  public void onClick(View v) {
    switch (()) {case .provider_add:
        mContentResolver = getContentResolver();
        String[] bookNames = new String[]{"Chinese", "Math", "English", "Sports"};
        String[] bookPublishers = new String[]{"XinHua", "GongXin", "DianZi", "YouDian"};
        for (int i = 0; i < ; i++) {
          ContentValues values = new ContentValues();
          (.BOOK_NAME, bookNames[i]);
          (.BOOK_PUBLISHER, bookPublishers[i]);
          (.CONTENT_URI, values);
        }
        break;
      case .provider_delete:
        String bookId = "1";
        if (!"".equals(bookId)) {
          ContentValues values1 = new ContentValues();
          (.BOOK_ID,
              bookId);
          (
              (
                  .CONTENT_URI,
                  bookId
              ), "_id = ?",
              new String[]{bookId}
          );
        } else {
          (
              .CONTENT_URI,
              null,
              null
          );
        }
        break;
      case .provider_query:
        Cursor cursor = (.CONTENT_URI, null, null, null, null);
        String text = "";
        if (cursor != null) {
          while (()) {
            String bookIdText =
                ((.BOOK_ID));
            String bookNameText =
                ((.BOOK_NAME));
            String bookPublisherText =
                ((.BOOK_PUBLISHER));
            text += "id = " + bookIdText + ",name = " + bookNameText + ",publisher = " + bookPublisherText + "\n";
          }
          ();
          (text);
        }
        break;
      case .provider_update:
        String bookId1 = "2";
        String bookName = "Art";
        String bookPublisher = "TieDao";
        ContentValues values2 = new ContentValues();
        (.BOOK_NAME,
            bookName);
        (.BOOK_PUBLISHER,
            bookPublisher);
        if ("".equals(bookId1)) {
          (
              .CONTENT_URI,
              values2, null, null);
        } else {
          (
              (
                  .CONTENT_URI, bookId1),
              values2, "_id = ? ", new String[]{bookId1});
        }
        break;default:
        ("MainActivity", "default");
        break;
    }
  }
}