一、权限动态申请
implementation 'pub.devrel:easypermissions:1.0.1'
/**
* 权限申请工具类
*/
public class PermissionsEasy extends EasyPermissions {
private static final boolean ENABLED = true;
public static boolean hasPermissions(Context context, @NonNull String... perms) {
return !ENABLED || EasyPermissions.hasPermissions(context, perms);
}
}
1.EasyPermission的简单使用
/**
* 检查拍照权限
*/
private void checkCameraPermission() {
if (PermissionsEasy.hasPermissions(this, Manifest.permission.CAMERA)) {
//执行具体的操作
...
} else {
//进行申请权限的操作
PermissionsEasy.requestPermissions(MainActivity.this,
"请求一下权限",
R.string.ok,
R.string.canel,
REQUEST_CODE_CAMERA_PERMISSION,
Manifest.permission.CAMERA);
}
}
重写onRequestPermissionsResult,对权限申请结果进行监听
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//回调权限请求框架,多个权限请求只需要调用一次
PermissionsEasy.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
实现EasyPermissions.PermissionCallbacks的接口
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
if(REQUEST_CODE_CAMERA_PERMISSION == requestCode){
//被授予了某种权限
//执行具体的操作
...
}
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
if(REQUEST_CODE_CAMERA_PERMISSION == requestCode){
//申请权限被拒绝
...
}
}
二、具体代码段
1.拍照
/**
* 打开照相机和文件
*/
private void openCamera() {
File outputImage = new File(mCompressPath, "img" + System.currentTimeMillis() + ".jpg");
if(Build.VERSION.SDK_INT > 24){
String p = getPackageName() + ".FileProvider";
imageUri = FileProvider.getUriForFile(MainActivity.this,
p,outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
//通过隐士Intent打开系统照相机
Intent takenIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takenIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(takenIntent, TAKE_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case TAKE_PHOTO:
//拍摄照片
if(resultCode == RESULT_OK){
//根据传入的imageUri做相应的使用
...
}else if(resultCode == RESULT_CANCELED){
//针对imageUri做一些收尾工作
...
}
break;
default:
break;
}
}
2.摄像
/**
* 打开摄像机
*/
private void openVideo() {
File outputImage = new File(mCompressPath, "img" + System.currentTimeMillis() + ".mp4");
if(Build.VERSION.SDK_INT > 24){
String p = getPackageName() + ".FileProvider";
imageUri = FileProvider.getUriForFile(MainActivity.this,
p,outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent,TAKE_VIDEO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case TAKE_VIDEO:
//拍摄照片
if(resultCode == RESULT_OK){
//根据传入的imageUri做相应的使用
...
}else if(resultCode == RESULT_CANCELED){
//针对imageUri做一些收尾工作
...
}
break;
default:
break;
}
}
3.图片选择
/**
* 打开照相机和文件
*/
private void selectImage() {
File outputImage = new File(mCompressPath, "img" + System.currentTimeMillis() + ".jpg");
if(Build.VERSION.SDK_INT > 24){
String p = getPackageName() + ".FileProvider";
imageUri = FileProvider.getUriForFile(MainActivity.this,
p,outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
Intent selectIntent = new Intent(Intent.ACTION_PICK, null);
selectIntent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mMediaType);
startActivityForResult(selectIntent, SELECT_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case SELECT_PHOTO:
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
//根据解析到的result做相应的使用
if (result != null) {
doCallback(result);
}
break;
default:
break;
}
}
4.图片、拍照多种选择混合使用
/**
* 打开照相机和文件
*/
private void openImage(String title) {
File outputImage = new File(mCompressPath, "img" + System.currentTimeMillis() + ".jpg");
if(Build.VERSION.SDK_INT > 24){
String p = getPackageName() + ".FileProvider";
imageUri = FileProvider.getUriForFile(MainActivity.this,
p,outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
Intent takenIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takenIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
Intent selectIntent = new Intent(Intent.ACTION_PICK, null);
selectIntent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mMediaType);
//创建一个选择器,让用户选择 是拍照还是 从图库选择
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_TITLE, title);
chooser.putExtra(Intent.EXTRA_INTENT,selectIntent);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{
takenIntent});
startActivityForResult(chooser, TAKE_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case TAKE_PHOTO:
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
//选择图片
if (result != null) {
...
}else {
//拍摄照片
if(resultCode == RESULT_OK){
...
}else if(resultCode == RESULT_CANCELED){
...
}
}
break;
case TAKE_VIDEO:
//录制视频
if(resultCode == RESULT_OK){
...
}else if(resultCode == RESULT_CANCELED){
...
}
break;
default:
break;
}
}
三、注意点
1)FileProvider的使用。当我们拍照、录像时,需要传递给系统应用一个ContentUri,指定生成的文件的路径。具体使用可以参考Android之FileProvider的使用