Подтвердить что ты не робот

Что может заставить Android-активность бесконечно возобновлять себя при возврате с камеры?

У меня есть странная ошибка в моем приложении, которая заставляет операцию перезапускаться в бесконечном цикле, когда я возвращаюсь из приложения камеры, после съемки.

Поток пользовательского интерфейса выглядит следующим образом:

  • Основная деятельность →
  • Принять операцию фото → в onCreate() открыть камеру с помощью startActivityForResult()
  • Экран камеры → снимок (или отмена) → возврат к Принять фото
  • Экран Accept Photo полностью создается и немедленно останавливается и воссоздается в бесконечном цикле

Странная часть заключается в том, что это происходит только для некоторых камер. На моем Nexus S работает Jellybean, фотокамера ведет себя правильно, в то время как Camera Zoom FX вызывает эту ошибку. На моем планшете Archos G9, на котором работает ICS, как фоновая камера, так и Zoom FX вызывают ошибку.

Я проверил код шаг за шагом, и я не могу найти источник перезапуска вызова. Когда я останавливаю отладчик во втором (и последующем) вызове onCreate(), в стеке вызовов есть вызов ActivityThread.handleRelaunchActivity(). В Intent нет много информации: действие равно null, класс - AcceptPhoto. Значение mFlags имеет значение 603979776, которое я не знаю, как перевести в фактические флаги намерения.

Странность здесь не останавливается. На моем планшете, в первый раз, когда я делаю снимок, приложение в порядке. Если я попытаюсь сделать второй снимок, экран сойдет с ума. Если вместо того, чтобы снимать секундное изображение, я возвращаюсь на предыдущий экран, все отлично, пока не открою новое действие. Не имеет значения, откуда, если я вернусь полностью к корневой активности и начну новую деятельность, она начнет мерцать.

Я постараюсь опубликовать код, но я подозреваю, что ошибка не вызвана моим кодом, но я запускаю что-то в базовом коде Android. На что я надеюсь, может быть, кто-то может указать мне в правильном направлении, чтобы найти способ обойти эту ошибку. Все может быть полезно, поэтому я благодарю вас за любую идею!

Код, используемый для открытия камеры (вызывается в AcceptPhoto.onCreate(), используя класс утилиты):

private void openCamera(Context context) {
    Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    File tempFile = getTempFile(context);
    try {
        if (tempFile != null) {

            pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));

            ((Activity) context).startActivityForResult(pictureIntent, GET_ITEM_PHOTO);
        } else {
            Toast.makeText(context, "Could not create temp file", Toast.LENGTH_SHORT).show();
        }
    } catch (Exception e) {
        Toast.makeText(context, "Error opening camera " + e.getMessage(), Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }
}

Код, используемый для отображения изображения, вызываемого в AcceptPhoto.onActivityResult():

private void displayPhoto() {
    if (cameraUtils == null) {
        cameraUtils = new CameraUtil();
    }
    previewImageView.setImageDrawable(null);
    File tempFile = cameraUtils.getTempFile(this);

    int rotation = 0;
    try {
        ExifInterface exif = new ExifInterface(tempFile.getPath());
        String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
        Log.i("SPRING", "Photo orientation " + orientation);
        rotation = getBitmapRotation(Integer.valueOf(orientation));
        Log.i("SPRING", "The image needs to be rotated by " + (rotation) + " degrees");
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    try {
        previewBitmap = BitmapEncoderUtil.loadPrescaledBitmap(tempFile);
        if (rotation != 0) {

            Matrix rotationMatrix = new Matrix();
            rotationMatrix.postRotate(rotation);

            int w = previewBitmap.getWidth();
            int h = previewBitmap.getHeight();

            Bitmap rotatedBitmap = Bitmap.createBitmap(previewBitmap, 0, 0, w, h, rotationMatrix, false);

            previewBitmap = rotatedBitmap;
        }
        previewImageView.setImageBitmap(previewBitmap);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Метод, используемый в классе утилиты для создания/извлечения файла, в котором камера сохраняет фотографию:

public File getTempFile(Context context) {

    String externalStorageStateString = Environment.getExternalStorageState();
    File cacheDirectory;
    // try to save in external storage
    if (externalStorageStateString.equals(Environment.MEDIA_MOUNTED)) {
        cacheDirectory = context.getExternalCacheDir();
    } else {
        // save in internal storage
        cacheDirectory = context.getCacheDir();
    }
    File tempSnapshotFile = new File(cacheDirectory, MissionOtherActivity.ITEM_SNAPSHOT_PATH);

    // make sure the file exists, possible fix for the camera bug
    try {
        if (tempSnapshotFile.exists() == false) {
            tempSnapshotFile.getParentFile().mkdirs();
            tempSnapshotFile.createNewFile();
        }

    } catch (IOException e) {
        Log.e("SPRING", "Could not create file.", e);
    }
    return tempSnapshotFile;
}
4b9b3361

Ответ 1

После долгих исследований, похоже, что вызов перезапуска происходит из onConfigurationChanged. Я до сих пор не понял, почему, но, по крайней мере, я знаю, чего не следует.

Это объясняет, почему некоторые камеры вызвали эту ошибку, а другие нет: некоторые камеры использовали ту же конфигурацию, что и мое приложение, а другие нет.

EDIT: после других исследований я обнаружил, что у меня была ошибка в моем расширенном классе Application. В методе onConfigurationChanged я менял конфигурацию, заставляя определенную локаль. Это вызвало новый вызов onConfigurationChanged(), который вызвал бесконечный цикл и последующую последовательность создания/уничтожения экрана. Я понятия не имею, почему я поместил этот код в метод onConfigurationChanged(), но я думаю, вы должны страдать, чтобы узнать:)