Chooser with camera intent and image picker intent

Arno van Lieshout picture Arno van Lieshout · Oct 15, 2014 · Viewed 20.3k times · Source

I have created a chooser for either picking an image from file or for making a picture.

The code I use works fine on a Nexus 5, however when I try it on a Samsung S5, the chooser does not display the camera icons.

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

SamsungNexus

When I change the order in which the intents are added to the chooser the Samsung device does show the camera but only shows android-system as the file option.

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 Nexus

Ideally I would like the Samsung device to show the same as the Nexus one when I add the gallery intent first. I can however not get this to work.

Answer

ashoke picture ashoke · Oct 18, 2014
  • If there are multiple intent matches for the extra intent (Intent.EXTRA_INITIAL_INTENTS) , it will show all of them combined under "Android System". When you click on "Android System", it will open another chooser with all those intent matches.

  • So, in your first screenshot for samsung device, the camera is indeed showing up - its just under "Android Systeem" (clicking this will show all camera intent matches).

  • If you make galleryIntent the extra instead of camera intent, it will combine all gallery related intents under "Android Systeem" (as seen in your 2nd screenshot for samsung device)

I guess the user can be confused if he does not know what this "Android Systeem" is !

  • With below solution you can directly add each one to your chooser

    In your 2nd code snippet, replace

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

    with :

    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[] {}));
    

This will manually add each matching intent directly to your chooser