Google相册与图库-意向选择器 [英] Google Photos vs Stock Gallery - Intent Picker

查看:98
本文介绍了Google相册与图库-意向选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用中,我允许用户从其图库中选择个人资料图片,如下所示:

In my app, I allow the user to pick a profile image from their gallery, like so:

当您单击第一个选项时,在我的Android 5.0设备上,我得到以下提示:

When You click the first option, on my Android 5.0 device, I get this:

如果我使用基于AOSP项目的普通Gallery应用程序,则一切正常且繁琐.但是,照片的应用似乎使用了不同的意图.

If I use the normal Gallery app that is based off the AOSP project, everything works fine and dandy. However, the Photo's app appears to use a different intent.

这是我如何处理普通画廊的代码:

Here is how I handle code for the normal gallery:

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

然后是意图结果处理程序:

And then the intent result handler:

public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (requestCode == RESULT_LOAD_IMAGE
            && resultCode == Activity.RESULT_OK) {

        if (data != null) {

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

上面的一些辅助功能:

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

    private static File getTempFile() {

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

            File file = new File(Environment.getExternalStorageDirectory(),
                    "temporary_holder.jpg");
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return file;
        }
        return null;
    }

其中一些可能不需要显示,但我将其全部包括在内,以防干扰.

Some of that is probably not needed to show but I included it all in case it is interfering.

当我使用Google相册挑选照片时,我的ImageView为空白(而不是填充所选的照片).未选择图像,并且无法像在图库"中设置图像那样进入手动裁剪视图. 所以基本上什么也没发生.

When I use Google Photos to pick a photo, my ImageView is blank (instead of filling with selected pick). The image is not selected and I can't go to the manual cropping view like I have it set with the Gallery. So basically, nothing happens.

响应代码的新代码

        photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        photoPickerIntent.setType("image/*");
        photoPickerIntent.putExtra("crop", "true");
        photoPickerIntent.putExtra("outputX", 300);
        photoPickerIntent.putExtra("outputY", 300);
        photoPickerIntent.putExtra("aspectX", 1);
        photoPickerIntent.putExtra("aspectY", 1);
        photoPickerIntent.putExtra("scale", true);
        photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
        photoPickerIntent.putExtra("outputFormat",
                Bitmap.CompressFormat.JPEG.toString());
        startActivityForResult(photoPickerIntent, RESULT_LOAD_IMAGE);



public void onActivityResult(int requestCode, int resultCode, Intent data) {



    if (resultCode == Activity.RESULT_OK) {

        if (data != null) {

            Log.i("data", data.toString());

            switch (requestCode) {

                case RESULT_LOAD_IMAGE:

                    Log.i("RESULT_LOAD_IMAGE", "MARK");
                    // 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.putExtra("crop", "true");
                    photoCropIntent.putExtra("aspectX", 1);
                    photoCropIntent.putExtra("aspectY", 1);
                    photoCropIntent.putExtra("outputX", 300);
                    photoCropIntent.putExtra("outputY", 300);
                    photoCropIntent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
                    photoCropIntent.putExtra("outputFormat",
                            Bitmap.CompressFormat.JPEG.toString());
                    photoCropIntent.setData(data.getData());

                    startActivityForResult(photoPickerIntent, RESULT_CROP_IMAGE);

                    break;

                case RESULT_CROP_IMAGE:

                    Log.i("RESULT_CROP_IMAGE", "MARK");

                    tempFile = getTempFile();
                    imagePath = Environment.getExternalStorageDirectory() + "/"   + "temporary_holder.jpg";
                    Log.i("imagePath", imagePath);

                    Uri selectedImageURI = data.getData();
                    InputStream image_stream;
                    try {
                        image_stream = getActivity().getContentResolver().openInputStream(selectedImageURI);
                        Bitmap bitmap = BitmapFactory.decodeStream(image_stream);
                        iPP.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    new UploadImage().execute();

                    break;

                default:
                    // Handle default case
            }
        }

    }

}

以上代码也不起作用.我试图使其类似于下面的答案.会发生什么:

The above code isn't working either. I tried to make it resemble the answer below. What happens is:

我单击从图库中选择".而且,它不再给我任何选择,现在可以从图库直接打开(这没什么大不了的).我单击图像,它似乎又重新开始了相同的intent -它带回图库,希望我选择其他图像:而不是裁剪Activity.然后在第二次之后,它将使用所选文件设置我的ImageView.

I click "Choose from Gallery". And it does not give me a choice anymore, now it opens directly from the stock Gallery (that is not a big deal). I click on the image, and it ... appears to start the same intent over again -- it brings back the gallery wanting me to pick another image: instead of the Cropping Activity. Then after the second time, it will set my ImageView with the selected file.

推荐答案

解决方案

首先,将photoPickerIntent更新为使用ACTION_GET_CONTENT,并删除与裁剪有关的其他内容,因为裁剪将在以后由另一个Intent处理:

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

然后,onActivityResult()将必须处理两个结果:RESULT_LOAD_IMAGE将发送另一种意图的作物,并且RESULT_CROP_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.

背景

在装有AOSP Gallery2(com.android.gallery3d)和照片的Android 5.0.1(API 21)设备上,我运行了Intent.系统提示我在图库"或照片"之间进行选择.

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.

当我选择照片"时,会出现一个选择器,然后我选择了一张图像.我立即返回我的Activity,没有任何裁剪选项.

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

当我选择Gallery时,会出现一个选择器,然后我选择了一个图像.然后,系统提示我选择一个用于裁剪的应用程序. 同时显示了照片和图库作为裁剪选项.

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.

这是选择Gallery时有趣的日志输出:

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

首先,请注意W/GalleryActivity﹕ action PICK is not supported.我不确定为什么会起作用,但根据Dianne Hackborn的说法,"......您应该考虑弃用ACTION_PICK.现代操作是ACTION_GET_CONTENT,它的支持性更好...... 我已经在上面的解决方案中解决了这个问题.

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.

但是,好消息是,似乎在拾取图像后,.putExtra("crop", "true");会导致Gallery发送另一个Intent进行裁剪.日志清楚地显示了要使用的操作和数据.

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.

看来,尽管照片"支持按Intent进行裁切,但它只是忽略了与"ACTION_PICK"中裁切有关的其他内容,而图库"则通过在选择图像后发送另一个Intent作为响应.无论如何,只要有Intent可以进行裁剪的详细信息,就可以找到上面的解决方案.

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.

这篇关于Google相册与图库-意向选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