Android在相机Intent之后崩溃

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

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

这发生在Samsung 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在相机Intent之后崩溃"

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

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

2. Just Start Camera不传递任何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。 在第二种情况下:

如果要在Intent(数据)中接收图像,请启动相机而不传递图像Uri:

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

在onActivityResult中将图像恢复为:

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


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

在相机按钮单击事件,您可以尝试这样做:

 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函数,这将有助于保存您在名为app的包名称的文件夹下的sdcard中单击的名为myImage.png的图像。

 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的数据。 有关更多信息,请参阅上一篇文章的答案。

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

希望有所帮助:)

首先,确保检查请求代码,您可能会在那里捕获其他人的结果。 其次,不要使用意图的数据Bitmap – 如果有的话,它很小,但由于你提供了存储捕获图像的路径,它甚至不应该存在(见这里 )。 因此,当您收到RESULT_OK请求时,将您提供的URL存储为输出文件路径并从那里读取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的最简单的解决方案之一

这是一个关于设备自我烦恼的例子!

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

private void setupCameraIntentHelper(){mCameraIntentHelper = new CameraIntentHelper(this,new 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); } } 

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