我想让用户从相机或设备中的现有图片(图库或其他)拍摄照片。我怎么能这样做?
我已经实现了下面的解决方案,这似乎工作正常,但文档很混乱,所以我想知道是否有更好的解决方案。
另外,请查看此相关帖子。在那里,您将看到如何获取图像路径或位图:Get/pick an image from Android's built-in Gallery app programmatically
因此,在我的解决方案中,您将创建一个TakePictureHelper
对象并执行以下操作。
假设您显示一个对话框,用户可以选择“相机”或“其他”。当用户选择一个选项时,您可以拨打takeFromCamera()
或takeFromOther()
。拍摄(或不拍摄)照片时,将调用onActivityResult()
方法。在那里你会调用retrievePicture
,它会返回图片的Uri,如果没有拍照,则为null。
如果我不清楚,请告诉我你的想法,分享想法或问我任何事情。
非常感谢!
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";
}
}
答案 0 :(得分:4)
基于@ yurezcv的回答,这是我想出的(最重要的是如何在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);
}
}
}
}
答案 1 :(得分:3)
此解决方案适用于我:
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);
}
它创建了一个意图对话框,其中包含来自摄像机,文件系统等的所选图像的所有可能变体。
答案 2 :(得分:1)
在您的布局中创建一个按钮(通过单击此按钮将打开一个对话框,您可以在其中选择是否选择相机或广场)。
现在初始化其类中的按钮:
- 在onCreate之前:
Button btu;
- 在onCreate中:
btu = (Button) findViewById(R.id.BtUp);
方法调用相机和图库
- 在onCreate启动之前
int CAMERA_REQUEST = 1;
- 方法调用相机
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);
}
- 方法调用库
public void callGallery() {
Intent intent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent,0);
}
创建一个显示AlertDialog的方法,该方法似乎选择:
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();
}
按钮
中调用AlertDialogbtu.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());
}
});
AndroidManifest.xml内部
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
答案 3 :(得分:1)
我找到了一种更好,更简单的方法从相机或画廊拍照,即使用此库https://android-arsenal.com/details/1/3623
您可以点击上面的链接或按以下步骤操作:
在项目中使用此库的步骤是:
向Gradle添加依赖项:
编译'com.frosquivel:magicalcamera:4.4'
实施代码:
PermissionGranted permissionGranted = new PermissionGranted(this); MagicalCamera magicalCamera = new MagicalCamera(this,permissionGranted); //参数this是当前活动 //拍摄照片的权限,如果用户检查拒绝,则为false permissionGranted.checkCameraPermission(); //用于在设备内存中搜索和写入照片 //正常或SD内存 permissionGranted.checkReadExternalPermission(); permissionGranted.checkWriteExternalPermission();
致电从相机拍照:
magicalCamera.takePhoto();
致电从图库中选择照片:
magicalCamera.selectedPicture( “my_header_name”);
覆盖OnActivityResult();获取位图和路径的方法:
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,“照片保存在设备中,请检查此路径:”+ path,Toast.LENGTH_SHORT).show(); }其他{ Toast.makeText(MainActivity.this,“抱歉你的照片不要写在devide,请联系fabian7593 @gmail并说出这个错误”,Toast.LENGTH_SHORT).show(); } }
有关详细信息,请参阅上面的链接