Android - How to take a picture from camera or gallery - android

I would like to ask the user to take a picture, either from camera or from the existing pictures in the device (gallery or whatever). How can I do that?
I have implemented the solution below, which seems to work fine, but the documentation is quite confusing so I would like to know if there are better solutions.
Also, check out this related post. There you will see how to get the image path or Bitmap: Get/pick an image from Android's built-in Gallery app programmatically
So, in my solution you would create a TakePictureHelper object and do the following.
Let's say you display a dialog where the user can choose "camera" or "other". When the user chooses an option you would call either takeFromCamera() or takeFromOther(). When the picture is taken (or not) the onActivityResult() method will be called. There you would call retrievePicture, which will return the Uri of the picture or null if no picture was taken.
Please let me know what you think, share ideas or ask me anything if I wasn't clear.
Thank you very much!
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TakePictureHelper {
public final static int REQUEST_CAMERA = 1;
public final static int REQUEST_OTHER = 2;
private Uri cameraImageUri;
/**
* Request picture from camera using the given title
*/
public void takeFromCamera(Activity activity, String title)
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File cameraImageOutputFile = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
createCameraImageFileName());
cameraImageUri = Uri.fromFile(cameraImageOutputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri);
activity.startActivityForResult(Intent.createChooser(intent, title), REQUEST_CAMERA);
}
/**
* Request picture from any app (gallery or whatever) using the given title
*/
public void takeFromOther(Activity activity, String title)
{
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
activity.startActivityForResult(Intent.createChooser(intent, title), REQUEST_OTHER);
}
/**
* Retrieve the picture, taken from camera or gallery.
*
* #return the picture Uri, or null if no picture was taken.
*/
public Uri retrievePicture(Activity activity, int requestCode, int resultCode, Intent data)
{
Uri result = null;
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_OTHER) {
result = data.getData();
} else if (requestCode == REQUEST_CAMERA) {
result = cameraImageUri;
}
}
return result;
}
private String createCameraImageFileName() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return timeStamp + ".jpg";
}
}

based on #yurezcv's answer, here's what I came up with (Most importantly how to retrieve image in onActivityResult):
private List<File> cameraImageFiles;
private void popImageChooser(){
// 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);
cameraImageFiles = new ArrayList<File>();
int i=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.MEDIA_IGNORE_FILENAME, ".nomedia");
File cameraImageOutputFile = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
createCameraImageFileName());
cameraImageFiles.add(cameraImageOutputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraImageFiles.get(i)));
i++;
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, getString(R.string.attach_images_title));
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, ACTIVITY_REQUEST_CODE_IMAGE);
}
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case ACTIVITY_REQUEST_CODE_IMAGE:
if(resultCode == RESULT_OK){
Uri uri = null;
if(imageReturnedIntent == null){ //since we used EXTRA_OUTPUT for camera, so it will be null
for(int i=0;i<cameraImageFiles.size();i++){
if(cameraImageFiles.get(i).exists()){
uri = Uri.fromFile(cameraImageFiles.get(i));
break;
}
}
Log.d("attachimage", "from camera: "+uri);
}
else { // from gallery
uri = imageReturnedIntent.getData();
Log.d("attachimage", "from gallery: "+uri.toString());
}
if(uri != null){
attachImage(uri);
}
}
}
}

This solution works for me:
private void addPhoto() {
// 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.MEDIA_IGNORE_FILENAME, ".nomedia");
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, getString(R.string.add_new));
// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
startActivityForResult(chooserIntent, YOUR_REQUEST_CODE);
}
It creates one intent dialog with all possible variants for select image from camera, filesystem, etc.

I found a better and easy way to take picture from camera or gallery i.e. using this library https://android-arsenal.com/details/1/3623
You can follow the link above or follow these steps:
Steps to use this library in your project are:
Add dependency to Gradle:
compile 'com.frosquivel:magicalcamera:4.4'
Implementation Code:
PermissionGranted permissionGranted = new PermissionGranted(this);
MagicalCamera magicalCamera = new MagicalCamera(this, permissionGranted);
//The parameter this, is the current activity
//permission for take photo, it is false if the user check deny
permissionGranted.checkCameraPermission();
//for search and write photoss in device internal memory
//normal or SD memory
permissionGranted.checkReadExternalPermission();
permissionGranted.checkWriteExternalPermission();
Call to Take Photo From Camera:
magicalCamera.takePhoto();
Call to Select Photo From Gallery:
magicalCamera.selectedPicture("my_header_name");
Override OnActivityResult(); method to get Bitmap and Path:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
magicalCamera.resultPhoto(requestCode, resultCode, data);//with this form you obtain the bitmap
Bitmap bitmap = magicalCamera.getPhoto();
imageView.setImageBitmap(bitmap);
//if you need path of bitmap use this code
String path = magicalCamera.savePhotoInMemoryDevice(magicalCamera.getPhoto(),"myPhotoName","myDirectoryName", MagicalCamera.JPEG, true);
if(path != null){
Toast.makeText(MainActivity.this, "The photo is save in device, please check this path: " + path, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "Sorry your photo dont write in devide, please contact with fabian7593#gmail and say this error", Toast.LENGTH_SHORT).show();
}
}
For more details refer to the link above

