如何从可移动SD卡(第二个外部存储)中删除文件?

7

我正在尝试从我的可移动SD卡(PATH_TO_SD_CARD/DCIM/1.PDF)上删除一个文件,并且我的安卓9系统与此相关的技术。

1. 我获取了volumePaths,其中第二个是我的SD卡。

private static String[] getVolumePaths(Context context) {
    String[] volumes = null;
    StorageManager managerStorage = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
    if (managerStorage == null) {
        return volumes;
    }
    try {
        return (String[]) managerStorage.getClass().getMethod("getVolumePaths", new Class[0]).invoke(managerStorage, new Object[0]);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
        return volumes;
    } catch (IllegalArgumentException e2) {
        e2.printStackTrace();
        return volumes;
    } catch (IllegalAccessException e3) {
        e3.printStackTrace();
        return volumes;
    } catch (InvocationTargetException e4) {
        e4.printStackTrace();
        return volumes;
    }
}

    String[] volumePaths = getVolumePaths(getContext());
    Log.v("VOLUME1: ", "-> "+volumePaths[0]);
    Log.v("VOLUME2: ", "-> "+volumePaths[1]);

LocCat:

2019-07-19 17:06:15.577 13257-13257/com.spicysoftware.spicypdfreader V/VOLUME2:: -> /storage/2585-1513

2. 我检查文件是否存在,返回true

Log.v("FILE EXISTS?", "-> "+new File("/storage/2585-1513/DCIM/1.PDF").exists());

LogCat

2019-07-19 17:06:16.577 13257-13257/com.spicysoftware.spicypdfreader V/FILE EXISTS? -> true

3.1 我想删除这个文件

但是这种方式不起作用,为什么呢?

new File("/storage/2585-1513/DCIM/1.PDF").delete();

3.2 我正在尝试通过DOCUMENT_FILE_TREE删除文件

// call for document tree dialog
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 123);

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case 123:
            if (resultCode == Activity.RESULT_OK) {
                String strFilePath = data.getData().getPath()+"/DCIM/1.PDF";
                try {
                    if(new File(strFilePath).delete()){
                        Log.v("FILE", "DELETED");
                    }else{
                        Log.v("FILE", "NOT DELETED");
                    }
                }catch (Exception e){
                    Log.v("ERROR: ", "-> "+e);
                }
            }
            break;
    }
}

LogCat

2019-07-19 17:23:20.523 14343-14343/com.spicysoftware.spicypdfreader V/FILE: NOT DELETED

所以我的问题是:如何从可移动的SD卡(第二个外部存储)中删除文件?这太奇怪了... 我已经花了两天时间解决这个问题,但没有找到任何解决方法来删除这个sd卡上的文件...
我也使用了存储访问框架,但没有起作用。 如果这是唯一的处理方式,请添加一个示例。
2个回答

6
如何从可移动sd卡(第二个外部存储)中删除文件? 您不能。您无法在可移动存储的任意位置进行读写访问。
我还使用了存储访问框架,但没有起作用。 不完全正确。您使用ACTION_OPEN_DOCUMENT_TREE获取Uri,然后尝试将其转换为File。这不起作用,因为Uri不是文件。
最简单的解决方案是:
- 使用ACTION_OPEN_DOCUMENT - 传递您获得的Uri(来自您的问题中的data.getData()),并将其传递给DocumentFile.fromSingleUri() - 在该DocumentFile上调用delete()

谢谢你的回答。我会尝试一下。但是你先说这不可能,然后又说我必须使用ACTION_OPEN_DOCUMENT来实现。所以像许多文件浏览器那样删除文件是可以实现的。 :) - MSeiz5
@MSeiz5:预安装的文件管理器由设备制造商授予了额外的权限。其他所有人都需要以某种方式通过存储访问框架进行操作。一些文件管理器将使用ACTION_OPEN_DOCUMENT_TREE,然后使用DocumentFile.fromTreeUri()listFiles()来获取该树的内容。 - CommonsWare
是的,那就是我的意思。这是可能的。但不像在外部存储器上那样直接。 - MSeiz5
我在网上找不到如何使用它的任何示例。你能否用一小段代码片段向我解释一下? - MSeiz5

1

为了安全起见,您可以访问SD卡,但是您只能写入和读取应用程序创建的目录中的文件或应用程序创建的目录中的文件(使用WRITE_EXTERNAL_STORAGE权限)。

enter image description here

例如,如果您的外部存储路径是:
/storage/13257-13257/

你的应用程序包名称是com.spicysoftware.spicypdfreader

你可以访问并删除在此路径内创建的文件:

 /storage/13257-13257/com.spicysoftware.spicypdfreader

顺便建议您使用ContextCompat.getExternalFilesDirs(context, null)来获取您的/files目录的路径/storage/13257-13257/com.spicysoftware.spicypdfreader/files
示例:
 File[] storages = ContextCompat.getExternalFilesDirs(context, null);
Log.i(TAG, "storage[0]: " + storages[0]);
Log.i(TAG, "storage[1]: " + storages[1]);

总之,在这里你可以删除文件:

new File("/storage/13257-13257/com.spicysoftware.spicypdfreader/files/1.PDF").delete();

或者在这里(/files 目录之外):
new File("/storage/13257-13257/com.spicysoftware.spicypdfreader/1.PDF").delete();

但是无法做到这一点:
new File("/storage/13257-13257/DCIM/1.PDF").delete();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接