0

I am developing an app where I have to search PDF files in my Internal Storage as well as removable SD card. This is code that I am using:

private void Search_Dir(File dir) {

        try {
            String pdfPattern = displayName;  //(displayName = pdf_name.pdf)
            File FileList[] = dir.listFiles();

            if(FileList != null)
            {
                for(int i = 0 ; i < FileList.length ; i++)
                {

                    if(FileList[i].isDirectory())
                    {
                        Search_Dir(FileList[i]);
                    }
                    else
                    {
                        if(FileList[i].getName().endsWith(pdfPattern))
                        {
                            path = FileList[i].toString();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Here path is a String which will contain the path of the PDF that I want to search. And the name of PDF that I am searching is displayName

I am calling this method like this:

Search_Dir(Environment.getExternalStorageDirectory());

But unfortunately this method searches the PDF in my internal storage only. I have defined READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE and I am requesting these permissions run time also.

I don't know if this matters but it was working perfectly fine before. I was getting the path for PDF files located in SD card also. But I did factory data reset on my phone and then again I installed my app. Since then its not working.

It is working on files located in my internal storage like /storage/emulated/0/..... but not on removable SD card.

My Question: What is it that I am doing wrong. Or is there any other method which I should use to search the files which will work on both internal storage and removable SD card.

Thank you.

Martin
  • 207
  • 2
  • 12
  • "I am developing an app where I have to search PDF files in my Internal Storage as well as removable SD card" -- by "Internal Storage", I assume that you mean what the Android SDK refers to as [external storage](https://commonsware.com/blog/2019/10/08/storage-situation-external-storage.html). In terms of the "removable SD card", we have not had reliable arbitrary read/write access to [removable storage](https://commonsware.com/blog/2019/10/11/storage-situation-removable-storage.html) for several years, and it only gets more restricted on Android 10+. – CommonsWare Jul 09 '20 at 11:49
  • Is there any other method that you can suggest @CommonsWare which I can use to search PDF files on removable storage. And also can you tell me how it was working previously. I didn't even change any code, I just did factory data reset on my phone and reinstalled my app and the method stopped working on external storage. – Martin Jul 09 '20 at 12:16
  • "Is there any other method that you can suggest @CommonsWare which I can use to search PDF files on removable storage" -- on Android 9 and older, query `MediaStore.Files` for a MIME type of `application/pdf`. On Android 10+, you would be stuck with the directory sweep sort of code that you have now (and requesting `android:requestLegacyExternalStorage="true"`). I do not recall a good way to find the root directory of a removable storage volume on Android 10; you can do that using `StorageVolume` on Android 11+. – CommonsWare Jul 09 '20 at 12:32
  • "And also can you tell me how it was working previously" -- it wasn't, insofar as removable storage is not going to be a subdirectory of `Environment.getExternalStorageDirectory()`. You must have had more than one `Search_Dir()` call. – CommonsWare Jul 09 '20 at 12:34
  • Below Q the second item returned by getExternalFilesDirs() gives you a path to the removable micro sd card. The card is only readable outside the obtained directory. – blackapps Jul 09 '20 at 12:55
  • I just want to read the file from the storage. Later on I can save the manipulated PDF as a new file in my internal storage where I have full access. – Martin Jul 09 '20 at 18:02
  • I have figured it out. There are methods that can be used to get the I'd (or whatever it is) of the removable SD card like /storage/3A62-76FA/... something like that. Here this 3A62-76FA thing is important. Once I get this, I say File file = new File("/storage/" + that_id); and then I call Search_Dir(file); and for internal storage I can simply call Search_Dir(Environment.getExternalStorageDirectory()); – Martin Jul 09 '20 at 18:05
  • Anyways thank you very much @CommonsWare. I will put the complete code here as an answer if you want. It is also an answer to another common issue of getting the real path of the PDF that is selected from the storage using Intent. – Martin Jul 09 '20 at 18:12
  • "It is also an answer to another common issue of getting the real path of the PDF that is selected from the storage using Intent" -- no, it is not. See https://stackoverflow.com/a/59123287/115145 and https://stackoverflow.com/a/49221353/115145, among others. "Once I get this, I say File file = new File("/storage/" + that_id)" -- there is no requirement for the mount point of removable storage to be based off of that ID. It might be, it might not be. – CommonsWare Jul 09 '20 at 18:24
  • What I understand from stackoverflow.com/a/59123287/115145 is that they are opening the file using content resolver. But can it also be used to get the real path? (like /storage/emulated/0/.. or /storage/38AE-06FG/.... whichever is applicable) or we can just open and read the file. – Martin Jul 10 '20 at 09:19

1 Answers1

1

Environment.getExternalStorageDirectory() gives you the path to primary storage of the device, which you can also call as internal storage.

You will have to get the root path of the removable storage (if available) in order to search for files there. If you don't want much headache then you can simply make a storage chooser or implement any one from a bunch of already available and tested ones.