美文网首页Android开发安卓开发博客Android开发
Android7.0拍照,权限验证,一行代码解决

Android7.0拍照,权限验证,一行代码解决

作者: Wocus | 来源:发表于2018-07-18 12:23 被阅读105次

    前言:

    此文章解决了一下问题
    1.Android7.0以上拍照的适配
    2.Android6.0以上权限动态的申请

    实现步骤

    ①在mainfest标签里加入以下该权限

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

    ②在application下加入该provider

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

    ③在res目录下创建xml文件夹,在里面新建filepaths.xml文件,代码如下

    <resources>
             <paths>
                  <external-path path="" name="sdcard_files"/>
                  <external-files-path path="" name="camera_has_sdcard"/>
                  <files-path path="" name="camera_no_sdcard"/>
            <paths/>
    <resources/>
    

    ④拷贝下面两个类

    SelectPhotoUtil.kt

    package com.wocus.wine.util
    
    import android.Manifest
    import android.annotation.SuppressLint
    import android.app.Activity
    import android.app.AlertDialog
    import android.content.Intent
    import android.content.pm.PackageManager
    import android.graphics.Bitmap
    import android.net.Uri
    import android.os.Build
    import android.os.Environment
    import android.provider.MediaStore
    import android.support.v4.content.FileProvider
    import java.io.File
    import java.text.SimpleDateFormat
    import java.util.*
    
    class SelectPhotoUtil(val activity: Activity, val isTailor:Boolean, val onResult: OnResult) {
    
        interface OnResult{
            fun onResultFile(file: File)
        }
    
        var file:File?=null
    
        /**
         * 权限申请
         */
        @SuppressLint("NewApi")
        fun requestReadExternalPermission(requestCode: Int) {
            if (activity.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                if (!activity.shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    activity.requestPermissions(arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE), requestCode)
                }
            }else{
                if (requestCode==1){
                    getCamera()
                }else{
                    getGallery()
                }
            }
        }
    
        /**
         * 拍照方式选择
         */
        fun showDialog() {
            AlertDialog.Builder(activity).setItems(arrayOf("拍照", "从相册选择")) { _, index ->
                if (index == 0) {
                    requestReadExternalPermission(1)
                } else {
                    requestReadExternalPermission(2)
                }
            }.create().show()
        }
    
        /**
         * 拍照
         */
        private fun getCamera() {
            var intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                val img_name = SimpleDateFormat("yyyyMMddHHmmss").format(Date()) + ".jpg"
                file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), img_name)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(activity, "com.wocus.wine.fileprovider", file!!))
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                } else {
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file))
                }
    
                activity.startActivityForResult(intent, 1)
            } else {
                ToastUtil.show(activity, "储存卡不可用!")
            }
        }
    
        /**
         * 从相册选择
         */
        private fun getGallery() {
            var intent = Intent(Intent.ACTION_GET_CONTENT)
            intent.addCategory(Intent.CATEGORY_OPENABLE)
            intent.type = "image/*"
            val img_name = SimpleDateFormat("yyyyMMddHHmmss").format(Date()) + ".jpg"
            file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), img_name)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(activity, "com.wocus.wine.fileprovider", file!!))
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            }
            activity.startActivityForResult(intent, 2)
        }
    
        /**
         * 选择图片回调
         */
        fun attachToActivityForResult(requestCode: Int, resultCode: Int, data: Intent?){
            if (resultCode == Activity.RESULT_OK) {
                when(requestCode){
                    1->{
                        if (isTailor){
                            if (Build.VERSION.SDK_INT>=24){
                                getZoom(FileProvider.getUriForFile(activity,"com.wocus.wine.fileprovider",file!!))
                            }else{
                                getZoom(Uri.fromFile(file!!))
                            }
                        }else{
                            onResult.onResultFile(file!!)
                        }
                    }
                    2->{
                        var imgUri= File(GetImagePath.getPath(activity,data!!.data))
                        if (isTailor){
                            if(Build.VERSION.SDK_INT>=24){
                                var dataUri:Uri=FileProvider.getUriForFile(activity,"com.wocus.wine.fileprovider",imgUri)
                                getZoom(dataUri)
                            }else{
                                getZoom(data!!.data)
                            }
                        }else{
                            onResult.onResultFile(imgUri)
                        }
                    }
                    3->{
                        onResult.onResultFile(file!!)
                    }
                }
            }
        }
    
        /**
         * 图片裁剪
         */
        public fun getZoom(uri: Uri){
            if (uri==null){
                return
            }
            val intent=Intent("com.android.camera.action.CROP")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                val outPutUri = Uri.fromFile(file);
                intent.setDataAndType(uri, "image/*");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);
                intent.putExtra("noFaceDetection", false);//去除默认的人脸识别,否则和剪裁匡重叠
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            } else {
                val outPutUri = Uri.fromFile(file);
                if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                    val url = GetImagePath.getPath(activity, uri);//这个方法是处理4.4以上图片返回的Uri对象不同的处理方法
                    intent.setDataAndType(Uri.fromFile(File(url)), "image/*");
                } else {
                    intent.setDataAndType(uri, "image/*");
                }
                intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);
            } // 设置裁剪
            intent.putExtra("crop", "true");
            // aspectX aspectY 是宽高的比例
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
            // outputX outputY 是裁剪图片宽高
            intent.putExtra("outputX", 200);
            intent.putExtra("outputY", 200);
            intent.putExtra("return-data", false);
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());// 图片格式
            activity.startActivityForResult(intent, 3)
        }
    
    
        /**
         * 权限回调
         */
        fun attrRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                when (requestCode) {
                    1 -> {
                        getCamera()
                    }
                    2->{
                        getGallery()
                    }
                }
            } else {
                ToastUtil.show(activity, "授权失败");
            }
        }
    
    
    }
    

    GetImagePath.java

    package com.wocus.wine.util;
    
    import android.annotation.SuppressLint;
    import android.content.ContentUris;
    import android.content.Context;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Environment;
    import android.provider.DocumentsContract;
    import android.provider.MediaStore;
    
    public class GetImagePath {
    
    //  4.4以上  content://com.android.providers.media.documents/document/image:3952
    //  4.4以下  content://media/external/images/media/3951
        @SuppressLint("NewApi")
        public static String getPath(final Context context, final Uri uri) {
    
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    
            // DocumentProvider
            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                }
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(
                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
    
                    return getDataColumn(context, contentUri, null, null);
                }
                // MediaProvider
                else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
    
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
    
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{
                            split[1]
                    };
    
                    return getDataColumn(context, contentUri, selection, selectionArgs);
                }
            }
            // MediaStore (and general)
            else if ("content".equalsIgnoreCase(uri.getScheme())) {
                // Return the remote address
                if (isGooglePhotosUri(uri))
                    return uri.getLastPathSegment();
    
                return getDataColumn(context, uri, null, null);
            }
            // File
            else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
    
            return null;
        }
    
        //Android 4.4以下版本自动使用该方法
        public static String getDataColumn(Context context, Uri uri, String selection,
                                           String[] selectionArgs) {
    
            Cursor cursor = null;
            final String column = "_data";
            final String[] projection = {
                    column
            };
    
            try {
                cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                        null);
                if (cursor != null && cursor.moveToFirst()) {
                    final int index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(index);
                }
            } finally {
                if (cursor != null)
                    cursor.close();
            }
            return null;
        }
    
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is ExternalStorageProvider.
         */
        public static boolean isExternalStorageDocument(Uri uri) {
            return "com.android.externalstorage.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is DownloadsProvider.
         */
        public static boolean isDownloadsDocument(Uri uri) {
            return "com.android.providers.downloads.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is MediaProvider.
         */
        public static boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
    
        /**
         * @param uri The Uri to check.
         * @return Whether the Uri authority is Google Photos.
         */
        public static boolean isGooglePhotosUri(Uri uri) {
            return "com.google.android.apps.photos.content".equals(uri.getAuthority());
        }
    }
    

    ⑤Activity中的使用

    package com.wocus.wine.activity
    
    import android.content.Intent
    import android.os.Bundle
    import android.support.v7.app.AppCompatActivity
    import com.bumptech.glide.Glide
    import com.wocus.wine.R
    import com.wocus.wine.util.SelectPhotoUtil
    import kotlinx.android.synthetic.main.activity_pay.*
    import java.io.File
    
    class PayActivity : AppCompatActivity() {
    
        var selectPhoto:SelectPhotoUtil?=null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_pay)
            selectPhoto=SelectPhotoUtil(this,true,object :SelectPhotoUtil.OnResult{
                override fun onResultFile(file: File) {
                    Glide.with(baseContext).load(file).into(testImg)
                }
            })
            testBtn.setOnClickListener {
                selectPhoto?.showDialog()
            }
        }
    
        /**
         * 权限回调
         */
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            selectPhoto?.attrRequestPermissionsResult(requestCode,permissions,grantResults)
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        }
    
    
        /**
         * 拍照回调
         */
        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            selectPhoto?.attachToActivityForResult(requestCode,resultCode,data)
            super.onActivityResult(requestCode, resultCode, data)
        }
    
    }
    
    

    调用第一步,初始化对象,参数第一个为Activity,第二个为是否剪裁,第三个为回调方法

    有不懂的Q我752422962

    相关文章

      网友评论

        本文标题:Android7.0拍照,权限验证,一行代码解决

        本文链接:https://www.haomeiwen.com/subject/feropftx.html