#在4.4以上中,谷歌对其已经做了权限限制,为了规范SD卡操作!在推出后,引起业界一片吐槽,迫于压力,google推出了一种全新的方式去操作SD卡:Android SAF
注:
一定要进行版本判断
一定要进行版本判断
一定要进行版本判断
private static int DOCUMENT_TREE_REQUEST = 1;
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
activity.startActivityForResult(intent, DOCUMENT_TREE_REQUEST);
通过上面意图会进入到:
http://jingyan.baidu.com/article/91f5db1b3fc3981c7f05e3f1.html(这时es文件管理器的操作方式,其实都一样)
选择SD卡后,会调用
public static String ACTION_OPEN_DOCUMENT_TREE_URL = "ACTION_OPEN_DOCUMENT_TREE";
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
SharedPreferences lee = getApplicationContext().getSharedPreferences("xxx", 0);
if (requestCode == 1) {
String p = lee.getString("URI", null);
Uri oldUri = null;
if (p != null) oldUri = Uri.parse(p);
Uri treeUri = null;
if (resultCode == Activity.RESULT_OK) {
// Get Uri from Storage Access Framework.
treeUri = data.getData();
// Persist URI - this is required for verification of writability.
if (treeUri != null) lee.edit().putString(ACTION_OPEN_DOCUMENT_TREE_URL, treeUri.toString()).commit();
}
// If not confirmed SAF, or if still not writable, then revert settings.
if (resultCode != Activity.RESULT_OK) {
/* DialogUtil.displayError(getActivity(), R.string.message_dialog_cannot_write_to_folder_saf, false,
currentFolder);||!FileUtil.isWritableNormalOrSaf(currentFolder)
*/
if (treeUri != null) lee.edit().putString(ACTION_OPEN_DOCUMENT_TREE_URL, oldUri.toString()).commit();
return;
}
// After confirmation, update stored value of folder.
// Persist access permissions.
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
Toast.makeText(getApplicationContext(),getApplicationContext().getString(R.string.success_get_premiss_tips),Toast.LENGTH_SHORT).show();
}
}
注意上面的 SharedPreferences lee = getApplicationContext().getSharedPreferences(“xxx”, 0); 会将URI保存到SharedPreferences中,
然后在需要删除外置SD卡时我们需要获取一个DocumentFile对象
public DocumentFile getDocumentFile(final File file, final boolean isDirectory,Context context) {
String baseFolder = getExtSdCardFolder(file,context);
boolean originalDirectory=false;
if (baseFolder == null) {
return null;
}
String relativePath = null;
try {
String fullPath = file.getCanonicalPath();
if(!baseFolder.equals(fullPath))
relativePath = fullPath.substring(baseFolder.length() + 1);
else originalDirectory=true;
}
catch (IOException e) {
return null;
}
catch (Exception f){
originalDirectory=true;
//continue
}
//此处更换你的SharedPreferences
SharedPreferences lee = context.getSharedPreferences("xxx", 0);
String uri = lee.getString(ACTION_OPEN_DOCUMENT_TREE_URL,null);
Uri parse = Uri.parse(uri);
// start with root of SD card and then parse through document tree.
DocumentFile document = DocumentFile.fromTreeUri(context, parse);
if(originalDirectory)return document;
String[] parts = relativePath.split("\\/");
for (int i = 0; i < parts.length; i++) {
DocumentFile nextDocument = document.findFile(parts[i]);
if (nextDocument == null) {
if ((i < parts.length - 1) || isDirectory) {
if( document.createDirectory(parts[i])==null){
return null;
}
nextDocument = document.createDirectory(parts[i]);
}
else {
nextDocument = document.createFile("image", parts[i]);
}
}
document = nextDocument;
}
return document;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getExtSdCardFolder(final File file,Context context) {
String[] extSdPaths = getExtSdCardPaths(context);
try {
for (int i = 0; i < extSdPaths.length; i++) {
if (file.getCanonicalPath().startsWith(extSdPaths[i])) {
return extSdPaths[i];
}
}
}
catch (IOException e) {
return null;
}
return null;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String[] getExtSdCardPaths(Context context) {
List<String> paths = new ArrayList<String>();
for (File file : context.getExternalFilesDirs("external")) {
if (file != null && !file.equals(context.getExternalFilesDir("external"))) {
int index = file.getAbsolutePath().lastIndexOf("/Android/data");
if (index < 0) {
Log.w("AmazeFileUtils", "Unexpected external file dir: " + file.getAbsolutePath());
}
else {
String path = file.getAbsolutePath().substring(0, index);
try {
path = new File(path).getCanonicalPath();
}
catch (IOException e) {
// Keep non-canonical path.
}
paths.add(path);
}
}
}
if(paths.isEmpty())paths.add("/storage/sdcard1");
return paths.toArray(new String[0]);
}
拿到DocumentFile对象后进行删除操作:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean delect(FileInfo f) {
DocumentFile documentFile = getDocumentFile(new File(f.filePath), f.IsDir, mContext);
if(documentFile!=null) {
documentFile.delete();
}else {
//当更换SD卡后,uri值会发生变化,拿到的DocumentFile会为null,而此处在进行一次上面操作既可
}
return true;
}
剩下的创建复制剪贴和File一样,只将换成documentFile既可!