0

I am looping a method which returns DocumentFile for 100 or even more times . Many times the method returns null while it has already been looped for around 35 times.

This is the method which is being looped.

 public  static DocumentFile documentfile(final File file ) {

    for (UriPermission permissionUri :con.getContentResolver().getPersistedUriPermissions()) {

        DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, permissionUri.getUri());

        String[] parts = (file.getPath()).split("\\/");

        for (int i = 3; i < parts.length; i++) {

            if (rootDocFile != null)
            {
                rootDocFile = rootDocFile.findFile(parts[i]);
            }

            else {

                rootDocFile = DocumentFile.fromTreeUri(con,permissionUri.getUri() );
                rootDocFile = rootDocFile.findFile(parts[i]);
            }

        }


        return rootDocFile;

    }
    return null;
}

This is how I am looping the method

for(int i=0;i<size;i++)
{
    documentfile(file).createFile(mime, name)
}

All the above code is being executed inside an Async Task.

Any help would be really Grateful.

EDIT: Tried with the Updated code but still received the same error.

Updated Code

public static DocumentFile DocumentFile(final File file)
{

    DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, permission().getUri());

    String[] parts = (file.getPath()).split("\\/");

    for (int i = 3; i < parts.length; i++)
    {

        rootDocFile = rootDocFile.findFile(parts[i]);

    }
    return rootDocFile;
}

public static UriPermission permission()
{
    for (UriPermission permissionUri : con.getContentResolver().getPersistedUriPermissions())
    {
        final File uri_path = new File(FileUtil.getFullPathFromTreeUri(permissionUri.getUri(), con));

        if (uri_path.getName().toLowerCase().equals(new File("SD_CARD_PATH").getName().toLowerCase()))
        {
            return permissionUri;

        }

    }

    return null;
}

This is how I am checking if the permission granted is for SD Card or not

public static boolean wrong_directory_selected(Uri uri, Context con)
    {

        final File uri_path=new File(FileUtil.getFullPathFromTreeUri(uri,con));
        if(uri_path.getName().toLowerCase().equals(new File("SD CARD PATH").getName().toLowerCase()))
        {

            return false;
        }
        return  true;
    }
Rahulrr2602
  • 701
  • 1
  • 13
  • 34
  • Please indent your code correctly. It’s not easy to read it as it stands. Thank you. – Ole V.V. Jul 23 '17 at 10:19
  • Method "documentfile" return null when "con.getContentResolver().getPersistedUriPermissions()" doesn't have any "UriPermission ". You have to focus on "con.getContentResolver().getPersistedUriPermissions()" and verify when doesn't have UriPermission. – anemomylos Jul 23 '17 at 12:05
  • @j.e.gr if I loop the method for eg 100 times then the code is working fine 35 to 40 times. It means that the permission has been given and I am also checking whether the permission has been given. – Rahulrr2602 Jul 23 '17 at 12:18
  • Why are you calling `getPersistedUriPermissions()` in a for loop when you clearly exit on the first value in the list? It seems possible to me the list returned by that call is sometimes empty. Are you perhaps calling `releasePersistableUriPermission()` somewhere else? From the way the code is structured, it's also possible `fromTreeUri()` is returning null. If we knew more about what you wanted to accomplish we might could offer a better way of achieving it. You could also add messages to logcat or debug it to see why the method returns null. – Dave Jul 23 '17 at 13:12
  • @Dave I am sure that the list is not empty because I am checking using a Shared Preference whether the user has given the permission or not. No I am not calling `releasePersistableUriPermission()` anywhere. I am trying to copy some files to SD Card. So first I am creating a File in SD Card and then transferring. Is there any reason for `fromTreeUri()` to return null. I don't much about programming. Any help would be really Grateful. – Rahulrr2602 Jul 23 '17 at 14:01
  • @Rahulrr2602 You loop the code 100 times on sd-card images? – Eftekhari Jul 23 '17 at 15:46
  • @Rahulrr2602 I mean does your `documentFile == null` always happens on a fixed number of loop or it's not exactly the same file each time? – Eftekhari Jul 23 '17 at 15:51
  • @Eftekhari Yes sometimes it is to get `DocumentFile` for a file from SD Card and sometimes it is to get `DocumentFile` for a Folder in SD Card. – Rahulrr2602 Jul 23 '17 at 15:54
  • @Eftekhari No there is no fixed number of times but in general many of my users have complained that the app crashes after many files have been transferred and also I am receiving Crash reports that `DocumentFile` is null. The code is working fine on all my test devices. – Rahulrr2602 Jul 23 '17 at 15:57
  • @Rahulrr2602 On which devices you've got `documentFile == null`? and which version of the android? – Eftekhari Jul 23 '17 at 17:26
  • @Eftekhari Samsung J2 Android 5.1.1, Samsung S5 Android 5.0 are the two of the many different from which I have received the crash Reports. I have tested the app on Lenovo Vibe P1 Android 6.0, Lenovo Vibe P1m Android 5.0, Lyf Flame 8 Android 5.0. – Rahulrr2602 Jul 23 '17 at 17:44

