Возможно ли обновить 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();
, чтобы вернуть количество изображений, и вы можете сравнить его с предыдущим значением.