Как узнать файл с внутренней или внешней памяти в Android? - PullRequest
1 голос
/ 08 ноября 2019

Я хочу знать, как определить путь к файлу из внутреннего или внешнего хранилища.

Я хочу удалить файл. Прежде чем удалить его, я хочу проверить, является ли он из внутренней памяти или внешней. если файл из внутреннего хранилища, то я могу просто удалить его следующим образом:

file.delete();

Но если файл из внешнего хранилища (SDCard). Затем я сначала проверил бы разрешение, а затем удалил его через среду доступа к хранилищу.

В настоящее время я делаю так.

            File selectedFile = Constant.allMemoryVideoList.get(fPosition).getFile().getAbsoluteFile();

            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (???????????? check if file is not from internal storage ???????????) {
                    List<UriPermission> permissions = getContentResolver().getPersistedUriPermissions();
                    if (permissions != null && permissions.size() > 0) {
                        sdCardUri = permissions.get(0).getUri();
                        deleteFileWithSAF();
                    } else {
                        AlertDialog.Builder builder = new AlertDialog.Builder(this);
                        builder.setTitle("Please select external storage directory (e.g SDCard)")
                                .setMessage("Due to change in android security policy it is not possible to delete or rename file in external storage without granting permission")
                                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        // call document tree dialog
                                        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                                        startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
                                    }
                                })
                                .setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {

                                    }
                                })
                                .show();
                    }

                } else {
                    deleteFile();
                }
            } else {
                deleteFile();
            }

deleteFileWithSAF ()

    private void deleteFileWithSAF() {
        //First we get `DocumentFile` from the `TreeUri` which in our case is `sdCardUri`.
        DocumentFile documentFile = DocumentFile.fromTreeUri(this, sdCardUri);

        //Then we split file path into array of strings.
        //ex: parts:{"", "storage", "extSdCard", "MyFolder", "MyFolder", "myImage.jpg"}
        // There is a reason for having two similar names "MyFolder" in
        //my exmple file path to show you similarity in names in a path will not
        //distract our hiarchy search that is provided below.
        String[] parts = (selectedFile.getPath()).split("\\/");

        // findFile method will search documentFile for the first file
        // with the expected `DisplayName`

        // We skip first three items because we are already on it.(sdCardUri = /storage/extSdCard)
        for (int i = 3; i < parts.length; i++) {
            if (documentFile != null) {
                documentFile = documentFile.findFile(parts[i]);
            }
        }

        if (documentFile == null) {

            // File not found on tree search
            // User selected a wrong directory as the sd-card
            // Here must inform user about how to get the correct sd-card
            // and invoke file chooser dialog again.

            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Please select root of external storage directory (click SELECT button at bottom)")
                    .setMessage("Due to change in android security policy it is not possible to delete or rename file in external storage without granting permission")
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // call for document tree dialog
                            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                            startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
                        }
                    })
                    .setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    })
                    .show();

        } else {

            // File found on sd-card and it is a correct sd-card directory
            // save this path as a root for sd-card on your database(SQLite, XML, txt,...)

            // Now do whatever you like to do with documentFile.
            // Here I do deletion to provide an example.


            if (documentFile.delete()) {// if delete file succeed
                // Remove information related to your media from ContentResolver,
                // which documentFile.delete() didn't do the trick for me.
                // Must do it otherwise you will end up with showing an empty
                // ImageView if you are getting your URLs from MediaStore.


                getApplicationContext().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(selectedFile)));
//                              Methods.removeMedia(this,selectedFile.getPath());

                if (deleteSingleFileCall){
                    Constant.allMemoryVideoList.remove(videoPosition);
                    adapter.notifyItemRemoved(videoPosition);
                    deleteSingleFileCall = false;
                }

                /*update the playback record to
                 * getFileName() contain file.getName()*/
                for (int i = 0; i < Constant.filesPlaybackHistory.size(); i++) {
                    if ((selectedFile.getName()).equals(Constant.filesPlaybackHistory.get(i).getFileName())) {
                        Constant.filesPlaybackHistory.remove(i);
                        break;
                    }
                }

                //save the playback history
                Paper.book().write("playbackHistory", Constant.filesPlaybackHistory);

            }
        }
    }

