1.前序:
提到ContentProvider ,我们首先想到的是“增删查改”,数据库访问,有点雷雨jdbc 其实还提供的一个服务,共享文件。
2.使用场景:
1.进程之间共享文件数据
2.由于权限问题,需要将数据迁移到低权限区域问题(我们知道Android自L开始,权限越加严格,很多文件不发轻易被外部访问)

3.实例

问题:A B 两个进程,且由于权限不可互访. B进程需要访问A进程数据怎么办呢?
这里采用方案:将文件复制到B权限目录去是可行的

code:
1).A进程,如何复制到B
Uri  uriA, uriB
Uri uirBProvider= Uri.parse("content://" + AUTHORITY + "/"
            +TABLE);
Uri uriB = mContentResolver.insert(uirBProvider, mContentValues);(1)//这里(1),(2),(3),(4)标注为按顺序来

inputStream = mContentResolver.openInputStream(uriA);  (2)
outputStream = mContentResolver.openOutputStream(uriB);
byte[] data = new byte[3 * 1024];
int num;
while ((num = inputStream.read(data)) > 0) {
    outputStream.write(data, 0, num);
}

2).B进程,复制到B的哪里去了呢?B进程的provider是BProvider

OurSQLiteOpenHelper  mDbHelper
ContentValues        values
BContentProvider{

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //这里为何要插入呢?这里表中有这两个字段:一个真是绝对路径,一个存uri(方便查询真实路径)。这里先创建好目准备存储文件,同事存储好//uri+rowId
        //方便(2)处的的使用,(2)处最终调用(3)才使用到这里的存储值
        values = values.put("_data", createDataFile());(4)
        rowId = mDbHelper.getWritableDatabase().insert(TABLE, "", values);
        Uri rowUri = ContentUris.appendId(uri.buildUpon(), rowId).build();
        return  rowUri;
    }

  //这里很重要,复制文件需要重写这个方法,(2)处openOutputStream,打开的就是这里查到的文件,也是insert生成的文件
    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        log("openFile: " + uri + "path:" + uri.getPath());
        return openFileHelper(uri, mode);(3)
    }

}
3).B进程中,(3)处代码的意义?
其实是ContentProvider自带的,当然我们可以重写(这里未粘贴全),其实就是获取(4)处createDataFile生成的文件地址

protected final @NonNull ParcelFileDescriptor openFileHelper(@NonNull Uri uri,
        @NonNull String mode) throws FileNotFoundException {
   //"_data" 字段即是(4)处存入的地址
    Cursor c = query(uri, new String[]{"_data"}, null, null, null);
    int count = (c != null) ? c.getCount() : 0;
    ........
    c.moveToFirst();
    int i = c.getColumnIndex("_data");
    String path = (i >= 0 ? c.getString(i) : null);
    c.close();
    return ParcelFileDescriptor.open(new File(path), modeBits);
}

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  6. Android(安卓)Resource介绍和使用
  7. Android(安卓)NDK入门实例 计算斐波那契数列二生成.so库文件
  8. Android系统文件夹目录结构详解
  9. Android进程通信Binder(1)-Binder进程通信的思想

随机推荐

  1. Android(安卓)ListView刷新 (Handler/Ser
  2. Android-NDK开发之基础--Android(安卓)JN
  3. Android交通违章查询开发实例(一)(HttpClien
  4. Android实现机制(二)——View绘制机制
  5. 好文章
  6. Android横竖屏切换重载问题与小结
  7. [Android算法] bitmap 将图片压缩到指定
  8. Android中的FrameLayout帧布局
  9. Android(安卓)自定义kotlin中BaseRecycle
  10. "Could not create java virtual machine