异常“打开失败:EACCES(权限被拒绝)”在安卓上

发布于 2024-12-27 09:12:55 字数 1032 浏览 3 评论 0 原文

我正在得到

打开失败:EACCES(权限被拒绝)

在线 OutputStream myOutput = new FileOutputStream(outFileName);

我检查了根目录,并尝试了 android.permission.WRITE_EXTERNAL_STORAGE

我该如何解决这个问题?

try {
    InputStream myInput;

    myInput = getAssets().open("XXX.db");

    // Path to the just created empty db
    String outFileName = "/data/data/XX/databases/"
            + "XXX.db";

    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
    buffer = null;
    outFileName = null;
}
catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

I am getting

open failed: EACCES (Permission denied)

on the line OutputStream myOutput = new FileOutputStream(outFileName);

I checked the root, and I tried android.permission.WRITE_EXTERNAL_STORAGE.

How can I fix this problem?

try {
    InputStream myInput;

    myInput = getAssets().open("XXX.db");

    // Path to the just created empty db
    String outFileName = "/data/data/XX/databases/"
            + "XXX.db";

    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
    buffer = null;
    outFileName = null;
}
catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

饮惑 2025-01-03 09:12:56

我在运行 CM 12.1 的 Samsung Galaxy Note 3 上遇到了同样的问题。对我来说,问题是我

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18"/>

必须使用它来拍摄和存储用户照片。当我尝试在 ImageLoader 中加载这些相同的照片时,出现(权限被拒绝) 错误。解决方案是显式添加,

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

因为上述权限仅限制 API 版本 18 之前的写入权限以及读取权限。

I had the same problem on Samsung Galaxy Note 3, running CM 12.1. The issue for me was that i had

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18"/>

and had to use it to take and store user photos. When I tried to load those same photos in ImageLoader i got the (Permission denied) error. The solution was to explicitly add

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

since the above permission only limits the write permission up to API version 18, and with it the read permission.

左耳近心 2025-01-03 09:12:56

除了所有答案之外,如果客户端使用 Android 6.0,Android 还添加了新的 权限模型

技巧:如果您的目标版本为 22 或更低版本,您的应用程序将在安装时请求所有权限,就像在运行 Marshmallow 以下操作系统的任何设备上一样。如果您正在尝试模拟器,那么从 android 6.0 开始,您需要明确转到设置 -> 应用程序 -> 。您的应用程序 ->权限并更改权限(如果您已授予任何权限)。

In addition to all answers, if the clients are using Android 6.0, Android added new permission model for (Marshmallow).

Trick: If you are targeting version 22 or below, your application will request all permissions at install time just as it would on any device running an OS below Marshmallow. If you are trying on the emulator then from android 6.0 onwards you need to explicitly go the settings->apps-> YOURAPP -> permissions and change the permission if you have given any.

‘画卷フ 2025-01-03 09:12:56

奇怪的是,在我的 newFile 之前添加斜杠 "/" 之后,我的问题就解决了。我将其更改

File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");

为:

File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");

更新
正如评论中提到的,正确的方法是:

File myFile= new File(Environment.getExternalStorageDirectory(), "newFile");

Strangely after putting a slash "/" before my newFile my problem was solved. I changed this:

File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");

to this:

File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");

UPDATE:
as mentioned in the comments, the right way to do this is:

File myFile= new File(Environment.getExternalStorageDirectory(), "newFile");
ゞ记忆︶ㄣ 2025-01-03 09:12:56

我遇到了同样的问题,但没有任何建议有帮助。但我发现了一个有趣的原因,在物理设备上,Galaxy Tab

当 USB 存储打开时,外部存储读写权限不会产生任何影响。
只需关闭 USB 存储,并获得正确的权限,问题就会得到解决。

I had the same problem and none of suggestions helped. But I found an interesting reason for that, on a physical device, Galaxy Tab.

When USB storage is on, external storage read and write permissions don't have any effect.
Just turn off USB storage, and with the correct permissions, you'll have the problem solved.

苯莒 2025-01-03 09:12:56

API 29+ 以上限制将文件存储在与应用目录无关的目录中。因此,要生成新文件或创建新文件,请使用您的应用程序目录,如下所示:-

所以正确的方法是:-

val file = File(appContext.applicationInfo.dataDir + File.separator + "anyRandomFileName/")

您可以将任何数据写入此生成的文件中!

上面的文件是可访问的,并且不会抛出任何异常,因为它位于您自己开发的应用程序的目录中。