Create in your layout a button (by clicking on this button will open a dialog where you can choose whether to choose the camera or galleria).
Now initializes the button in its class:
- Before onCreate:
Button btu;
- Inside onCreate:
btu = (Button) findViewById(R.id.BtUp);
Methods call camera and gallery
- Before onCreate boot
int CAMERA_REQUEST = 1;
- Method Call camera
public void callCamera() {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra("crop", "true");
cameraIntent.putExtra("aspectX", 0);
cameraIntent.putExtra("aspectY", 0);
cameraIntent.putExtra("outputX", 200);
cameraIntent.putExtra("outputY", 150);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
- Method Call gallery
public void callGallery() {
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,0);
}
Create a method to show the AlertDialog, which appear to choose:
public void showAlertDialog(Context context) {
this.context = context;
final String items[] = {getString(R.string.TextTakeCam), getString(R.string.TextTakeGal)};
AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.this);
ab.setTitle(getString(R.string.TextTitleDia));
AlertDialog.Builder builder = ab.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int choice) {
if (choice == 0) {
callCamera();
} else if (choice == 1) {
image.setVisibility(View.INVISIBLE);
callGallery();
}
}});
ab.show();
}
Call AlertDialog in button
btu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = getString(R.string.TextUp);
String msg = getString(R.string.TextUp2);
showAlertDialog2(MainActivity.this,title,msg,true);
//maneger.UpdateC(edname.getText().toString(),edfoto.getText().toString(),ednum. getText().toString());
}
});
Inside AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Related

How to access photos and camera in android using one intent