Так я загружаю файлы как внутреннего, так и внешнего хранилища.

StorageUtil - это библиотека https://github.com/hendrawd/StorageUtil

String[] allPath = StorageUtil.getStorageDirectories(this);
private File directory;
for (String path: allPath){
    directory = new File(path);
    Methods.load_Directory_Files(directory);
}

Все загруженные файлы в следующихarraylist.

//all the directory that contains files
public static ArrayList<File> directoryList = null;
//list of all files (internal and external)
public static ArrayList<FilesInfo> allMemoryVideoList = new ArrayList<>();

FilesInfo: Содержит всю информацию о файле, такую ​​как миниатюра, продолжительность, каталог, новый или воспроизведенный ранее, если воспроизводился, то последняя позиция воспроизведения и т. д.

LoadDirectoryFiles ()

public static void  load_Directory_Files(File directory) {

    //Get all file in storage
    File[] fileList = directory.listFiles();
    //check storage is empty or not
    if(fileList != null && fileList.length > 0)
    {
        for (int i=0; i<fileList.length; i++)
        {
            boolean restricted_directory = false;
            //check file is directory or other file
            if(fileList[i].isDirectory())
            {
                for (String path : Constant.removePath){
                    if (path.equals(fileList[i].getPath())) {
                        restricted_directory = true;
                        break;
                    }
                }
                if (!restricted_directory)
                    load_Directory_Files(fileList[i]);
            }
            else
            {
                String name = fileList[i].getName().toLowerCase();
                for (String ext : Constant.videoExtensions){
                    //Check the type of file
                    if(name.endsWith(ext))
                    {
                        //first getVideoDuration
                        String videoDuration = Methods.getVideoDuration(fileList[i]);
                        long playbackPosition;
                        long percentage = C.TIME_UNSET;
                        FilesInfo.fileState state;

                        /*First check video already played or not. If not then state is NEW
                         * else load playback position and calculate percentage of it and assign it*/

                        //check it if already exist or not if yes then start from there else start from start position
                        int existIndex = -1;
                        for (int j = 0; j < Constant.filesPlaybackHistory.size(); j++) {
                            String fListName = fileList[i].getName();
                            String fPlaybackHisName = Constant.filesPlaybackHistory.get(j).getFileName();
                            if (fListName.equals(fPlaybackHisName)) {
                                existIndex = j;
                                break;
                            }
                        }

                        try {
                            if (existIndex != -1) {
                                //if true that means file is not new
                                state = FilesInfo.fileState.NOT_NEW;
                                //set playbackPercentage not playbackPosition
                                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
                                retriever.setDataSource(fileList[i].getPath());
                                String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                                retriever.release();

                                int duration = Integer.parseInt(time);
                                playbackPosition = Constant.filesPlaybackHistory.get(existIndex).getPlaybackPosition();

                                if (duration > 0)
                                    percentage = 1000L * playbackPosition / duration;
                                else
                                    percentage = C.TIME_UNSET;

                            }
                            else
                                state = FilesInfo.fileState.NEW;

                            //playbackPosition have value in percentage
                            Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
                                    directory,videoDuration, state, percentage, storageType));

                            //directory portion
                            currentDirectory = directory.getPath();
                            unique_directory = true;

                            for(int j=0; j<directoryList.size(); j++)
                            {
                                if((directoryList.get(j).toString()).equals(currentDirectory)){
                                    unique_directory = false;
                                }
                            }

                            if(unique_directory){
                                directoryList.add(directory);
                            }

                            //When we found extension from videoExtension array we will break it.
                            break;

                        }catch (Exception e){
                            e.printStackTrace();
                            Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
                                    directory,videoDuration, FilesInfo.fileState.NOT_NEW, C.TIME_UNSET, storageType));
                        }

                    }
                }
            }
        }
    }
    Constant.directoryList = directoryList;
}

Изображение Чтобы читатель мог легко понять, что происходит.

enter image description here

...