首页 文章

Android上的例外'open failed: EACCES (Permission denied)'

提问于
浏览
225

我正进入(状态

开放失败: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();
}

25 回答

  • 5

    我的问题是“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();
        }
    }
    
  • 3

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

    所以我不得不关闭USB连接,一切正常 .

  • 1

    我在三星Galaxy Note 3上遇到了同样的问题,运行CM 12.1 . 我的问题是我有

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

    并且必须使用它来拍摄和存储用户照片 . 当我试图在ImageLoader中加载那些相同的照片时,我得到了 (Permission denied) 错误 . 解决方案是明确添加

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

    由于上述权限仅将写入权限限制为API版本18,并且具有读取权限 .

  • 222

    我有同样的问题...... <uses-permission 在错误的地方 . 这是正确的:

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

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

  • 0

    对于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

  • 27

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

  • 308

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

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

  • 13

    我也遇到了同样的问题 . 我发现如果你去 Settings -> Application Manager -> Your App -> Permissions -> Enable Storage ,它就解决了这个问题 .

  • 4

    除了所有答案,如果客户使用Android 6.0,Android为(Marshmallow)添加了新的permission model .

    Trick: 如果您的目标是22或更低版本,您的应用程序将在安装时请求所有权限,就像在Marshmallow下运行操作系统的任何设备上一样 . 如果您正在尝试使用模拟器,那么从Android 6.0开始,您需要明确地去设置 - > apps-> YOURAPP - >权限并更改权限(如果您已经提供) .

  • 0

    我希望 /data 以下的所有内容都属于"internal storage" . 但是,您应该能够写入 /sdcard .

  • 5

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

    启用USB存储时,外部存储读写权限不起作用 . 只需关闭USB存储,并使用正确的权限,您将解决问题 .

  • 4

    更改 /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>
    
  • 2

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

  • 0

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

  • 2

    奇怪的是在我的 newFile 之前放了一个斜线 "/" 我的问题解决了 . 我改变了这个:

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

    对此:

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

    也许答案是这样的:

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

  • 49

    在我的情况下,我使用了file picker library,它返回了外部存储的路径,但它从 /root/ 开始 . 即使在运行时授予了WRITE_EXTERNAL_STORAGE权限,我仍然会收到错误 EACCES (Permission denied) .
    因此,使用 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
    
  • 13

    我正在我的init.rc中的/ data /下创建一个文件夹(与Nexus 7上的aosp混在一起)这个问题 .

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

  • 5

    如果您通过以下adb命令拥有root设备,则可以绕过6.0版后的存储权限实施:

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

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

  • 2

    在清单中添加权限 .

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

    我遇到了同样的问题(API> = 23) .

    解决方案https://stackoverflow.com/a/13569364/1729501对我有用,但断开应用程序调试是不切实际的 .

    我的解决方案是在Windows上安装正确的adb设备驱动程序 . 谷歌USB驱动程序不适用于我的设备 .

    第1步:下载适用于您的设备品牌的adb驱动程序 .

    第2步:转到设备管理器 - >其他设备 - >查找带有“adb”字样的条目 - >选择更新驱动程序 - >在步骤1中输入位置

  • 3

    添加权限后解决了我的问题

    <uses-permission android:name="android.permission.INTERNET"/>
    
  • 7

    添加gradle依赖项

    implementation 'com.karumi:dexter:4.2.0'
    

    在主要活动中添加以下代码 .

    import com.karumi.dexter.Dexter;
    import com.karumi.dexter.MultiplePermissionsReport;
    import com.karumi.dexter.PermissionToken;
    import com.karumi.dexter.listener.PermissionRequest;
    import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
    
        new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
    
    
                    checkMermission();
                }
            }, 4000);
        }
    
        private void checkMermission(){
            Dexter.withActivity(this)
                    .withPermissions(
                            android.Manifest.permission.READ_EXTERNAL_STORAGE,
                            android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            android.Manifest.permission.ACCESS_NETWORK_STATE,
                            Manifest.permission.INTERNET
                    ).withListener(new MultiplePermissionsListener() {
                @Override
                public void onPermissionsChecked(MultiplePermissionsReport report) {
                    if (report.isAnyPermissionPermanentlyDenied()){
                        checkMermission();
                    } else if (report.areAllPermissionsGranted()){
                        // copy some things
                    } else {
                        checkMermission();
                    }
    
                }
                @Override
                public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                    token.continuePermissionRequest();
                }
            }).check();
        }
    
  • 12

    Build 在user462990的回答之上

    要在用户响应权限请求对话框时收到通知,请使用:( kotlin中的代码)

    override fun onRequestPermissionsResult(requestCode: Int,
                               permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        MY_PERMISSIONS_REQUEST_READ_CONTACTS -> {
            // If request is cancelled, the result arrays are empty.
            if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
    
                // permission was granted, yay! Do the
                // contacts-related task you need to do.
    
            } else {
    
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
    
            }
            return
        }
    
        // Add other 'when' lines to check for other
        // permissions this app might request.
    
        else -> {
            // Ignore all other requests.
        }
    }
    

    }

相关问题