我得到了

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

当前回答

在我的例子中,我使用的是一个文件选择器库,它返回到外部存储的路径,但它从/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

其他回答

在manifest中添加权限。

<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"/>

我使用下面的过程来处理android 11和targetapi30的情况

作为预先创建的文件dir根据范围存储在我的情况下根目录文件//<图像/视频…按照要求> 复制选中的文件,并在从我的外部存储选择时复制缓存目录中的文件 然后在一次上传(在我的发送/上传按钮点击)复制文件从缓存目录到我的范围存储目录,然后做我的上传过程

使用这个解决方案,因为在播放商店上传应用程序时,它会生成MANAGE_EXTERNAL_STORAGE权限的警告,在我的情况下,有时会被播放商店拒绝。

同样,我们使用目标API 30,所以我们不能从内部存储共享或转发文件到应用程序

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

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

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

users -permission标记需要在application标记之外。

在我的例子中,我使用的是一个文件选择器库,它返回到外部存储的路径,但它从/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