If you use whatsapp and you click the attach button, a menu/popup will be inflated showing you a list of appications you can use to select images and even take pictures from your camera using the photo app
I making an app that have almost the same functionality as whatapp of accessing and taking pictures. the problem is, I can't take pictures using the photo app listed as one of apps in my popup dialog but i can take pictures when using whatsapp. When I click photo app from the dialog shown in my application, it shows me all my pictures. but when I click the photo app from whatsapp popup, it goes directly to the camera
public class ImagePickerActivity extends Activity {
private final int SELECT_PHOTO = 1;
private ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_picker);
imageView = (ImageView)findViewById(R.id.imageView);
Button pickImage = (Button) findViewById(R.id.btn_pick);
pickImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
try {
final Uri imageUri = imageReturnedIntent.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
imageView.setImageBitmap(selectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
In my android manifest
<uses-feature android:name="android.hardware.camera"
android:required="true" />
What do I need to change in my code to be able to take pictures from photo app?
Below code will provide the showing of Camera and Browse storage options in a native 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);
This will help you.!!
And displaying the same in customized dialog as whatsapp refer the link below
click here..
Try to add android.permission.WRITE_EXTERNAL_STORAGE
to your manifest.
camera:
Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, 0);//zero can be replaced with any action code
gallery:
Intent pickPhoto = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , 1);//one can be replaced with any action code
onactivity result code:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case 1:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
imageview.setImageURI(selectedImage);
}
break;
case 0:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
imageview.setImageURI(selectedImage);
}
break;
}
}
To access camera and photos using one intent
populate a custom dialog's listview with intents from apps that can either take pictures using camera or access photos in the storage like this
private void acquirePicture(){
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams WMLP = dialog.getWindow().getAttributes();
WMLP.gravity = Gravity.CENTER;
dialog.getWindow().setAttributes(WMLP);
dialog.getWindow().setBackgroundDrawable(
new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setCanceledOnTouchOutside(true);
dialog.setContentView(R.layout.about_dialog);
dialog.setCancelable(true);
lv=(ListView)dialog.findViewById(R.id.listView1);
populateDialogsListView();
dialog.show();
}
Poputate dialog's listview (lv) with apps that can perform the two actions
public void populateDialogListView(){
PackageManager pm=getPackageManager();
List<ResolveInfo> photoIntents = new ArrayList<>();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(
captureIntent, PackageManager.GET_RESOLVED_FILTER);
final List<ResolveInfo> listGalley = packageManager.queryIntentActivities(photoPickerIntent, PackageManager.GET_RESOLVED_FILTER);
for (ResolveInfo activity : listCam) {
photoIntents.add(activity);
}
for (ResolveInfo activity : listGalley) {
photoIntents.add(activity);
}
Collections.sort(photoIntents,
new ResolveInfo.DisplayNameComparator(pm));
AppAdapter appAdapter = new AppAdapter(pm, photoIntents);
lv.setAdapter(appAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
ResolveInfo launchable=appAdapter.getItem(position);
ActivityInfo activity=launchable.activityInfo;
ComponentName name=new ComponentName(activity.applicationInfo.packageName,
activity.name);
IntentFilter filter = launchable.filter;
int actioncode;
Intent intent = new Intent();
Uri uri;
if(filter.hasAction(Intent.ACTION_PICK)){
actioncode = 1;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
intent.setData(uri);
}else{
actioncode = 0;
}
intent.setComponent(name);
startActivityForResult(intent,actioncode);
}
});
}
Since you are creating a custom dialog with a listview, you have to create adapter for that listview(lv) which will fill the listview with app's name and app's icon
class AppAdapter extends ArrayAdapter<ResolveInfo> {
private PackageManager pm=null;
AppAdapter(PackageManager pm, List<ResolveInfo> apps) {
super(Custom_chooser.this, R.layout.row, apps);
this.pm=pm;
}
#Override
public View getView(int position, View convertView,
ViewGroup parent) {
if (convertView==null) {
convertView=newView(parent);
}
bindView(position, convertView);
return(convertView);
}
private View newView(ViewGroup parent) {
return(getLayoutInflater().inflate(R.layout.row, parent, false));
}
private void bindView(int position, View row) {
TextView label=(TextView)row.findViewById(R.id.label);
label.setText(getItem(position).loadLabel(pm));
ImageView icon=(ImageView)row.findViewById(R.id.icon);
icon.setImageDrawable(getItem(position).loadIcon(pm));
}
Any problem, let me know
So to launch them to the native camera application or the camera application the user has selected as their default I believe you would use this.
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Intent chooser = Intent.createChooser(intent, title);
// Always use string resources for UI text.
// This says something like "Take a photo with"
String title = getResources().getString(R.string.chooser_title)
// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
Edited it with a sample of what should be required to do so. It may not be simply cut and paste but you should be able to figure it out from that. Sorry, short on time so i cant really elaborate at the moment.

an android file picker or camera for taking pictures or videos not working on nexus 4

I am trying to open an android file picker or camera for taking pictures or videos using the following code:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICKFILE_RESULT_CODE && Activity.RESULT_OK == resultCode) {
try {
// Get the Uri of the selected file
Uri uri = data.getData();
LogS.d("File Uri: " + uri.toString());
// Get the path
String path = BeanUtils.getPath(getActivity().getApplicationContext(), uri);
AnnexFile f = new AnnexFile(path);
if (!addedFiles.contains(f)) {
addFileToLayout(f);
addedFiles.add(f);
} else {
Toast.makeText(getActivity(), R.string.you_allready_added_this_file_, Toast.LENGTH_SHORT).show();;
}
} catch (Exception e) {
LogS.e(e);
Toast.makeText(getActivity(), getString(R.string.file_manager_invalid), Toast.LENGTH_LONG).show();
}
} else if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE && Activity.RESULT_OK == resultCode) {
try {
Uri uri = data.getData();
LogS.d("File Uri: " + uri.toString());
// Get the path
String path = BeanUtils.getPath(getActivity().getApplicationContext(), uri);
AnnexFile f = new AnnexFile(path);
if (!addedFiles.contains(f)) {
addFileToLayout(f);
addedFiles.add(f);
} else {
Toast.makeText(getActivity(), R.string.you_allready_added_this_file_, Toast.LENGTH_SHORT).show();;
}
} catch (Exception e) {
LogS.e(e);
Toast.makeText(getActivity(), getString(R.string.file_manager_invalid), Toast.LENGTH_LONG).show();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void openImageIntent() {
// Camera.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getActivity().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);
}
final Intent videoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
final List<ResolveInfo> listVideoCam = packageManager.queryIntentActivities(videoIntent, 0);
for (ResolveInfo res : listVideoCam){
final String packageName = res.activityInfo.packageName;
final Intent intent = new Intent(videoIntent);
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/*;video/*");
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[]{}));
startActivityForResult(chooserIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
The code works perfect on Samsung S4 and Sony Experia J but fails on Nexus 4 (android 5.1.1). When I debugged the application on nexus 4 I found that the following Uri uri = data.getData(); is null if the end user tries to make a picture. The application works on all devices if the user tries to make a video or to open an existing media file.
When I debugged the application on nexus 4 I found that the following Uri uri = data.getData(); is null if the end user tries to make a picture
You are assuming that ACTION_IMAGE_CAPTURE returns a result in the form of a Uri. It is not documented to do so. There are thousands of camera apps, pre-installed and user-installed. Many of them will advertise support for ACTION_IMAGE_CAPTURE. None have to return a Uri result.

Nullpointer exception on getPackageManger method while using in openImageIntent method to select image either from camera or gallary

I'm calling image intent method to get the options of camera or gallary while clicking on image view.I found the code here
Allow user to select camera or gallery for image
user David Manpearl
and this is the code I'm using
public static final int YOUR_SELECT_PICTURE_REQUEST_CODE=222;
public void openImageIntent1() {
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "userDir" + File.separator);
root.mkdirs();
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
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 = this.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[]{}));
startActivityForResult(chooserIntent, 222);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
if(requestCode == 222) {
final boolean isCamera;
if(data == null)
isCamera = true;
else {
final String action = data.getAction();
if(action == null)
isCamera = false;
else
isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
}
Uri selectedImageUri;
if(isCamera)
selectedImageUri = outputFileUri;
else
selectedImageUri = data == null ? null : data.getData();
}
}
}
}
}
In this ,getting error on final PackageManager packageManager = this.getPackageManager() line.
Can you please help?
Thank you
I'm calling this method in another class by making object of this call
Never instantiate an Activity with new. It won't get properly initialized, and calling any activity or context method won't work. So it's no good for anything you'd want to use it for.
Instead, pass in a Context as a parameter to methods that need it like this.
To instantiate an activity, use startActivity() with Intent.

Android using camera app

In my app i'm using the camera app on the phone in order to take a picture. After taking the picture it returns back to my app. I noticed that it acts differently in different phones. In Galaxy s3 I found that after taking a picture it shows the picture and gives an option to save it (and then go back to my app) or discard (and go back to the camera app). The problem is that when the screen is rotated the app crushes when the save/discard screen appears. The only way to stop it from crushing is to take the picture without rotating the screen and keep it that way.
Is there a solution to this problem? Maybe there is a way that I can define that it won't allow rotation at this screen?
Here is the code:
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//Specify target file
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
newPicName = android.os.Environment.getExternalStorageDirectory() + "/"+app.APP_FOLDER + "/" + app.getSession()+ "_"+app.getDateTime()+ "_" +sdf.format(cal.getTime()) +".jpg";
File imageFile = new File(newPicName);
Uri imageFileUri = Uri.fromFile(imageFile);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(intent, 0);
If you just want to limit the orientation of the screen you need to specify it in your manifest… For example:
<activity
android:name="com.xxx"
android:label="#string/xxx"
android:screenOrientation="portrait" > //this limits the screen to only portrait.
</activity>
Additional Info
This is how I do it and it works for me perfectly.
//instance variables
private static final int TAKE_PICTURE = 0;
private Uri mUri;
private Bitmap mPhoto;
//First I create a method to capture the image.
private void captureImage() {
Intent i = new Intent("android.media.action.IMAGE_CAPTURE");
File f = new File(Environment.getExternalStorageDirectory(), "profile.jpg");
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
mUri = Uri.fromFile(f);
startActivityForResult(i, TAKE_PICTURE);
}
//Then I handle the result.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PICTURE://this is a constant defined in my instance variables.
if (resultCode == Activity.RESULT_OK) {
getContentResolver().notifyChange(mUri, null);
ContentResolver cr = getContentResolver();
try {
mPhoto = android.provider.MediaStore.Images.Media.getBitmap(cr, mUri);
//set your photo in a screen…
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
}
Try following code :
private File tempFile;
private static final int CAMERA_IMAGE = 1;
public void takePicFromCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (tempFile != null) {
Log.i(""image Path : "", tempFile.getPath());
Uri picUri = Uri.fromFile(tempFile); // convert path to Uri
intent.putExtra(MediaStore.EXTRA_OUTPUT, picUri);
Log.i("Picture Uri", " : " + picUri);
}
startActivityForResult(intent, MedicationConstants.CAMERA_IMAGE);
}
public void onActivityResult(int requestCode, int resultCode, final Intent intent) {
if (requestCode == MedicationConstants.CAMERA_IMAGE) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (tempFile != null) {
//do anything with image file. Store in database. Or even should add functionality of dropping
}
}
}, 2000);
}
}
In on onActivityResult you should add functionality of image cropping. Please have a look at simple-crop-image-lib. It is great library & works for almost all device.
Thanks

Android How can I call Camera or Gallery Intent Together

If I want to capture image from native camera, I can do:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, IMAGE_CAPTURE);
If I want to get image from gallery, I can do:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
I am wondering how can put the above two together.
That means GET IMAGE FROM GALLERY OR CAPTURE PHOTO
Is there any example code to do it?
Thanks.
If you want to take picture from Camera or Gallery Intent Together, Then check below link. Same question also posted here.
Capturing image from gallery & camera in android
UPDATED CODE:
check below code, In this code not same as you want into listview, but it gives the option in the dialogBox choose image from Gallary OR Camera.
public class UploadImageActivity extends Activity {
ImageView img_logo;
protected static final int CAMERA_REQUEST = 0;
protected static final int GALLERY_PICTURE = 1;
private Intent pictureActionIntent = null;
Bitmap bitmap;
String selectedImagePath;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
img_logo= (ImageView) findViewById(R.id.imageView1);
img_logo.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startDialog();
}
});
}
private void startDialog() {
AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(
getActivity());
myAlertDialog.setTitle("Upload Pictures Option");
myAlertDialog.setMessage("How do you want to set your picture?");
myAlertDialog.setPositiveButton("Gallery",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent pictureActionIntent = null;
pictureActionIntent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(
pictureActionIntent,
GALLERY_PICTURE);
}
});
myAlertDialog.setNegativeButton("Camera",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
Intent intent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment
.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(f));
startActivityForResult(intent,
CAMERA_REQUEST);
}
});
myAlertDialog.show();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
bitmap = null;
selectedImagePath = null;
if (resultCode == RESULT_OK && requestCode == CAMERA_REQUEST) {
File f = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
if (!f.exists()) {
Toast.makeText(getBaseContext(),
"Error while capturing image", Toast.LENGTH_LONG)
.show();
return;
}
try {
bitmap = BitmapFactory.decodeFile(f.getAbsolutePath());
bitmap = Bitmap.createScaledBitmap(bitmap, 400, 400, true);
int rotate = 0;
try {
ExifInterface exif = new ExifInterface(f.getAbsolutePath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
img_logo.setImageBitmap(bitmap);
//storeImageTosdCard(bitmap);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (resultCode == RESULT_OK && requestCode == GALLERY_PICTURE) {
if (data != null) {
Uri selectedImage = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage, filePath,
null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
selectedImagePath = c.getString(columnIndex);
c.close();
if (selectedImagePath != null) {
txt_image_path.setText(selectedImagePath);
}
bitmap = BitmapFactory.decodeFile(selectedImagePath); // load
// preview image
bitmap = Bitmap.createScaledBitmap(bitmap, 400, 400, false);
img_logo.setImageBitmap(bitmap);
} else {
Toast.makeText(getApplicationContext(), "Cancelled",
Toast.LENGTH_SHORT).show();
}
}
}
}
Also add pemission:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
store Image to sdcard:
private void storeImageTosdCard(Bitmap processedBitmap) {
try {
// TODO Auto-generated method stub
OutputStream output;
// Find the SD Card path
File filepath = Environment.getExternalStorageDirectory();
// Create a new folder in SD Card
File dir = new File(filepath.getAbsolutePath() + "/appName/");
dir.mkdirs();
String imge_name = "appName" + System.currentTimeMillis()
+ ".jpg";
// Create a name for the saved image
File file = new File(dir, imge_name);
if (file.exists()) {
file.delete();
file.createNewFile();
} else {
file.createNewFile();
}
try {
output = new FileOutputStream(file);
// Compress into png format image from 0% - 100%
processedBitmap
.compress(Bitmap.CompressFormat.PNG, 100, output);
output.flush();
output.close();
int file_size = Integer
.parseInt(String.valueOf(file.length() / 1024));
System.out.println("size ===>>> " + file_size);
System.out.println("file.length() ===>>> " + file.length());
selectedImagePath = file.getAbsolutePath();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Let's say that you have two intents. One that would open a camera, one that would open a gallery. I will call these cameraIntent and gallerIntent in the example code. You can use intent chooser to combine these two:
Kotlin:
val chooser = Intent.createChooser(galleryIntent, "Some text here")
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(cameraIntent))
startActivityForResult(chooser, requestCode)
Java:
Intent chooser = Intent.createChooser(galleryIntent, "Some text here");
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { cameraIntent });
startActivityForResult(chooser, requestCode);
This is, as you asked, how you can put the two together (without having to make your own UI/ dialog).
If you want to show all the apps installed in the phone that can deal with photos such as Camera, Gallery, Dropbox, etc.
You can do something like:
1.- Ask for all the intents available:
Intent camIntent = new Intent("android.media.action.IMAGE_CAPTURE");
Intent gallIntent=new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*");
// look for available intents
List<ResolveInfo> info=new ArrayList<ResolveInfo>();
List<Intent> yourIntentsList = new ArrayList<Intent>();
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(camIntent, 0);
for (ResolveInfo res : listCam) {
final Intent finalIntent = new Intent(camIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
yourIntentsList.add(finalIntent);
info.add(res);
}
List<ResolveInfo> listGall = packageManager.queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
final Intent finalIntent = new Intent(gallIntent);
finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
yourIntentsList.add(finalIntent);
info.add(res);
}
2.- Show a custom dialog with the list of items:
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(context.getResources().getString(R.string.select_an_action));
dialog.setAdapter(buildAdapter(context, activitiesInfo),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
Intent intent = intents.get(id);
context.startActivityForResult(intent,1);
}
});
dialog.setNeutralButton(context.getResources().getString(R.string.cancel),
new android.content.DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
This is a full example: https://gist.github.com/felixgborrego/7943560
In fact your dialog title is "select an action" means the dialog is a Intent chooser actually. not a user customed dialog. The every single item presents a Intent.
public void click(View view) {
File file = getExternalFilesDir(Environment.DIRECTORY_DCIM);
Uri cameraOutputUri = Uri.fromFile(file);
Intent intent = getPickIntent(cameraOutputUri);
startActivityForResult(intent, -1);
}
private Intent getPickIntent(Uri cameraOutputUri) {
final List<Intent> intents = new ArrayList<Intent>();
if (true) {
intents.add(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
}
if (true) {
setCameraIntents(intents, cameraOutputUri);
}
if (intents.isEmpty()) return null;
Intent result = Intent.createChooser(intents.remove(0), null);
if (!intents.isEmpty()) {
result.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(new Parcelable[] {}));
}
return result;
}
private void setCameraIntents(List<Intent> cameraIntents, Uri output) {
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, output);
cameraIntents.add(intent);
}
}
You may need solve permissions by yourself if run on OS >= 23
Here's my demo:(Appearance differences since OS different)
I think I encountered your case before. An idea is that we will create a one item list alert dialog with selectable item, and each item will do a unique function defined by your own intention. If you want an icon for each element in items list, it should take a bit more work to do. Hope it will helpful.
String title = "Open Photo";
CharSequence[] itemlist ={"Take a Photo",
"Pick from Gallery",
"Open from File"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(R.drawable.icon_app);
builder.setTitle(title);
builder.setItems(itemlist, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:// Take Photo
// Do Take Photo task here
break;
case 1:// Choose Existing Photo
// Do Pick Photo task here
break;
case 2:// Choose Existing File
// Do Pick file here
break;
default:
break;
}
}
});
AlertDialog alert = builder.create();
alert.setCancelable(true);
alert.show();
Create a button in your XML layout and the add the attribute android:onClick="takeAPicture"
then in your main activity create a method with the same name from the onClick attribute.
public void takeAPicture(View view){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(intent, IMAGE_CAPTURE);
}
And just do another method for when you want to get the image from the gallery:
public void getImageFromGallery(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
public static Intent getPickImageIntent(Context context) {
Intent chooserIntent = null;
List<Intent> intentList = new ArrayList<>();
Intent pickIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoIntent.putExtra("return-data", true);
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context)));
intentList = addIntentsToList(context, intentList, pickIntent);
intentList = addIntentsToList(context, intentList, takePhotoIntent);
if (intentList.size() > 0) {
chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
context.getString(R.string.pick_image_intent_text));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
}
return chooserIntent;
}
private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) {
List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
Intent targetedIntent = new Intent(intent);
targetedIntent.setPackage(packageName);
list.add(targetedIntent);
}
return list;
}

Categories

Resources