Android Q中文件沙盒模式读写文件 08-16

嘛~好久没写了

当前Android Q中启用了沙盒存储模式,限制了APP向SDcard中读写文件,当前谷歌尚未将该限制强制执行,可以通过设置属性启用旧存储特性。[原文]

沙盒模式下,每个APP在访问sdcard时会进入过滤视图,只能访问私有路径(Context.getExternalFilesDir())和公共存储空间(多媒体,MediaStore)。

官方文档给对应的解决方案,但是在我看来并不详尽,目前可以看到有以下三个解决方案:

文件位置 所需权限 访问方法 (*) 卸载应用时是否移除文件? 是否需要权限
特定于应用的目录 getExternalFilesDir()
媒体集合 (照片、视频、音频) READ_EXTERNAL_STORAGE (仅当访问其他应用的文件时) MediaStore
下载内容 (文档和 电子书籍) 存储访问框架 (加载系统的文件选择器)

除了第一种写在“/sdcard/Android/data/packageName/file”路径中可以正常使用InputStream&OutputStream读写文件,另外两种方法都无法直接对文件IO操作。
所以后续有向SDcard中写文件的需求优先向APP私有路径中写入。

但是,需要解决APP之间共享文件的场景,比如手机唯一标识配置文件(UUID啥的),这种需求场景需要对MediaStore和SAF存储访问框架做调研。

一、存储访问框架

访问存储框架是一个基于intent发起的文件检索UI,一般只能在View存在时调用系统的文件检索框架,在startActivityForResult() 的回调中收到文件对象。

/**
   * Fires an intent to spin up the "file chooser" UI and select an image.
   * 视图检索文件
   */
  public void performFileSearch() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*");
    startActivityForResult(intent, READ_REQUEST_CODE);
  }

但咱是写SDK的,不能在FileManager单例或者静态方法中读文件的话,对咱毫无意义

二、MediaStore

MediaStore是外部存储空间的公共媒体集合,存放的都是多媒体文件,在API >= 29后加入了download集合

一般Android中通过手机数据库查询Uri来对MediaStore中的文件做查询,然后读取文件,下面以MediaStore.Files查询所有文件为例:

  private void testFiles() {
    ContentResolver contentResolver= this.getApplicationContext().getContentResolver();
    String [] photoColumns=new String[]{
        MediaStore.Files.FileColumns._ID,
        MediaStore.Files.FileColumns.DATA,
        MediaStore.Files.FileColumns.TITLE,
        MediaStore.Files.FileColumns.MIME_TYPE,
        MediaStore.Files.FileColumns.SIZE
    };
    Cursor cursor;
    cursor=contentResolver.query
        (MediaStore.Files.getContentUri("external"), photoColumns,
            null,
            null,
            null);
    while (cursor.moveToNext()) {
      String _id=
          cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
      String filePath=
          cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA));
      String title=
          cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE));
      String mime_type=
          cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE));
      Log.d(TAG, "_id = " + _id);
      Log.d(TAG, "title = " + title);
      Log.d(TAG, "filePath = " + filePath);
      Log.d(TAG, "mime_type = " + mime_type);
    }
    Log.d(TAG, "Finish Cursor Search");
  }

通过上述代码可以在所有文件中找到指定文件,和绝对路径。同理,换成Image、Video、Audio、Downloads都一样,只是在数据库查询时把Uri替换掉。

PS: 但是查询有个致命伤,在开启沙盒模式时,只能在数据库中查询到Image、Video、Audio三个分类视图中的文件,那么我SDK向SDcard中写入的配置文件就不能在沙盒模式下通过数据库查询到。

只能获取到mime_type == {“image/”, “video/”, “audio/*”}这三类文件

这可怎么办呀

上边代码中通过ContentResolver.query查询到文件详情,但如果需要修改文件内容,则使用ContentResolver.openFileDescriptor()获取单个文件描述符。配置文件拿不到,先不管这个文件读写了。

小结

目前只能先使用官方支持的规避方案:通过设置android:requestLegacyExternalStorage="false"属性来关闭APP的沙盒机制。
我还会回来的

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

推荐阅读更多精彩内容