我得到了
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+,您需要请求读/写权限,即使它们已经在您的清单中。
// 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
奇怪的是,在我的newFile之前加上斜杠“/”后,我的问题就解决了。我改了这个:
File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");
:
File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");
更新:
正如评论中提到的,正确的做法是:
File myFile= new File(Environment.getExternalStorageDirectory(), "newFile");
在我的例子中,我使用的是一个文件选择器库,它返回到外部存储的路径,但它从/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