Android(写入外部 SD 卡):java.io.IOException:权限被拒绝
Android (Write on external SD-Card): java.io.IOException: Permission denied
当我想在我的外部 SD 卡(名为 /storage/B9BE-18A6)上创建文件时,出现 "Permission denied" 错误。
我知道你必须以编程方式请求写入权限,因为 Android M。所以我插入了 Arpit Patel (Android 6.0 Marshmallow. Cannot write to SD Card)
的解决方案
我不知道为什么我仍然没有这样做的权限。
你们有其他解决方案可以让我在 SD 卡上创建文件吗?
创建文件的代码
FloatingActionButton fab_new_file = (FloatingActionButton) rLayoutFrgEmpresas.findViewById(R.id.fab_menu_item_file);
fab_new_file.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int permission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Log.v("Permission: " ,"Denied");
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Permission to access the SD-CARD is required")
.setTitle("Permission required");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.i(TAG, "Clicked");
makeRequest();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
makeRequest();
}
}else{
Log.v("Permission: " ,"Granted");
File file = new File(textView_currentPath.getText() + "/" + "testfile.txt");
Log.v("filepatch: ", ""+file);
if (!file.exists()) {
Log.v("Does "+file+" exists?", "No");
try {
file.createNewFile();
getFilesFromDir(textView_currentPath.getText() + "", textView_currentPath.getText() + "");
Log.v("File "+file,"has been created!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
LogCat
04-11 16:31:40.709 23404-23404/spicysoftware.com.phonemanager D/ViewRootImpl@ab22b33[MainActivity]: ViewPostImeInputStage processPointer 0
04-11 16:31:40.773 23404-23404/spicysoftware.com.phonemanager D/ViewRootImpl@ab22b33[MainActivity]: ViewPostImeInputStage processPointer 1
04-11 16:31:40.783 23404-23404/spicysoftware.com.phonemanager V/Permission:: Granted
04-11 16:31:40.783 23404-23404/spicysoftware.com.phonemanager V/filepatch:: /storage/B9BE-18A6/testfile.txt
04-11 16:31:40.783 23404-23404/spicysoftware.com.phonemanager V/Does /storage/B9BE-18A6/testfile.txt exists?: No
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: java.io.IOException: Permission denied
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.io.UnixFileSystem.createFileExclusively0(Native Method)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.io.File.createNewFile(File.java:948)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at spicysoftware.com.phonemanager.StorageFragment.onClick(StorageFragment.java:187)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.view.View.performClick(View.java:6207)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.view.View$PerformClick.run(View.java:23639)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.os.Looper.loop(Looper.java:154)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6688)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.lang.reflect.Method.invoke(Native Method)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
解决方法
感谢@greenapps 让我走上了正确的道路。
解决方案在 https://developer.android.com/guide/topics/providers/document-provider.html
中有很好的记录
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
String mimeType = "text/plain";
String filename = "file"+System.currentTimeMillis() + ".txt";
intent.setType(mimeType);
intent.putExtra(Intent.EXTRA_TITLE, filename);
startActivityForResult(intent, CREATE_REQUEST_CODE);
SD卡是只读的。所以你不能写。您只能写入 SD 卡上的应用特定目录。在你的情况下它将是
/storage/B9BE-18A6/Android/data/spicysoftware.com.phonemanager
如果你想写在整个SD卡上那么文件class和FileOutputStream是不行的。那么你必须使用存储访问框架。
当我想在我的外部 SD 卡(名为 /storage/B9BE-18A6)上创建文件时,出现 "Permission denied" 错误。
我知道你必须以编程方式请求写入权限,因为 Android M。所以我插入了 Arpit Patel (Android 6.0 Marshmallow. Cannot write to SD Card)
的解决方案我不知道为什么我仍然没有这样做的权限。 你们有其他解决方案可以让我在 SD 卡上创建文件吗?
创建文件的代码
FloatingActionButton fab_new_file = (FloatingActionButton) rLayoutFrgEmpresas.findViewById(R.id.fab_menu_item_file);
fab_new_file.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int permission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Log.v("Permission: " ,"Denied");
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Permission to access the SD-CARD is required")
.setTitle("Permission required");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.i(TAG, "Clicked");
makeRequest();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
makeRequest();
}
}else{
Log.v("Permission: " ,"Granted");
File file = new File(textView_currentPath.getText() + "/" + "testfile.txt");
Log.v("filepatch: ", ""+file);
if (!file.exists()) {
Log.v("Does "+file+" exists?", "No");
try {
file.createNewFile();
getFilesFromDir(textView_currentPath.getText() + "", textView_currentPath.getText() + "");
Log.v("File "+file,"has been created!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
LogCat
04-11 16:31:40.709 23404-23404/spicysoftware.com.phonemanager D/ViewRootImpl@ab22b33[MainActivity]: ViewPostImeInputStage processPointer 0
04-11 16:31:40.773 23404-23404/spicysoftware.com.phonemanager D/ViewRootImpl@ab22b33[MainActivity]: ViewPostImeInputStage processPointer 1
04-11 16:31:40.783 23404-23404/spicysoftware.com.phonemanager V/Permission:: Granted
04-11 16:31:40.783 23404-23404/spicysoftware.com.phonemanager V/filepatch:: /storage/B9BE-18A6/testfile.txt
04-11 16:31:40.783 23404-23404/spicysoftware.com.phonemanager V/Does /storage/B9BE-18A6/testfile.txt exists?: No
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: java.io.IOException: Permission denied
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.io.UnixFileSystem.createFileExclusively0(Native Method)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.io.File.createNewFile(File.java:948)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at spicysoftware.com.phonemanager.StorageFragment.onClick(StorageFragment.java:187)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.view.View.performClick(View.java:6207)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.view.View$PerformClick.run(View.java:23639)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.os.Looper.loop(Looper.java:154)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6688)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at java.lang.reflect.Method.invoke(Native Method)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
04-11 16:31:40.784 23404-23404/spicysoftware.com.phonemanager W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
解决方法 感谢@greenapps 让我走上了正确的道路。 解决方案在 https://developer.android.com/guide/topics/providers/document-provider.html
中有很好的记录 Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
String mimeType = "text/plain";
String filename = "file"+System.currentTimeMillis() + ".txt";
intent.setType(mimeType);
intent.putExtra(Intent.EXTRA_TITLE, filename);
startActivityForResult(intent, CREATE_REQUEST_CODE);
SD卡是只读的。所以你不能写。您只能写入 SD 卡上的应用特定目录。在你的情况下它将是
/storage/B9BE-18A6/Android/data/spicysoftware.com.phonemanager
如果你想写在整个SD卡上那么文件class和FileOutputStream是不行的。那么你必须使用存储访问框架。