允许用户为图像选择相机或画廊

我想要做的事情看起来很简单,但是经过几天的寻找,我还是不太明白。

我有一个应用程序,允许用户选择多个(最多5)图像。我用的是 ImageView。当用户单击 ImageView时,我希望允许他们选择

  1. 从图库中选择图像,或者
  2. 使用相机捕捉图像。

我从使用 ACTION_GET_CONTENT意图开始,这对于到达画廊非常有效。因此,我尝试使用 ACTION_PICK_ACTIVITY意图允许用户选择相机或画廊:

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);

但看来我只能加一个 EXTRA_INTENT。菜单显示如预期,但唯一的选项是画廊和文件... . 没有照相机)。

有没有更好更简单的方法来解决这个问题? 谢谢你的帮助。

121706 次浏览

您必须创建自己的选择器对话框,合并两个意图解析结果。

要做到这一点,您需要使用 Query 意图活动()查询 PackageManager 以获得两个原始意图,并为每个检索到的活动创建一个可能意图的最终列表,如下所示:

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);
}

(我直接在这里写的,所以这可能无法编译)

然后,有关从列表创建自定义对话框的更多信息,请参见 https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog

我也有这个问题,我所做的就是创建一个 AlertDialog 并使用 setItems ()方法和 DialogInterface 侦听器:

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();
}
});

如何启动一个单独的意图,从 Gallery 或 Camera 中选择图像,或者从任何注册用于浏览文件系统的应用程序中选择图像。

与其创建一个包含一系列意图选项的对话框,不如使用 Inent.createChooser 来获取各种“ Camera”、“ Gallery”甚至第三方文件系统浏览器应用程序(如“ Astro”等)的图形图标和简称。

这描述了如何使用标准的选择器意图并向其添加其他意图。

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();
}
}
}
}

我找到了 这个使用:

galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

因为其中一个意图向用户显示了在 Android 4中选择“文档”的选项,这让我感到非常困惑。用这个代替显示“画廊”选项:

Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

通过使用 AlertDialog 和 Inent.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();

添加我的解决方案-它将返回一个回调,无论它是从相机还是厨房旁边的意图:

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;
} }

这应该可以解决 Tina 的 null outputFileUri 问题:

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 );
}
}
}

注意: 我在 android.Support.v4.app 中使用这段代码。根据所使用的片段/活动版本,重写的方法可能会发生变化。

对于那些在4.4向上得到错误,而试图使用图像选择可以使用下面的代码。

与其创建一个包含一系列意图选项的对话框,不如使用 Inent.createChooser 来获取各种“ Camera”、“ Gallery”甚至第三方文件系统浏览器应用程序(如“ Astro”等)的图形图标和简称。

这描述了如何使用标准的选择器意图并向其添加其他意图。

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();
}
}

解决了过大的图像问题,避免了内存不足。

    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);
}

基于大卫的回答,我在 onActivityResult()上的两分钱。它处理5.1.1中引入的更改,并检测用户是否从库中选择了单个或多个图像。

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;
}

我已经合并了一些解决方案,使一个完整的直到从画廊或相机选择一个图像。以下是 选图软件(也是 Github lib)的特点:

  • 图库和相机请求的合并意图。
  • 调整所选大图像的大小(例如: 2500 x 1600)
  • 必要时旋转图像

截图:

ImagePicker starting intent

编辑 : 下面是一段代码片段,用于合并画廊和照相机应用程序的意图。 你可以看到完整的代码在 选图软件(也在一个 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;
}

你可以试试这个:

打开画廊:

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) {}
}

打开相机:

 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);


}

您可以创建选项对话框

开放式相机:

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);
}

公开展览厅:

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);
}

得到选拔结果

@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();
}

方法保存捕获的图像

 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();


}

试试这边

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();

然后创建 onactivityresult 方法并执行类似的操作

@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);
}
}
}

看这个 http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample

在 Android 中为图像选择相机或图库

我在 相机或画廊图像选择上下了很大的功夫,并且为这个作品创造了一些直到类。 使用这些类 选择图像相机或画廊太容易了 只花了你5-10分钟的时间。

步骤1: 在代码中添加这些类。

返回文章页面 http://www.codesend.com/view/f8f7c637716bf1c693d1490635ed49b3/

BitmapUtils:- Http://www.codesend.com/view/81c1c2a3f39f1f7e627f01f67be282cf/

ConvertUriToFilePath:- Http://www.codesend.com/view/f4668a29860235dd1b66eb419c5a58b5/

MediaUtils:- < a href = “ https://codeshare.io/5vKEMl”rel = “ nofollow norefrer”> https://codeshare.io/5vkeml

我们需要在清单中加入这些许可:

  <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" />

这是 Android-Marshmallow 的 类函数(checkAndRequestPermission)自动检查权限和 Android-Nougat。

第二步: 调用相机类来启动相机意图:

 //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);

步骤3: 在活动中添加 onActivityResult,用于接收来自意图的数据

    @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();
}
}
}

我希望它能帮助你,如果任何人有任何建议,以改善这些类请添加您的评论。

根据大卫 · 曼珀尔的回答
Https://stackoverflow.com/a/12347567/7226732

我们只需要修改 OnActivityResult ()

 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.getExtras() == 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();
}
}
}
}
}

并在图像视图中设置捕获或拾取图像。