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);