【问题标题】:check if a uri is from removable storage检查 uri 是否来自可移动存储
【发布时间】:2018-02-11 10:08:23
【问题描述】:

如何检查从 action_open_document 树中选择的 Uri 用户是否来自可移动 SD 卡? 我检查了这个,但它对于主 sd 卡和可移动 sd 卡是一样的! 还有其他方法吗?

   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

     String id=DocumentsContract.getTreeDocumentId(uri);

                    Uri mainuri=DocumentsContract.buildDocumentUriUsingTree(uri,id);


                    grantUriPermission(G.context.getPackageName(), uri,   Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

          if(   "com.android.externalstorage.documents".equals(uri.getAuthority())){

// its return true for primary and removable sd card !!


}

【问题讨论】:

    标签: android uri removable-storage


    【解决方案1】:

    没有。

    不要求以任何方式识别来自存储提供商的Uri。您的假设(对于某个存储提供程序的权限是 com.android.externalstorage.documents)在任何 Android 设备上都不必正确。设备制造商可以使用自己的Uri 结构提供自己的存储提供商。

    【讨论】:

    • 有没有办法确定用户选择的可移动存储?
    • @Mostafa:正如我所写,不。此外,您的应用程序不应该关心。如果您使用的是存储访问框架,请平等对待所有存储提供者。
    • 我也发布了你的另一个答案,我的问题与这个问题非常相似 - stackoverflow.com/questions/52830390/…
    • @Mostafa 如果您在 uri.getPath() 中找到类似 XXXX-XXXX 的字符串,则它是可移动媒体
    【解决方案2】:

    由于android Q,你必须使用SAF。为了知道 URI 是否是可移动媒体,您可以尝试使用路径字符串:如果您在 uri.getPath() 中找到类似“HHHH-HHHH:”(其中 H = 十六进制字符串字符)的字符串,则表示是一种可移动媒体。

     /**
     * Check if SAF uri point to a removable media
     * Search for this regular expression:
     * ".*\\b[ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]]-[ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]]:\\b.*"
     * @param uri: SAF URI
     * @return true if removable, false if is internal
     */
    public boolean isRemovable (Uri uri) {
        String path = uri.getPath();
        String r1 = "[ABCDEF[0-9]]";
        String r2 = r1 + r1 + r1 + r1;
        String regex = ".*\\b" + r2 + "-" + r2 + ":\\b.*";
        if (path != null) {
            return path.matches(regex);
        } else return false;
    }
    

    最后一种方法使用较少的内存。以下方法更快,由于正则表达式字符串消耗更多内存,但更短且更快:

    public boolean isRemovable (Uri uri) {
        String path = uri.getPath();
        if (path != null) {
            return path.matches(".*\\b[ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]]-[ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]]:\\b.*");
        } else return false;
    }
    

    更新: 原始正则表达式仅适用于 SDCARD 上的子文件夹。要包含根目录,请删除最后的 '\d' 字符。这是正确的正则表达式:

    ".*\\b[ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]]-[ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]][ABCDFE[0-9]]:.*"
    

    所以正确的函数是:

    private boolean isRemovable (Uri uri) {
        String path = uri.getPath();
        String r1 = "[ABCDEF[0-9]]";
        String r2 = r1 + r1 + r1 + r1;
        String regex = ".*\\b" + r2 + "-" + r2 + ":.*";
        if (path != null) {
            return path.matches(regex);
        } else return false;
    }
    

    【讨论】:

    • 这为我解决了这个问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-07-11
    • 2011-10-26
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2020-10-04
    相关资源
    最近更新 更多