意图在Android中的相机或图库之间进行选择

时间:2014-08-27 10:21:11

标签: java android android-intent

我试图发起从相机或Android的图库中选择图像的意图。我检查了THIS帖子,目前我的代码即将开始工作:

private Intent getPickIntent() {
    final List<Intent> intents = new ArrayList<Intent>();
    if (allowCamera) {
        setCameraIntents(intents, cameraOutputUri);
    }
    if (allowGallery) {
        intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
    }

    if (intents.isEmpty()) return null;
    Intent result = Intent.createChooser(intents.remove(0), null);
    if (!intents.isEmpty()) {
        result.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[] {}));
    }
    return result;
}

private void setCameraIntents(List<Intent> cameraIntents, Uri output) {
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = context.getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for (ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
        cameraIntents.add(intent);
    }
}

当我设置allowCamera=true时,它可以正常工作。

当我设置allowGallery=true时,它会显示以下选择器:

enter image description here

但如果我设置allowCamera=trueallowGallery =true,则显示的选择器为:

enter image description here

如果您选择Android System,则会显示第一个选择器。

我希望选择器像:

enter image description here

我怎样才能扩展&#34; Android System选项?

6 个答案:

答案 0 :(得分:8)

            Intent galleryintent = new Intent(Intent.ACTION_GET_CONTENT, null);
            galleryintent.setType("image/*");

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

            Intent chooser = new Intent(Intent.ACTION_CHOOSER);
            chooser.putExtra(Intent.EXTRA_INTENT, galleryintent);
            chooser.putExtra(Intent.EXTRA_TITLE, "Select from:");

            Intent[] intentArray = { cameraIntent };
            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
            startActivityForResult(chooser, REQUEST_PIC);

答案 1 :(得分:7)

In your linked post您可以找到解决方案。与您的代码的不同之处在于如何创建图库意图:

final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

不是ACTION_PICK你用ACTION_GET_CONTENT做了什么。似乎如果列表中有一个ACTION_PICK(“容器意图”),系统会遍历它以显示选择内容,但是一旦你包含了相机意图,它就不能再遍历了(因为有一个直接意图和一个容器意图)。

this answer的评论中,您发现ACTION_PICKACTION_GET_CONTENT之间存在差异。

有一些可用的解决方案建议使用自定义对话框。但是这个对话框没有标准图标(参见develper docs here)。因此,我建议您继续使用您的解决方案并解决问题。

答案 2 :(得分:3)

## Intent to choose between Camera and Gallery Heading and can crop image after capturing from camera ##


public void captureImageCameraOrGallery() {

        final CharSequence[] options = { "Take photo", "Choose from library",
                "Cancel" };
        AlertDialog.Builder builder = new AlertDialog.Builder(
                Post_activity.this);

        builder.setTitle("Select");

        builder.setItems(options, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                if (options[which].equals("Take photo")) {
                    try {
                        Intent cameraIntent = new Intent(
                                android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(cameraIntent, TAKE_PICTURE);
                    } catch (ActivityNotFoundException ex) {
                        String errorMessage = "Whoops - your device doesn't support capturing images!";

                    }

                } else if (options[which].equals("Choose from library")) {
                    Intent intent = new Intent(
                            Intent.ACTION_PICK,
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(intent, ACTIVITY_SELECT_IMAGE);
                } else if (options[which].equals("Cancel")) {
                    dialog.dismiss();

                }

            }
        });
        dialog = builder.create();
        dialog.getWindow().getAttributes().windowAnimations = R.style.dialog_animation;

        dialog.show();

    }

public void onActivityResult(int requestcode, int resultcode, Intent intent) {
        super.onActivityResult(requestcode, resultcode, intent);
        if (resultcode == RESULT_OK) {
            if (requestcode == TAKE_PICTURE) {
                picUri = intent.getData();
                startCropImage();
            } else if (requestcode == PIC_CROP) {
                Bitmap photo = (Bitmap) intent.getExtras().get("data");
                Drawable drawable = new BitmapDrawable(photo);
                backGroundImageLinearLayout.setBackgroundDrawable(drawable);
            } else if (requestcode == ACTIVITY_SELECT_IMAGE) {
                Uri selectedImage = intent.getData();
                String[] filePath = { MediaStore.Images.Media.DATA };
                Cursor c = getContentResolver().query(selectedImage, filePath,
                        null, null, null);
                c.moveToFirst();
                int columnIndex = c.getColumnIndex(filePath[0]);
                String picturePath = c.getString(columnIndex);
                c.close();
                Bitmap thumbnail = (BitmapFactory.decodeFile(picturePath));
                Drawable drawable = new BitmapDrawable(thumbnail);
                backGroundImageLinearLayout.setBackgroundDrawable(drawable);

            }
        }
    }