另一个选项是 manifest application tag 中的 android:requestLegacyExternalStorage="true",如 Uriel 建议,但它不是永久解决方案!

To store a file in a directory which is foreign to the app's directory is restricted above API 29+. So to generate a new file or to create a new file use your application directory like this :-

So the correct approach is :-

val file = File(appContext.applicationInfo.dataDir + File.separator + "anyRandomFileName/")

You can write any data into this generated file !

The above file is accessible and would not throw any exception because it resides in your own developed app's directory.

The other option is android:requestLegacyExternalStorage="true" in manifest application tag as suggested by Uriel but its not a permanent solution !

养猫人 2025-01-03 09:12:56

我希望 /data 下面的所有内容都属于“内部存储”。但是,您应该能够写入 /sdcard

I would expect everything below /data to belong to "internal storage". You should, however, be able to write to /sdcard.

千紇 2025-01-03 09:12:56

更改 /system/etc/permission/platform.xml
中的权限属性
和组需要如下提及。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    <group android:gid="sdcard_rw" />
    <group android:gid="media_rw" />    
</uses-permission>

Change a permission property in your /system/etc/permission/platform.xml
and group need to mentioned as like below.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    <group android:gid="sdcard_rw" />
    <group android:gid="media_rw" />    
</uses-permission>
淡莣 2025-01-03 09:12:56

当我试图在 Galaxy S5 (android 6.0.1) 上的 DCIM/camera 文件夹中写入图像时,我遇到了同样的错误,我发现只有这个文件夹受到限制。我只是可以写入 DCIM/任何文件夹,但不能写入相机。
这应该是基于品牌的限制/定制。

I had the same error when was trying to write an image in DCIM/camera folder on Galaxy S5 (android 6.0.1) and I figured out that only this folder is restricted. I simply could write into DCIM/any folder but not in camera.
This should be brand based restriction/customization.

咿呀咿呀哟 2025-01-03 09:12:56

当您的应用程序属于系统应用程序时,它无法访问SD卡。

When your application belongs to the system application, it can't access the SD card.

你在看孤独的风景 2025-01-03 09:12:56

也许答案是这样的:

在API>=23的设备上,如果你安装了应用程序(该应用程序不是系统应用程序),你应该在“设置-应用程序”中检查存储权限,每个应用程序都有权限列表,你应该检查一下!尝试

Maybe the answer is this:

on the API >= 23 devices, if you install app (the app is not system app), you should check the storage permission in "Setting - applications", there is permission list for every app, you should check it on! try

各自安好 2025-01-03 09:12:56

请记住,即使您在清单中设置了所有正确的权限:
允许第三方应用程序在您的外部卡上写入的唯一位置是“它们自己的目录”
(即/sdcard/Android/data/)
尝试写入其他任何地方:你会得到异常:
EACCES(权限被拒绝)

keep in mind that even if you set all the correct permissions in the manifest:
The only place 3rd party apps are allowed to write on your external card are "their own directories"
(i.e. /sdcard/Android/data/)
trying to write to anywhere else: you will get exception:
EACCES (Permission denied)

痴者 2025-01-03 09:12:56
Environment.getExternalStoragePublicDirectory();

从 Android 29 开始使用此已弃用的方法时,您将收到相同的错误:

java.io.FileNotFoundException:打开失败:EACCES(权限被拒绝)

此处的解决方案:

getExternalStoragePublicDirectory 在 Android 中已弃用问

Environment.getExternalStoragePublicDirectory();

When using this deprecated method from Android 29 onwards you will receive the same error:

java.io.FileNotFoundException: open failed: EACCES (Permission denied)

Resolution here:

getExternalStoragePublicDirectory deprecated in Android Q

滥情稳全场 2025-01-03 09:12:56

就我而言,我使用的是 文件选择器库,它返回外部存储的路径,但它启动了来自/root/。即使在运行时授予了WRITE_EXTERNAL_STORAGE权限,我仍然收到错误EACCES(权限被拒绝)
因此,请使用Environment.getExternalStorageDirectory()来获取外部存储的正确路径。

示例:
无法写入: /root/storage/emulated/0/newfile.txt
可以写入: /storage/emulated/0/newfile.txt

boolean externalStorageWritable = isExternalStorageWritable();
File file = new File(filePath);
boolean canWrite = file.canWrite();
boolean isFile = file.isFile();
long usableSpace = file.getUsableSpace();

