Android相机意图后崩溃

我已经发布了一个应用程序,其中一个基本function是允许用户拍照,然后将该照片保存在其外部存储上的特定文件夹中。

一切似乎工作正常,但我现在得到了两个报告,声称拍照后,点击“完成”退出相机(并返回到活动),该应用程序是强制closures,使用户回到主屏幕。

这发生在三星Nexus S和Galaxy Tab上。 下面我已经发布了我的代码来显示我设置我的意图,以及如何处理保存并显示onActivityResult()中的照片。 任何指导什么可能会导致它在点击“完成”后退出相机应用程序崩溃,将不胜感激!

再一次,这似乎在大多数设备上工作正常,但我想知道如果他们是一个更有效的,我应该采取的普遍的方法。 谢谢

我如何发射相机的意图

case ACTION_BAR_CAMERA: // numbered image name fileName = "image_" + String.valueOf(numImages) + ".jpg"; output = new File(direct + File.separator + fileName); // create // output while (output.exists()) { // while the file exists numImages++; // increment number of images fileName = "image_" + String.valueOf(numImages) + ".jpg"; output = new File(outputFolder, fileName); } camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); uriSavedImage = Uri.fromFile(output); // get Uri of the output camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); //pass in Uri to camera intent startActivityForResult(camera, 1); break; default: return super.onHandleActionBarItemClick(item, position); } return true; } 

