OnActivityResult иногда не вызывается после намерения ACTION_GET_CONTENT

Я работаю над приложением для редактирования изображений для Android. В одной из моих действий я вызываю намерение выбрать изображение из галереи в onCreate следующим образом:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

Затем я получаю данные следующим образом:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Crashlytics.log("onActivityResult called");
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK && data != null) {
        Crashlytics.log("Data received from image pick intent");
        imageUri = data.getData();
        loadImage();
    } else {
        //if we do not select a picture, go back to the dashboard
        Crashlytics.log("Data not received");
        onBackPressed();
        Log.d(TAG, "no picture selected");
    }
}

Метод loadImage:

private void loadImage() {
    try {
        photoBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
    } catch (IOException e) {
        Crashlytics.log("IOException from getBitmap");
        Log.d(TAG, e.getMessage());
        showToastAndPressBack();
        return;
    }

    if (photoBitmap == null) {
        Crashlytics.log("photoBitmap is null in onActivityResult");
        showToastAndPressBack();
        return;
    }

    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    imgVWidth = size.x;
    int height = size.y;
    imgVHeight = (int) (((float) imgVWidth / photoBitmap.getWidth()) * photoBitmap.getHeight());
    photoInImgViewBitmap = Bitmap.createScaledBitmap(photoBitmap, imgVWidth, imgVHeight, true);
    imageAlreadyPicked = true;
}

Теперь моя проблема в том, что иногда я вижу NPE-s в Crashlytics, утверждающем, что photoBitmap имеет значение null, когда пользователь нажимает следующую кнопку.

@OnClick(R.id.toolbar_next)
void onToolbarNextClick() {
    float originalScale = (float) (previewImageView.getHeight()) / (float) (photoBitmap.getHeight());
    ...
}

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

Вопрос: почему onActivityResult называется иногда, а иногда нет? Существуют ли другие возможные причины photoBitmap, равные нулю?

Ответ 1

Чтобы начать работу с камерой, используйте этот код

   Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_REQUEST);

Чтобы получить растровое изображение

 @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == Activity.RESULT_OK){
        if(requestCode==CAMERA_REQUEST) {
            Bitmap photo = (Bitmap) data.getExtras().get("data"); }
         }else{
           //Camera request cancelled}
        }

Ответ 2

Попробуйте это, он отлично работает

     Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(i, LOAD_IMAGE_RESULTS);

  @SuppressLint("Recycle")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

           if (requestCode == LOAD_IMAGE_RESULTS && resultCode == RESULT_OK && data != null) {
                    // Let read picked image data - its URI
                    Uri pickedImage = data.getData();

                    // Let read picked image path using content resolver
                    String[] filePath = {MediaStore.Images.Media.DATA};
                    @SuppressLint("Recycle") Cursor cursor = null;
                    if (pickedImage != null) {
                        cursor = getContentResolver().query(pickedImage, filePath, null, null, null);
                    }
                    if (cursor != null) {
                        cursor.moveToFirst();

                        String imagePath = cursor.getString(cursor.getColumnIndex(filePath[0]));
      }
    }
}

теперь вы можете конвертировать imagepath в растровое изображение

Ответ 3

Используйте это, чтобы выбрать из галереи:

Intent i = new Intent(Intent.ACTION_PICK);
i.setType("image/*");
startActivityForResult(i, REQUEST_CODE);

Теперь u получит обратный вызов в onActivityResult:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_CODE:
            if (resultCode != RESULT_CANCELED) {
//use data to get the selected image
            }
            break;
    }
}

Ответ 4

Вызвать super.onActivityResult после кода последней строки метода. Вы сказали андроиду, что сделали, когда вызвали супер.

Также я заметил, что вы регистрировали последовательность char. Не делайте этого, чтобы вы ничего не исправляли с этим.

 Crashlytics.log("Data not received");

Вам нужно сохранить некоторые данные. Считается, что пользователь отменен, потому что ваш код не фиксирует это.

/* Предположим, что метод log имеет вход int */

Crashlytics.log("Data not received");
Crashlytics.log(requestCode);
Crashlytics.log(resultCode);