我得到了

open failed: EACCES(权限被拒绝)

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();
}

当前回答

我有同样的问题(API >= 23)。

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

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

步骤1:下载适合您的设备品牌的adb驱动程序。

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

其他回答

Android 10 (API 29)引入了作用域存储。更改清单以请求遗留存储并不是长期解决方案。

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

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

点击这里阅读更多。

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

如果你有一个根设备,可以通过以下adb命令绕过6.0后的存储权限强制执行:

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

我在运行CM 12.1的三星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,以及它的读权限。

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