我如何设置onActivityResult()

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { // If data was passed successfully Bundle extras = data.getExtras(); //Bundle extras = data.getBundleExtra(MediaStore.EXTRA_OUTPUT); /*ad = new AlertDialog.Builder(this).create(); ad.setIcon(android.R.drawable.ic_menu_camera); ad.setTitle("Save Image"); ad.setMessage("Save This Image To Album?"); ad.setButton("Ok", this); ad.show();*/ bmp = (Bitmap) extras.get("data"); // Set the bitmap to the bundle // of data that was just // received image.setImageBitmap(bmp); // Set imageview to image that was // captured image.setScaleType(ScaleType.FIT_XY); } } 

Solutions Collecting From Web of "Android相机意图后崩溃"

首先让我们弄清楚 – 我们有两个选项可以在Camera的onActivityResult中获取图像数据:

1. 通过传递您想要保存的图像的确切位置Uri来启动相机。

2. 刚开始相机不通过任何Loaction Uri。


1。 第一种情况:

启动相机通过传递图像Uri你想保存的地方:

 String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg"; File imageFile = new File(imageFilePath); Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri Intent it = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); it.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri); startActivityForResult(it, CAMERA_RESULT); 

在onActivityResult接收图像为:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (RESULT_OK == resultCode) { iv = (ImageView) findViewById(R.id.ReturnedImageView); // Decode it for real BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); bmpFactoryOptions.inJustDecodeBounds = false; //imageFilePath image path which you pass with intent Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions); // Display it iv.setImageBitmap(bmp); } } 

2。 第二种情况:

启动相机不传递图像Uri,如果你想以意图(数据)接收图像:

 Intent it = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(it, CAMERA_RESULT); 

在onActivityResult recive图像为:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (RESULT_OK == resultCode) { // Get Extra from the intent Bundle extras = data.getExtras(); // Get the returned image from extra Bitmap bmp = (Bitmap) extras.get("data"); iv = (ImageView) findViewById(R.id.ReturnedImageView); iv.setImageBitmap(bmp); } } 


*****快乐编码!!!! *****

在相机button点击事件你可以试试这个:

 final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(this))); startActivityForResult(intent, TAKE_PHOTO_CODE); declare TAKE_PHOTO_CODE globally as: private static final int TAKE_PHOTO_CODE = 1; 

在代码中添加getTempFile函数,这将有助于将名为myImage.png的图像保存在名为应用程序包名称的文件夹下的sdcard中。

 private File getTempFile(Context context) { final File path = new File(Environment.getExternalStorageDirectory(), context.getPackageName()); if (!path.exists()) { path.mkdir(); } return new File(path, "myImage.png"); } 

现在OnActivityResult函数添加这个:

 if (requestCode == TAKE_PHOTO_CODE) { final File file = getTempFile(this); try { Uri uri = Uri.fromFile(file); Bitmap captureBmp = Media.getBitmap(getContentResolver(), uri); image.setImageBitmap(captureBmp); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } 

如果您遇到内存问题,请添加以下代码:

 @Override protected void onPause() { image.setImageURI(null); super.onPause(); } 

我希望这能帮到您

我怀疑3个可能的问题可能导致你的问题:

  1. 有些设备在调用extras.get("data");时返回null extras.get("data");onActivityResult方法,所以你的问题可能是一个NullPointerException 。 为了解决这个问题,你需要传递确切的URI位置来告诉相机应用程序在哪里存储,并在onActivityResult使用它来检索图像的Bitmap

  2. extras.get("data");其他设备返回一个完整大小的Bitmap extras.get("data");onActivityResult 。 如果位图太大,可能会导致OutOfMemmoryError ,所以也许你需要以更小的尺寸解码你的图像,以免占用太多的内存堆。 这两个链接可以帮助你在这种情况下:

    http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

    BitmapFactory OOM驱使我坚果

  3. 也许你的活动被GC销毁,所以你必须使用onSavedInstanceStateonRestoreInstanceState来保存你的Activity的数据。 看到这个以前的post的答案更多的信息。

我不知道你们是否已经处理了这些问题。

希望帮助:)

首先,请确保检查请求代码,您可能会在那里捕获其他人的结果。 其次,不要使用意图的数据位图 – 如果有的话,它是小的,但是因为你提供了存储捕获图像的path,它甚至不应该在那里(见这里 )。 因此,将您提供的url存储为输出文件path,并在您收到RESULT_OK请求时从中读取Bitmap:

  ... // save your file uri, not necessarily static mUriSavedImage = Uri.fromFile(output); startActivityForResult(camera, MY_REQUEST_CODE); /* Make a String like "com.myname.MY_REQUEST_CODE" and hash it into int to give it a bit of uniqueness */ } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == MY_REQUEST_CODE) { if (resultCode == RESULT_OK) { Bitmap bmp = BitmapFactory.decodeFile(mUriSavedImage); if (bmp != null) { image.setImageBitmap(bmp); // Set imageview to image that was // captured image.setScaleType(ScaleType.FIT_XY); } else { Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show(); } } } else { super.onActivityResult(requestCode, resultCode, data); } } 

我面临同样的问题。 显然,解决的办法是使uriSavedImage静态。 不知道这是否是最好的方法。 但是这对我有用。

按照此链接给出的步骤。 希望这对你有用。

要么

在不破坏的情况下提取图像

MainActivity中写下面的代码

 // Storage for camera image URI components private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath"; private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI"; // Required for camera operations in order to save the image file on resume. private String mCurrentPhotoPath = null; private Uri mCapturedImageURI = null; @Override public void onSaveInstanceState(Bundle savedInstanceState) { if (mCurrentPhotoPath != null) { savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath); } if (mCapturedImageURI != null) { savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString()); } super.onSaveInstanceState(savedInstanceState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) { mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY); } if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) { mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY)); } super.onRestoreInstanceState(savedInstanceState); } 

你好,我所知道的答案已经给出,但因为这也是我find的最简单的解决scheme之一

这是这个设备自我打扰的例子!

AndroidCameraUtils – 下载项目并从库项目下面包含它是您可以使用的代码片段!

如果你想使用它,你可以使用它来创build一个新的CameraIntentHelper(这个新的CameraIntentHelperCallback(){@Override public void onPhotoUriFound(Date dateCameraIntentStarted,Uri photoUri,int rotateXDegrees){messageView.setText(getString(R.string.activity_camera_intent_photo_uri_found)+ photoUri.toString ());

  Bitmap photo = BitmapHelper.readBitmap(CameraIntentActivity.this, photoUri); if (photo != null) { photo = BitmapHelper.shrinkBitmap(photo, 300, rotateXDegrees); ImageView imageView = (ImageView) findViewById(de.ecotastic.android.camerautil.sample.R.id.activity_camera_intent_image_view); imageView.setImageBitmap(photo); } } @Override public void deletePhotoWithUri(Uri photoUri) { BitmapHelper.deleteImageWithUriIfExists(photoUri, CameraIntentActivity.this); } @Override public void onSdCardNotMounted() { Toast.makeText(getApplicationContext(), getString(R.string.error_sd_card_not_mounted), Toast.LENGTH_LONG).show(); } @Override public void onCanceled() { Toast.makeText(getApplicationContext(), getString(R.string.warning_camera_intent_canceled), Toast.LENGTH_LONG).show(); } @Override public void onCouldNotTakePhoto() { Toast.makeText(getApplicationContext(), getString(R.string.error_could_not_take_photo), Toast.LENGTH_LONG).show(); } @Override public void onPhotoUriNotFound() { messageView.setText(getString(R.string.activity_camera_intent_photo_uri_not_found)); } @Override public void logException(Exception e) { Toast.makeText(getApplicationContext(), getString(R.string.error_sth_went_wrong), Toast.LENGTH_LONG).show(); Log.d(getClass().getName(), e.getMessage()); } }); 

}

 @Override protected void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); mCameraIntentHelper.onSaveInstanceState(savedInstanceState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mCameraIntentHelper.onRestoreInstanceState(savedInstanceState); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); mCameraIntentHelper.onActivityResult(requestCode, resultCode, intent); } } 

: – 我尝试了很多相机应用程序的例子,当然还有另一种方法来处理它,但对于初学者和不太熟悉核心概念的人来说,这个项目会更加舒适。 谢谢!