Android 如何在 KITKAT 4.4.2 版本的 SDCARD 上避免“EACCES 权限被拒绝”。谷歌的新政策

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22406061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:55:48  来源:igfitidea点击:

Howto avoid the "EACCES permission denied" ON SDCARD with KITKAT 4.4.2 Version. New policy from google

androidfile-permissionsandroid-4.4-kitkat

提问by mcfly soft

With the android kitkat 4.4.2 version is a new google policy implemented for writeaccess, which I do not understand so far.

android kitkat 4.4.2 版本是为 writeaccess 实施的新谷歌策略,目前我不明白。

I read a lot about this issue with other apps. They get a "EACCES permission denied". My app needs to write/unzip a zipfile, also write to a sqlite-database.

我在其他应用程序中阅读了很多有关此问题的信息。他们得到“EACCES 许可被拒绝”。我的应用程序需要编写/解压缩一个 zipfile,还需要写入一个 sqlite 数据库。

How can this EACCES permission denied issue be solved with Android version 4.4.2 KITKAT ?

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

采纳答案by WiFi

I found a working solution to this issue in xda forum; there is no need for rooting.
Here's an example :

我在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);
}

回答by nikis

From the docs:

从文档:

Starting in Android 4.4, multiple external storage devices are surfaced to developers through Context.getExternalFilesDirs(), Context.getExternalCacheDirs(), and Context.getObbDirs().

从 Android 4.4 开始,多个外部存储设备通过Context.getExternalFilesDirs()、Context.getExternalCacheDirs() 和 Context.getObbDirs()呈现给开发人员。

External storage devices surfaced through these APIs must be a semi-permanent part of the device (such as an SD card slot in a battery compartment). Developers expect data stored in these locations to be available over long periods of time. For this reason, transient storage devices (such as USB mass storage drives) should not be surfaced through these APIs.

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

The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions.Restricting writes in this way ensures the system can clean up files when applications are uninstalled.

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

回答by lucasddaniel

You need to ask the android about the permission on real time like this:

您需要像这样实时询问 android 权限:

private static final int MY_PERMISSIONS_REQUEST_STORAGE = 123456;

if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_STORAGE);
}

@Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_STORAGE: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Intent chooserIntent = cameraHelper.openImageIntent();
                    startActivityForResult(chooserIntent, MY_PERMISSIONS_REQUEST_STORAGE);
                }
            }
        }
    }

回答by Roop The Great

The only solution as of now is this problem can only be solved by rooting your phone and changing permissions of the ext sdcard from the root directory using file explorers,which is not recommended as it voids yours phone's warranty and also triggers some security apps like KNOX in phones like samsung galaxy S5 S4 Note3 and also Note2.

目前唯一的解决方案是这个问题只能通过root你的手机并使用文件资源管理器从根目录更改ext sdcard的权限来解决,不推荐这样做,因为它会使你的手机保修失效并且还会触发一些安全应用程序,如KNOX在三星 Galaxy S5 S4 Note3 和 Note2 等手机中。

Sorry for posting this bitter fact.

很抱歉发布了这个痛苦的事实。

lets hope an update from the google itself who can put us out of this situation.

让我们希望谷歌本身的更新能让我们摆脱这种情况。

But also think before updating jellybean to kitkat as the JB is most convenient OS of Android. and the difference b/w JB & Kitkat is not so high.

但在将 jellybean 更新为 kitkat 之前也要考虑一下,因为 JB 是最方便的 Android 操作系统。并且黑白 JB 和 Kitkat 的差异不是那么大。

Hope I Helped U......

希望我帮助了你......