我需要将文件从资产复制到外部存储。这是我的代码:
File f = new File(Environment.getExternalStorageDirectory() + File.separator
+ "MyApp" + File.separator + "tessdata" + File.separator + "eng.traineddata");
if (!f.exists()) {
AssetManager assetManager = getAssets();
try {
f.createNewFile();
InputStream in = assetManager.open("eng.traineddata");
OutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + File.separator
+ "MyApp" + File.separator + "tessdata" + File.separator + "eng.traineddata");
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
out.write(buffer, 0, read);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: ", e);
}
}
我还在演出中添加了许可
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
执行f.createNewFile()
时发生异常,说“权限被拒绝”。
我该如何解决?
答案 0 :(得分:27)
在我的情况下,这是由于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" />
可以找到权限的详细示例代码here。
答案 1 :(得分:11)
最近在API级别29,他们更改了访问外部存储的方式。 如果您尝试访问公用文件夹(即下载),则会引发权限被拒绝错误。
您需要在清单文件的应用程序标记中指定以下代码。
android:requestLegacyExternalStorage="true"
或者您可以将文件保存在根目录中,以避免出现此错误。
答案 2 :(得分:9)
在f.mkdirs()
之前f.createNewFile()
。您可能正在尝试在不存在的目录中创建新文件
答案 3 :(得分:2)
试试这个:
private void copy() {
File dirOri = new File(Environment.getExternalStorageDirectory() +"/somefolder/somefile");
File dirDest = new File(Environment.getExternalStorageDirectory() + "/yourfolder");
FileChannel src = null;
FileChannel dst = null;
try {
src = new FileInputStream(dirOri).getChannel();
dst = new FileOutputStream(dirDest).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
} catch (Exception e) {}
}
- 编辑 -
添加清单:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
答案 4 :(得分:1)
如果您使用的是SDK-23,则需要像这样在清单文件中写入权限
<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE" />
答案 5 :(得分:0)
我一直在努力地寻找答案。大多数解决方案不适用于API29。@ishann的回答启发了我搜索android:requestLegacyExternalStorage。原来,他们引入了范围存储的概念,这意味着应用程序默认情况下只能访问其专用文件夹。例如,“图片”的文件夹模式现在应为:
/storage/emulated/0/Android/data/com.myapp.myapp/files/Pictures
即使授予了两个权限,在全局位置创建文件或文件夹也会失败:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
以下代码对我有用:
File files[] = this.getApplicationContext().getExternalFilesDirs(Environment.DIRECTORY_PICTURES);
for(File f : files){
Log.e("debug", f.getAbsolutePath());
File newdir = new File(f.getAbsolutePath(), "/newtest/");
boolean result = newdir.mkdirs();
Log.e("debug", result + " ; " + newdir.exists());
break;
}
相关文件
https://developer.android.com/training/data-storage#scoped-storage