Wednesday, February 1, 2017

Is it possible to refresh Media Store on Android Nougat?

Leave a Comment

I have copied files from the app-private folder to either Pictures or DCIM and I want to open the gallery widget in my app and display these images. However, my gallery widget creates a gallery of thumbnails using MediaStore id's and the newly added images dont appear there.

I tried all three solutions suggested on stackoverflow in order to refresh the media store and tell android about the existence of the new files

  1. sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, - forbidden in newer APIs

2.

MediaScannerConnection.scanFile(context,  new String[]{ pathToFile1, pathToFile2 },  null, // tried also with a String[] with the mimetype, no difference  new MediaScannerConnectionClient() {     public void onMediaScannerConnected(){     }     public void onScanCompleted(String path, Uri uri){         // URI is null, and the gallery doesn't display the image     } }); 

3.

public static void scanFile(Context context, String path, String mimeType ) {     Client client = new Client(path, mimeType);     MediaScannerConnection connection =             new MediaScannerConnection(context, client);     client.connection = connection;     connection.connect(); }  private static final class Client implements MediaScannerConnectionClient {     private final String path;     private final String mimeType;     MediaScannerConnection connection;      public Client(String path, String mimeType) {         this.path = path;         this.mimeType = mimeType;     }      @Override     public void onMediaScannerConnected() {         connection.scanFile(path, mimeType);     }      @Override     public void onScanCompleted(String path, Uri uri) {         connection.disconnect();     } } 

Again, uri is null

Why does Android make it so hard to perform such a normal, legit action? How do I achieve this effect in Nougat?

EDIT: I also tried sending broadcast for ACTION_MEDIA_SCANNER_SCAN_FILE

And I even took into consideration this: https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en

So now Im sending content:// instead of file:// URI but still nothing!

EDIT2:

I tried this

public static void scheduleJob(Context context) {   JobScheduler js =       (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);   JobInfo job = new JobInfo.Builder(     MY_BACKGROUND_JOB,     new ComponentName(context, MyJobService.class))       .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)       .setRequiresCharging(true)       .build();   js.schedule(job); } 

as explained here

https://developer.android.com/topic/performance/background-optimization.html

But again, when I open my gallery the new image is not there

2 Answers

Answers 1

Turns out I was trying to scan the path of the file I had copied to another place and then deleted, rather than the path of the newly created file.

With a combination of the media scanner and ACTION_MEDIA_SCANNER_SCAN_FILE and trying to scan the right file, I was able to refresh the media store.

Answers 2

I am doing the similar thing and it is working in Nougat also. Whenever I call getFilePaths(); method, It returns me fresh ArrayList of all the images present in Storage of the phone. -

public ArrayList<String> getFilePaths() {      Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;     String[] projection = {MediaStore.Images.ImageColumns.DATA};     Cursor c = null;     SortedSet<String> dirList = new TreeSet<String>();     ArrayList<String> resultIAV = new ArrayList<String>();      String[] directories = null;     if (u != null)     {         c = getContentResolver().query(u, projection, null, null, null);     }      if ((c != null) && (c.moveToFirst()))     {         do         {             String tempDir = c.getString(0);             tempDir = tempDir.substring(0, tempDir.lastIndexOf("/"));             try{                 dirList.add(tempDir);             }             catch(Exception e)             {              }         }         while (c.moveToNext());         directories = new String[dirList.size()];         dirList.toArray(directories);      }      for(int i=0;i<dirList.size();i++)     {         File imageDir = new File(directories[i]);         File[] imageList = imageDir.listFiles();         if(imageList == null)             continue;         for (File imagePath : imageList) {             try {                  if(imagePath.isDirectory())                 {                     imageList = imagePath.listFiles();                  }                 if ( imagePath.getName().contains(".jpg")|| imagePath.getName().contains(".JPG")                         || imagePath.getName().contains(".jpeg")|| imagePath.getName().contains(".JPEG")                         || imagePath.getName().contains(".png") || imagePath.getName().contains(".PNG")                         || imagePath.getName().contains(".gif") || imagePath.getName().contains(".GIF")                         || imagePath.getName().contains(".bmp") || imagePath.getName().contains(".BMP")                         )                 {                        String path= imagePath.getAbsolutePath();                     resultIAV.add(path);                  }             }             //  }             catch (Exception e) {                 e.printStackTrace();             }         }     }      return resultIAV;   } 

Now You will get Path to all images. You can call getFilePaths().size(); to return number of images and you can compare it with previous value.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment