Reputation: 179
String chooseTitle = activity.getString(R.string.select_or_take_picture);
Intent getIntent = new Intent();
getIntent.setType("image/*");
getIntent.setAction(Intent.ACTION_GET_CONTENT);
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
galleryIntent.setType("image/*");
PackageManager pm = activity.getApplicationContext().getPackageManager();
for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
intent.setAction(Intent.ACTION_PICK);
intents.add(intent);
}
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, photoUri);
for (ResolveInfo ri : pm.queryIntentActivities(cameraIntent, 0)) {
Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
intents.add(intent);
}
Intent chooserIntent = Intent.createChooser(getIntent, chooseTitle);
chooserIntent.putExtra(
Intent.EXTRA_INITIAL_INTENTS,
intents.toArray(new Parcelable[] {})
);
By doing this way, the chooser shows:
The camera intent doesn't show at all.
But if I change the line
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, photoUri);
to
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
It works just fine:
But the problem is, I really want to pass photoUri
. How can I do with it?
I know a possible alternative is to write my own chooser dialog, but I do want to know if it's a bug in intent chooser, or if I don't use it correctly.
p.s. @dkarmazi, Here's how I generate Uri:
public Uri generatePhotoUri() {
String timeStamp = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date());
String imageFileName = "XXX_" + timeStamp + ".jpg";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = new File(storageDir, imageFileName);
return Uri.fromFile(imageFile);
}
Here's my onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_PHOTO:
if (resultCode != Activity.RESULT_OK) {
break;
}
Uri source = data == null ?
mPhotoUri : // take picture
data.getData(); // choose from other app
if (source == null) {
break;
}
// TODO: do with source
break;
}
//....
}
@dkarmazi, I've debugged it, and I make sure resultCode is RESULT_CANCELED
.
Upvotes: 2
Views: 1654
Reputation: 179
Thank @dkarmazi very much for helping me debug this issue. It seems we haven't enough reputation to refine the answer together, so I'm posting the solution here. Later in our chat we find a probable cause, and after my experimenting, now it works. It's actually an issue how I gather cameraIntent
s, so change this part of code
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, photoUri);
for (ResolveInfo ri : pm.queryIntentActivities(cameraIntent, 0)) {
Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
intents.add(intent);
}
to
final Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
for(ResolveInfo ri : pm.queryIntentActivities(cameraIntent, 0)) {
final String packageName = ri.activityInfo.packageName;
final Intent intent = new Intent(cameraIntent);
intent.setComponent(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name));
intent.setPackage(packageName);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
intents.add(intent);
}
Also need to change
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
galleryIntent.setType("image/*");
PackageManager pm = activity.getApplicationContext().getPackageManager();
for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
Intent intent = pm.getLaunchIntentForPackage(ri.activityInfo.packageName);
intent.setAction(Intent.ACTION_PICK);
intents.add(intent);
}
to
Intent galleryIntent = new Intent(Intent.ACTION_PICK);
galleryIntent.setType("image/*");
PackageManager pm = activity.getApplicationContext().getPackageManager();
for (ResolveInfo ri: pm.queryIntentActivities(galleryIntent, PackageManager.MATCH_DEFAULT_ONLY)) {
final String packageName = ri.activityInfo.packageName;
final Intent intent = new Intent(galleryIntent);
intent.setComponent(new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name));
intent.setPackage(packageName);
intents.add(intent);
}
I hate the boilerplate of it, but finally it works.
Upvotes: 0
Reputation: 3259
I recently worked on the same problem and here is my solution:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
Then, once the user takes a picture, you should be able to access it by using the provided photoUri
Here is some documentation on EXTRA_OUTPUT and you can also lookup ACTION_IMAGE_CAPTURE on the same page.
UPDATE on Intent Chooser:
// we create intent chooser by picking one of the intents
Intent chooserIntent = Intent.createChooser(cameraIntent, getResources().getString(R.string.pick_action_string_for_user));
// then we add any additional intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { getIntent });
// chooserIntent is ready
startActivityForResult(chooserIntent, requestCode);
Upvotes: 2