Log.d(TAG, "externalStorageWritable: " + externalStorageWritable);
Log.d(TAG, "filePath: " + filePath);
Log.d(TAG, "canWrite: " + canWrite);
Log.d(TAG, "isFile: " + isFile);
Log.d(TAG, "usableSpace: " + usableSpace);

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

输出 1:

externalStorageWritable: true
filePath: /root/storage/emulated/0/newfile.txt
isFile: false
usableSpace: 0

输出 2:

externalStorageWritable: true
filePath: /storage/emulated/0/newfile.txt
isFile: true
usableSpace: 1331007488

In my case I was using a file picker library which returned the path to external storage but it started from /root/. And even with the WRITE_EXTERNAL_STORAGE permission granted at runtime I still got error EACCES (Permission denied).
So use Environment.getExternalStorageDirectory() to get the correct path to external storage.

Example:
Cannot write: /root/storage/emulated/0/newfile.txt
Can write: /storage/emulated/0/newfile.txt

boolean externalStorageWritable = isExternalStorageWritable();
File file = new File(filePath);
boolean canWrite = file.canWrite();
boolean isFile = file.isFile();
long usableSpace = file.getUsableSpace();

Log.d(TAG, "externalStorageWritable: " + externalStorageWritable);
Log.d(TAG, "filePath: " + filePath);
Log.d(TAG, "canWrite: " + canWrite);
Log.d(TAG, "isFile: " + isFile);
Log.d(TAG, "usableSpace: " + usableSpace);

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

Output 1:

externalStorageWritable: true
filePath: /root/storage/emulated/0/newfile.txt
isFile: false
usableSpace: 0

Output 2:

externalStorageWritable: true
filePath: /storage/emulated/0/newfile.txt
isFile: true
usableSpace: 1331007488
浮萍、无处依 2025-01-03 09:12:56

我正在 init.rc 中的 /data/ 下创建一个文件夹(在 Nexus 7 上使用 aosp),并且遇到了这个问题。

事实证明,给予文件夹 rw (666) 权限是不够的,必须是 rwx (777),然后一切就可以了!

I am creating a folder under /data/ in my init.rc (mucking around with the aosp on Nexus 7) and had exactly this problem.

It turned out that giving the folder rw (666) permission was not sufficient and it had to be rwx (777) then it all worked!

梦醒时光 2025-01-03 09:12:56

如果您通过以下 adb 命令拥有 root 设备,则可以绕过 6.0 后存储权限的强制执行:

root@msm8996:/ # getenforce
getenforce
Enforcing
root@msm8996:/ # setenforce 0
setenforce 0
root@msm8996:/ # getenforce
getenforce
Permissive

The post 6.0 enforcement of storage permissions can be bypassed if you have a rooted device via these adb commands:

root@msm8996:/ # getenforce
getenforce
Enforcing
root@msm8996:/ # setenforce 0
setenforce 0
root@msm8996:/ # getenforce
getenforce
Permissive
稀香 2025-01-03 09:12:56

我在小米设备(android 10)上遇到了同样的错误。以下代码解决了我的问题。
库:Dexter(https://github.com/Karumi/Dexter) 和图像选择器(https://github.com/Dhaval2404/ImagePicker)

添加清单( android:requestLegacyExternalStorage="true")

    public void showPickImageSheet(AddImageModel model) {
    BottomSheetHelper.showPickImageSheet(this, new BottomSheetHelper.PickImageDialogListener() {
        @Override
        public void onChooseFromGalleryClicked(Dialog dialog) {
            selectedImagePickerPosition = model.getPosition();
            Dexter.withContext(OrderReviewActivity.this)                   .withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE)
                    .withListener(new MultiplePermissionsListener() {
                        @Override
                        public void onPermissionsChecked(MultiplePermissionsReport report) {
                            if (report.areAllPermissionsGranted()) {
                                ImagePicker.with(OrderReviewActivity.this)
                                        .galleryOnly()
                                        .compress(512)
                                        .maxResultSize(852,480)
                               .start();
                            }
                        }

                        @Override
                        public void onPermissionRationaleShouldBeShown(List<PermissionRequest> list, PermissionToken permissionToken) {
                            permissionToken.continuePermissionRequest();
                        }

                    }).check();

            dialog.dismiss();
        }

        @Override
        public void onTakePhotoClicked(Dialog dialog) {
            selectedImagePickerPosition = model.getPosition();
            ImagePicker.with(OrderReviewActivity.this)
                    .cameraOnly()
                    .compress(512)
                    .maxResultSize(852,480)
                    .start();

            dialog.dismiss();
        }

        @Override
        public void onCancelButtonClicked(Dialog dialog) {
            dialog.dismiss();
        }
    });
}

