Селектор с намерением камеры и намерением выбора изображения

Я создал средство выбора для выбора изображения из файла или для создания изображения.

Код, который я использую, отлично работает на Nexus 5, однако, когда я пробую его на Samsung S5, в меню выбора не отображаются значки камеры.

public Intent makePhotoIntent(String title, Context ctx, String uniqueImageId){

        //Build galleryIntent
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        galleryIntent.setType("image/*");

        //Create chooser
        Intent chooser = Intent.createChooser(galleryIntent,title);

        if (checkexCameraHardware()){
            Intent  cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            mTempImage = null;
            try {
                mTempImage = createImageFile(uniqueImageId);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (mTempImage != null){
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempImage)); //add file ure (photo is saved here)
                Intent[] extraIntents = {cameraIntent};
                chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
            }
        }
        return chooser;
    }

SamsungНексус

Когда я меняю порядок, в котором намерения добавляются в средство выбора, устройство Samsung показывает камеру, но показывает только Android-систему в качестве параметра файла.

public Intent makePhotoIntent(String title, Context ctx, String uniqueImageId){

        //Build galleryIntent
        Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        galleryIntent.setType("image/*");

        //Create chooser
        Intent chooser = Intent.createChooser(galleryIntent,title);

        if (checkexCameraHardware()){
            Intent  cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            mTempImage = null;
            try {
                mTempImage = createImageFile(uniqueImageId);
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (mTempImage != null){
                cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempImage)); //add file ure (photo is saved here)

                //I have to re-create the chooser here or the Samsung will not show the 'camera' icons.
                //I have to add the cameraIntent first.
                chooser = Intent.createChooser(cameraIntent,title);
                Intent[] extraIntents = {galleryIntent};

                //Intent[] extraIntents = {cameraIntent};
                chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
            }
        }
        return chooser;
    }

SamsungНексус

В идеале я хотел бы, чтобы устройство Samsung отображало то же, что и устройство Nexus, когда я сначала добавляю намерение галереи. Однако я не могу заставить это работать.


person Arno van Lieshout    schedule 15.10.2014    source источник
comment
какое устройство Samsung вы используете   -  person Lokesh    schedule 22.10.2014


Ответы (3)


  • Если для дополнительного намерения (Intent.EXTRA_INITIAL_INTENTS) имеется несколько совпадений, все они будут показаны вместе в разделе "Система Android". Когда вы нажимаете «Система Android», открывается другой селектор со всеми этими совпадениями намерений.

  • Итак, на вашем первом снимке экрана для устройства Samsung камера действительно отображается — она находится прямо под «Android System» (нажав на нее, вы увидите все совпадения намерений камеры).

  • Если вы сделаете galleryIntent дополнительным вместо намерения камеры, оно объединит все намерения, связанные с галереей, в разделе «Система Android» (как показано на вашем втором снимке экрана для устройства Samsung)

Я думаю, что пользователь может быть сбит с толку, если он не знает, что такое «Android System»!

  • С помощью приведенного ниже решения вы можете напрямую добавить каждый из них в свой chooser

    Во втором фрагменте кода замените

    Intent[] extraIntents = {galleryIntent};
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
    

    с :

    List<Intent> galleryIntents = new ArrayList<Intent>();
    PackageManager pm = getApplicationContext().getPackageManager();
    for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
        Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
        intent.setAction(Intent.ACTION_PICK);
        galleryIntents.add(intent); 
    }
    chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, galleryIntents.toArray(new Parcelable[] {}));
    

Это вручную добавит каждое соответствующее намерение непосредственно в ваш chooser

person ashoke    schedule 18.10.2014
comment
Это работает, однако действие, запущенное средством выбора, не имеет действия Intent.ACTION_PICK и поэтому не возвращается с изображением. Однако, если я добавлю это намерение.setAction(Intent.ACTION_PICK), результат всегда отменяется. - person Arno van Lieshout; 21.10.2014

Попробуйте этот способ, надеюсь, это поможет вам решить вашу проблему

Пожалуйста, следуйте этим шагам, и это лучший и простой способ выбрать изображение из галереи и с камеры.

Шаг 1. объявить глобально переменные

public static final int rcCC = 33;
boolean isCC = false;

Шаг 2 . Скопируйте эти методы и вставьте свой код

void picPhoto() {
    String str[] = new String[] { "Camera", "Gallery" };
    new AlertDialog.Builder(getActivity()).setItems(str,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    performImgPicAction(which);
                }
            }).show();
}

void performImgPicAction(int which) {
    Intent in;
    if (which == 1) {
        in = new Intent(
                Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    } else {
        in = new Intent();
        in.setAction(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    }
    startActivityForResult(
            Intent.createChooser(in, "Select profile picture"), which);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);


        try {
            if (rcCC == requestCode) {
                getActivity();
                if (resultCode == Activity.RESULT_OK) {
                    isCC = true;

                }
            } else {
                getActivity();
                if (resultCode == Activity.RESULT_OK) {
                    BitmapFactory.Options option = new BitmapFactory.Options();
                    option.inDither = false;
                    option.inPurgeable = true;
                    option.inInputShareable = true;
                    option.inTempStorage = new byte[32 * 1024];
                    option.inPreferredConfig = Bitmap.Config.RGB_565;
                    if (Build.VERSION.SDK_INT < 19) {
                        Uri selectedImageURI = data.getData();
                        uImage = BitmapFactory.decodeFile(Common.getPath(
                                selectedImageURI, getActivity()), option);
                    } else {

                        ParcelFileDescriptor pfd;
                        try {
                            pfd = context
                                    .getContentResolver()
                                    .openFileDescriptor(data.getData(), "r");
                            FileDescriptor fileDescriptor = pfd
                                    .getFileDescriptor();

                            uImage = BitmapFactory.decodeFileDescriptor(
                                    fileDescriptor, null, option);
                            pfd.close();

                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    try {
                        ivProfile_image.setImageBitmap(uImage);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

}

Шаг 3. вызовите метод, где вы хотите выбрать изображение и показать диалог

  picPhoto();

Шаг 4.

Сделать разрешение пользователя в файле манифеста,

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.CAMERA" />

Спасибо

person Saveen    schedule 21.10.2014
comment
Это не то, что я ищу. Я знаю, что это можно сделать с помощью собственного диалогового окна оповещения. - person Arno van Lieshout; 21.10.2014

Попробуйте таким образом, я надеюсь, что это сработает для вас, я проверяю вкладку samsung galaxy tab 2, она показывает опцию камеры

Объявите о своем намерении так

  Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    galleryIntent.setType("image/*");

    //Create chooser
    Intent chooser = Intent.createChooser(galleryIntent,title);

        Intent  cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        fileUri = getOutputMediaFileUri(uniqueImageId);
            cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, fileUri); //add file ure (photo is saved here)
            Intent[] extraIntents = {cameraIntent};
            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);

            startActivityForResult(chooser, Constants.SEND_IMAGE_FROM_CEMERA); 

и метод getOutputMediaFileUri (uniqueImageId), который возвращает вам Uri изображения

getOutputMediaFileUri(String uniqueImageId){

        File mediaStorageDir = new File(
                Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                "IMAGE_DIRECTORY_NAME");

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            }
        }


        File mediaFile;
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "IMG_" + uniqueImageId + ".jpg");

        return Uri.fromFile(mediaFile);
}
person Lokesh    schedule 22.10.2014
comment
Это то же самое, что и мой оригинальный пример. Я знаю, как создать Uri для намерения камеры. Это не проблема. - person Arno van Lieshout; 23.10.2014