Android读取内置、外置存储文件内容Uri

记录Android读取内置、外置SD卡和外置USB文件内容处理过程。

1、最开始想到的是获取文件路径,通过FileInputStream来读取。发现内置与外置SD卡路径不同,通过判断也是可以实现的。但是读取USB需要权限申请才行,而且权限申请后系统文件居然不显示USB内容了,只能通过代码读取文件或文件夹自己实现显示,路径还和外置SD卡一样,还不好判断是应该用OTG读取USB还是直接读取外置SD卡,果断放弃了读取USB文件内容,只保留读取SD卡内容。

2、后面想到为什么要将Uri转成路径呢,为什么不直接通过Uri读取文件内容,想到就试试,发现什么都不用判断,不管是内置外置SD卡或者外接USB,直接就可以读取,简直不能再简单了。代码如下:

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_KML && resultCode == RESULT_OK && data != null) {
        String path = data.getData().getPath();
        if (path != null && (path.toUpperCase().endsWith(".KML") || path.toUpperCase().endsWith(".OVKML"))) {
            new Thread(() -> {
                try {
                    KmlReader reader = new KmlReader(kmlReaderCallback);
                    //直接通过Uri读取文件内容,不用判断是内置还是外置SD卡或USB
                    InputStream inputStream = getContentResolver().openInputStream(data.getData());
                    reader.read(inputStream);
                } catch (IOException | XmlPullParserException e) {
                    e.printStackTrace();
                    Logs.e(e.toString());
                    AndroidUtilities.runOnUIThread(() -> ToastUtils.show(getString(R.string.file_open_error)));
                }
            }).start();
        } else {
            ToastUtils.show(getString(R.string.wrong_format));
        }
    }
}

3、有大神知道这是为什么吗?查看源码:

public final @Nullable InputStream openInputStream(@NonNull Uri uri)
        throws FileNotFoundException {
    Objects.requireNonNull(uri, "uri");
    // 这边获取的Uri协议一直都是content,不管是内置还是外置存储
    String scheme = uri.getScheme(); 
    if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
        // Note: left here to avoid breaking compatibility.  May be removed
        // with sufficient testing.
        OpenResourceIdResult r = getResourceId(uri);
        try {
            InputStream stream = r.r.openRawResource(r.id);
            return stream;
        } catch (Resources.NotFoundException ex) {
            throw new FileNotFoundException("Resource does not exist: " + uri);
        }
    } else if (SCHEME_FILE.equals(scheme)) {
        // Note: left here to avoid breaking compatibility.  May be removed
        // with sufficient testing.
        return new FileInputStream(uri.getPath());
    } else {
        // 这是将文件当做Asset资源文件读取?
        AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r", null);
        try {
            return fd != null ? fd.createInputStream() : null;
        } catch (IOException e) {
            throw new FileNotFoundException("Unable to create stream");
        }
    }
}
public FileInputStream createInputStream() throws IOException {
    if (mLength < 0) {
        // ParcelFileDescriptor.AutoCloseInputStream继承自FileInputStream
        return new ParcelFileDescriptor.AutoCloseInputStream(mFd);
    }
    // AutoCloseInputStream继承自ParcelFileDescriptor.AutoCloseInputStream
    return new AutoCloseInputStream(this);
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值