变量
private static final int TAKE_PHOTO=1;
private Button takePhotoBtn,chooseFromAlbumBtn;
private ImageView showImg;
private Uri imageUri;
private String fileurl;
动态获取调用摄像机权限
android6.0之后拍照权限属于危险权限,需要动态获取,更多危险权限:链接 Android 运行时权限
注意:这个要先把拍照的权限给了
//在这里判断权限是否授权
if (ContextCompat.checkSelfPermission(PictureAc.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
//如果没有请求权限在这里请求
ActivityCompat.requestPermissions(PictureAc.this,new String[]{Manifest.permission.CAMERA},1);
}else{
if (hasSdcard()) {
openCamera();
}else{
Toast.makeText(PictureAc.this,"没有SD卡",Toast.LENGTH_LONG).show();
}
}
//这里接收动态获取权限时候的结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
if (hasSdcard()) {
openCamera();
}else{
Toast.makeText(PictureAc.this,"没有SD卡",Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(this,"您拒绝了该权限的获取",Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
这里首先判断SD卡是否存在
public static boolean hasSdcard() {
return Environment.getExternalStorageState().equals("mounted");
}
调用摄像头
然后调用摄像头
@SuppressLint("WrongConstant")
public void openCamera() {
int currentapiVersion = Build.VERSION.SDK_INT;
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
if (hasSdcard()) {
String pacname = Environment.getExternalStorageDirectory() + "/Pictures/";
File dirFile = new File(pacname);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
fileurl = pacname + "123.jpg";
File filename = new File(this.fileurl);
if (filename.exists()) {
filename.delete();
}
if (currentapiVersion < 24) {
imageUri = Uri.fromFile(new File(this.fileurl));
intent.putExtra("output", imageUri);
} else {
intent.addFlags(1);
imageUri = FileProvider.getUriForFile(this, "aiom.w3studio.apps.android.sdhr.myapplication.fileprovider", new File(this.fileurl));
intent.putExtra("output", imageUri);
}
}
startActivityForResult(intent, TAKE_PHOTO);
}
在这里面先创建图片存储路径,注意要先把权限给了
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
在这里要特别注意:要判断路径是否存在,不存在的时候先创建,因为不同手机是不一样的,有的手机当路径不存在的时候会自动创建,但是有的手机不会自动创建,为了兼容,最好将路径创建出来。
在Android7.0系统开始,使用真实本地路径被认为是不安全的,会抛出异常,用FileProvider来对数据进行封装共享给外部,从而提供应用的安全性,第一个参数传content对象,第二个参数可以是任意的唯一字符串,参数三是file对象
拍照回调
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode){
case TAKE_PHOTO:
if (resultCode==RESULT_OK){
Toast.makeText(PictureAc.this,"摄像头调用成功!",Toast.LENGTH_LONG).show();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//不会加载,只会获取图片的一个尺寸
//options里面储存了图片的高度和宽度
//读取文件
BitmapFactory.decodeFile(fileurl ,options);
//改变图片的大小
double ratio = Math.max(options.outWidth *1.0d/1024f,options.outHeight *1.0d/1024);
options.inSampleSize =(int) Math.ceil(ratio);
//设置后会加载图片
options.inJustDecodeBounds = false;
//图片压缩完成
Bitmap bitmap= BitmapFactory.decodeFile(fileurl ,options);
showImg.setImageBitmap(bitmap);
}
break;
default:
break;
}
}
这里需要注意的是,直接放照片会有显示不出来的现象,所以要压缩一下图片显示,并且,在指定Uri的情况下data返回的会是空,所以这时候就不要使用data获取值了