i faced the same error on xiaomi devices (android 10 ). The following code fixed my problem.
Libraries: Dexter(https://github.com/Karumi/Dexter) and Image picker(https://github.com/Dhaval2404/ImagePicker)

Add manifest ( android:requestLegacyExternalStorage="true")

    public void showPickImageSheet(AddImageModel model) {
    BottomSheetHelper.showPickImageSheet(this, new BottomSheetHelper.PickImageDialogListener() {
        @Override
        public void onChooseFromGalleryClicked(Dialog dialog) {
            selectedImagePickerPosition = model.getPosition();
            Dexter.withContext(OrderReviewActivity.this)                   .withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE)
                    .withListener(new MultiplePermissionsListener() {
                        @Override
                        public void onPermissionsChecked(MultiplePermissionsReport report) {
                            if (report.areAllPermissionsGranted()) {
                                ImagePicker.with(OrderReviewActivity.this)
                                        .galleryOnly()
                                        .compress(512)
                                        .maxResultSize(852,480)
                               .start();
                            }
                        }

                        @Override
                        public void onPermissionRationaleShouldBeShown(List<PermissionRequest> list, PermissionToken permissionToken) {
                            permissionToken.continuePermissionRequest();
                        }

                    }).check();

            dialog.dismiss();
        }

        @Override
        public void onTakePhotoClicked(Dialog dialog) {
            selectedImagePickerPosition = model.getPosition();
            ImagePicker.with(OrderReviewActivity.this)
                    .cameraOnly()
                    .compress(512)
                    .maxResultSize(852,480)
                    .start();

            dialog.dismiss();
        }

        @Override
        public void onCancelButtonClicked(Dialog dialog) {
            dialog.dismiss();
        }
    });
}
夏日浅笑〃 2025-01-03 09:12:56

就我而言,由于我无法在 sd 卡上创建新文件,因此错误出现在该行上

      target.createNewFile();

,因此我必须使用 DocumentFile 方法。

      documentFile.createFile(mime, target.getName());

对于上述问题,可以用这种方法解决问题,

    fos=context.getContentResolver().openOutputStream(documentFile.getUri());

也请参阅此线程,
如何使用 Android 5.0 (Lollipop) 提供的新 SD 卡访问 API?

In my case the error was appearing on the line

      target.createNewFile();

since I could not create a new file on the sd card,so I had to use the DocumentFile approach.

      documentFile.createFile(mime, target.getName());

For the above question the problem may be solved with this approach,

    fos=context.getContentResolver().openOutputStream(documentFile.getUri());

See this thread too,
How to use the new SD card access API presented for Android 5.0 (Lollipop)?

手心的温暖 2025-01-03 09:12:56

我使用以下流程来处理 Android 11 和 targetapi30 的情况

  1. 在我的情况下,根据范围存储在根目录文件中作为预创建的文件目录//<图像/视频...根据要求>

  2. 复制选取的文件,并在从我的外部存储选取时将文件复制到缓存目录中

  3. 然后在上传时(单击我的发送/上传按钮)将文件从缓存目录复制到我的作用域存储目录,然后执行我的上传过程

使用此解决方案,因为在播放商店中上传应用程序时,它会生成 MANAGE_EXTERNAL_STORAGE 权限的警告就我而言,有时会被游戏商店拒绝。

此外,由于我们使用目标 API 30,因此我们无法将文件从内部存储共享或转发到应用程序

I Use the below process to handle the case with android 11 and targetapi30

  1. As pre-created file dir as per scoped storage in my case in root dir files//<Image/Video... as per requirement>

  2. Copy picked file and copy the file in cache directory at the time of picking from my external storage

  3. Then at a time to upload ( on my send/upload button click) copy the file from cache dir to my scoped storage dir and then do my upload process

use this solution due to at time upload app in play store it generates warning for MANAGE_EXTERNAL_STORAGE permission and sometimes rejected from play store in my case.

Also as we used target API 30 so we can't share or forward file from our internal storage to app

七颜 2025-01-03 09:12:56

2022 Kotlin 请求许可的方式:

private val writeStoragePermissionResult =
   registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->}

