调取相机

2019-08-15  本文已影响0人  LeoFranz

相片动辄5-6MB,所以存储在SQLite中是绝对不合适的,那就应该构建一个内容提供器,暴露相片访问接口,并将实体相片文件保存在沙盒目录下,即包名目录下。

谷歌支持库中提供了FileProvider,我们局不需要自己构建内容提供器了。
仅仅需要声明

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.bignerdranch.android.criminalintent.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/files" />
        </provider>

xml文件下的file文件内容如下:

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

目的在于告知Provider应该暴露哪些文件。

一个相片对应一个对象实例,比如一次犯罪活动,就在Crime类中提供定位照片文件的方法

public String getPhotoFilename() {
        return "IMG_" + getId().toString() + ".jpg";
    }

public File getPhotoFile(Crime crime) {
        File firlDir = mContext.getFilesDir();
        return new File(firlDir, crime.getPhotoFilename());
    }

然后就是调用相机的关键代码了,

final Intent captureImage = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        boolean canTakePhoto = mPhotoFile != null &&
                captureImage.resolveActivity(packageManager) != null;
        mPhotoButton.setEnabled(canTakePhoto);

        mPhotoButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = FileProvider.getUriForFile(getActivity(),
                        "com.bignerdranch.android.criminalintent.fileprovider",
                        mPhotoFile);
                captureImage.putExtra(MediaStore.EXTRA_OUTPUT, uri);

                List<ResolveInfo> cameraActivities = getActivity()
                        .getPackageManager().queryIntentActivities(captureImage,
                                PackageManager.MATCH_DEFAULT_ONLY);

                for (ResolveInfo activity : cameraActivities) {
                    getActivity().grantUriPermission(activity.activityInfo.packageName,
                            uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                }

                startActivityForResult(captureImage, REQUEST_PHOTO);
            }
        });

ACTION_IMAGE_CAPTURE打开相机应用,默认只能返回缩略图,并将其包括在onActivityResult返回的intent中。
要获取全尺寸照片,就要制定EXTRA_OUTPUT所match的uri,照片会存在对应uri指向的位置。
获取照片

public void onActivityResult(int requestCode, int resultCode, Intent data) {
...
else if (requestCode == REQUEST_PHOTO) {
            Uri uri = FileProvider.getUriForFile(getActivity(),
                    "com.bignerdranch.android.criminalintent.fileprovider",
                    mPhotoFile);

            getActivity().revokeUriPermission(uri,
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

            updatePhotoView();
        }

private void updatePhotoView() {
        if (mPhotoFile == null || !mPhotoFile.exists()) {
            mPhotoView.setImageDrawable(null);
        } else {
            Bitmap bitmap = PictureUtils.getScaledBitmap(
                    mPhotoFile.getPath(), getActivity());
            mPhotoView.setImageBitmap(bitmap);
        }
    }
//最后方法的核心是
BitmapFactory.decodeFile(path, options);

可见和郭婶的相机调用方案接近。

demo地址

上一篇 下一篇

猜你喜欢

热点阅读