美文网首页Android实践Android知识Android开发
Android 使用ContentProvider在应用间共享数

Android 使用ContentProvider在应用间共享数

作者: CoderMiner | 来源:发表于2016-11-03 20:17 被阅读966次

    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{
          //具体的代码请参看源码
          //。。。。
      }
    }
    

    相关文章

      网友评论

        本文标题:Android 使用ContentProvider在应用间共享数

        本文链接:https://www.haomeiwen.com/subject/mhriuttx.html