private fun askForStoragePermission(): Boolean =
   if (hasPermissions(
           requireContext(),
           Manifest.permission.READ_EXTERNAL_STORAGE,
           Manifest.permission.WRITE_EXTERNAL_STORAGE
       )
   ) {
       true
   } else {
       writeStoragePermissionResult.launch(
           arrayOf(
               Manifest.permission.READ_EXTERNAL_STORAGE,
               Manifest.permission.WRITE_EXTERNAL_STORAGE,
           )
       )
       false
   }

fun hasPermissions(context: Context, vararg permissions: String): Boolean = permissions.all {
    ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}

2022 Kotlin way to ask permission:

private val writeStoragePermissionResult =
   registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->}

private fun askForStoragePermission(): Boolean =
   if (hasPermissions(
           requireContext(),
           Manifest.permission.READ_EXTERNAL_STORAGE,
           Manifest.permission.WRITE_EXTERNAL_STORAGE
       )
   ) {
       true
   } else {
       writeStoragePermissionResult.launch(
           arrayOf(
               Manifest.permission.READ_EXTERNAL_STORAGE,
               Manifest.permission.WRITE_EXTERNAL_STORAGE,
           )
       )
       false
   }

fun hasPermissions(context: Context, vararg permissions: String): Boolean = permissions.all {
    ActivityCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
转身以后 2025-01-03 09:12:55

Google 在 Android Q 上推出了一项新功能:外部存储的过滤视图。对此问题的快速修复是在 AndroidManifest.xml 文件中添加此代码:

<manifest ... >
    <!-- This attribute is "false" by default on apps targeting Android Q. -->
    <application android:requestLegacyExternalStorage="true" ... >
     ...
    </application>
</manifest>

您可以在此处阅读有关它的更多信息:https://developer.android.com/training/data-storage/use-cases

编辑: 我开始明白投反对票,因为这个答案超出了Android 11 的日期。因此,无论谁看到此答案,请转到上面的链接并阅读说明。

Google has a new feature on Android Q: filtered view for external storage. A quick fix for that is to add this code in the AndroidManifest.xml file:

<manifest ... >
    <!-- This attribute is "false" by default on apps targeting Android Q. -->
    <application android:requestLegacyExternalStorage="true" ... >
     ...
    </application>
</manifest>

You can read more about it here: https://developer.android.com/training/data-storage/use-cases

Edit: I am starting to get downvotes because this answer is out of date for Android 11. So whoever sees this answer please go to the link above and read the instructions.

寂寞美少年 2025-01-03 09:12:55

对于 API 23+,您需要请求读/写权限,即使它们已经在您的清单中。

// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}

AndroidManifest.xml

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

有关请求 API 23+ 权限的官方文档,请检查 https://developer.android.com/training /permissions/requesting.html

For API 23+ you need to request the read/write permissions even if they are already in your manifest.

// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};

/**
 * Checks if the app has permission to write to device storage
 *
 * If the app does not has permission then the user will be prompted to grant permissions
 *
 * @param activity
 */
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}

AndroidManifest.xml

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

For official documentation about requesting permissions for API 23+, check https://developer.android.com/training/permissions/requesting.html

洛阳烟雨空心柳 2025-01-03 09:12:55

我遇到了同样的问题... 位于错误的位置。这是正确的:

 <manifest>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        ...
        <application>
            ...
            <activity> 
                ...
            </activity>
        </application>
    </manifest> 

uses-permission 标记需要位于 application 标记之外。

I had the same problem... The <uses-permission was in the wrong place. This is right:

 <manifest>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        ...
        <application>
            ...
            <activity> 
                ...
            </activity>
        </application>
    </manifest> 

The uses-permission tag needs to be outside the application tag.

岛徒 2025-01-03 09:12:55

android:requestLegacyExternalStorage="true" 添加到 Android 清单
它可在 SDK 29+ 上与 Android 10 (Q) 配合使用
或迁移 Android X 后。

 <application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:hardwareAccelerated="true"
    android:icon=""
    android:label=""
    android:largeHeap="true"
    android:supportsRtl=""
    android:theme=""
    android:requestLegacyExternalStorage="true">

Add android:requestLegacyExternalStorage="true" to the Android Manifest
It's worked with Android 10 (Q) at SDK 29+
or After migrating Android X.

 <application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:hardwareAccelerated="true"
    android:icon=""
    android:label=""
    android:largeHeap="true"
    android:supportsRtl=""
    android:theme=""
    android:requestLegacyExternalStorage="true">
