【问题标题】:how to get my app write on Sd card with Oreo如何使用 Oreo 让我的应用程序在 SD 卡上写入
【发布时间】:2019-07-15 09:42:27
【问题描述】:

我在运行 Android Oreo 的外部 sd 卡上写入时遇到一个奇怪的问题:

首先是常用命令 getExternalFilesDir(null).getAbsolutePath() 要么 Environment.getExternalStorageDirectory().getAbsolutePath()

返回模拟存储的路径,而不是真正的 sd 卡,有时称为辅助外部存储。

但这不是问题,因为我设法使用我帖子末尾描述的方法 getExternalStoragePath() 获取到 SD 卡的路径。

现在奇怪的是我无法让我的应用程序(假设包是 com.example.myapp)创建目录

SDCARDPATH/Android/data/com.example.myapp/files

尽管已正确授予所有必要的授权(但 WRITE_EXTERNAL_STORAGE 和 READ_EXTERNAL_STORAGE 可能仅适用于模拟存储,我觉得问题就在那里!)这是我正在做的事情:

String SDCARDPATH=getExternalStoragePath(this, true);
File md = new File(new File(new File(new    File(SDCARDPATH,"Android"),"data"),PACKAGE_NAME),"files");
if(!md.exists()) {
                try {
                    md.mkdirs();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }

奇怪的是,如果我通过手机文件资源管理器手动创建目录,则应用程序可以在该目录中写入和读取而不会遇到任何问题。

所以我的问题是如何在我的外部 sdcard 上正确创建该目录

附注我看到我手机上安装的一些应用程序已经设法在 sd 卡上创建了他们的应用程序目录。

最后这里是我使用的getExternalStoragePath方法,是在网上抓到的:

提前感谢大家的帮助,

 public static String getExternalStoragePath(Context mContext, boolean is_removable) {

    StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
    Class<?> storageVolumeClazz = null;
    try {
        storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
        Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
        Method getPath = storageVolumeClazz.getMethod("getPath");
        Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
        Object result = getVolumeList.invoke(mStorageManager);
        final int length = Array.getLength(result);
        for (int i = 0; i < length; i++) {
            Object storageVolumeElement = Array.get(result, i);
            String path = (String) getPath.invoke(storageVolumeElement);
            boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
            if (is_removable == removable) {
                return path;
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
    return null;
}

【问题讨论】:

  • 我也遇到了同样的问题,并且使用 andorid Q 中的存储访问框架情况变得更糟
  • @Pemba Tamang 你解决问题了吗?
  • 我正在为一个 arduino 项目的个人制作一个应用程序,我刚刚硬编码了路径。对不起队友
  • I have a strange problem 您正在使用反射。遇到“奇怪的问题”不要感到惊讶

标签: android


【解决方案1】:

我设法使用我帖子末尾描述的方法 getExternalStoragePath() 获取 SD 卡的路径

该代码不适用于所有版本的 Android。特别是,它不适用于 Android 10+。如果它在 Android 9.0 上也失败了,我一点也不感到惊讶,因为它依赖于对系统类的反射。它也会在不存在这些类和方法的旧设备上失败。

首先,通常的命令 getExternalFilesDir(null).getAbsolutePath() 或 Environment.getExternalStorageDirectory().getAbsolutePath() 返回到模拟存储的路径,而不是真正的 sd 卡,有时称为辅助外部存储

使用getExternalFilesDirs()(注意末尾的s)。这将返回一个File[]。如果该数组有 2+ 个元素,则除第一个元素之外的所有元素都指向可移动存储上的目录,您可以在应用程序中使用这些目录,而无需任何权限。该目录应该已经创建,但您可以在File 上调用mkdirs() 以确保它存在。

【讨论】:

  • 谢谢,这就是诀窍,调用 getExternalFilesDirs() 并检查数组结果创建我无法使用 mkdirs() 创建的目录: for (File file : getExternalFilesDirs(null)) { if (file != null) { String fpath=file.getAbsolutePath(); } }
  • 我如何接受你的回答?我没有看到任何按钮
  • @Leadev:我很高兴你让它工作了!在接受方面,在答案左侧寻找一个灰色的复选标记 - 单击它会将其变为绿色并将答案标记为已接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多