Google Photos vs Stock Gallery - Intent Picker

我的未来我决定 提交于 2019-11-27 14:52:17

Solution

First, update the photoPickerIntent to use ACTION_GET_CONTENT, and remove the extras related to cropping, since cropping will be handled by another Intent later:

        Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        photoPickerIntent.setType("image/*");
        // Do not include the extras related to cropping here;
        // this Intent is for selecting the image only.
        startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);

Then, onActivityResult() will have to handle two results: RESULT_LOAD_IMAGE will send another intent for the crop, and RESULT_CROP_IMAGE will continue processing as you did before:

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            if (data != null) {
                switch (requestCode) {
                case RESULT_LOAD_IMAGE:
                    // Received an image from the picker, now send an Intent for cropping
                    final String CROP_ACTION = "com.android.camera.action.CROP";
                    Intent photoCropIntent = new Intent(CROP_ACTION);
                    photoCropIntent.setData(data.getData());

                    // TODO: first get this running without extras, then test each one here
                    startActivityForResult(photoCropIntent, RESULT_CROP_IMAGE);
                    break;
                case RESULT_CROP_IMAGE:
                    // Received the cropped image, continue processing.  Note that this 
                    // is just copied and pasted from your question and may have 
                    // omissions.
                    tempFile = getTempFile();

                    filePath = Environment.getExternalStorageDirectory() + "/"
                            + "temporary_holder.jpg";
                    Log.d("LOAD REQUEST filePath", filePath);

                    Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
                    iPP.setImageBitmap(selectedImage);

                    imagePath = filePath;
                    new UploadImage().execute();
                    break;
                default:
                    // Handle default case
                }
            }
        }

Note that although I've tested parts of this code, I haven't tested this entire block of code at runtime. If it doesn't work right out-of-the-box, though, it should be pretty close. Please comment if you have any questions or issues, and I'll update my answer accordingly.

Background

On an Android 5.0.1 (API 21) device with both AOSP Gallery2 (com.android.gallery3d) and Photos installed, I ran your Intent. I was prompted to choose between Gallery or Photos.

When I chose Photos, a picker was presented, and I picked an image. I was immediately returned to my Activity, with no cropping options.

When I chose Gallery, a picker was presented, and I picked an image. I was then prompted to choose an app for cropping. Both Photos and Gallery were presented as options for cropping.

Here's the interesting log output when choosing Gallery:

// Send the Intent
3-07 15:20:10.347      719-817/? I/ActivityManager﹕ Displayed android/com.android.internal.app.ResolverActivity: +127ms

