使用FileProvider调用相机时onActivityResult返回null Intent问题
问题分析与解决方案
我来帮你捋清楚这个问题~其实这不是代码bug,是相机应用的正常行为,听我慢慢说:
为什么会出现Intent data为null的情况?
当你通过FileProvider生成Uri,并把这个Uri通过Intent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri)传递给相机应用时,大部分相机应用会直接把拍摄的图片保存到你指定的这个Uri路径下,而不会在返回的Intent里再携带图片数据,所以onActivityResult里的data就会是null。
而当你注释掉那行代码时,相当于没有给相机指定输出路径,这时候相机应用会自己保存图片,然后把图片的缩略图或者Uri放在Intent的data里返回给你的应用,所以这时候data不为null。
正确的处理方式
既然图片已经成功保存到你指定的路径了,那完全不需要依赖返回的data来获取图片,直接用你创建的图片文件路径来处理就好:
确保启动相机时正确传递输出Uri
先把你的启动相机代码补全,确保传递了EXTRA_OUTPUT:private static final int REQUEST_CAMERA = 100; private String mCurrentPhotoPath; // 保存图片路径,作为类成员变量 private void invokeCamera() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 检查是否有相机应用可以处理这个Intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { File photoFile = null; try { photoFile = createImageFile(); mCurrentPhotoPath = photoFile.getAbsolutePath(); // 提前保存图片路径 } catch (IOException ex) { // 处理文件创建失败的异常 ex.printStackTrace(); } if (photoFile != null) { Uri pictureUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", photoFile); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri); startActivityForResult(takePictureIntent, REQUEST_CAMERA); } } } // 你的createImageFile方法,记得返回File对象 private File createImageFile() throws IOException { // 创建唯一的图片文件名 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* 文件名前缀 */ ".jpg", /* 文件名后缀 */ storageDir /* 存储目录 */ ); return image; }在onActivityResult里直接用保存的路径加载图片
不需要管data是否为null,只要结果是RESULT_OK,就用之前保存的mCurrentPhotoPath来处理图片:@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) { // 直接从保存的路径加载图片 File imageFile = new File(mCurrentPhotoPath); if (imageFile.exists()) { // 这里可以根据需求加载图片,比如显示到ImageView Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath()); ImageView imageView = findViewById(R.id.your_image_view_id); imageView.setImageBitmap(bitmap); } } }
补充说明
不同的相机应用可能有细微的行为差异,但遵循Android官方规范的应用都会按照EXTRA_OUTPUT的约定来保存图片。所以你的代码其实是正确的,data为null是正常现象,不用太在意,只要图片能成功保存到指定路径,直接用路径处理就没问题啦~
内容的提问来源于stack exchange,提问作者SpaceSloth
相关产品推荐
相关产品推荐

