Android 使用ContentProvider在应用间共享数据

Android 使用ContentProvider在应用间共享数据

题图 www.gratisography.com

在开发的过程中,有时会有需求要实现应用程序之间实现数据共享,在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"; //表中的列名

}

继承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);
  }
}

内容提供者

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="http://schemas.android.com/apk/res/android"
    package="com.example.demo.gank">
    。。。。
    <permission android:name="com.example.demo.gank.provider.READ_PROVIDER" android:protectionLevel="normal"></permission>
    <permission android:name="com.example.demo.gank.provider.WRITE_PROVIDER" android:protectionLevel="normal"></permission>

    <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>

运行工程,这个工程应用是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";

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{
      //具体的代码请参看源码
      //。。。。
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容