I'm trying to allow my user to pick a picture from the phone gallery or to take a picture with the camera.
I wrote a piece of code working really well on my Samsung S6
private void openPictureIntent() {
final List<Intent> cameraIntents = new ArrayList<>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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);
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[cameraIntents.size()]));
startActivityForResult(chooserIntent, SELECT_PICTURE_CODE);
}
Then I tried it on a Nexus 5X and my app crashed. I learned that the intent retrieved in onActivityResult is null with some devices. The solution is to give the uri where to save the image taken with the camera. I implemented it and my code became
private void openPictureIntent() {
// Determine Uri of camera image to save.
final File dir = new File(Environment.getExternalStorageDirectory() + File.separator + "Directory" + File.separator);
dir.mkdirs();
final String fname = UUID.randomUUID() + ".jpg";
final File sdImageMainDirectory = new File(dir, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
new File(outputFileUri.getPath()).delete();
// Camera.
final List<Intent> cameraIntents = new ArrayList<>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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[cameraIntents.size()]));
startActivityForResult(chooserIntent, SELECT_PICTURE_CODE);
}
This is working but I'm not satisfied. I would like my photo to be stored with other camera photo and not in a special directory. How could I achieve that ?
I learned that the intent retrieved in onActivityResult is null with some devices.
It is supposed to be null for all camera apps. Some camera app developers fail to read the documentation for ACTION_IMAGE_CAPTURE.
I would like my photo to be stored with other camera photo and not in a special directory
That is not supported by ACTION_IMAGE_CAPTURE.
Related
I try to take the picture Uri in the onActivityResult() and i'm get resultCode == 0 only on Android 12.
on all the other devices I tested it works fine.
this is the code to start gallery and camera
final File root = new File(Environment.getExternalStorageDirectory() +
File.separator + "HofitApp" + File.separator);
root.mkdirs();
final String fname = "AddProductImage.jpg";
final File sdImageMainDirectory = new File(root, fname);
// mProductImageUri = Uri.fromFile(sdImageMainDirectory);
mProductImageUri = FileProvider.getUriForFile(this,
BuildConfig.APPLICATION_ID + ".provider", sdImageMainDirectory);
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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, mProductImageUri);
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[cameraIntents.size()]));
startActivityForResult(chooserIntent, EXT_PICK_IMAGE_REQUEST_CODE);
Has anyone have this problem and know how to fix it?
I have tried all kind of ways, i try to change from Uri.fromFile(sdImageMainDirectory)
to FileProvider and still not working properly, result code is zero after taking a picture.
thanks
Replace your Temp Image Location -
final File root = new File(Environment.getExternalStorageDirectory() +
File.separator + "HofitApp" + File.separator);
to
final File root = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.path+File.separator+"HofitApp"+File.separator;
and camera capture intent go like that -
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
cameraIntent.clipData = ClipData.newRawUri("", uri)
cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivityForResult(cameraIntent, IMAGE_CAPTURE_REQUEST)
Im trying to start the choosePictureIntent. This is done by clicking on an image in an Ap
#Override
public void imageClicked(int position) {
if(data.get(position).getImgUri() != null) {
// IGNORE THIS
Intent intent= new Intent(context, FullScreenActivity.class);
intent.putExtra("data", data.get(position));
context.startActivity(intent);
} else {
// THIS IS THE CODE
Object[] chooseData;
chooseData = Utils.getChoosePictureIntent(context, context.getPackageManager());
Intent chooserIntent = (Intent) chooseData[0];
chooserIntent.putExtra("data", data.get(position)); // data is an array of information
chooserIntent.putExtra("outputFileUri", (Uri) chooseData[1]);
((Activity) context).startActivityForResult(chooserIntent, PICTURE_REQUEST);
}
}
When I click on the image, nothing happens, but I know that the else statement gets executed. After that, if I click on the view besides the image, the whole app freezes.
There are no error messages.
Any help is appreciated.
The source of getChoosePictureIntent():
public static String getUniqueFileName(String prefix, String surfix) {
return prefix + System.currentTimeMillis() + surfix;
}
public static Object[] getChoosePictureIntent(Context context, PackageManager manager) {
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "imagedir" + File.separator);
root.mkdirs();
final String fName = Utils.getUniqueFileName("img_purchase_", ".jpg");
final File sdImageMainDirectory = new File(root, fName);
Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = manager;
final 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(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, context.getString(R.string.picture_chooser));
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
return new Object[]{chooserIntent, outputFileUri};
}
If you are using targetSdk >=24, then you need to add File Provider in order to replace the File Uri received from Camera App to Content Uri because API level 24 has blocked File Uri from another app for security reason.You can check out this link for more info
I'm having trouble creating a chooser intent that allows the users to select either a Camera App, a Gallery App, or a File Browser App.
So far, I can only get Camera + Gallery or Camera + File Browser but not all 3 options
In the below method it seems like following line is being ignored:
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, galleryIntent);
Code:
public void openUploadIntent() {
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fname = "ABCD_" + timeStamp;
final File sdImageMainDirectory = new File(storageDir, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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);
}
//Gallery.
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
//Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Filesystem.
final Intent fsIntent = new Intent();
fsIntent.setType("*/*");
fsIntent.setAction(Intent.ACTION_GET_CONTENT);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(fsIntent, "Select Source");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, galleryIntent);
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.ize()]));
startActivityForResult(chooserIntent, 99999);
}
Well i figured it out.
It looks like each call to EXTRA_INTIAL_INTENTS replaces the last.
This is my final working code (on Samsung Galaxy S)
public void openImageIntent() {
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fname = "ABCD_" + timeStamp;
final File sdImageMainDirectory = new File(storageDir, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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);
}
//Gallery.
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// Filesystem.
final Intent fsIntent = new Intent();
fsIntent.setType("*/*");
fsIntent.setAction(Intent.ACTION_GET_CONTENT);
cameraIntents.add(fsIntent);
//Create the Chooser
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));
startActivityForResult(chooserIntent, 99999);
}
I want to create a dialog like this:
I need to create the dialog when user clicks on the profile image like given in link. Current I'm doing this
final CharSequence[] items = { "Gallery", "Camera", "Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Gallery")) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp1.jpg");
mImageCaptureUri = Uri.fromFile(f);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
startActivityForResult(intent, CAMERA_CODE);
} else if (items[item].equals("Camera")) {
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, GALLERY_CODE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
I dont know how to do as the design given please help me on this.
There are two ways you can achieve this.
Using Custom Alert dialog.
Using Intent by query intent activities.
By default, Android doesn't show the option to open camera and gallery in a single shot. But doing some tricks will help to achieve this.
Refer the below code which is used to display Camera and Gallery browse options in a single default dialog.
// Picks Camera first.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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);
}
final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_PICK);
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent,
"Select Image from");
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, TAKE_PHOTO_CODE);
Already answered here for same type of issue. !!
--> queryIntentActivityOptions not working
Hope this helps you,
I have a problem when I called my code bellow from android devices, they show the Gallery and Camera, but when I run this code on Nexus 4 (android v4.4, KitKat), it didn't show the camera choosing. It shown only Gallery.
Please help me for this issue
Thanks, :)
private Uri outputFileUri = null;
private String pathImage = null;
private void chooseImage() {
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + getString(R.string.app_name) + File.separator);
root.mkdirs();
final String fname = String.valueOf(System.currentTimeMillis());
final File sdImageMainDirectory = new File(root, fname);
outputFileUri = Uri.fromFile(sdImageMainDirectory);
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final 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(Intent.ACTION_PICK);
galleryIntent.setType("image/*");
// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent, getString(R.string.title_pick_photo));
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, IActivity.PICK_GALLERY);
}