Android 6.0:尽管有权限,但 SD 卡目录创建失败
Android 6.0: SD Card Directory creation fails in spite of having permissions
我正在尝试创建外部目录结构以将一些文件从设备存储移动到 Android 手机中的 SD 卡。我已按照 https://developer.android.com/training/permissions/requesting.html 中给出的步骤和多个 Whosebug 答案进行操作。但是,当我尝试创建目录时,我的程序失败了。
我的 AndroidManifest.xml
文件包含以下行:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
相关代码如下:
public int mkFolder(String folderName){
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)){
Log.d(TAG, "Error: external storage is unavailable");
return 0;
}
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d(TAG, "Error: external storage is read only.");
return 0;
}
Log.d(TAG, "External storage is not read only or unavailable");
boolean writePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
boolean readPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
final boolean permissionNotGranted = writePermission|| readPermission;
if (permissionNotGranted) {
Log.i(TAG, "STORAGE permissions NOT granted");
// Should we show an explanation?
boolean shouldShowRationaleForWritePermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
boolean shouldShowRationaleForReadPermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (shouldShowRationaleForWritePermssion || shouldShowRationaleForReadPermssion) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}
} else {
Log.i(TAG, "STORAGE permissions granted");
}
// File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
File folder = new File(folderName);
int result = 0;
if (folder.exists()) {
Log.d(TAG,"folder exist:"+folder.toString());
result = 2; // folder exist
}else{
try {
if (folder.mkdirs()) {
Log.d(TAG, "folder created:" + folder.toString());
result = 0; // folder created
} else {
Log.d(TAG, "create folder fails:" + folder.toString());
result = 1; // create folder fails
}
}catch (Exception ecp){
ecp.printStackTrace();
}
}
return result;
}
public static final int REQUEST_EXTERNAL_STORAGE = 112;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[], @NonNull int[] grantResults) {
Log.e(TAG, "onRequestPermissionsResult invoked");
switch (requestCode) {
case REQUEST_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
Log.i(TAG, "Permission to write to external storage granted");
Toast.makeText(this, "Permission to write to external storage granted", Toast.LENGTH_LONG).show();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.e(TAG, "Permission to write to external storage NOT granted");
Toast.makeText(this, "Permission to write to external storage NOT granted", Toast.LENGTH_LONG).show();
}
}
// other 'case' lines to check for other
// permissions this app might request
}
}
这是日志的摘录:
MainActivity: /storage/0000-0000 false true
MainActivity: /storage/0000-0000/MyDir does not exist. Creating target parent directory
MainActivity: STORAGE permissions granted
MainActivity: Creation of directory /storage/0000-0000/MyDir failed with return value 1. Aborting...
谁能帮我理解我的代码中的错误是什么?
您不能直接访问文件系统上的任意位置 removable storage, starting with Android 4.4. WRITE_EXTERNAL_STORAGE
is meaningless here, as external storage 不是可移动存储。
改用存储访问框架(ACTION_OPEN_DOCUMENT_TREE
和 kin)。或者,将您的工作限制在作为 getExternalFilesDirs()
、getExternalCacheDirs()
和 getExternalMediaDirs()
(Context
上的所有方法)的一部分返回的可移动存储位置。
我正在尝试创建外部目录结构以将一些文件从设备存储移动到 Android 手机中的 SD 卡。我已按照 https://developer.android.com/training/permissions/requesting.html 中给出的步骤和多个 Whosebug 答案进行操作。但是,当我尝试创建目录时,我的程序失败了。
我的 AndroidManifest.xml
文件包含以下行:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
相关代码如下:
public int mkFolder(String folderName){
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)){
Log.d(TAG, "Error: external storage is unavailable");
return 0;
}
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d(TAG, "Error: external storage is read only.");
return 0;
}
Log.d(TAG, "External storage is not read only or unavailable");
boolean writePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
boolean readPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
final boolean permissionNotGranted = writePermission|| readPermission;
if (permissionNotGranted) {
Log.i(TAG, "STORAGE permissions NOT granted");
// Should we show an explanation?
boolean shouldShowRationaleForWritePermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
boolean shouldShowRationaleForReadPermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (shouldShowRationaleForWritePermssion || shouldShowRationaleForReadPermssion) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}
} else {
Log.i(TAG, "STORAGE permissions granted");
}
// File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
File folder = new File(folderName);
int result = 0;
if (folder.exists()) {
Log.d(TAG,"folder exist:"+folder.toString());
result = 2; // folder exist
}else{
try {
if (folder.mkdirs()) {
Log.d(TAG, "folder created:" + folder.toString());
result = 0; // folder created
} else {
Log.d(TAG, "create folder fails:" + folder.toString());
result = 1; // create folder fails
}
}catch (Exception ecp){
ecp.printStackTrace();
}
}
return result;
}
public static final int REQUEST_EXTERNAL_STORAGE = 112;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[], @NonNull int[] grantResults) {
Log.e(TAG, "onRequestPermissionsResult invoked");
switch (requestCode) {
case REQUEST_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
Log.i(TAG, "Permission to write to external storage granted");
Toast.makeText(this, "Permission to write to external storage granted", Toast.LENGTH_LONG).show();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Log.e(TAG, "Permission to write to external storage NOT granted");
Toast.makeText(this, "Permission to write to external storage NOT granted", Toast.LENGTH_LONG).show();
}
}
// other 'case' lines to check for other
// permissions this app might request
}
}
这是日志的摘录:
MainActivity: /storage/0000-0000 false true
MainActivity: /storage/0000-0000/MyDir does not exist. Creating target parent directory
MainActivity: STORAGE permissions granted
MainActivity: Creation of directory /storage/0000-0000/MyDir failed with return value 1. Aborting...
谁能帮我理解我的代码中的错误是什么?
您不能直接访问文件系统上的任意位置 removable storage, starting with Android 4.4. WRITE_EXTERNAL_STORAGE
is meaningless here, as external storage 不是可移动存储。
改用存储访问框架(ACTION_OPEN_DOCUMENT_TREE
和 kin)。或者,将您的工作限制在作为 getExternalFilesDirs()
、getExternalCacheDirs()
和 getExternalMediaDirs()
(Context
上的所有方法)的一部分返回的可移动存储位置。