Я пытаюсь открыть намерение камеры и загрузить захваченное изображение в Android. Проблема заключается в том, что приложение камеры правильно записывает во входной URI, и записанные данные могут быть успешно декодированы в битовую карту только при первом вызове . При последующих вызовах он не записывает байты во входной файл, и я проверил, что файл, расположенный по этому URI, все еще имеет 0 байтов после того, как управление вернулось из приложения камеры.
Вот код для создания файла URI для ввода в приложение камеры.
private @NonNull Uri getImageUri() {
Uri outputFileUri = null;
final String imageFileName = "JPEG_"
+ new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".jpeg" ;
File imagePath = new File(getFilesDir(), "images");
if(!imagePath.isDirectory()) {
imagePath.mkdirs();
}
File newFile = new File(imagePath, imageFileName);
if (newFile.exists()) {
newFile.delete();
}
try {
if(!newFile.createNewFile())
Log.e(MyActivity.class.getSimpleName(), "Error creating file");
} catch (IOException e) {
e.printStackTrace();
}
if(!(null != newFile && newFile.isFile())) {
throw new IllegalStateException("Cannot create file ");
}
outputFileUri = FileProvider.getUriForFile(
this.getApplicationContext(), "com.myapp.android.fileprovider", newFile);
if(null == outputFileUri){
throw new IllegalStateException( "Cannot create file for clicking image");
}
Log.e(MyActivity.class.getSimpleName(), "output file uri " + outputFileUri);
return outputFileUri;
}
Ниже приведен код, который открывает намерение камеры:
private List<Intent> getCameraIntents(@NonNull final Uri path){
if(!mCameraIntents.isEmpty()) return mCameraIntents;
@NonNull final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
@NonNull final List<ResolveInfo> listCam =
getPackageManager().queryIntentActivities(captureIntent, 0);
@NonNull final ArrayList<Intent> cameraIntents = new ArrayList<>(1);
for (ResolveInfo res : listCam) {
Intent intent = new Intent(captureIntent);
intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
intent.setPackage(res.activityInfo.packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, path);
cameraIntents.add(intent);
}
mCameraIntents.addAll(cameraIntents);
return cameraIntents;
}
/**
* Create a chooser intent to select the source to get image from.<br />
* The source can be camera's (ACTION_IMAGE_CAPTURE) or gallery's (ACTION_GET_CONTENT).<br />
* All possible sources are added to the intent chooser.
*/
private Intent imageChooser() {
// Determine Uri of camera image to save.
@NonNull final Uri outputFileUri = getImageUri();
@NonNull final List<Intent> allIntents = getCameraIntents(outputFileUri);
allIntents.addAll(getGalleryIntents());
@NonNull final Intent mainIntent = allIntents.remove(allIntents.size() - 1);
// Create a chooser from the main intent
Intent chooserIntent = Intent.createChooser(
mainIntent,
getResources().getString(R.string.snap_app_chooser_message));
// Add all other intents
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
allIntents.toArray(new Parcelable[allIntents.size()]));
mSnapUri = outputFileUri;
return chooserIntent;
}
Тогда я просто называю это,
startActivityForResult(imageChooser(), REQUEST_IMAGE_CAPTURE);
Ниже приведен код для декодирования захваченного изображения, записанного в файле URI приложением камеры.
@NonNull @Override protected Bitmap doInBackground(@NonNull final Uri... snapUris) {
Bitmap snap = null;
try {
Log.e(MyActivity.class.getSimpleName(), "snap uri " + snapUris[0]);
snap = MediaStore.Images.Media.getBitmap(
mActivity.get().getContentResolver(),
snapUris[0]);
if(null == snap ){
InputStream is =
mActivity.get().getContentResolver()
.openInputStream(snapUris[0]);
snap = BitmapFactory.decodeStream(is);
}
if (null == snap) {
Log.e(MyActivity.class.getSimpleName(), "Problem with uri path");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return snap;
}
}
Может ли кто-нибудь помочь мне понять, почему приложение камеры не записывает захваченное изображение в URI файла после первого вызова? Что меняется между первым вызовом камеры и следующим вызовом, когда она не может записать во второй и последующие URI файлов. Не выводится ли выходной поток приложения камеры после первого вызова должным образом?
Я протестировал его на телефонах Xiaomi и Lenovo, и у меня аналогичное поведение