Android : Why Intent.EXTRA_LOCAL_ONLY shows Google Photos

Giru Bhai picture Giru Bhai · Jan 4, 2015 · Viewed 8.2k times · Source

What I'm trying to do in my application is to let the user choose a picture from his phone's gallery(Don't want to get gallery images only but also allowing a user to choose their app of choice). The code I'm using is as follows:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 1);

As per Intent.EXTRA_LOCAL_ONLY doesnt work

EXTRA_LOCAL_ONLY only tells the receiving app that it should return only data that is present.

After adding intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); in above code,it hide google drive app and picasa app but still shows google photos(those photos are not in my device.)

Also I tried Android image picker for local files only but It hide all the apps having remote images excluding google photos.

Note : All the image paths are correct as I did Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT (thanks to @Paul Burke) but I don't want to pick internet/remote images.

So my question Is there any way to hide google photos app while pick an image from local device only. or Is google photos is part of Intent.EXTRA_LOCAL_ONLY

Answer

Nuwisam picture Nuwisam · Jan 5, 2015

EXTRA_LOCAL_ONLY only tells the receiving app that it should return only data that is present.

Google+ Photos stores both local and remote pictures and because of that is registered for that intent with that extra. However apparently it ignores wherever calling intent has EXTRA_LOCAL_ONLY set to true.

You could try removing G+ Photos from list manually (however this seems a bit hacky):

List<Intent> targets = new ArrayList<Intent>();
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
List<ResolveInfo> candidates = getPackageManager().queryIntentActivities(intent, 0);

for (ResolveInfo candidate : candidates) {
  String packageName = candidate.activityInfo.packageName;
  if (!packageName.equals("com.google.android.apps.photos") && !packageName.equals("com.google.android.apps.plus") && !packageName.equals("com.android.documentsui")) {
      Intent iWantThis = new Intent();
      iWantThis.setType("image/*");
      iWantThis.setAction(Intent.ACTION_GET_CONTENT);
      iWantThis.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
      iWantThis.setPackage(packageName);
      targets.add(iWantThis);
    }
}
Intent chooser = Intent.createChooser(targets.remove(0), "Select Picture");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targets.toArray(new Parcelable[targets.size()]));
startActivityForResult(chooser, 1);

Few words of explanation: targets.remove(0) will remove and return first Intent from targets list, so the chooser will consist only of one application. Then with Intent.EXTRA_INITIAL_INTENTS we add the rest.

The code snippet is modified version from this link.

Please remember to check all conditions like if there is at least one app available and so on.