3

I am developing an app that needs to allow the user to select a Profile picture, and I want to give them an easy option to either take a picture, or choose an existing one from the Gallery.

My searches took me to this Stackoverflow discussion, so I modified the code in one of the answers for my purposes. Here is what I have:

public static Uri openImageIntent(Activity context) {
    Uri outputFileUri = null;
    File cache_dir = context.getExternalFilesDir("photos");

    cache_dir.mkdirs();

    File image_file = null;
    try {
        image_file = File.createTempFile("profile", ".jpg", cache_dir);
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (image_file != null) {
        File sdImageMainDirectory = new File(cache_dir.getAbsolutePath(), image_file.getName());
        outputFileUri = Uri.fromFile(sdImageMainDirectory);

        // Camera.
        List<Intent> cameraIntents = new ArrayList<Intent>();
        Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        PackageManager packageManager = context.getPackageManager();
        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, outputFileUri);
            cameraIntents.add(intent);
        }

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

        // Chooser of filesystem options.
        final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");

        // Add the camera options.
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));

        context.startActivityForResult(chooserIntent, Constants.RequestCodes.CHOOSE_PICTURE);
    }

    return outputFileUri;
 }

As you can see, it creates a chooser by combining the ACTION_IMAGE_CAPTURE and ACTION_GET_CONTENT intents, with the latter being filtered for "image/*". The goal here is to open up a custom choose that lets the user either pick the Camera app to take a new picture, or choose the Gallery app (or Photos, or a file browser) to pick an existing image. I also had to do some work in onActivityResult() to correctly receive the picture and use it depending on the choice, but I don't think that's relevant here.

On 4.3 and below, this works great. It opens a chooser that looks something like this:

enter image description here

However, on KitKat, the chooser looks like this:

enter image description here

As you can see, it seems to be ignoring the "image/*" filter, and just giving me some generic "Documents" app for opening files.

Obviously something has changed in KitKat, but I don't know what it is, and I can't find anyone else who has encountered this problem.

Any ideas?

Community
  • 1
  • 1
Russell Stewart
  • 1,960
  • 4
  • 24
  • 31
  • 1
    That's odd. Gallery still shows that it supports `ACTION_GET_CONTENT` for `image/*` on a Nexus 4 running Android 4.4.2. Does anything change if you temporarily comment out your `EXTRA_INITIAL_INTENTS` line? – CommonsWare Feb 04 '14 at 18:07
  • Well, that just caused it to open "Documents" right away without a chooser at all. However, this led me to an interesting discovery. It turns out that "Documents" is actually a pretty convenient interface for choosing photos, and it does properly filter the files so I only see photos. So it works. But it's not very clear. Non-technical users might not expect "Documents" (with an icon of a text document) to be a place where they can choose a photo. Not sure what I can do about that, but I'll play around with it. Thanks for your help! – Russell Stewart Feb 04 '14 at 18:13
  • Hi rnstewart, did you manage to get it working with LabeledIntent? I run into this too. Btw its nice that e.g. Dropbox or Google Drive is also an option in this intent chooser. – Michal Mar 06 '14 at 10:57

2 Answers2

0

So it turns out that "Documents" is actually the correct app for choosing a photo. It works the way it is supposed to, only showing me images from my gallery. The name and icon are not exactly clear on this point, and I'm worried that it might cause some confusion for less technical users. But I guess I'll just have to deal with that.

Russell Stewart
  • 1,960
  • 4
  • 24
  • 31
0

Check out this: https://developer.android.com/guide/topics/providers/document-provider.html

Google introduced Storage Access Framework in KitKat, it provides a common system UI for picking documents instead individual apps.