• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Need some help with File.listFiles() not returning files with text file extensions.

So I`m very novice to the android development, and only know a few things here or there. Recently I attempted to make an app which needs to read .xml files from external storage. I`ve ensure I have the required permission in my manifest like so:

Code:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

and also that I request it if necessary:

Java:
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},101);
        }

I`ve also ensured that on my device the permission is displayed as granted.

The actual code I`ve tried to acquire files consist of :
Java:
@RequiresApi(api = Build.VERSION_CODES.O)
    public ArrayList<String[]> getFiles(String suffix, String root_dir){
        ArrayList<String[]> ret = new ArrayList<String[]>();
        try {
            root_dir = Environment.getExternalStorageDirectory().toString() + "/" + root_dir;
            Path dirName = Paths.get(root_dir);
            DirectoryStream<Path> paths = Files.newDirectoryStream(dirName, "*"+suffix);

            paths.forEach(path -> {
                Log.e(TAG, "getFiles: HAS FILE : "+path.toString());
                if (path.endsWith(suffix)) {
                    String sPath = path.toString();
                    String[] splitted = sPath.split(File.separator);
                    ret.add(new String[]{sPath, splitted[splitted.length - 1]});
                }
            });
        } catch (IOException exception) {
            exception.printStackTrace();
        }

        return ret;
    }

This snippet did not return any files, and so didn't this one which I`ve tried next:
Java:
public ArrayList<String []> getLongAndShortFileHandles(String root_dir, String suffix) {

        ArrayList<String[]> ret = new ArrayList<>();

        String path = Environment.getExternalStorageDirectory().toString()+"/"+root_dir+"/";

        File directory = new File(path);
        File[] files = directory.listFiles((dir, name) -> name.endsWith(suffix));
        Log.e(TAG, "getLongAndShortFileHandles: Has dir "+path+", with "+((files==null) ? "null" : files.length) + " number of files");
        for (int i = 0; i < Objects.requireNonNull(files).length; i++)
        {
            Log.e(TAG, "getLongAndShortFileHandles: HAS FILE "+files[i].getName());
            String [] temp = new String [] {files[i].getAbsolutePath(),files[i].getName()};
            ret.add(temp);
        }

        return ret;
    }

This already was a bit weird since multiple far more experienced people told me that this supposed to work. I`ve preceded to try it with different directories and file types. My original assumption was that file type (text or binary) mattered as .jpg, .wav, .mp3, .mp4 files were easily located, but files like .txt, .json, .xml were not.

However I`ve realized that renaming any of the abovementioned files to .jpg allowed my app to detect it. This made me utterly confused, so I tried to pass different name filters into the listFiles function, including null so it uses the default one. Sadly all of that was for no avail.

Now I don't have any clues, and begin to suspect that it might be a bug. To ensure my information is exact my target SDK version is 30, and my minimal accepted is 19. My android studio version is 4.1.2 and my device is a physical device (Galaxy A40) with android 11.

P.S. My device file explorer can see the files without any problems and i can open them with Internet app.

EDIT:
I`ve tried accessing files directly and that seemed to work.
Java:
        this.test = (Button) findViewById(R.id.select_to_test);
        this.test.setOnClickListener(v -> {
            String path = Environment.getExternalStorageDirectory().toString()+"/cascade_app/cascades/50.xml";
            Intent intent = new Intent(v.getContext(),CheckCascade.class);
            intent.putExtra("fh",path);
            File debugFile = new File(path);
            Toast.makeText(this, "File "+path+" does "+((debugFile.exists())? "exist":"not exist"), Toast.LENGTH_SHORT).show();
            startActivity(intent);
        });

    }
 
Last edited:
Hi, I have had similar issue (couldn't read json files from external storage). It turns out the reason is that in Android 11 they changed entirely the way how application can access media files.

In order to use the same File API to get ALL files in Android 11, you need to do following:

1. Add <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> to manifest
2. Check if you have all files access by using: Environment.isExternalStorageManager()
3. If you don't, you can request the permission this way:
Uri uri = Uri.parse("package:" + BuildConfig.APPLICATION_ID);
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, uri);
context.startActivity(intent);

This will redirect you to the Settings when use can gran your application All files access. When granted, you can use all the same method to access ALL files on Android 11.
 
Back
Top Bottom