Android鐘對(duì)數(shù)據(jù)的存儲(chǔ)與訪問(wèn)是很有必要的译打,在Android中對(duì)于數(shù)據(jù)存儲(chǔ)提供了如下幾種方法:
文件形式
SharedPreferences(參數(shù)-鍵值對(duì)形式)
SQLite數(shù)據(jù)庫(kù)(空間2T)
Content provider (Android組件-內(nèi)容提供者)
網(wǎng)絡(luò)(云存儲(chǔ))
這次寫的是Content provider (Android組件-內(nèi)容提供者)對(duì)外共享數(shù)據(jù)嘱蛋。將一個(gè)應(yīng)用中的數(shù)據(jù)庫(kù)通過(guò)ContentProvider共享給其他應(yīng)用,增剪验,刪苹祟,改显拳,查窿克。具體數(shù)據(jù)庫(kù)操作棕硫,請(qǐng)看上一篇
因?yàn)镃ontentProvider是Android四大組件之一髓涯,所以使用ContentProvider·是需要在清單文件AndroidManifest注冊(cè)的
<!--authorities 是provider的唯一標(biāo)識(shí) ,name是要注冊(cè)的ContentProvider的路徑-->
<provider
android:authorities="com.example.administrator.foundationdemo.provider.PersonProvider"
android:name="com.example.administrator.foundationdemo.provider.PersonProvider"/>
實(shí)現(xiàn)類PersonProvider代碼
package com.example.administrator.foundationdemo.provider;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.Nullable;
import com.example.administrator.foundationdemo.sqlite.service.MySQLite;
/**
* Created by Administrator on 2016/12/14.
*/
public class PersonProvider extends ContentProvider {
/** Uri講解:
* Uri代表要操作的數(shù)據(jù)哈扮,Uri主要包含了兩部分信息:
* 1.需要操作的ContentProvider
* 2.對(duì)ContentProvider中的什么數(shù)據(jù)進(jìn)行操作
* 一個(gè)Uri由以下幾部分組成:
* content://com.example.administrator.foundationdemo.provider.PersonProvider/person/10
* |-scheme-|------------主機(jī)名或authority(唯一標(biāo)識(shí))----------------------|-路徑-|-ID-|
* ContentProvider(類容提供者)的scheme已經(jīng)由Android所規(guī)定纬纪,scheme為:content://
* 主機(jī)名(或叫Authority)用于唯一標(biāo)識(shí)這個(gè)ContentProvider,外部調(diào)用者可以根據(jù)這個(gè)標(biāo)識(shí)找到他調(diào)用共享數(shù)據(jù)
* 路徑(path)可以用來(lái)表示我們要操作的數(shù)據(jù)滑肉,路徑結(jié)構(gòu)根據(jù)實(shí)際情況而定包各,如下:
* 要操作person表中id為10的記錄,可以這樣構(gòu)建路徑:/person/10
* 要操作person表中id為10的記錄的name字段靶庙,可以這樣構(gòu)建路徑:/person/10/name
* 要操作那個(gè)表XXX,那么機(jī)構(gòu)路徑就為:/XXX
* 將字符串轉(zhuǎn)換成Uri
* 調(diào)用方法:Uri uri = Uri.parse("string")
*/
private MySQLite mySQLite;
//用于判斷Uri是否匹配類
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
//匹配碼
private static final int PERSONS = 1;
private static final int PERSON = 2;
static {
//添加待匹配的Uri 主機(jī)名(或叫Authority) //路徑 匹配碼
URI_MATCHER.addURI("com.example.administrator.foundationdemo.provider.PersonProvider","person",PERSONS);
//添加待匹配的Uri 主機(jī)名(或叫Authority) //路徑 #代表未知數(shù)字 匹配碼
URI_MATCHER.addURI("com.example.administrator.foundationdemo.provider.PersonProvider","person/#",PERSON);
}
@Override
public boolean onCreate() {
//ContentProvider實(shí)例被創(chuàng)建時(shí)系統(tǒng)調(diào)用
mySQLite = new MySQLite(this.getContext(),"mySQLite");
return false;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] columns, String whereClause, String[] whereArgs, String orderBy) {
//供外部應(yīng)用查詢ContentProvider內(nèi)的數(shù)據(jù)
SQLiteDatabase db = mySQLite.getWritableDatabase();
//操作ContentProvider數(shù)據(jù)前问畅,先判斷Uri是否匹配,判斷scheme與路徑是否是要操作的表的路徑
switch (URI_MATCHER.match(uri)){
case PERSONS:
return db.query("person",columns, whereClause,whereArgs,null,null,orderBy);
case PERSON:
long rowid = ContentUris.parseId(uri);//獲取Uri中操作數(shù)據(jù)的ID
String where = "personId="+rowid;//獲取操作數(shù)據(jù)庫(kù)的條件語(yǔ)句
if (null == whereClause||"".equals(whereClause)){//判斷是否還有其他條件語(yǔ)句
where += " and "+ whereClause;//組拼條件語(yǔ)句
}
return db.query("person",columns, where,whereArgs,null,null,orderBy);
default:
throw new IllegalArgumentException("this id Unknown Uri "+uri);
}
}
@Nullable
@Override
public String getType(Uri uri) {
/**
* 用于返回要操作數(shù)據(jù)MIME類型(類容類型)
* 1六荒、如果操作的類型屬于集合類型數(shù)據(jù)护姆,那么MIME類型字符串應(yīng)該以‘vud.android.cursor.dir/’開(kāi)頭
* 例如:如果要得到所有person記錄的Uri為:content://com.example.administrator.foundationdemo.provider.PersonProvider/person
* 那么要返回的MIME類型字符串應(yīng)該為:vud.android.cursor.dir/person
* 2、如果操作的類型屬于非集合類型數(shù)據(jù)恬吕,那么MIME類型字符串應(yīng)該以‘vud.android.cursor.item/’開(kāi)頭
* 例如:如果要得到id為1的person記錄的Uri為:content://com.example.administrator.foundationdemo.provider.PersonProvider/person/1
* 那么要返回的MIME類型字符串應(yīng)該為:vud.android.cursor.item/person
*/
switch (URI_MATCHER.match(uri)){
case PERSONS:
return "vud.android.cursor.dir/person";
case PERSON:
return "vud.android.cursor.item/person";
default:
throw new IllegalArgumentException("this id Unknown Uri "+uri);
}
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
//供外部應(yīng)用向ContentProvider內(nèi)插入數(shù)據(jù)
SQLiteDatabase db = mySQLite.getWritableDatabase();
//操作ContentProvider數(shù)據(jù)前签则,先判斷Uri是否匹配,判斷scheme與路徑是否是要操作的表的路徑
switch (URI_MATCHER.match(uri)){
case PERSONS:
long rowid = db.insert("person","nsme",contentValues);//主鍵值
//返回修改數(shù)據(jù)的Uri
//方法一:手動(dòng)書寫(易錯(cuò))
Uri insertUri = Uri.parse("content://com.example.administrator.foundationdemo.provider.PersonProvider/person/"+rowid);
//方法二:Android提供API(推薦)
insertUri = ContentUris.withAppendedId(uri,rowid);
//設(shè)置數(shù)據(jù)的變化通知--> (uri,設(shè)置必須要的數(shù)據(jù)變化的監(jiān)聽(tīng)者)
this.getContext().getContentResolver().notifyChange(uri,null);
return insertUri;
default:
throw new IllegalArgumentException("this id Unknown Uri "+uri);
}
}
@Override
public int delete(Uri uri, String whereClause, String[] whereArgs) {
//供外部應(yīng)用刪除ContentProvider內(nèi)的數(shù)據(jù)
SQLiteDatabase db = mySQLite.getWritableDatabase();
//操作記錄數(shù)
int number = 0;
//操作ContentProvider數(shù)據(jù)前铐料,先判斷Uri是否匹配渐裂,判斷scheme與路徑是否是要操作的表的路徑
switch (URI_MATCHER.match(uri)){
case PERSONS:
number = db.delete("person",whereClause,whereArgs);
break;
case PERSON:
long rowid = ContentUris.parseId(uri);//獲取Uri中操作數(shù)據(jù)的ID
String where = "personId="+rowid;//獲取操作數(shù)據(jù)庫(kù)的條件語(yǔ)句
if (null == whereClause||"".equals(whereClause)){//判斷是否還有其他條件語(yǔ)句
where += " and "+ whereClause;//組拼條件語(yǔ)句
}
number = db.delete("person",where,whereArgs);
break;
default:
throw new IllegalArgumentException("this id Unknown Uri "+uri);
}
//返回操作記錄數(shù)
return number;
}
@Override
public int update(Uri uri, ContentValues contentValues, String whereClause, String[] whereArgs) {
//供外部應(yīng)用更新ContentProvider內(nèi)的數(shù)據(jù)
SQLiteDatabase db = mySQLite.getWritableDatabase();
//操作記錄數(shù)
int number = 0;
//操作ContentProvider數(shù)據(jù)前,先判斷Uri是否匹配钠惩,判斷scheme與路徑是否是要操作的表的路徑
switch (URI_MATCHER.match(uri)){
case PERSONS:
number = db.update("person", contentValues, whereClause,whereArgs);
break;
case PERSON:
long rowid = ContentUris.parseId(uri);//獲取Uri中操作數(shù)據(jù)的ID
String where = "personId="+rowid;//獲取操作數(shù)據(jù)庫(kù)的條件語(yǔ)句
if (null == whereClause||"".equals(whereClause)){//判斷是否還有其他條件語(yǔ)句
where += " and "+ whereClause;//組拼條件語(yǔ)句
}
number = db.update("person",contentValues,where,whereArgs);
break;
default:
throw new IllegalArgumentException("this id Unknown Uri "+uri);
}
//返回操作記錄數(shù)
return number;
}
}
監(jiān)聽(tīng)數(shù)據(jù)變化的SourceProviderActivity代碼
package com.example.administrator.foundationdemo.provider;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.example.administrator.foundationdemo.R;
public class SourceProviderActivity extends AppCompatActivity {
//要監(jiān)聽(tīng)其變化的Uri
private Uri uri = Uri.parse("content://com.example.administrator.foundationdemo.provider.PersonProvider/person");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_source_provider);
//設(shè)置監(jiān)聽(tīng)器
this.getContentResolver().registerContentObserver(uri,true,new PersonCotentObserver(new Handler()));
}
private class PersonCotentObserver extends ContentObserver{
public PersonCotentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
//是否是自己修改數(shù)據(jù)
if (!selfChange){
//select * from person order by personId decs limit 1
Cursor cursor = getContentResolver().query(uri, null, null, null, "personId decs limit 1");
if (cursor.moveToFirst()){
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.d("FLY",name);
}
}
}
}
}
操作類ProviderActivity代碼:
package com.example.administrator.foundationdemo.provider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.example.administrator.foundationdemo.R;
public class ProviderActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_provider);
}
private void testInsert(){
//別的應(yīng)用添加類容提供者數(shù)據(jù)需要代碼
Uri uri = Uri.parse("content://com.example.administrator.foundationdemo.provider.PersonProvider/person");
ContentResolver contentResolver = this.getContentResolver();
ContentValues values = new ContentValues();
values.put("name","laowang");
values.put("phone", "12345678910");
contentResolver.insert(uri, values);
}
private void testDelete(){
//別的應(yīng)用添加類容提供者數(shù)據(jù)需要代碼
Uri uri = Uri.parse("content://com.example.administrator.foundationdemo.provider.PersonProvider/person/1");
ContentResolver contentResolver = this.getContentResolver();
contentResolver.delete(uri, null, null);
}
private void testUpdate(){
//別的應(yīng)用添加類容提供者數(shù)據(jù)需要代碼
Uri uri = Uri.parse("content://com.example.administrator.foundationdemo.provider.PersonProvider/person/1");
ContentResolver contentResolver = this.getContentResolver();
ContentValues values = new ContentValues();
values.put("name","xxxxx");
contentResolver.update(uri, values, null, null);
}
private void testQuery(){
//別的應(yīng)用添加類容提供者數(shù)據(jù)需要代碼
Uri uri = Uri.parse("content://com.example.administrator.foundationdemo.provider.PersonProvider/person");
ContentResolver contentResolver = this.getContentResolver();
//所有字段所有類容 id升序排列
Cursor cursor = contentResolver.query(uri, null, null, null, "personId asc");
while (cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.d("FLY","name:"+name+"\n");
}
cursor.close();
}
}