迷雾森÷林ヴ 2025-01-03 09:12:55

我在模拟器内运行应用程序时观察到过一次。在模拟器设置中,您需要正确指定外部存储(“SD 卡”)的大小。默认情况下,“外部存储”字段为空,这可能意味着不存在此类设备,并且即使在清单中授予了权限,也会抛出 EACCES。

I have observed this once when running the application inside the emulator. In the emulator settings, you need to specify the size of external storage ("SD Card") properly. By default, the "external storage" field is empty, and that probably means there is no such device and EACCES is thrown even if permissions are granted in the manifest.

耀眼的星火 2025-01-03 09:12:55

除了所有答案之外,请确保您没有将手机用作 USB 存储设备。

我在启用 USB 存储模式的 HTC Sensation 上遇到了同样的问题。我仍然可以调试/运行该应用程序,但无法保存到外部存储。

In addition to all the answers, make sure you're not using your phone as a USB storage.

I was having the same problem on HTC Sensation on USB storage mode enabled. I can still debug/run the app, but I can't save to external storage.

过去的过去 2025-01-03 09:12:55

请注意,解决方案:

<application ...
    android:requestLegacyExternalStorage="true" ... >

是暂时的,您的应用迟早应该迁移到使用作用域存储

在 Android 10 中,您可以使用建议的解决方案来绕过系统限制,但在 Android 11 (R) 中,强制使用作用域存储,如果继续使用旧逻辑,您的应用可能会崩溃!

此视频可能会很有帮助。

Be aware that the solution:

<application ...
    android:requestLegacyExternalStorage="true" ... >

Is temporary, sooner or later your app should be migrated to use Scoped Storage.

In Android 10, you can use the suggested solution to bypass the system restrictions, but in Android 11 (R) it is mandatory to use scoped storage, and your app might break if you kept using the old logic!

This video might be a good help.

无畏 2025-01-03 09:12:55

我的问题是“TargetApi(23)”,如果您的 minSdkVersion 低于 23,则需要它。

因此,我使用以下代码片段请求许可

protected boolean shouldAskPermissions() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}

@TargetApi(23)
protected void askPermissions() {
    String[] permissions = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE"
    };
    int requestCode = 200;
    requestPermissions(permissions, requestCode);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// ...
    if (shouldAskPermissions()) {
        askPermissions();
    }
}

My issue was with "TargetApi(23)" which is needed if your minSdkVersion is bellow 23.

So, I have request permission with the following snippet

protected boolean shouldAskPermissions() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}

@TargetApi(23)
protected void askPermissions() {
    String[] permissions = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE"
    };
    int requestCode = 200;
    requestPermissions(permissions, requestCode);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// ...
    if (shouldAskPermissions()) {
        askPermissions();
    }
}
过期以后 2025-01-03 09:12:55

Android 10 (API 29) 引入了分区存储。更改清单以请求旧存储并不是长期解决方案。

当我将之前的 Environment.getExternalStorageDirectory() 实例(API 29 已弃用)替换为 context.getExternalFilesDir(null) 时,我修复了该问题。

请注意,如果存储位置不可用,context.getExternalFilesDir(type) 可能会返回 null,因此无论何时检查您是否具有外部权限,请务必检查这一点。

点击此处了解更多信息。

Android 10 (API 29) introduces Scoped Storage. Changing your manifest to request legacy storage is not a long-term solution.

I fixed the issue when I replaced my previous instances of Environment.getExternalStorageDirectory() (which is deprecated with API 29) with context.getExternalFilesDir(null).

Note that context.getExternalFilesDir(type) can return null if the storage location isn't available, so be sure to check that whenever you're checking if you have external permissions.

Read more here.

薆情海 2025-01-03 09:12:55

我也有同样的经历。我发现,如果您转到设置 ->应用管理器->您的应用程序 ->权限->启用存储,它解决了问题。

I'm experiencing the same. What I found is that if you go to Settings -> Application Manager -> Your App -> Permissions -> Enable Storage, it solves the issue.

人海汹涌 2025-01-03 09:12:55

事实证明,这是一个愚蠢的错误,因为我的手机仍然连接到台式电脑,但没有意识到这一点。

所以我必须关闭 USB 连接,一切正常。

It turned out, it was a stupid mistake since I had my phone still connected to the desktop PC and didn't realize this.

So I had to turn off the USB connection and everything worked fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文