如何从我的应用程序中正确识别AnkiDroid(或任何其他外部应用程序)的文件存储目录?

How to correctly identify the file storage directory of AnkiDroid (or any other external app) from my application?

我使用 AnkiDroid API 创建卡片并将其发送到 AnkiDroid 应用程序 (https://github.com/ankidroid/Anki-Android/wiki/AnkiDroid-API)。但是有一个问题与通过 API 发送媒体文件有关。它们存储在外部存储中,在我的例子中是“/storage/emulated/0/AnkiDroid”。我可以从那里添加和读取文件,但我认为对于其他设备或者如果我切换到 SD 卡,这条路径可能会有所不同。问题:如何正确识别应用程序的外部存储目录路径?

这里是前 AnkiDroid 项目维护者。

您拥有的路径是 AnkiDroid 媒体文件的默认路径。

AnkiDroid用户可以通过配置修改这个路径,你可能知道:

此设置是使用 Android 的常用设置存储技术存储的,出于安全原因,其他应用无法访问该技术。

我认为 属性 目前没有暴露给其他应用(source code), but that is a valid use case so please create a new issue at https://github.com/ankidroid/Anki-Android/issues

同时,为了与当前和以前版本的 AnkiDroid 兼容,我认为您有两个选择:

  • 扫描 SD 卡寻找一个叫 collection.media。这个文件夹在 AnkiDroid 文件夹里面,按照惯例名字不能改。如果找到多个,请比较最后修改日期并询问用户。
  • 设置类似于上面屏幕截图中的设置。想要使用非默认文件夹的用户将不得不在两个应用程序中设置它,这有点不方便,但并不是一个疯狂的要求。

注意硬码!!! 我知道这不是最好的方法。 但对我有用。

public ArrayList getExternalFolderPath(String folderName){

    ArrayList<String> arrayList = new ArrayList<>();

    //get all storages in phone
    File externalStorages[] = getExternalFilesDirs(null);

    for (File es: externalStorages){
        String exF = es.toString();

        //cut out what don't need
        exF = exF.split("/Android/data")[0];

        File file = new File(exF);
        File[] files = file.listFiles();
        for (File f: files){
            Log.i(TAG, "getAnkiExternalFolder()" + f.toString());
            //add in array the path
            if(f.toString().contains(folderName)){
                arrayList.add(f.toString());
            }
        }
    }
    return arrayList;
}

还需要添加清单条目。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

如果 API 级别达到 23 级以上,则请求用户阅读权限: https://developer.android.com/training/permissions/requesting