拍摄图像后在 onActivityResult 中获取空 uri

Getting null uri in onActivityResult after take image capture

我正在开发一个 android 应用程序,我需要从该应用程序捕获图像并 return 捕获 uri 以将其传递给 api。我正在研究 oreo 8 。我在 Whosebug 上尝试了很多解决方案,但其中 none 可以正常工作。 我在 onActivityResult 中得到空 uri。 我试图像这样直接从数据中获取它:

uri = data.getData();

我也试过像这样从 Bitmap 获取 uri:

Bitmap photo = (Bitmap) data.getExtras().get("data"); uri = getImageUri(getApplicationContext(), photo);

但还是不行。

这是我当前的代码:

button2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(hasStoragePermission(IMAGE_CAPTURE)){
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(takePictureIntent, IMAGE_CAPTURE);
                }
            }
        }
    });
}

@Override
protected void onActivityResult(int requestCode, final int resultCode, Intent data) {
    switch(requestCode) {
        case 0: {
            if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
                if (data == null) {
                    Toast.makeText(getApplicationContext(), "error selecting file!, Please try again ", Toast.LENGTH_LONG).show();
                    return;
                } else {
                    uri = data.getData();
                }
            }

            break;
        }

        case 1: {
            if (requestCode == IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
                if (data == null) {
                    Toast.makeText(getApplicationContext(), "error selecting file!, Please try again ", Toast.LENGTH_LONG).show();
                    return;
                } else {
                        uri = data.getData();
                        /* // Also I try this:
                        Bitmap photo = (Bitmap) data.getExtras().get("data");
                        uri = getImageUri(getApplicationContext(), photo); */
                }
            }
            break;
        }
    }
        super.onActivityResult(requestCode, resultCode, data);
}







public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}
    private boolean hasStoragePermission(int requestCode) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED &&
                checkSelfPermission(Manifest.permission.CAMERA)
                        != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
            requestPermissions(new String[]{Manifest.permission.CAMERA},
                    requestCode);
            return false;
        } else {
            return true;
        }
    } else {
        return true;
    }
}

这是 运行 时间权限检查器:

  private boolean hasStoragePermission(int requestCode) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED &&
                checkSelfPermission(Manifest.permission.CAMERA)
                        != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);
            requestPermissions(new String[]{Manifest.permission.CAMERA},
                    requestCode);
            return false;
        } else {
            return true;
        }
    } else {
        return true;
    }
}

这是我的权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

我错过了什么? 谢谢!

对于 android 8.0 或更高版本,您必须添加创建文件提供程序才能访问照片。添加文件提供程序

在应用程序标签下的清单文件中添加以下标签。

<provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="com.example.provider"
                android:exported="false"
                android:grantUriPermissions="true"
                tools:replace="android:authorities">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths"
                    tools:replace="android:resource" />

</provider>

在 xml 文件夹中创建 provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="." />
</paths>

意图捕捉图像

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    // Create the File where the photo should go
                    File photoFile = null;
                    try {
                        photoFile = createImageFile();
                    } catch (IOException ex) {
                        // Error occurred while creating the File

                    }
                    // Continue only if the File was successfully created
                    if (photoFile != null) {
                        if ((Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)) {
                            photoURI = FileProvider.getUriForFile(getContext(),
                                    "com.example.provider",
                                    photoFile);
                            //FAApplication.setPhotoUri(photoURI);
                        } else {
                            photoURI = Uri.fromFile(photoFile);
                        }

                        takePicture.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                        startActivityForResult(takePicture, 101);

并且在onActivity result

if (requestCode == 101) {
                    Uri contentUri = FileProvider.getUriForFile(getContext(), "com.example.provider", new File(mCurrentPhotoPath)); //You wll get the proper image uri here.
                }

createImageFile()

private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);


        /*File file = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
                + File.separator
                + imageFileName);
        if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {
            mCurrentPhotoPath = file.getAbsolutePath();
        }*/


        File file = File.createTempFile(
                imageFileName,   //prefix
                ".jpg",          //suffix
                storageDir       //directory
        );

        // Save a file: path for use with ACTION_VIEW intents

        return file;
    }