如何使用KITKAT 4.4.2版本避免使用"EACCES权限被拒绝"SDCARD.来自谷歌的新政策

mcf*_*oft 22 android file-permissions android-4.4-kitkat

随着android kitkat 4.4.2版本是针对writeaccess实施的新google策略,到目前为止我还不明白.

我在其他应用中阅读了很多关于这个问题的内容.他们得到"EACCES权限被拒绝".我的应用程序需要编写/解压缩zipfile,也写入sqlite数据库.

如何通过Android版本4.4.2 KITKAT解决此EACCES权限被拒绝的问题?

nik*_*kis 9

来自文档:

从Android 4.4开始,通过Context.getExternalFilesDirs(),Context.getExternalCacheDirs()和Context.getObbDirs()向开发人员展示了多个外部存储设备.

通过这些API浮出的外部存储设备必须是设备的半永久性部分(例如电池盒中的SD卡插槽).开发人员希望存储在这些位置的数据能够长时间使用.因此,不应通过这些API显示瞬态存储设备(如USB大容量存储驱动器).

WRITE_EXTERNAL_STORAGE权限只能授予对设备上主外部存储的写访问权限.不得允许应用程序写入辅助外部存储设备,但合成权限允许的特定于程序包的目录除外.以这种方式限制写入可确保系统在卸载应用程序时清理文件.

  • SD卡安全/许可的这种变化正在左右破坏应用程序.它可能有助于应用程序在卸载时清理文件,但设备正在接收使用此新规则的Android更新,并且它是用户SD卡上的孤立文件,因为现有应用程序不再具有从先前可写文件夹中删除或移动文件的权限.这令人非常沮丧. (10认同)

小智 7

我在xda论坛找到了解决这个问题的工作方案; 没有必要生根.
这是一个例子:

/**
 * Returns an OutputStream to write to the file. The file will be truncated immediately.
 */
public OutputStream write()
        throws IOException {
    if (file.exists() && file.isDirectory()) {
        throw new IOException("File exists and is a directory.");
    }

    // Delete any existing entry from the media database.
    // This may also delete the file (for media types), but that is irrelevant as it will be truncated momentarily in any case.
    String where = MediaStore.MediaColumns.DATA + "=?";
    String[] selectionArgs = new String[] { file.getAbsolutePath() };
    contentResolver.delete(filesUri, where, selectionArgs);

    ContentValues values = new ContentValues();
    values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
    Uri uri = contentResolver.insert(filesUri, values);

    if (uri == null) {
        // Should not occur.
        throw new IOException("Internal error.");
    }

    return contentResolver.openOutputStream(uri);
}
Run Code Online (Sandbox Code Playgroud)