关闭

Android 6.0运行时权限和7.0拍照(相册)并剪裁显示

3014人阅读 评论(0) 收藏 举报
分类:

原生的获取方法:

ActivityCompat.requestPermissions(this, new String[]{
                        Manifest.permission.READ_CONTACTS,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.CAMERA,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.RECORD_AUDIO,
                        Manifest.permission.CALL_PHONE
                }, 0);

最近看到一个比较精简的6.0权限的封装工具类,写个Demo试了下,用起来还是蛮方便的,在这里分享一下。
PermissionUtil代码:

public class PermissionUtil {
    private static int mRequestCode = -1;
    private static OnPermissionListener mOnPermissionListener;
    public interface OnPermissionListener {
        void onPermissionGranted();
        void onPermissionDenied();
    }

    @TargetApi(Build.VERSION_CODES.M)
    public static void requestPermissions(Context context, int requestCode, String[] permissions, OnPermissionListener listener) {
        if (context instanceof Activity) {
            mOnPermissionListener = listener;
            List<String> deniedPermissions = getDeniedPermissions(context, permissions);
            if (deniedPermissions.size() > 0) {
                mRequestCode = requestCode;
                ((Activity) context).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
            } else {
                if (mOnPermissionListener != null)
                    mOnPermissionListener.onPermissionGranted();
            }
        } else {
            throw new RuntimeException("Context must be an Activity");
        }
    }

    /**
     * 获取请求权限中需要授权的权限
     */
    private static List<String> getDeniedPermissions(Context context, String... permissions) {
        List<String> deniedPermissions = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_DENIED) {
                deniedPermissions.add(permission);
            }
        }
        return deniedPermissions;
    }

    /**
     * 请求权限结果,对应Activity中onRequestPermissionsResult()方法。
     */
    public static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (mRequestCode != -1 && requestCode == mRequestCode) {
            if (mOnPermissionListener != null) {
                if (verifyPermissions(grantResults)) {
                    mOnPermissionListener.onPermissionGranted();
                } else {
                    mOnPermissionListener.onPermissionDenied();
                }
            }
        }
    }

    /**
     * 验证所有权限是否都已经授权
     */
    private static boolean verifyPermissions(int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }
}

就是上面这个,下面说一下怎么用!
首先,在你的基类里设置监听回调,比如我的是这样的:

/**
 * 基类
 */
public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        PermissionUtil.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

然后继承基类就可以了!比如我要获取相机权限。
核心代码:

public void requestCameraPermission(View view){
        PermissionUtil.requestPermissions(this, 1, new String[]{Manifest.permission.CAMERA}, new PermissionUtil.OnPermissionListener() {
            @Override
            public void onPermissionGranted() {
                //打开相机
            }

            @Override
            public void onPermissionDenied() {
                //用户拒绝权限,让用户去设置里手动获取权限
                goSetting();
            }
        });
    }



或者用严大的库:
AndPermission.with(this)
                .requestCode(1)
                .permission(Manifest.permission.CAMERA)
                .callback(this)
                .start();


 @PermissionYes(1)
    private void getPermissionYes(List<String> grantedPermissions) {
        if (AndPermission.hasPermission(this,grantedPermissions)){
            //执行逻辑
        }else {
            goSetting();
        }
    }

    @PermissionNo(1)
    private void getPermissionNo(List<String> deniedPermissions) {
        if (AndPermission.hasPermission(this,deniedPermissions)){
            //执行逻辑
        }else {
           goSetting();
        }
    }

    public void goSetting(){
        Toast.makeText(this,"缺少相机拍照权限,请授予",Toast.LENGTH_SHORT).show();
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", getPackageName(), null));
        startActivity(intent);
    }

——————————————————————————————————————————
下面是6.0运行时权限和7.0的结合使用:

public class MainActivity extends BaseActivity {
    private ImageView imageView;
    private File file, cropFile;
    private Uri uri, cropUri;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageView);

        PermissionUtil.requestPermissions(this, 1, new String[]{Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionUtil.OnPermissionListener() {
            @Override
            public void onPermissionGranted() {
                if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                    file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "temp.jpg");
                    if (file.exists()) {
                        file.delete();
                    } else {
                        try {
                            file.createNewFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            @Override
            public void onPermissionDenied() {
                goSetting();
            }
        });
    }

    /**
     * @param view
     * 打开相机
     */
    public void openCamera(View view) {
        //7.0判断
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = FileProvider.getUriForFile(MainActivity.this, "com.thtj.picdemo.fileprovider", file);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            uri = Uri.fromFile(file);
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        startActivityForResult(intent, 1);
    }

    /**
     * @param view
     * 打开相册
     */
    public void openAlbum(View view) {
        Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(intent, 2);
    }

    /**
     * @param requestCode
     * @param resultCode
     * @param data
     * 打开相机和相册以及剪裁图片后的回调
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case 1:
                cropPhoto(uri);
                break;
            case 2:
                if (data == null)
                    return;
                uri = data.getData();
                cropPhoto(uri);
                break;
            case 3:
                try {
                    imageView.setImageBitmap(BitmapFactory.decodeStream(getContentResolver().openInputStream(cropUri)));
                    file.delete();
                    cropFile.delete();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    /**
     * @param uri
     * 图片剪裁
     */
    public void cropPhoto(Uri uri) {
        // 创建cropFile对象,用于存储剪裁后的图片
        cropFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "cropTemp.jpg");
        if (cropFile.exists()) {
            cropFile.delete();
        } else {
            try {
                cropFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        cropUri = Uri.fromFile(cropFile);
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.setDataAndType(uri, "image/*");
        intent.putExtra("crop", "true");
        //解决华为手机显示圆形剪裁框的问题
        if (Build.MANUFACTURER.contains("HUAWEI")) {
            intent.putExtra("aspectX", 9998);
            intent.putExtra("aspectY", 9999);
        } else {
            intent.putExtra("aspectX", 1);
            intent.putExtra("aspectY", 1);
        }
        intent.putExtra("outputX", 300);
        intent.putExtra("outputY", 300);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri);
        startActivityForResult(intent, 3);
    }
}

7.0的唯一之处在于FileProvider的使用:
清单文件添加provider:

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="包名.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths_public"/>
        </provider>

res文件夹下创建xml文件夹,里面创建file_paths_public:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="Pictures"/>
    <paths>
        <external-path
            name="download"
            path=""/>
    </paths>
</paths>

最后就是权限了:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:94077次
    • 积分:1122
    • 等级:
    • 排名:千里之外
    • 原创:50篇
    • 转载:0篇
    • 译文:0篇
    • 评论:12条
    文章分类
    最新评论