问题
What I\'m trying to do seems very simple, but after a few days of searching I can\'t quite figure it out.
I have an application that allows the user to select multiple(up to 5) images. I\'m using an ImageView
. When the user clicks on the ImageView
, I\'d like to allow them the option to
- Select the image from the gallery, or
- Use the camera to capture an image.
I started by using the ACTION_GET_CONTENT
intent, and that works well for getting to the gallery. So then I tried using the ACTION_PICK_ACTIVITY
intent to allow the user to choose camera or gallery:
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
Intent gallIntent=new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType(\"image/*\");
Intent camIntent = new Intent(\"android.media.action.IMAGE_CAPTURE\");
pickIntent.putExtra(Intent.EXTRA_INTENT, camIntent);
pickIntent.putExtra(Intent.EXTRA_INTENT, gallIntent)
pickIntent.putExtra(Intent.EXTRA_TITLE, \"Select Source\");
startActivityForResult(pickIntent, IMAGE_SELECTOR);
But it appears I can only add one EXTRA_INTENT
. The menu show up as expected, but the only options are Gallery and Files....no Camera).
Is there a better/easier way to do this that I\'m missing? Thanks for any help.
回答1:
You'll have to create your own chooser dialog merging both intent resolution results.
To do this, you will need to query the PackageManager with PackageManager.queryIntentActivities() for both original intents and create the final list of possible Intents with one new Intent for each retrieved activity like this:
List<Intent> yourIntentsList = new ArrayList<Intent>();
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);
}
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);
}
(I wrote this directly here so this may not compile)
Then, for more info on creating a custom dialog from a list see https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog
回答2:
How to launch a single Intent to select images from either the Gallery or the Camera, or any application registered to browse the filesystem.
Rather than creating a Dialog with a list of Intent options, it is much better to use Intent.createChooser in order to get access to the graphical icons and short names of the various 'Camera', 'Gallery' and even Third Party filesystem browser apps such as 'Astro', etc.
This describes how to use the standard chooser-intent and add additional intents to that.
private Uri outputFileUri;
private void openImageIntent() {
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
root.mkdirs();
final String fname = Utils.getUniqueImageFilename();
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(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, YOUR_SELECT_PICTURE_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == YOUR_SELECT_PICTURE_REQUEST_CODE) {
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();
}
}
}
}
回答3:
I found this. Using:
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
for one of the intents shows the user the option of selecting 'documents' in Android 4, which I found very confusing. Using this instead shows the 'gallery' option:
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
回答4:
I also had this issue and what I did was create an AlertDialog and use the setItems() method along with the DialogInterface listener:
AlertDialog.Builder getImageFrom = new AlertDialog.Builder(Fotos.this);
getImageFrom.setTitle("Select:");
final CharSequence[] opsChars = {getResources().getString(R.string.takepic), getResources().getString(R.string.opengallery)};
getImageFrom.setItems(opsChars, new android.content.DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == 0){
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}else
if(which == 1){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
getResources().getString(R.string.pickgallery)), SELECT_PICTURE);
}
dialog.dismiss();
}
});
回答5:
I have merged some solutions to make a complete util for picking an image from Gallery or Camera. These are the features of ImagePicker util (also in a Github lib):
- Merged intents for Gallery and Camera resquests.
- Resize selected big images (e.g.: 2500 x 1600)
- Rotate image if necesary
Screenshot:
Edit: Here is a fragment of code to get a merged Intent for Gallery and Camera apps together. You can see the full code at ImagePicker util (also in a Github lib):
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;
}
回答6:
this code will help you, in that there is two button one for Camera and another for Gallery, and Image will be displayed in ImageView
https://github.com/siddhpuraamitr/Choose-Image-From-Gallery-Or-Camera
回答7:
For those getting error on 4.4 upward while trying to use the Image selection can use the code below.
Rather than creating a Dialog with a list of Intent options, it is much better to use Intent.createChooser in order to get access to the graphical icons and short names of the various 'Camera', 'Gallery' and even Third Party filesystem browser apps such as 'Astro', etc.
This describes how to use the standard chooser-intent and add additional intents to that.
private void openImageIntent(){
// Determine Uri of camera image to save.
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "amfb" + File.separator);
root.mkdir();
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(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[]{}));
startActivityForResult(chooserIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
final boolean isCamera;
if (data == null) {
isCamera = true;
} else {
final String action = data.getAction();
if (action == null) {
isCamera = false;
} else {
isCamera = action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
}
}
Uri selectedImageUri;
if (isCamera) {
selectedImageUri = outputFileUri;
//Bitmap factory
BitmapFactory.Options options = new BitmapFactory.Options();
// downsizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 8;
final Bitmap bitmap = BitmapFactory.decodeFile(selectedImageUri.getPath(), options);
preview.setImageBitmap(bitmap);
} else {
selectedImageUri = data == null ? null : data.getData();
Log.d("ImageURI", selectedImageUri.getLastPathSegment());
// /Bitmap factory
BitmapFactory.Options options = new BitmapFactory.Options();
// downsizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 8;
try {//Using Input Stream to get uri did the trick
InputStream input = getContentResolver().openInputStream(selectedImageUri);
final Bitmap bitmap = BitmapFactory.decodeStream(input);
preview.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
} else if (resultCode == RESULT_CANCELED){
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
}
回答8:
This should take care of Tina's null outputFileUri issue:
private static final String STORED_INSTANCE_KEY_FILE_URI = "output_file_uri";
@Override
public void onSaveInstanceState( Bundle outState ) {
super.onSaveInstanceState( outState );
if ( outputFileUri != null ) {
outState.putString( STORED_INSTANCE_KEY_FILE_URI, outputFileUri.toString() );
}
}
@Override
public void onViewStateRestored( Bundle savedInstanceState ) {
super.onViewStateRestored( savedInstanceState );
if ( savedInstanceState != null ) {
final String outputFileUriStr = savedInstanceState.getString( STORED_INSTANCE_KEY_FILE_URI );
if ( outputFileUriStr != null && !outputFileUriStr.isEmpty() ) {
outputFileUri = Uri.parse( outputFileUriStr );
}
}
}
Note: I'm using this code inside android.support.v4.app.Fragment your overridden methods might change depending on what Fragment/Activity version you're using.
回答9:
You can create option dialog
Open Camera:
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(cameraIntent, CAMERA_IMAGE);
}
Open Gallery:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, GALLARY_IMAGE);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, GALLARY_IMAGE);
}
To get selection result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == GALLARY_IMAGE) {
Uri selectedImageUri = data.getData();
String selectedImagePath = getRealPathFromURI(selectedImageUri);
} else if (requestCode == CAMERA_IMAGE) {
Bundle extras = data.getExtras();
Bitmap bmp = (Bitmap) extras.get("data");
SaveImage(bmp);
}
}
}
public String getRealPathFromURI(Uri uri) {
if (uri == null) {
return null;
}
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
Method to save captured image
private void SaveImage(final Bitmap finalBitmap) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/Captured Images/");
if (!myDir.exists())
myDir.mkdirs();
String fname = "/image-" + System.currentTimeMillis() + ".jpg";
File file = new File(myDir, fname);
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
localImagePath = myDir + fname;
} catch (Exception e) {
e.printStackTrace();
}
}
});
t.start();
}
回答10:
Resolved too big image issue and avoid to out of memory.
private static final int SELECT_PICTURE = 0;
private static final int REQUEST_CAMERA = 1;
private ImageView mImageView;
private void selectImage() {
final CharSequence[] items = {"Take Photo", "Choose from Library",
"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("Take Photo")) {
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, REQUEST_CAMERA);
} else if (items[item].equals("Choose from Library")) {
Intent intent = new Intent(
Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(
Intent.createChooser(intent, "Select File"),
SELECT_PICTURE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
File f = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bm;
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
btmapOptions.inSampleSize = 2;
bm = BitmapFactory.decodeFile(f.getAbsolutePath(),
btmapOptions);
// bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
mImageView.setImageBitmap(bm);
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "test";
f.delete();
OutputStream fOut = null;
File file = new File(path, String.valueOf(System
.currentTimeMillis()) + ".jpg");
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
String tempPath = getPath(selectedImageUri, this.getActivity());
Bitmap bm;
btmapOptions.inSampleSize = 2;
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
mImageView.setImageBitmap(bm);
}
}
}
public String getPath(Uri uri, Activity activity) {
String[] projection = {MediaStore.MediaColumns.DATA};
Cursor cursor = activity
.managedQuery(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
回答11:
Adding my solution - it will return a callback whether it is from the camera or from the galley alongside the intent:
public class ImagePickerManager extends BaseAdapter {
private List<ResolveInfo> mApplications;
private TreeSet<Integer> mImageCaptureIntents;
private TreeSet<Integer> mImagePickerIntents;
private Context mContext;
private final ImagePickerManagerListener listener;
private static enum intentType {
choosePhoto,
takePhoto,
unknown;
public int getIntValue() {
switch (this) {
case choosePhoto:
return 0;
case takePhoto:
return 1;
case unknown:
return 2;
}
return 0;
}
}
public interface ImagePickerManagerListener {
void onChooseImage(Intent intent);
void onCaptureImage(Intent intent);
}
public ImagePickerManager(Context context,ImagePickerManagerListener listenr) {
this.mContext = context;
this.listener = listenr;
mImageCaptureIntents = new TreeSet<>();
mImagePickerIntents = new TreeSet<>();
//Picking photo intent
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
mApplications = mContext.getPackageManager().queryIntentActivities(intent, 0);
int index = 0;
for (int i = 0; i < mApplications.size(); i++) {
mImagePickerIntents.add(index);
index++;
}
//Capture photo intent
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
List<ResolveInfo> resolveInfoList = mContext.getPackageManager().queryIntentActivities(intent, 0);
mApplications.addAll(resolveInfoList);
for (int i = 0; i < mApplications.size(); i++) {
mImageCaptureIntents.add(index);
index++;
}
}
public static void openChooseAndCaptureImageDialog(final Context context, final ImagePickerManagerListener listener) {
Log.d("openChooseAndCaptureImageDialog", "enter");
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final ImagePickerManager imagePickerManager = new ImagePickerManager(context,listener);
builder.setTitle(context.getString(R.string.image_picker_dialog_box_title));
builder.setAdapter(imagePickerManager, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialoginterface, int i) {
ResolveInfo resolveInfo = (ResolveInfo) imagePickerManager.getItem(i);
Intent pickerIntent = imagePickerManager.getIntentForPackage(context,resolveInfo,i);
switch (imagePickerManager.getIntentType(i)){
case choosePhoto:
listener.onChooseImage(pickerIntent);
break;
case takePhoto:
listener.onCaptureImage(pickerIntent);
break;
case unknown:
break;
}
}
});
builder.setCancelable(true);
builder.setInverseBackgroundForced(true);
AlertDialog dialog = builder.create();
dialog.show();
}
private intentType getIntentType(int index) {
if (mImageCaptureIntents.contains(index)) {
return intentType.takePhoto;
} else if(mImagePickerIntents.contains(index)) {
return intentType.choosePhoto;
}
return intentType.unknown;
}
private Intent getIntentForPackage(Context context, ResolveInfo info,int index) {
Intent intent = context.getPackageManager().getLaunchIntentForPackage(info.activityInfo.packageName);
ComponentName chosenName = new ComponentName(
info.activityInfo.packageName,
info.activityInfo.name);
intent.setComponent(chosenName);
intent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
if (mImageCaptureIntents.contains(index)) {
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
} else if(mImagePickerIntents.contains(index)) {
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
}
return intent;
}
@Override
public int getCount() {
return mApplications.size();
}
@Override
public Object getItem(int position) {
return mApplications.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ResolveInfo item = mApplications.get(position);
if (convertView == null) {
TextView applicationTextView = new TextView(mContext);
LayoutParams param = new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
applicationTextView.setLayoutParams(param);
final int horizontalPadding = (int) FVRGeneralUtils.convertDpToPx(mContext, 15);
final int verticalPadding = (int) FVRGeneralUtils.convertDpToPx(mContext, 5);
applicationTextView.setPadding(horizontalPadding,verticalPadding, horizontalPadding, verticalPadding);
applicationTextView.setGravity(android.view.Gravity.CENTER_VERTICAL);
Resources.Theme th = mContext.getTheme();
TypedValue tv = new TypedValue();
if (th.resolveAttribute(android.R.attr.textAppearanceMedium, tv, true)) {
applicationTextView.setTextAppearance(mContext, tv.resourceId);
}
applicationTextView.setMinHeight((int) FVRGeneralUtils.convertDpToPx(mContext, 25));
applicationTextView.setCompoundDrawablePadding((int) FVRGeneralUtils.convertDpToPx(mContext, 7));
convertView = applicationTextView;
}
TextView textView = (TextView) convertView;
textView.setText(item.loadLabel(mContext.getPackageManager()));
textView.setCompoundDrawablesWithIntrinsicBounds(item.loadIcon(mContext.getPackageManager()), null, null, null);
return textView;
} }
回答12:
You can try this :
To open Gallery :
private void browseImage() {
try {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, GALLERY_IMAGE_PICK); //GALLERY_IMAGE_PICK it is a string
} catch (Exception e) {}
}
To open Camera :
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
回答13:
This is simple by using AlertDialog and Intent.ACTION_PICK
//camOption is a string array contains two items (Camera, Gallery)
AlertDialog.Builder builder = new AlertDialog.Builder(CarPhotos.this);
builder.setTitle(R.string.selectSource)
.setItems(R.array.imgOption, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
if (which==0) {
Intent intent = new Intent(this, CameraActivity.class);
startActivityForResult(intent, REQ_CAMERA_IMAGE); }
if (which==1) {
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
}
}
});
builder.create();
builder.show();
回答14:
Building upon David's answer, my two pennies on the onActivityResult()
part. It takes care of the changes introduced in 5.1.1 and detects whether the user has picked a single or multiple image from the library.
private enum Outcome {
camera, singleLibrary, multipleLibrary, unknown
}
/**
* Returns a List<Uri> containing the image uri(s) chosen by the user
*
* @param data The data intent coming from the onActivityResult()
* @param cameraUri The uri that had been passed to the intent when the chooser was invoked.
* @return A List<Uri>, never null.
*/
public List<Uri> getPicturesUriFromIntent(Intent data, Uri cameraUri) {
Outcome outcome = Outcome.unknown;
if (data == null || (data.getData() == null && data.getClipData() == null)) {
outcome = Outcome.camera;
} else if (data.getData() != null && data.getClipData() == null) {
outcome = Outcome.singleLibrary;
} else if (data.getData() == null) {
outcome = Outcome.multipleLibrary;
} else {
final String action = data.getAction();
if (action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
outcome = Outcome.camera;
}
}
// list the uri(s) we got back
List<Uri> uris = new ArrayList<>();
switch (outcome) {
case camera:
uris.add(cameraUri);
break;
case singleLibrary:
uris.add(data.getData());
break;
case multipleLibrary:
final ClipData clipData = data.getClipData();
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
uris.add(item.getUri());
}
break;
}
return uris;
}
回答15:
Try this way
final CharSequence[] items = { "Take Photo", "Choose from Library",
"Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
if (items[item].equals("Take Photo")) {
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, REQUEST_CAMERA);
} else if (items[item].equals("Choose from Library")) {
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(
Intent.createChooser(intent, "Select File"),
SELECT_FILE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
Then create onactivityresult method and do something like this
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
File f = new File(Environment.getExternalStorageDirectory()
.toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
Bitmap bm;
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(f.getAbsolutePath(),
btmapOptions);
// bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
ivImage.setImageBitmap(bm);
String path = android.os.Environment
.getExternalStorageDirectory()
+ File.separator
+ "Phoenix" + File.separator + "default";
f.delete();
OutputStream fOut = null;
File file = new File(path, String.valueOf(System
.currentTimeMillis()) + ".jpg");
try {
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == SELECT_FILE) {
Uri selectedImageUri = data.getData();
String tempPath = getPath(selectedImageUri, MainActivity.this);
Bitmap bm;
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
ivImage.setImageBitmap(bm);
}
}
}
See this http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample
回答16:
As per David Manpearl answer
https://stackoverflow.com/a/12347567/7226732
we just need to modify onActivityResult() like
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == YOUR_SELECT_PICTURE_REQUEST_CODE) {
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 = fileUri;
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
Toast.makeText(CreateWaterType.this, "Image Saved!", Toast.LENGTH_SHORT).show();
image_view.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(CreateWaterType.this, "Failed!", Toast.LENGTH_SHORT).show();
}
} else {
selectedImageUri = data == null ? null : data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
Toast.makeText(CreateWaterType.this, "Image Saved!", Toast.LENGTH_SHORT).show();
image_view.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(CreateWaterType.this, "Failed!", Toast.LENGTH_SHORT).show();
}
}
}
}
}
and set the capture or pick images in image view.
回答17:
Selecting camera or gallery for image in Android
I had worked hard on Camera or gallery Image Selection, and created some util class for this work. With the use of these class 'Selecting image camera or gallery is too easy' it just took 5-10 mints of your development.
Step-1: Add these classes in your code.
ImagePickerUtils :- http://www.codesend.com/view/f8f7c637716bf1c693d1490635ed49b3/
BitmapUtils :- http://www.codesend.com/view/81c1c2a3f39f1f7e627f01f67be282cf/
ConvertUriToFilePath :- http://www.codesend.com/view/f4668a29860235dd1b66eb419c5a58b5/
MediaUtils :- https://codeshare.io/5vKEMl
We need to Add these Permission in menifest :
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
This class function (checkAndRequestPermissions) auto check the permission in Android-Marshmallow and Android - Nougat.
Step-2. Calling camera class for launching camera intent :
//Create a global veriable .
private Uri mCameraUri;
private static final int CAMERA_REQUEST_CODE = 100;
// Call this function when you wants to select or capture an Image.
mCameraUri = ImagePickerUtils.createTakePictureIntent(this, CAMERA_REQUEST_CODE);
Step-3: Add onActivityResult in your Activity for receiving data from Intent
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Uri fileUri = ImagePickerUtils.getFileUriOfImage(this, data, mCameraUri);
try {
Bitmap bitmap = null;
if (CAMERA_REQUEST_CODE == requestCode) {
bitmap = new BitmapUtils().getDownsampledBitmap(this, fileUri, imageView.getWidth(), imageView.getHeight());
}
if (bitmap != null)
imageView.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I hope it helps you, If any one having any suggestion to improve these class please add your review in comments.
来源:https://stackoverflow.com/questions/4455558/allow-user-to-select-camera-or-gallery-for-image