2

如何检查从 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 !!


}
4

2 回答 2

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;
}
于 2020-06-12T19:08:57.517 回答
2

不。

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

于 2017-09-02T16:01:49.720 回答