// Choose Gallery
03-07 15:20:27.762      719-735/? I/ActivityManager﹕ START u0 {act=android.intent.action.PICK typ=image/* flg=0x3000000 cmp=com.android.gallery3d/.app.GalleryActivity (has extras)} from uid 10084 on display 0
// (fixing highlighting after MIME type on previous line) */
03-07 15:20:27.814  22967-22967/? W/GalleryActivity﹕ action PICK is not supported
03-07 15:20:27.814  22967-22967/? V/StateManager﹕ startState class com.android.gallery3d.app.AlbumSetPage
03-07 15:20:27.967      719-817/? I/ActivityManager﹕ Displayed com.android.gallery3d/.app.GalleryActivity: +190ms

// Pick an image
3-07 15:21:45.993  22967-22967/? V/StateManager﹕ startStateForResult class com.android.gallery3d.app.AlbumPage, 1
03-07 15:21:46.011  22967-22967/? D/AlbumPage﹕ onSyncDone: ********* result=0
03-07 15:21:46.034  22967-24132/? I/GLRootView﹕ layout content pane 1080x1701 (compensation 0)
03-07 15:21:48.447     719-1609/? I/ActivityManager﹕ START u0 {act=com.android.camera.action.CROP dat=content://media/external/images/media/1000 flg=0x2000000 cmp=android/com.android.internal.app.ResolverActivity (has extras)} from uid 10100 on display 0

First, note W/GalleryActivity﹕ action PICK is not supported. I'm not sure why it works, but according to Dianne Hackborn, "...you should consider ACTION_PICK deprecated. The modern action is ACTION_GET_CONTENT which is much better supported..." I've addressed this in my solution above.

The good news is, however, it seems that after picking an image, .putExtra("crop", "true"); causes Gallery to send another Intent for cropping. And the log clearly shows the action and data to use.

I tested this cropping intent, and I was prompted to choose an app for cropping, just like before. And again, both Photos and Gallery were presented as options, and they both brought up cropping interfaces.

It seems that although Photos supports cropping by Intent, it just ignores the extras relating to cropping in ACTION_PICK, whereas Gallery responds by sending another Intent after picking an image. Regardless, having the details of a working cropping Intent leads to the solution above.

I have solved this problem this way.

Pick image:

private void pickUserImage() {

    if (doHavePermission()) {
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        photoPickerIntent.setType("image/*");
        photoPickerIntent.putExtra("crop", "true");
        photoPickerIntent.putExtra("scale", true);
        photoPickerIntent.putExtra("outputX", 256);
        photoPickerIntent.putExtra("outputY", 256);
        photoPickerIntent.putExtra("aspectX", 1);
        photoPickerIntent.putExtra("aspectY", 1);
        photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
        startActivityForResult(photoPickerIntent, PICK_FROM_GALLERY);
    }
}

used method getTempUri() is

private Uri getTempUri() {
    return Uri.fromFile(getTempFile());
}

private File getTempFile() {

    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

        File file = new File(Environment.getExternalStorageDirectory(),TEMP_PHOTO_FILE);
        try {
            file.createNewFile();
        } catch (IOException e) {
            Log.printStackTrace(e);
        }

        return file;
    } else {

        return null;
    }
}

get the picked image

    @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == PICK_FROM_GALLERY) {
            if (data!=null) {

                Uri selectedImageUri = data.getData();
                //String tempPath = getPath(selectedImageUri, UserProfileActivity.this);
                String url = data.getData().toString();
                if (url.startsWith("content://com.google.android.apps.photos.content")){
                    try {
                        InputStream is = getContentResolver().openInputStream(selectedImageUri);
                        if (is != null) {
                            Bitmap selectedImage = BitmapFactory.decodeStream(is);
                            //You can use this bitmap according to your purpose or Set bitmap to imageview
                            if (selectedImage != null) {
                                isImageUpdated = true;
                                isImageUpdated = true;
                                Bitmap resizedBitmap = null;
                                if (selectedImage.getWidth() >= 256 && selectedImage.getHeight() >= 256) {
                                    resizedBitmap = Bitmap.createBitmap(selectedImage,
                                            selectedImage.getWidth() - 128,
                                            selectedImage.getHeight() - 128,
                                            256, 256);
                                }
                                if (resizedBitmap != null) {
                                    imageViewUserImage.setImageDrawable(ImageHelper.getRoundedCornerImage(resizedBitmap, 20));
                                } else {
                                    imageViewUserImage.setImageDrawable(ImageHelper.getRoundedCornerImage(selectedImage, 20));
                                }
                            }
                        }
                    } catch (FileNotFoundException e) {
                        Log.printStackTrace(e);
                    }
                } else {
                    File tempFile = getTempFile();
                    String filePath = Environment.getExternalStorageDirectory() + "/" + TEMP_PHOTO_FILE;
                    Log.d(TAG, "path " + filePath);

                    Bitmap selectedImage = BitmapFactory.decodeFile(filePath);
                    if (selectedImage != null) {
                        isImageUpdated = true;
                        imageViewUserImage.setImageDrawable(ImageHelper.getRoundedCornerImage(selectedImage, 20));
                    }
                    if (tempFile.exists()) {
                        tempFile.delete();
                    }
                }
            }
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Image converted to rounded corner image as follows:

public class ImageHelper {

    public static RoundedBitmapDrawable getRoundedCornerImage(Bitmap bitmap, int cornerRadius) {
        RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(null, bitmap);
        dr.setCornerRadius(cornerRadius);
        return dr;
    }
}

Its too late to answer but it can help someone else.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!