Android 使用ContentProvider在應用間共享數據

Android 使用ContentProvider在應用間共享數據

在開發的過程中,有時會有需求要實現應用程序之間實現數據共享,在 Android 系統中提供了一個內容提供者 ContentProvider

可以實現這個功能,需要繼承這個類,并實現相關的接口,其他的應用就可以通過uri來訪問相關的數據,在 Android 中最常見的

內容提供者就是 MediaProvider ,所有的應用都可以通過uri來訪問系統中的媒體數據,我們也可以實現這樣的功能,首先就是要

確定你的應用是否要向外提供數據

設計數據存儲

我們這里是通過數據庫最為媒介來提供數據,需要設計具體的數據庫的數據結構,通過系統提供的 SQLiteOpenHelper 類來創建數據庫

核心的代碼:

簡單的數據結構,根據自己的需求設計數據庫的數據結構

public final class Settings implements BaseColumns{
    private Settings(){}

public static final String TABLE_NAME = "settings";  //數據庫中標的名稱

public static final String COLUMN_NAME_TITLE = "name"; //表中的列名
public static final String COLUMN_NAME_VALUE = "value"; //表中的列名

}</code></pre>

繼承 SQLiteOpenHelper 來創建數據庫

private static class DatabaseHelper extends SQLiteOpenHelper{
    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS settings");
    onCreate(db);
}

@Override
public void onCreate(SQLiteDatabase db) {
    String sql = " CREATE TABLE "+Settings.TABLE_NAME +" ("
            + Settings._ID +" INTEGER PRIMARY KEY,"
            + Settings.COLUMN_NAME_TITLE +" TEXT,"
            + Settings.COLUMN_NAME_VALUE +" TEXT"
            + ");";
    db.execSQL(sql);
}

}</code></pre>

內容提供者

ContentProvider 需重載的接口如下:

  • public Uri insert(Uri uri, ContentValues values)
  • public int delete(Uri uri, String selection, String[] selectionArgs)
  • public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
  • public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  • public String getType(Uri uri)

    URI的設計

    [content://][com.example.demo.gank.provider][/settings][/1]

    |-----A-----|---------------B---------------|-----C----|--D-|

  • A:是Scheme,固定為 content://

  • B: 是Authority,用來識別特定的 Content Provider ,一般使用應用的報名來命名
  • C:是資源的路徑
  • D: 資源的ID

    為了傳入的uri執行不同的操作,可以通過Android中的 UriMatcher 實體類,將uri映射不同的內容

設置權限

可以為provider設置權限

<?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="

  <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">

      <provider
          android:authorities="com.example.demo.gank.provider"
          android:name="com.example.demo.gank.provider.SettingsProvider"
          android:readPermission="com.example.demo.gank.provider.READ_PROVIDER"
          android:writePermission="com.example.demo.gank.provider.WRITE_PROVIDER"
          android:exported="true">

      </provider>
  </application>

</manifest></code></pre>

運行工程,這個工程應用是A,A應用安裝之后,這個應用就是一個內容提供者

再建一個工程B,在B中訪問數據,這個是工程B中訪問數據庫的代碼

Uri uri = Uri.parse("content://com.example.demo.gank.provider/settings"); //和A中提供的uri保持一致
  Cursor c = getContentResolver().query(uri,new String[]{"name","value"}," name =? ", //是在A中定義的數據庫的字段
                    new String[]{"settings"},null);
            if(c != null && c.moveToFirst()){
                String value = c.getString(c.getColumnIndex("value"));
                log.e(TAG,"=================query value: "+value);
            }

在B中的 AndroidManifest.xml' 中加入相關的權限

<uses-permission android:name="com.example.demo.gank.provider.READ_PROVIDER"/>
  <uses-permission android:name="com.example.demo.gank.provider.WRITE_PROVIDER"/>

運行結果就是得到A中數據庫的內容

代碼

Settings.java

public static final String SCHEME = "content://";

private static final String PATH_SETTINGS = "/settings"; private static final String PATH_SETTINGS_ID = "/settings/";

public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.example.demo.gank.settings"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.example.demo.gank.settings";</code></pre>

SettingsProvider.java

public class SettingsProvider extends ContentProvider{

private static final String DB_NAME = "settings.db";
private static final int DB_VERSION = 1;

private static final int SETTINGS = 1;
private static final int SETTINGS_ID = 2;
//....

static {
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    sUriMatcher.addURI(Settings.AUTHORITY,"settings",SETTINGS);
    sUriMatcher.addURI(Settings.AUTHORITY,"settings/#",SETTINGS_ID);

    sProjectionMap = new HashMap<>();
    sProjectionMap.put(Settings.COLUMN_NAME_TITLE,Settings.COLUMN_NAME_TITLE);
    sProjectionMap.put(Settings.COLUMN_NAME_VALUE,Settings.COLUMN_NAME_VALUE);
    sProjectionMap.put(Settings._ID,Settings._ID);
}

@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
    return null;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    return 0;
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    return 0;
}

@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    return null;
}

@Nullable
@Override
public String getType(Uri uri) {
    return null;
}

@Override
public boolean onCreate() {
    mOPenHelper = new DatabaseHelper(getContext());
    return true;
}

private static class DatabaseHelper extends SQLiteOpenHelper{
    //具體的代碼請參看源碼
    //。。。。
}

}</code></pre>

 

來自:http://www.jianshu.com/p/f69c7e0a4ba5

 

 本文由用戶 1294055889 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!