MediaStore.EXTRA_OUTPUT 呈现数据为空,其他保存照片的方式?
Posted
技术标签:
【中文标题】MediaStore.EXTRA_OUTPUT 呈现数据为空,其他保存照片的方式?【英文标题】:MediaStore.EXTRA_OUTPUT renders data null, other way to save photos? 【发布时间】:2013-04-27 06:11:09 【问题描述】:Google 提供了这种通过意图拍照的通用代码:
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
问题是,如果你像我一样,想将照片作为附加信息传递,使用EXTRA_OUTPUT
似乎会丢失照片数据,并使后续操作认为意图数据为空。
It appears 这是 android 的一个大错误。
我正在尝试拍照,然后在新视图中将其显示为缩略图。我想将它保存为用户画廊中的全尺寸图像。有谁知道不使用EXTRA_OUTPUT
来指定图像位置的方法?
这是我目前拥有的:
public void takePhoto(View view)
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
// takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type)
return Uri.fromFile(getOutputMediaFile(type));
/** Create a File for saving an image or video */
@SuppressLint("SimpleDateFormat")
private static File getOutputMediaFile(int type)
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "JoshuaTree");
if (! mediaStorageDir.exists())
if (! mediaStorageDir.mkdirs())
Log.d("JoshuaTree", "failed to create directory");
return null;
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE)
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
else
return null;
return mediaFile;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == CAMERA_REQUEST_CODE)
if (resultCode == RESULT_OK)
handleSmallCameraPhoto(data);
private void handleSmallCameraPhoto(Intent intent)
Bundle extras = intent.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
Intent displayIntent = new Intent(this, DisplayPhotoActivity.class);
displayIntent.putExtra("BitmapImage", mImageBitmap);
startActivity(displayIntent);
【问题讨论】:
试试这个 takePictureIntent.putExtra("return-data", true); @JRowan 没有保存的迹象:| 让 mediaFile 对你的班级来说是全局的,或者如果你愿意的话甚至是静态的,那么你将始终准备好该文件 您是否设置了写入外部存储的权限? 【参考方案1】:如果您指定了 MediaStore.EXTRA_OUTPUT,则拍摄的图像将被写入该路径,并且不会向 onActivityResult 提供任何数据。您可以从您指定的内容中读取图像。
在此处查看另一个已解决的相同问题:Android Camera : data intent returns null
【讨论】:
这很好,但 EXTRA_OUTPUT 只是阻止相机在我的应用程序中拍照。我希望他们只是扔掉整个相机库并尽快编写一个新的。 只需添加路径必须以目录结尾。如果您尝试指定图片.jpg 之类的文件,它将在内部崩溃并拒绝确认您在相机中单击 ACCEPT_PICTURE 按钮。 另外,API 21 中提供了 Camera2,所以我们很快就不必再处理所有这些晦涩难懂的东西了! 是的,你是对的。但是文档告诉我们 getData 应该返回图像的 URI。 developer.android.com/guide/topics/media/… 实际上在某些设备(例如摩托罗拉 razr)中,您可以取回数据。【参考方案2】:基本上,有两种方法可以从相机中检索图像,如果您使用通过意图附加功能发送捕获的图像,则无法在 ActivityResult on intent.getData() '上检索它,因为它通过附加功能保存图像数据。
所以这个想法是:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
并在 ActivityResults 上检索它,检查检索到的意图:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
if (resultCode == RESULT_OK)
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
if (intent.getData() != null)
ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(intent.getData(), "r");
FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
parcelFileDescriptor.close();
else
Bitmap imageRetrieved = (Bitmap) intent.getExtras().get("data");
【讨论】:
但是当我使用文件输出流保存照片时,图像位图旋转了 270 度。 有一个错字: ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(intent.getData()), "r") "getData()"后面多了一个括号 谢谢@RodrigoBorba 非常感谢。我尝试了 intent.data 而不是 intent.extras.get("data")【参考方案3】:您可以通过以下方式实现您想要的:
public void onClick(View v)
switch(v.getId())
case R.id.iBCamera:
File image = new File(appFolderCheckandCreate(), "img" + getTimeStamp() + ".jpg");
Uri uriSavedImage = Uri.fromFile(image);
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
i.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
i.putExtra("return-data", true);
startActivityForResult(i, CAMERA_RESULT);
break;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode)
case CAMERA_RESULT:
if(resultCode==RESULT_OK)
handleSmallCameraPhoto(uriSavedImage);
break;
private void handleSmallCameraPhoto(Uri uri)
Bitmap bmp=null;
try
bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
catch (FileNotFoundException e)
e.printStackTrace();
Intent displayIntent = new Intent(this, DisplayPhotoActivity.class);
displayIntent.putExtra("BitmapImage", bmp);
startActivity(displayIntent);
private String appFolderCheckandCreate()
String appFolderPath="";
File externalStorage = Environment.getExternalStorageDirectory();
if (externalStorage.canWrite())
appFolderPath = externalStorage.getAbsolutePath() + "/MyApp";
File dir = new File(appFolderPath);
if (!dir.exists())
dir.mkdirs();
else
showToast(" Storage media not found or is full ! ");
return appFolderPath;
private String getTimeStamp()
final long timestamp = new Date().getTime();
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timestamp);
final String timeString = new SimpleDateFormat("HH_mm_ss_SSS").format(cal.getTime());
return timeString;
编辑:
将这些添加到清单中:
开始 Api 19 及更高版本 READ_EXTERNAL_STORAGE 应显式声明
*<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />*
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
向你显现。
【讨论】:
是的,同意第 1 点 w.r.t 得到回答的时间。但是现在你必须让 READ_EXTERNAL_STORAGE 开始 API 19。看看developer.android.com/reference/android/…(没有冒犯,但不同意 2 和 3) 仅当您确实需要访问 SD 卡时,因为您可以访问您的沙盒文件结构。至于样式,有太多不必要的空格、新行、未对齐的括号和缩进。你应该阅读干净的代码,这本书比我能解释得更好。【参考方案4】:试试这个android.provider.MediaStore.EXTRA_OUTPUT
希望能解决你的错误。以下代码适用于我:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
我遇到了同样的问题,每次使用getIntent().getData()
检索其他活动的数据时都为空,然后通过写完整的android.provider.MediaStore.EXTRA_OUTPUT
来解决,这解决了我的错误。
【讨论】:
以上是关于MediaStore.EXTRA_OUTPUT 呈现数据为空,其他保存照片的方式?的主要内容,如果未能解决你的问题,请参考以下文章