Возможно ли обновить Media Store на Android Nougat?

Я скопировал файлы из приватной папки приложения в Pictures или DCIM, и я хочу открыть виджет галереи в своем приложении и отобразить эти изображения. Однако мой виджет галереи создает галерею миниатюр с использованием идентификатора MediaStore, и новые добавленные изображения не появляются там.

Я попробовал все три решения, предложенные в stackoverflow, чтобы обновить медиа-магазин и сообщить Android о существовании новых файлов

  • sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, - запрещено в новых API

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();
    }
}

Опять же, uri имеет значение null

Почему Android так сложно выполнять такое нормальное, законное действие? Как добиться этого эффекта в Нуге?

EDIT: я также попытался отправить трансляцию для ACTION_MEDIA_SCANNER_SCAN_FILE

И я даже принял во внимание это: https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en

Итак, теперь я отправляю content:// вместо file:// URI, но все равно ничего!

EDIT2:

Я пробовал это

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);
}

как описано здесь

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

Но опять же, когда я открываю свою галерею, нового изображения нет.

Ответ 1

Оказывается, я пытался проверить путь к файлу, который я скопировал в другое место, а затем удалил, а не путь к вновь созданному файлу.

С комбинацией медиа-сканера и ACTION_MEDIA_SCANNER_SCAN_FILE и попыткой сканирования нужного файла я смог обновить медиа-магазин.

Ответ 2

Я делаю подобное, и он работает в Нуге. Всякий раз, когда я вызываю метод getFilePaths();, он возвращает мне свежий ArrayList всех изображений, хранящихся в Хранении телефона. -

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;


}

Теперь вы получите Путь ко всем изображениям. Вы можете вызвать getFilePaths().size();, чтобы вернуть количество изображений, и вы можете сравнить его с предыдущим значением.