1. 程式人生 > >Android 對5.0+的外接SD卡刪除操作

Android 對5.0+的外接SD卡刪除操作

#在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);

選擇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既可!