Android 在外部 SD 卡上写入文件 for android 5+

Ank*_*ria 2 file-io android android-sdcard android-file

我无法将文件写入外部 SD 卡。我收到错误消息 EAcess denied。我在互联网上搜索了很多,发现从 Android 4.4 + android 的存储访问框架 (SAF) 写入文件是必需的。

但我正在使用一些能够在 SD 卡上写入(创建/删除/重命名)文件的 android 应用程序。他们没有使用 SAF。

因此,请帮助我了解如何在不使用 SAF 框架的情况下执行此操作。

谢谢

Noi*_*oan 5

谈论 Android 的外部存储器有很多困惑。它实际上并不指向 Removable SD MICRO CARD。那么,谷歌认为“外部存储器”是什么意思

参考Android API 文档

每个 Android 兼容设备都支持共享的“外部存储”,您可以使用它来保存文件。这可以是可移动存储介质(例如 SD 卡)或内部(不可移动)存储。保存到外部存储的文件是全球可读的,用户可以在启用 USB 大容量存储以在计算机上传输文件时对其进行修改。

事实是 Environment.getExternalStorageDirectory() 和 Context.getExternalFilesDirs() 可以返回位于内部存储中的模拟外部存储器。因此,这些函数本身并没有给出预期的结果。SECONDARY_STORAGE 环境变量可以帮助获得可移动内存的真实路径,但由于 OEM 实现,不允许在其根目录上写入。在这种情况下,我们应该尝试通过 Context.getExternalFilesDirs() 或 ContextCompat.getExternalFilesDirs() 来获取应用程序的数据文件夹,该文件夹上允许读取和写入应用程序的数据文件。

我使用以下方法解决了我的问题,请检查它并希望它可以帮助您解决问题。

@TargetApi(Build.VERSION_CODES.KITKAT)
private String getRemovablePath(){
    String secondaryStore = System.getenv("SECONDARY_STORAGE");     
    if (secondaryStore != null){
        secondaryStore = secondaryStore.split(":")[0];
        secondaryStore += File.separator + "Backups/";
        File file = new File(secondaryStore);
        if((file.mkdir() || file.isDirectory()) && isFileWritable(secondaryStore)){
            return secondaryStore;
        } else {
            secondaryStore = null;
        }           
    } 

    // try again by fix address
    if(secondaryStore == null){
        if (new File("/Removable/MicroSD/").exists()){              
            secondaryStore = "/Removable/MicroSD/";
        } else if( new File("/storage/extSdCard/").exists()){
            secondaryStore = "/storage/extSdCard/";
        } else if( new File("/storage/sdcard1/").exists()){
            secondaryStore = "/storage/sdcard1/";
        } else if( new File("/storage/usbcard1/").exists()){
            secondaryStore = "/storage/usbcard1/";
        } else if( new File("/storage/external_SD/").exists()){
            secondaryStore = "/storage/external_SD/";
        }   
        /** add more fix addresses you know */
        secondaryStore += "Backups/";
        File file = new File(secondaryStore);
        if((file.mkdir() || file.isDirectory()) && isFileWritable(secondaryStore)){                             
            return secondaryStore;
        } else {
            secondaryStore = null;
        }           

    }       
    /** Try data folder*/
    if(secondaryStore == null){         
        int ver = Build.VERSION.SDK_INT;
        File[] externalRoots = null;
        if(ver <= Build.VERSION_CODES.JELLY_BEAN_MR2){          
            externalRoots = ContextCompat.getExternalFilesDirs(getBaseContext(), null);
        } else {
            externalRoots = getExternalFilesDirs(null);
        }   

        if(externalRoots.length > 1){
            secondaryStore = externalRoots[1].getAbsolutePath() + File.separator;
            return secondaryStore;
        } else {
            secondaryStore = null;
        }               
    }


    return secondaryStore;          
}
Run Code Online (Sandbox Code Playgroud)