ContentResolver не содержит только что созданное изображение в немедленном запросе после создания файла
Я использую этот код для копирования изображения с помощью documentFile.createFile()
private void newcopyFile(File fileInput, String outputParentPath,
String mimeType, String newFileName) {
DocumentFile documentFileGoal = DocumentFile.fromTreeUri(this, treeUri);
String[] parts = outputParentPath.split("\\/");
for (int i = 3; i < parts.length; i++) {
if (documentFileGoal != null) {
documentFileGoal = documentFileGoal.findFile(parts[i]);
}
}
if (documentFileGoal == null) {
Toast.makeText(MainActivity.this, "Directory not found", Toast.LENGTH_SHORT).show();
return;
}
DocumentFile documentFileNewFile = documentFileGoal.createFile(mimeType, newFileName);
InputStream inputStream = null;
OutputStream outputStream = null;
try {
outputStream = getContentResolver().openOutputStream(documentFileNewFile.getUri());
inputStream = new FileInputStream(fileInput);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (outputStream != null) {
byte[] buffer = new byte[1024];
int read;
if (inputStream != null) {
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
}
if (inputStream != null) {
inputStream.close();
}
inputStream = null;
outputStream.flush();
outputStream.close();
outputStream = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
И вот как я запрашиваю ContentResolver
после создания изображения немедленно обновить галерею изображений с результатом запроса, который должен содержать информацию о вновь созданном изображении.
cursorPhotos = MainActivity.this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projectionsImages,
null,
null,
MediaStore.Images.Media.DATE_TAKEN + " DESC"
);
Но немедленный запрос не смог найти вновь созданное изображение. И если я через некоторое время снова выполню запрос, в результате появится только что созданное изображение.
Кажется, что предоставление информации для вновь созданного изображения требует времени для ContentResolver
(если за это отвечает ContentResolver), так как он будет работать в фоновом режиме, пока я выполняю немедленный запрос.
Есть ли способ или слушатель, чтобы знать, когда вновь созданное изображение зарегистрировано ContentResolver
?
2 ответа
Вы можете использовать это или так я реализовал слушателя (наблюдателя) для ContentResolver
изменения, используя ContentObserver
знать, когда подходящее время для запуска запроса на получение вновь созданного изображения из ContentResolver
,
Сначала создать ContentObserver
Учебный класс:
Этот класс, как говорит его название, наблюдает за любыми изменениями содержимого в нашем желаемом Uri.
class MyObserver extends ContentObserver {
public MyObserver(android.os.Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
this.onChange(selfChange, null);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
//(SDK>=16)
// do s.th.
// depending on the handler you might be on the UI
// thread, so be cautious!
// This is my AsyncTask that queries ContentResolver which now
// is aware of newly created media file.
// You implement your own query here in whatever way you like
// This query will contain info for newly created image
asyncTaskGetPhotosVideos = new AsyncTaskGetPhotosVideos();
asyncTaskGetPhotosVideos.execute();
}
}
и в конце вашего метода копирования вы можете установить ContentObserver
на ваш ContentResolver
на конкретном ури.
getContentResolver().registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
myObserver);
и не забудьте отменить регистрацию вашего наблюдателя, иначе вы столкнетесь с утечкой памяти. Я бы предпочел это в конце моей AsyncTask (onPostExecute).
getContentResolver().unregisterContentObserver(myObserver);
Вы можете выбрать ContentObserver
на желаемом Uri в течение всего жизненного цикла приложения, чтобы получать уведомления об изменении, удалении или вставке носителей извне или внутри вашего приложения.
Для этого подхода вы можете зарегистрировать своего наблюдателя в onResume()
метод жизненного цикла и отменить его регистрацию в onPause()
метод.
Извините, я отправил неправильный код
Когда вы добавляете файлы в файловую систему Android, эти файлы не выбираются программой MedaScanner автоматически. Но часто они должны быть.
Таким образом, чтобы добавить файл в контент-провайдера вручную
Так что используйте этот код:-
Intent intent =
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
Для большего количества методов сделать это и для справки посетите этот сайт:-
http://www.grokkingandroid.com/adding-files-to-androids-media-library-using-the-mediascanner/