Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to refresh Media Store on Android Nougat?

Tags:

android

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

like image 691
Kaloyan Roussev Avatar asked Jan 23 '17 09:01

Kaloyan Roussev


Video Answer


2 Answers

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.

like image 137
Kaloyan Roussev Avatar answered Sep 18 '22 08:09

Kaloyan Roussev


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.

like image 30
karanatwal.github.io Avatar answered Sep 18 '22 08:09

karanatwal.github.io