private void startCropImage() {
        try {
            Intent cropIntent = new Intent("com.android.camera.action.CROP");
            cropIntent.setDataAndType(picUri, "image/*");
            cropIntent.putExtra("crop", "true");
            cropIntent.putExtra("aspectX", 1);
            cropIntent.putExtra("aspectY", 1);
            // indicate output X and Y
            cropIntent.putExtra("outputX", 256);
            cropIntent.putExtra("outputY", 256);
            // retrieve data on return
            cropIntent.putExtra("return-data", true);
            // start the activity - we handle returning in onActivityResult
            startActivityForResult(cropIntent, PIC_CROP);
        } catch (ActivityNotFoundException anfe) {
            // display an error message
            String errorMessage = "Whoops - your device doesn't support the crop action!";
            Toast toast = Toast
                    .makeText(this, errorMessage, Toast.LENGTH_SHORT);
            toast.show();
        }
    }

答案 3 :(得分:1)

您可能需要为此创建自定义对话框:

以下是用户点击特定按钮时要调用的方法的代码:

private void ChooseGallerOrCamera() {
    final CharSequence[] items = { "Take Photo", "Choose from Gallery",
            "Cancel" };

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("Add Photo!");
    builder.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (items[item].equals("Take Photo")) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File f = new File(android.os.Environment
                        .getExternalStorageDirectory(), "MyImage.jpg");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                startActivityForResult(intent, REQUEST_CAMERA);
            } else if (items[item].equals("Choose from Gallery")) {
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(
                        Intent.createChooser(intent, "Select File"),
                        SELECT_FILE);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}

处理onActivityResult()的代码:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        Bitmap mBitmap;
        if (requestCode == REQUEST_CAMERA) {
            File camFile = new File(Environment.getExternalStorageDirectory()
                    .toString());
            for (File temp : camFile.listFiles()) {
                if (temp.getName().equals("MyImage.jpg")) {
                    camFile = temp;
                    break;
                }
            }
            try {

                BitmapFactory.Options btmapOptions = new BitmapFactory.Options();

                mBitmap = BitmapFactory.decodeFile(camFile.getAbsolutePath(),
                        btmapOptions);
                //Here you have the bitmap of the image from camera

            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (requestCode == SELECT_FILE) {
            Uri selectedImageUri = data.getData();

            String tempPath = getPath(selectedImageUri, MyActivity.this);
            BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
            mBitmap = BitmapFactory.decodeFile(tempPath, btmapOptions);

            //Here you have the bitmap of the image from gallery
        }
    }
}

public String getPath(Uri uri, Activity activity) {
    String[] projection = { MediaColumns.DATA };
    Cursor cursor = activity
            .managedQuery(uri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

修改 尝试使用此:

private void letUserTakeUserTakePicture() {

    Intent pickIntent = new Intent();
    pickIntent.setType("image/*");
    pickIntent.setAction(Intent.ACTION_GET_CONTENT);
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.fromFile(getTempFile(getActivity())));

    String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
    Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
    chooserIntent.putExtra
            (Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takePhotoIntent});

    startActivityForResult(chooserIntent, Values.REQ_CODE_TAKEPICTURE);
}

答案 4 :(得分:0)

在活动选择器中显示摄像机和视频文件的意图:

#import controller.mipay.controller as mipay
import importlib

my_mapping = {'mipay':'controller.mipay.controller'}

class Request(Resource):
    parser = RequestChecker()

    def post(self):
        req = self.parser.parse_args()  # <---- JSON/Dictionary

        # method_to_call = getattr(mipay, req['PaymentEndpoint'])
        mipay= importlib.import_module(my_mapping[req['PaymentMethod']])
        method_to_call = getattr(mymodule, req['PaymentEndpoint'])

        return method_to_call()

答案 5 :(得分:0)

您的代码已经非常达到目标。只需交换图库和相机添加顺序即可。

if (allowGallery) {
    intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
}
if (allowCamera) {
    setCameraIntents(intents, cameraOutputUri);
}

这是我的测试结果。由于我的操作系统是Android Nougat(7.0),因此外观上的差异

第一个屏幕截图已在您的订单中,第二个屏幕截图在交换后。就像您说的那样,在第一种情况下,单击系统徽标将显示图库项目。

enter image description here enter image description here