一、介绍
ContentProvider为应用程序之间共享数据提供统一的接口,ContentProvider本身并没有存储功能,它最终还是通过SQLite存储数据。
二、应用场景
增删改查其他应用程序中私有数据。
三、使用步骤
1.写一个类继承ContentProvider,实现增删改查的方法,声明uriMatcher匹配规则,来检查uri路径是否正确;
2.清单文件配置:
<provider
android:name="com.example.storagedemo.provider.MyContentProvider" android:authorities="com.example.storagedemo.provider.MyContentProvider"
android:exported="true" />
android:exported=”true”表示允许其他应用程序访问该provider,android:authorities是该provider唯一的标识,其他应用程序就是通过该标识找到它。
3.在另一个程序里面通过contentResolver增删改查。
四、示例代码
继承contentResolver的类MyContentProvider
package com.example.storagedemo.provider;
import com.example.storagedemo.db.DBUtil;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
public class MyContentProvider extends ContentProvider {
private static final UriMatcher sUriMatcher;
private DBUtil dbUtil;
@Override
public boolean onCreate() {
dbUtil = new DBUtil(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor c = null;
switch (sUriMatcher.match(uri)) {
case ProviderConstants.DEVICE_COLLECTION:
c = dbUtil.query();
break;
case ProviderConstants.DEVICE_SINGLE:
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
return c;
}
@Override
public String getType(Uri uri) {
switch (sUriMatcher.match(uri)) {
case ProviderConstants.DEVICE_COLLECTION:
return ProviderConstants.CONTENT_TYPE;
case ProviderConstants.DEVICE_SINGLE:
return ProviderConstants.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
switch (sUriMatcher.match(uri)) {
case ProviderConstants.DEVICE_COLLECTION:
return null;
case ProviderConstants.DEVICE_SINGLE:
long rowid = dbUtil.insert(initialValues.getAsString(ProviderConstants.FILD_NAME));
Uri insertUri = ContentUris.withAppendedId(uri, rowid);
notifyChange(uri);
return insertUri;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
int count = 0;
int a = sUriMatcher.match(uri);
switch (sUriMatcher.match(uri)) {
case ProviderConstants.DEVICE_COLLECTION:
//count = dbUtil.deleteAll();
break;
case ProviderConstants.DEVICE_SINGLE:
count = dbUtil.delete(where);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
notifyChange(uri);
return count;
}
private void notifyChange(Uri uri) {
Context context = this.getContext();
if (context != null) {
context.getContentResolver().notifyChange(uri, null);
}
}
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
int count = 0;
switch (sUriMatcher.match(uri)) {
case ProviderConstants.DEVICE_COLLECTION:
break;
case ProviderConstants.DEVICE_SINGLE:
return dbUtil.update(values.getAsString(ProviderConstants.FILD_NAME));
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
notifyChange(uri);
return count;
}
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(ProviderConstants.AUTHORITY, ProviderConstants.PATH_COLLECTION, ProviderConstants.DEVICE_COLLECTION);
sUriMatcher.addURI(ProviderConstants.AUTHORITY, ProviderConstants.PATH_SINGLE, ProviderConstants.DEVICE_SINGLE);
}
}
常量类ProviderConstants
package com.example.storagedemo.provider;
import android.net.Uri;
public class ProviderConstants {
// 这个是每个Provider的标识,在Manifest中使用
public static final String AUTHORITY = "com.example.storagedemo.provider.MyContentProvider";
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.jacp.demo";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.jacp.demo";
public static final int DEVICE_COLLECTION = 1;
public static final int DEVICE_SINGLE = 2;
public static final String PATH_SINGLE = "StrorageMsg/#";
public static final String PATH_COLLECTION = "StrorageMsg";
public static final String CONTENT_URI_SINGLE = "content://" + AUTHORITY + "/" + PATH_SINGLE;
public static final String CONTENT_URI_COLLECTION = "content://" + AUTHORITY + "/" + PATH_COLLECTION;
public static final Uri URI_COLLECTION = Uri.parse(CONTENT_URI_COLLECTION);
public static final Uri URI_SINGLE = Uri.parse("content://" + AUTHORITY + "/StrorageMsg/1");
public static final String FILD_NAME = "msg";
}
ContentResolverUtil类,本应用程序或者其他应用程序就是通过该类实现对保存于该应用程序SQLite中的数据进行增删改查的。
package com.example.storagedemo.provider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
public class ContentResolverUtil {
public static String getInfo(Context context) {
Cursor cursor = query(context);
String msg = null;
if (cursor != null) {
while (cursor.moveToNext()) {
msg = cursor.getString(cursor.getColumnIndex(ProviderConstants.FILD_NAME));
}
cursor.close();
}
return msg;
}
public static void insert(Context context, String msg) {
ContentResolver resolver = context.getContentResolver();
ContentValues values = new ContentValues();
values.put(ProviderConstants.FILD_NAME, msg);
resolver.insert(ProviderConstants.URI_SINGLE, values);
}
public static void deleteAll(Context context) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(ProviderConstants.URI_COLLECTION, null, null);
}
public static void update(Context context, String msg) {
ContentResolver resolver = context.getContentResolver();
//把id为1的记录的name字段值更改新为liming
ContentValues updateValues = new ContentValues();
updateValues.put("name", "liming");
//resolver.update(updateIdUri, updateValues, null, null);
}
private static Cursor query(Context context) {
ContentResolver resolver = context.getContentResolver();
return resolver.query(ProviderConstants.URI_COLLECTION, null, null, null, null);
}
public static boolean isExist(Context context) {
return query(context) != null;
}
}
DBHelper类
package com.example.storagedemo.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "zeng.db";
private static final int DATABASE_VERSION = 1;
DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS StrorageMsg" +
"(_id INTEGER PRIMARY KEY AUTOINCREMENT,msg VARCHAR)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
}
}
DBUtil类
package com.example.storagedemo.db;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.List;
public class DBUtil {
public static final String MSG = "msg";
public static final String TABLE_NAME = "StrorageMsg";
private SQLiteDatabase db;
public DBUtil(Context context) {
DBHelper helper = new DBHelper(context);
db = helper.getWritableDatabase();
}
public void insert(List<String> msgs) {
db.beginTransaction();
try {
for (String msg : msgs) {
db.execSQL("INSERT INTO " + TABLE_NAME+ " VALUES(null,?)",
new Object[]{msg});
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
public long insert(String msg) {
ContentValues cv = new ContentValues();
cv.put(MSG, msg);
return db.insert(TABLE_NAME, null, cv);
}
public int update(String msg) {
ContentValues cv = new ContentValues();
cv.put("msg", msg);
return db.update(TABLE_NAME, cv, MSG + " = ?", new String[]{msg});
}
public int delete(String msg) {
return db.delete(TABLE_NAME, MSG + "= ?", new String[]{msg});
}
public Cursor query() {
return db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
}
public void closeDB() {
db.close();
}
}
MainActivity中调用
package com.example.storagedemo;
import com.example.storagedemo.R;
import com.example.storagedemo.db.DBUtil;
import com.example.storagedemo.provider.ContentResolverUtil;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.util.Log;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contentProvider();
}
private void contentProvider() {
ContentResolverUtil.insert(this, "This is contentProvider");
String result = ContentResolverUtil.getInfo(this);
Log.d("zeng", "contentProvider result: " + result);
}
}