美文网首页Android
Android8.0文件读写适配

Android8.0文件读写适配

作者: 费麭 | 来源:发表于2017-12-18 23:58 被阅读0次

写在前面:本文是实际开发中遇到的坑点,记为笔记

1. 背景

公司给配了一台最新的华为手机,是android 8.0的,app装上去,没多久发现app里上传文件有一些上传不上去。

2. 问题

走了一遍debug,发现获取文件的路径失败。原先的逻辑是获取文件的path:如果是文件,返回文件的路径;如果是content,通过contentResolver-cursor查询并返回content的实际文件路径。但是在8.0上,如果是别的app的FileProvider提供的只能临时读写的文件,是获取不到实际路径的。怎么办?

3. 方案

我先去网上查了一些别人的方案,搜到的全是关于7.0上如何使用FileProvider。去android官网看了官方资料也没有找到方案。偶然看到ContentResolver可以读取content://xxx/xxx/xx的Uri,我立马试了一下,果然可行。

Uri data = getIntent().getData();
if (data != null) {
    InputStream inputStream = null;
    try {
        inputStream = getContentResolver().openInputStream(data);
        ImageView imageView = findViewById(R.id.imageView);
        imageView.setImageBitmap(BitmapFactory.decodeStream(inputStream));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        Toast.makeText(this, "load failed", Toast.LENGTH_SHORT).show();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException ignored) {
            }
        }
    }
}
4. 总结

回头总结有趣的发现,ContentResolver也是很基础的组件了,
官方描述是:

  1. ContentProvider 用于app间共享数据
  2. ContentResolver 读写这些共享数据

FileProvider就是一种ContentProvider。

ContentResolver 有很多很实用的方法:

ContentResolver cr = getContentResolver();
// r for read mode,  rw for read/write mode
ParcelFileDescriptor pfd = cr.openFileDescriptor(uri, "r");
InputStream is = cr.openInputStream(uri);
OutputStream os = cr.openOutputStream(uri, "rw");
AssetFileDescriptor afd = cr.openAssetFileDescriptor(uri, "rw");

// crud
Uri uri2 = cr.insert(uri, ...);
Cursor cursor = cr.query(uri, ...);
int deletedRows = cr.delete(uri, ...);
int updatedRows = cr.update(uri, ...);

// 获取MIME类型,如text/html
String type = cr.getType(uri);

要多使用起来。

最后,在解决这个问题的时候,我起初并没有找到完美的解决方案。迷惘之际,同事给我提供了一种思路:当你找不到最优解决方案的时候,先找一个临时的解决方案,将问题的风险先降下来一部分。所以当时使用了一个字符串拼接获取路径的方法,解决了部分问题。这个思路可以采纳,避免时间浪费。

相关文章

网友评论

    本文标题:Android8.0文件读写适配

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