1 Answers1

1

Inside the else part of your code and on the first line, you are creating a new DocumentFile just from the sd-card's URI and then on the second line, you try to find a file on the root directory of the sd-card which provides you nothing.

I can't guess the logic behind your else part after you getting null out of the user`s provided URI.

When you get null from this approach it means that the user has been selected a wrong directory as the sd-card. So the first thing you have to do is to ask the user to provide the correct path to the sd-card.

public static DocumentFile documentfile(final File file ) {   
  for (UriPermission permissionUri : con.getContentResolver().getPersistedUriPermissions()) {   
        DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, permissionUri.getUri());    
        String[] parts = (file.getPath()).split("/");    
          for (int i = 3; i < parts.length; i++) {        
            if (rootDocFile != null) {
                rootDocFile = rootDocFile.findFile(parts[i]);
            }
            if (rootDocFile != null) {
                break;
            }
            //else {
            //    rootDocFile = DocumentFile.fromTreeUri(con, permissionUri.getUri());
            //    rootDocFile = rootDocFile.findFile(parts[i]);
            //}        
          }
      }
      return rootDocFile;
}

If rootDocFile is null then ask the user for the correct path

See my previous explanation here

Eftekhari
  • 1,001
  • 1
  • 19
  • 37
  • Thank You very much for the answer will try it and accept it as the correct answer if it solves my problem. It might take a few days to roll out a new update and check if it is working fine. – Rahulrr2602 Jul 24 '17 at 06:00
  • I Tried your suggestion but I still received the same error. I have also updated the code. Can you please help me. – Rahulrr2602 Jul 30 '17 at 09:10
  • The error is from `DocumentFile move = DocumentFile(new File("path)).createFile(mime,"name);` The error is `java.lang.NullPointerException`. Trying to createFile on a null DocumentFile is causing the error. – Rahulrr2602 Jul 30 '17 at 12:47
  • Did you provide read write external storage access to the user? – Eftekhari Jul 30 '17 at 13:45
  • Yes I have added the permission. And also for users using Android 6+ I am asking runtime permission. – Rahulrr2602 Jul 30 '17 at 13:47
  • 1
    Ok, how we create a file with the `DocumentFile` is another story and needs you to ask another question on stacoverflow with a detailed explanation and the exact code you are using and provide the link here for me. – Eftekhari Jul 30 '17 at 14:27
  • 1
    For the sake of this question just make sure you have your desired file through the loop method provided here as the answer to your question. – Eftekhari Jul 30 '17 at 14:28
  • 1
    If you get an error on file creation doesn't mean your `DocumentFile` which you get from the loop is null. – Eftekhari Jul 30 '17 at 14:29
  • OK. Accepting your answer as right answer and will soon create a new question. Thank you very much for helping with this question – Rahulrr2602 Jul 30 '17 at 14:36
  • I have created new a Question https://stackoverflow.com/q/45403633/7317019 . Can you please have a look and help me. – Rahulrr2602 Jul 30 '17 at 19:09