关闭

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

3503人阅读 评论(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
查看评论

Android6.0,7.0拍照和相册异常,运行时权限

关于Android7.0调用系统相机拍照、访问相册的一些问题: 在Android6.0中Google提出了动态申请权限的Api,调用相机拍照,访问SDcard等操作都需要先申请对应的权限如下: android:name="android.permission.CAMER...
  • xiaoxie12321
  • xiaoxie12321
  • 2017-08-08 10:02
  • 981

android 6.0运行时权限应用之图库图片选取

public class MainActivity extends AppCompatActivity { public static final int REQUEST_CODE=200; public static final int REQUEST_CODE_PICK_IMAG...
  • oneblue123
  • oneblue123
  • 2016-11-26 22:47
  • 2715

Android拍照,相册选择图片以及Android6.0权限管理

概述在android开发过程中,拍照或者从相册中选择图片是很常见的功能。android6.0后,推出了动态权限管理。以往我们将涉及到的权限全部写在清单文件中,只要用户安装了该程序,程序在运行过程中都会获得相应权限。android6.0后,对于一些特别敏感的权限,开发者必须在程序中进行声明。
  • zahngjialiang
  • zahngjialiang
  • 2016-10-02 11:24
  • 27256

Android调用系统相机和相册

拍照和相册的功能在实际开发中是最常见的功能,这里记录下。 准备工作 权限 1234 "android.permission.WRITE_EXTERNAL_STORAGE" /> "android.permissio...
  • xjbclz
  • xjbclz
  • 2016-09-25 12:33
  • 14793

android 6.0权限开发---拍照,打开相册问题

android6.0的权限机制改得跟ios类似,两个系统之间互相模仿也是好事,取长补短。在某些权限需要用到的时候,要先询问用户。 官方说明:http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-c...
  • p522947409
  • p522947409
  • 2016-11-16 11:13
  • 5763

Android6.0的权限管理(相机权限的举例)

android的权限管理!
  • dong19900415
  • dong19900415
  • 2016-09-29 09:57
  • 9116

相机拍照功能之权限和Android版本问题

对于Android 6.0之前,想要使用系统的相机进行拍照,那么只要在AndroidManifedt.xml中进行添加相应的权限,主要是两个: uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE...
  • memgxingfeixiang
  • memgxingfeixiang
  • 2016-09-13 16:47
  • 19173

Android7.0 拍照 选择照片 权限 实现

Android7.0 拍照 选择照片 权限 实现
  • LauraChen93
  • LauraChen93
  • 2017-07-05 14:18
  • 1935

Android 照相机权限的声明

最近写项目,发现在AndroidManifest.xml中声明了调用相机权限之后,打开app无法启动相机,经过一番搜查发现: 问题在于当写项目所使用的API的版本过高时(比如我所用的测试机为android 5.0,而我写这个工程所用的API为27,即android 7.0 ),导致APP无法自动向...
  • wangpeikai
  • wangpeikai
  • 2016-12-25 02:42
  • 5246

Android - 运行时权限AndPermission开源库的应用

版权声明:转载必须注明本文转自严振杰的博客: http://blog.csdn.net/yanzhenjie1003 下载地址:运行时权限开源库AndPermission:https://github.com/yanzhenjie/AndPermission。  介绍看这里 项目升级到an...
  • qq_29756625
  • qq_29756625
  • 2016-11-28 10:07
  • 5125
    个人资料
    • 访问:108590次
    • 积分:1310
    • 等级:
    • 排名:千里之外
    • 原创:52篇
    • 转载:0篇
    • 译文:0篇
    • 评论:12条
    文章分类
    最新评论