簡體   English   中英

意圖在Android中的相機或圖庫之間進行選擇

[英]Intent to choose between the camera or the gallery in Android

我正試圖發起一個意圖從相機或Android的畫廊中選擇一個圖像。 我檢查過這篇文章,目前我的代碼即將開始工作:

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它會顯示以下選擇器:

在此輸入圖像描述

但是如果我設置allowCamera=true並且allowGallery =true則顯示的選擇器是:

在此輸入圖像描述

如果您選擇Android System則會顯示第一個選擇器。

我希望選擇器是這樣的:

在此輸入圖像描述

如何“擴展” Android System選項?

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

在您的鏈接帖子中,您可以找到解決方案。 您的代碼的不同之處在於如何創建圖庫意圖:

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

不是ACTION_PICK而是使用ACTION_GET_CONTENT 似乎如果單個ACTION_PICK在列表中(“容器意圖”),系統會遍歷它以顯示選擇內容,但是一旦你包含相機意圖它就不能再遍歷(因為有一個)直接意圖和一個容器意圖)。

此答案的評論中,您會發現ACTION_PICKACTION_GET_CONTENT之間的區別。

有一些解決方案建議使用自定義對話框。 但是這個對話框沒有標准圖標(參見這里的 develper文檔)。 所以我建議保持你的解決方案,並解決hierarchie問題。

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

您可能需要為此創建自定義對話框:

以下是用戶單擊特定按鈕時要調用的方法的代碼:

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

用於在活動選擇器中顯示攝像機和視頻文件的意圖:

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

    Intent cameraIntent = new Intent(MediaStore.ACTION_VIDEO_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_VIDEO_CAPTURE);

您的代碼已經非常實現了目標。 只需交換畫廊和相機添加訂單。

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)

第一個截圖在您的訂單中,第二個截圖在交換后。 就像你說的,在第一種情況下,點擊系統徽標將顯示圖庫項目。

在此輸入圖像描述 在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM