API результатов действия (камера TakePicture()): сбой при доставке результата ResultInfo (сбой приложения)
Я боролся с проблемой того, что моя активность иногда разрушалась при съемке с помощью приложения камеры., Что приводило к ошибке ниже и сбою приложения.
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity
{com.example.myapp/com.example.myapp.activities.MyActivity}
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Я следил за документацией Google о том, как сделать снимок с помощью камеры здесь. После 3 или 4 испытаний он по-прежнему выдавал указанную выше ошибку.
Я отказался от старого
startActivityForResult
метод для нового
Activity Result APIs
, но все еще существует та же проблема.
В документации здесь конкретно говорится следующее:
При запуске действия для получения результата возможно (и, в случаях операций с интенсивным использованием памяти, таких как использование камеры, почти наверняка), ваш процесс и ваше действие будут уничтожены из-за нехватки памяти.
По этой причине API результатов деятельности отделяют обратный вызов результата от того места в коде, где вы запускаете другое действие. Поскольку обратный вызов результата должен быть доступен при воссоздании вашего процесса и действия, обратный вызов должен безусловно регистрироваться каждый раз, когда создается ваше действие, даже если логика запуска другого действия происходит только на основе пользовательского ввода или другой бизнес-логики.
Таким образом, в нем говорится, что даже если действие будет уничтожено, новые API результатов действий каким-то образом справятся с этой проблемой.
Вот код, который я использую сейчас:
public class MyActivity extends FragmentActivity{
private Uri photoURI;
private ImageView firstImage;
ActivityResultLauncher<Uri> intentActivityResultLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_activity);
firstImage = findViewById(R.id.imageView_camera_open_one);
intentActivityResultLauncher=registerForActivityResult(new ActivityResultContracts.TakePicture(),
result -> {
if (firstImage != null && photoURI != null)
firstImage.setImageURI(photoURI);
});
}
private void openCamera(int viewId) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
Toast.makeText(this, "Error).show();
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
intentActivityResultLauncher.launch(photoURI);
}
}
}
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG" + timeStamp;
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
currentPhotoPath = image.getAbsolutePath();
return image;
}
}
Добавление
android:configChanges="orientation|screenSize"
или фиксация активности на портрете не помогает.
Есть ли подходящее решение для этого?
Полная трассировка стека:
java.lang.RuntimeException: Unable to resume activity {com.example.myapp/com.example.myapp.activities.Activity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.myapp/com.example.myapp.activities.Activity}: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4626)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.myapp/com.example.myapp.activities.Activity}: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at android.app.ActivityThread.deliverResults(ActivityThread.java:5324)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4613)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.myapp.activities.Activity.onActivityResult(MyActivity.java:269)
at android.app.Activity.dispatchActivityResult(Activity.java:8294)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5317)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4613)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4659)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2261)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)