可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using intent to launch camera:
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
getParent().startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
and using:
Bitmap thumbnail = (Bitmap) data.getExtras().get(\"data\");
photoImage.setImageBitmap(thumbnail);
photoImage.setVisibility(View.VISIBLE);
But it is only a thumbnail, how do I get the full bitmap? I know I can use my own Activity and use:
Camera.PictureCallback()
But is there anyway to do it using Intent?
Thanks!
edit:
I also tried:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri uri = data.getData();
imageView.setImageURI(uri);
}
It works for photo selected from gallery, but for camera intent, data.getData() returns null.
回答1:
To get full sized camera image you should point camera to save picture in temporary file, like:
private URI mImageUri;
Intent intent = new Intent(\"android.media.action.IMAGE_CAPTURE\");
File photo;
try
{
// place where to store camera taken picture
photo = this.createTemporaryFile(\"picture\", \".jpg\");
photo.delete();
}
catch(Exception e)
{
Log.v(TAG, \"Can\'t create file to take picture!\");
Toast.makeText(activity, \"Please check SD card! Image shot is impossible!\", 10000);
return false;
}
mImageUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
//start camera intent
activity.startActivityForResult(this, intent, MenuShootImage);
private File createTemporaryFile(String part, String ext) throws Exception
{
File tempDir= Environment.getExternalStorageDirectory();
tempDir=new File(tempDir.getAbsolutePath()+\"/.temp/\");
if(!tempDir.exists())
{
tempDir.mkdirs();
}
return File.createTempFile(part, ext, tempDir);
}
Then after image capture intent finished to work - just grab your picture from imageUri
using following code:
public void grabImage(ImageView imageView)
{
this.getContentResolver().notifyChange(mImageUri, null);
ContentResolver cr = this.getContentResolver();
Bitmap bitmap;
try
{
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
imageView.setImageBitmap(bitmap);
}
catch (Exception e)
{
Toast.makeText(this, \"Failed to load\", Toast.LENGTH_SHORT).show();
Log.d(TAG, \"Failed to load\", e);
}
}
//called after camera intent finished
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
//MenuShootImage is user defined menu option to shoot image
if(requestCode==MenuShootImage && resultCode==RESULT_OK)
{
ImageView imageView;
//... some code to inflate/create/find appropriate ImageView to place grabbed image
this.grabImage(imageView);
}
super.onActivityResult(requestCode, resultCode, intent);
}
P.S. Code need to be revised with respect to new security restriction applied in Android M - FileProvider: mImageUri
has to be packed with FileProvider
回答2:
Open Camera and save image into some specific directory
private String pictureImagePath = \"\";
private void openBackCamera() {
String timeStamp = new SimpleDateFormat(\"yyyyMMdd_HHmmss\").format(new Date());
String imageFileName = timeStamp + \".jpg\";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
pictureImagePath = storageDir.getAbsolutePath() + \"/\" + imageFileName;
File file = new File(pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, 1);
}
Handle Image
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
File imgFile = new File(pictureImagePath);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.imageviewTest);
myImage.setImageBitmap(myBitmap);
}
}
}
回答3:
Even though this is an old question and it has an accepted answer,
I would like to share my solution.
In this case you don\'t have to create a temporary file.
Additionally we creating a chooser which offers to user both: take a picture with the camera or pick an existing one from a gallery.
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, galleryIntent);
chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.chooseaction));
Intent[] intentArray = {cameraIntent};
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooser, RESULT_LOAD_IMAGE);
and here we retrieving results:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// todo use appropriate resultCode in your case
if (requestCode == RESULT_LOAD_IMAGE && resultCode == FragmentActivity.RESULT_OK) {
if (data.getData() != null) {
// this case will occur in case of picking image from the Gallery,
// but not when taking picture with a camera
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
// do whatever you want with the Bitmap ....
} catch (IOException e) {
e.printStackTrace();
}
} else {
// this case will occur when taking a picture with a camera
Bitmap bitmap = null;
Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.ImageColumns.ORIENTATION}, MediaStore.Images.Media.DATE_ADDED,
null, \"date_added DESC\");
if (cursor != null && cursor.moveToFirst()) {
Uri uri = Uri.parse(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
String photoPath = uri.toString();
cursor.close();
if (photoPath != null) {
bitmap = BitmapFactory.decodeFile(photoPath);
}
}
if (bitmap == null) {
// for safety reasons you can
// use thumbnail if not retrieved full sized image
bitmap = (Bitmap) data.getExtras().get(\"data\");
}
// do whatever you want with the Bitmap ....
}
super.onActivityResult(requestCode, resultCode, data);
}
}
回答4:
I also used the answer from Vicky but I had to save the uri to a bundle to avoid loss of it on orientation change. So if you don\'t get a result from your intent after tilting the device it might be because your uri did not survive the orientation change.
static final int CAMERA_CAPTURE_REQUEST = 1;
static final String ARG_CURRENT_PIC_URI = \"CURRENT_PIC_URI\";
String pictureImagePath = folderName + \"/\" + imageFileName;
File file = new File(Environment.getExternalStorageDirectory(), pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);
mCurrentPicUri = outputFileUri.getPath();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST);
Activity Result code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_CAPTURE_REQUEST && resultCode == Activity.RESULT_OK)
{
File imgFile = new File(mCurrentPicUri);
// do something with your image
// delete uri
mCurrentPicUri = \"\";
}
}
save the uri to the bundle:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save uri to bundle
outState.putString(ARG_CURRENT_PIC_URI, mCurrentPicUri);
}
retrieve it from your saved bundle during on create:
if (bundle.containsKey(ARG_CURRENT_PIC_URI))
mCurrentPicUri = bundle.getString(ARG_CURRENT_PIC_URI);
回答5:
To capture maximum picture size from camera, i hope these simple steps will be quite useful
public static Camera mCamera;
Camera.Parameters parameters = mCamera.getParameters();
parameters.getSupportedPictureSizes();
List<Camera.Size> supportedSizes = parameters.getSupportedPictureSizes();
mSizePicture1 = supportedSizes.get(0);
int cameraSize = supportedSizes.size();
mSizePicture2 = supportedSizes.get(cameraSize - 1);
if (mSizePicture1.height < mSizePicture2.height)
mSizePicture = supportedSizes.get(cameraSize - 1);
else
mSizePicture = supportedSizes.get(0);
parameters.setPictureSize(mSizePicture.width, mSizePicture.height);
Here, the supported size of the each mobile is taken, from that which size is maximum that is fixed as picture size to capture.
回答6:
Don\'t use onActivityResult
\'s data. It took me many hours to test different solutions. A camera saves a picture (even if you don\'t set permissions for camera and card reading in AndroidManifest), but then onActivityResult
returns data == null
and MediaStore
returns wrong path. In these solutions you simply get last gallery image, not your photo.
private Uri photoUri;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
...
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_RESULT) {
if (resultCode == RESULT_OK) {
if (photoUri != null) {
image.setImageURI(photoUri);
}
}
}
}
private void showCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
File file = null;
try {
file = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
photoUri = null;
if (file != null) {
photoUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intent, CAMERA_REQUEST);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat(\"yyyyMMdd_HHmmss\").format(new Date());
File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
// File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(timeStamp, \".jpg\", storageDir);
}