0

The File from which I'm trying to create the array Files[] currentDir via File.listFiles() consists of one subdirectory which happens to be a Link (see image link below).

In the Activity where I'm trying to create currentDir, I'm trying to et the length of it afterwards, but I get the NullpointerException: Attempt to get length of null array.

the corresponding code:

File directory = new File("/storage/self")
currentDir = directory.listFiles();
...

for(File mFile:currentDir){...}

Here's the link to my image: AVD File Explorer.

Using a debugger, I foud out, that currentDir stayed empty (null), indeed.

My guess is, that it's because the directory primary is actually a link.

I found the following thread, and I tried to implement the suggestions: Similar Question on SOF.

I tried:

File directory = directory.getCanonicalFile();
String[] files = directory.listFiles();

and I tried:

...

String mPath = null;
            try {
                mPath = directory.getCanonicalPath();
            } catch (IOException e) {
                e.printStackTrace();
            }

    File[] currentDir = null;

    Path dirPath = Paths.get(mPath);

    if (Files.isSymbolicLink(dirPath)) {
        Path[] files = null;

        try {
            dirPath = Files.readSymbolicLink(dirPath);
            files =  Files.list(dirPath).toArray(size -> new Path[size]);
            currentDir = new File[files.length];

            for(int i = 0; i <files.length; i++){
                currentDir[i] = files[i].toFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    else{
        currentDir = directory.listFiles();
    }

...

for(File mFile:currentDir){...}

(Honestly, I don't like that approach, that's why my question doesn't focus on how to recognise a Link.)

The activity never enters the if statement if (Files.isSymbolicLink(dirPath)) {...}, probably because the directory itself isn't a Link so it's useless, but then again, how am I supposed to get that subdirectory in the first place, if listFiles() doesn't work?

Is there an approach to solve that problem?

Schelmuffsky
  • 320
  • 1
  • 13
  • Have you tried to do ```new File("/storage/self").exists()``` and see whether is in fact true.... don't know perhaps there is something more basic that is not working at play here. Notice that one can execute processes with alternative root directory and so the fact that you can see the expected structure in that explorer is not guarantee that that is what you program is seeing. – Valentin Ruano Jun 08 '18 at 20:55
  • I just tested it, and yes it exists. It would have been very curiouse if it didn't exist, because i had retrieved it via `listFiles()`, before I applied `listeFiles()` on it, aswell. But thanks for your idea! – Schelmuffsky Jun 08 '18 at 21:06
  • I wonder whether is a permissions issue, perhaps you don't have read access to this directory? What about ```directory.canRead()``` then? – Valentin Ruano Jun 08 '18 at 21:28
  • Even though I added ` and ``, `directory.canRead()` still returns false. Is that normal, do I have to implement a PermissionRequest? https://developer.android.com/training/permissions/requesting – Schelmuffsky Jun 08 '18 at 22:13
  • I cannot help any further than this as I don't have the expertise for that... if /storage/self is a special location that is out of limits (unless you have rooted the device) then you are out of luck. Perhaps the user-permission approach you are trying is ok... but if you think of it, it makes no sense that the app would give itself permission to do things, what is supposed to happen is that that app container will ask the user whether he can do such and such.... Perhaps the configuration you are altering would cause that enquire to happen but I guess is not working since you are asking. – Valentin Ruano Jun 08 '18 at 22:20
  • I would suggest that now that you know more of what is going on, perhaps you should post an new question for this newly-found problem with permissions Please try it first on your own using devel docs so that you can post what you have tried so far and the relevant code. – Valentin Ruano Jun 08 '18 at 22:22
  • I think, you already helped me a lot. I'll try the implementation again but differently, then I'll see how far it gets me... – Schelmuffsky Jun 08 '18 at 22:23
  • You can always reward me by accepting my answer in that case if none one comes with a better one after a while. – Valentin Ruano Jun 08 '18 at 22:53

1 Answers1

0

There seems to be several reason why listFiles would return a null even other than it is not directory and it does not exists.

Looking at its code it does interrogates to the SecurityManager whether the app has right to access the folder and since mobile app are typically quite restricted as to what they can do with the phone (e.g. access or modify personal information, contacts, etc) It would not be surprising if that is the problem here.

It that is what is preventing your code to work here, I reckon that you need to add whatever code is necessary so that the app ask permission to the user to access those resources.

Valentin Ruano
  • 2,726
  • 19
  • 29
  • There might be something to it. `android:name="android.permission.WRITE_EXTERANAL_STORAGE"/>` and `` is in the Manifest file, but `ContextCompat.checkSelfPermission()` returns still false. – Schelmuffsky Jun 08 '18 at 22:19
  • That is as much as I can help. – Valentin Ruano Jun 08 '18 at 22:23
  • For further handling (by anyone): The answerer was right as far as permission wasn't handled completely. Now, I got the permission for writing and reading on external Storage, and i can check on it successfully, **BUT** even though that's working and I can proove the existence of the `File` `directory`, it still can't be read via `directory.canRead()`. This leads me to the assumption that it's not a permission problem, leading back to my initial question. – Schelmuffsky Jun 09 '18 at 00:06
  • Not sure if I'm getting this right... Is canRead() returning false? if so this is likely to still be a permissions problem as the ways canRead() would return false on an existing directory are limited otherwise (please look into canRead() to find that out). If that is true, that would mean that your attempts to gain permission (truth those configuration changes) are simply not working whatever the reason is. – Valentin Ruano Jun 09 '18 at 05:22
  • Please be aware that file system read permissions do not ensure read permission from within the Java VM as the SecurityManager may limit (and it will) what an app may or may not be able to do. – Valentin Ruano Jun 09 '18 at 05:24
  • But I get `PERMISSION_GRANTED` from `checkSelfPermission()`, and I have no problem accessing the parent File of `directory` `/storage` to list `/storage/emulated` and `/storage/self`. – Schelmuffsky Jun 09 '18 at 08:24
  • I would suggest that you update your question or create a new one somewhere else with the code extract that show the contradiction between what canRead() and checkSelfPermission() are telling you. AFAIK having permissions to list a parent directory does not grant you permission to list the children contents; so that would be circumstantial evidence at best and doesn't prove the "murder" if you know what I mean. – Valentin Ruano Jun 09 '18 at 11:38
  • that is a good idea. i think i will do that. thank you! I'll mark the questions as answered, now, because of the new, updated question i will post in the future, not because the problem is solved. I hope that won't be misleading for future visitors. – Schelmuffsky Jun 09 '18 at 16:21