简体   繁体   English

OnActivityResult 有时不会在 ACTION_GET_CONTENT 意图后调用

[英]OnActivityResult sometimes not called after ACTION_GET_CONTENT intent

I'm working on an image editing Android application.我正在开发一个图像编辑 Android 应用程序。 In one of my activities I call an intent to pick an image from the gallery in onCreate() like this:在我的一项活动中,我调用了从onCreate() 中的图库中选择图像的意图,如下所示:

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

Then I receive data like this:然后我收到这样的数据:

@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");
    }
}

The loadImage method: 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;
}

Now my problem is that sometimes I see NPE-s in Crashlytics claiming that photoBitmap is null when the user presses the next button.现在我的问题是,有时我在Crashlytics 中看到NPE-s声称当用户按下下一步按钮时 photoBitmap 为空。

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

The only Crashlytics log I see is that the user leaves for the intent (I placed a Crashlytics log inside onPause ).我看到的唯一Crashlytics日志是用户离开的意图(我在onPause放置了一个Crashlytics日志)。 No log for onActivityResult , so my best guess is that onActivityResult is not called, thus my bitmap is not loaded, thus it will be null when the user presses next.没有onActivityResult日志,所以我最好的猜测是没有调用onActivityResult ,因此我的位图没有加载,因此当用户按下下一步时它将为空。

Question: why is onActivityResult called sometimes, and sometimes not?问题:为什么有时调用onActivityResult有时不调用? Are there any other possible causes of photoBitmap being null?是否还有其他可能导致photoBitmap为空的原因?

You must add following code for taking images from devices您必须添加以下代码才能从设备获取图像

choosebtn.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         Intent i1=new Intent();
         i1.setType("image/*");
         i1.setAction(Intent.ACTION_GET_CONTENT);
         startActivityForResult(i1,1);
      }
});


@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 1 && resultCode == RESULT_OK && data != null && data.getData() != null)
    {
        imguri=data.getData();
        mainpreview.setImageURI(data.getData());
    } else {
        Toast.makeText(getApplicationContext(),"please choose image",Toast.LENGTH_SHORT).show();
    }
}

To start camera activity use this code要开始相机活动,请使用此代码

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

To get bitmap获取位图

@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
  }
}

Try this it worked perfect试试这个它完美无缺

     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's read picked image data - its URI
                    Uri pickedImage = data.getData();

                    // Let's 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]));
      }
    }
}

now you can convert imagepath to bitmap现在您可以将imagepath转换为位图

Call super.onActivityResult after your code last line of method.在您的代码最后一行方法之后调用super.onActivityResult You've told android your done when you call the super.当你打电话给超级时,你已经告诉安卓你已经完成了。

Also I noticed your logging a char sequence.我也注意到你记录了一个字符序列。 Don't do that Your not going to fix anything with this.不要那样做你不会用这个解决任何问题。

 Crashlytics.log("Data not received");

You need to save some data.您需要保存一些数据。 Considered the user canceled because your code doesn't capture this.考虑用户取消,因为您的代码没有捕获这个。

/* assume log method has an int input */ /* 假设 log 方法有一个 int 输入 */

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

Use this to select from gallery:使用它从图库中选择:

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

Now u will get a callback in onActivityResult:现在你将在 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM