总结
- ContentProvider是android系统提供的一种跨进程数据共享机制,例如系统的MediaProvider、SettingProvider
- 自己定义ContentProvider通过继续一个ContentProvider,实现增删改查方法,其他程序则通过ContentResolver进行调用
1.自定义ContentProvider
我们实现一个k-v数据查询,代码如下
public class KVDataProvider extends ContentProvider {
private static final String TAG = "KVDataProvider";
// uri格式
// frameworks/base/core/java/android/content/ContentUris.java
// 组成格式:content://authority/path/id
private static final String AUTHORITY = "com.example.contentprovider_KVContentProvider";
private static final String PATH = "kvdata";
// 创建UriMatcher对象,主要作用是根据 Uri 匹配对应的数据表
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int CODE_ALL = 1;
private static final int CODE_STRING = 2;
static {
uriMatcher.addURI(AUTHORITY, PATH, CODE_ALL);
uriMatcher.addURI(AUTHORITY, PATH + "/string", CODE_STRING);
uriMatcher.addURI(AUTHORITY, PATH + "/string/*", CODE_STRING);
}
// 使用sp进行数据存储
private SharedPreferences sharedPreferences;
@Override
public boolean onCreate() {
Log.d(TAG, ">>>onCreate<<<");
sharedPreferences = getContext().getSharedPreferences(PATH, Context.MODE_PRIVATE);
return false;
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
Log.d(TAG, ">>>onTrimMemory<<<");
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Log.d(TAG, ">>>query<<<");
int code = uriMatcher.match(uri);
if (code == CODE_STRING) {
// 用selection 作为sp的key去查询
String value = sharedPreferences.getString(selection, null);
MatrixCursor cursor = new MatrixCursor(new String[]{"string"});
cursor.addRow(new Object[]{value});
return cursor;
}
return null;
}
// 用于指定某种扩展名的文件与应用程序的对应关系,例如.txt --> text/plain。一般返回null即可,不需要定义type
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
Log.d(TAG, ">>>insert<<<");
String key = uri.getLastPathSegment();
String value = values.getAsString("string");
Log.d(TAG, "insert: " + key + " --> " + value);
sharedPreferences.edit().putString(key, value).apply();
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.d(TAG, ">>>delete<<<");
int code = uriMatcher.match(uri);
if (code == CODE_STRING) {
// 用selection 作为sp的key去查询
sharedPreferences.edit().remove(selection).apply();
return 1;
}
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
Log.d(TAG, ">>>delete<<<");
return 0;
}
}
2.配置到mainfest中
<provider
android:enabled="true"
android:exported="true"
android:name=".KVDataProvider"
android:authorities="com.example.contentprovider_KVContentProvider" />
3.其他程序使用
public final class KVDataQuery {
private static final String SCHEME = "content://";
private static final String AUTHORITY = "com.example.contentprovider_KVContentProvider";
private static final String PATH_STRING = "kvdata/string";
public static String getData(Context context, String key) {
Cursor cursor = context.getContentResolver().query(Uri.parse(SCHEME + AUTHORITY + "/" + PATH_STRING), null, key, null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToNext();
String value = cursor.getString(cursor.getColumnIndex("string"));
cursor.close();
return value;
}
return null;
}
public static void setData(Context context, String key, String value) {
ContentValues values = new ContentValues(1);
values.put("string", value);
context.getContentResolver().insert(Uri.parse(SCHEME + AUTHORITY + "/" + PATH_STRING + "/" + key), values);
}
}
4.运行示例
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String value = KVDataQuery.getData(this, "test");
Log.d(TAG, "get: key=test value=" + value);
KVDataQuery.setData(this, "test", "12345");
Log.d(TAG, "set: key=test value=12345");
value = KVDataQuery.getData(this, "test");
Log.d(TAG, "get: key=test value=" + value);
}
}