谷歌照片与图库 - 意图选择器

The*_*ter 5 camera android android-intent android-photos

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

在此输入图像描述

当您单击第一个选项时,在我的Android 5.0设备上,我得到了这个:

在此输入图像描述

如果我使用基于AOSP项目的普通图库应用程序,一切正常,花花公子.但是,Photo的应用似乎使用了不同的意图.

以下是我处理普通图库代码的方法:

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);
Run Code Online (Sandbox Code Playgroud)

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的一些辅助函数:

   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;
    }
Run Code Online (Sandbox Code Playgroud)

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

当我使用Google相册选择照片时,我的ImageView是空白的(而不是填充选定的选择).图像未被选中,我无法进入手动裁剪视图,就像我使用图库设置一样. 所以基本上没有任何反应.


响应答案的新规范

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

    }

}
Run Code Online (Sandbox Code Playgroud)

上面的代码也没有用.我试着使它类似于下面的答案.会发生什么:

我点击"从图库中选择".而且它不再给我一个选择,现在它直接从库存库开放(这不是什么大不了的事).我点击图片,它似乎intent再次开始相同- 它带回了画廊,希望我选择另一个图像:而不是裁剪Activity.然后在第二次之后,它将ImageView使用所选文件设置我.

unr*_*gnu 5

解

首先,更新photoPickerIntent要使用的ACTION_GET_CONTENT,并删除与裁剪相关的额外内容,因为裁剪将在Intent稍后由另一个处理:

        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);
Run Code Online (Sandbox Code Playgroud)

然后,onActivityResult()将必须处理两个结果:RESULT_LOAD_IMAGE将为裁剪发送另一个意图,RESULT_CROP_IMAGE并将继续像以前一样处理:

    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
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

请注意,虽然我已经测试了此代码的一部分,但我还没有在运行时测试整个代码块.但是,如果它开箱即用,它应该非常接近.如果您有任何问题或疑问,请发表评论,我会相应更新我的答案.

背景

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

当我选择照片时,会出现一个选择器,我选择了一个图像.我立刻回到了我的Activity身边,没有任何裁剪选择.

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

选择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
Run Code Online (Sandbox Code Playgroud)

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

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

我测试了这个裁剪意图,我被提示选择一个用于裁剪的应用程序,就像之前一样.同样,照片和图库都作为选项呈现,它们都带来了裁剪界面.

似乎虽然Photos支持裁剪Intent,但它只是忽略了与裁剪相关的额外内容ACTION_PICK,而Gallery Intent在选择图像后通过发送另一个来响应.无论如何,拥有工作裁剪的细节Intent会导致上述解决方案.