先说说流程:拍照后将图片转为Bitmap显示在页面上。先吐槽一下,以前拍照几行代码就搞定了,现在拍照是真的麻烦,要写一大堆代码!
1.解决android6.0动态权限问题
2.解决android7.0拍照崩溃问题
3.解决图片路径获取不到问题(有的手机Environment.getExternalStorageDirectory()获取不到路径)。
4.解决File转Bitmap后某些手机会自动旋转90度的问题
步骤一:Android6.0动态权限申请
Android6.0后增加了权限机制。当有权限时,直接调用takePhoto()方法牌照,没有权限时,先申请权限。
private void checkPermission(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED ||ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE},0);
}else{
takePhoto();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePhoto();
}else {
showToast("请打开权限");
}
}
showToast就是Toast.makeToast....。
步骤二:takePhoto()方法
private void takePhoto(){
fileName=Utils.getFileName(this);
Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
uri= FileProvider.getUriForFile(RegisterActivity.this,getPackageName()+".fileprovider",fileName);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}else{
uri=Uri.fromFile(fileName);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, Activity.DEFAULT_KEYS_DIALER);
}
public static File getFileName(Context context){
File filePath=new File(Environment.getExternalStorageDirectory(),"images");
if(!filePath.exists()){
filePath.mkdirs();
}
File fileName=new File(filePath,System.currentTimeMillis()+".jpg");
if(!fileName.exists()){
try {
fileName.createNewFile();
} catch (IOException e) {
e.printStackTrace();
return getFilesDir(context);
}
}
return fileName;
}
public static File getFilesDir(Context context){
File filePath=new File(context.getFilesDir(),"images");
if(!filePath.exists()){
filePath.mkdirs();
}
File fileName=new File(filePath,System.currentTimeMillis()+".jpg");
if(!fileName.exists()){
try {
fileName.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return fileName;
}
1.某些手机Environment.getExternalStorageDirectory()获取不到路径,因为在catch里获取getFilesDir()确保文件路径一定能获取到。
2.自Android 7.0后系统禁止应用向外部公开file://URI ,因此需要FileProvider来向外界传递URI。
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!--指定Uri的共享路径-->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/whty_traffic_file_paths" />
</provider>
whty_traffic_file_paths文件
<?xml version="1.0" encoding="utf-8"?>
<paths >
<files-path name="my_images1" path="images"/>
<external-path name="my_images2" path="images"/>
</paths>
步骤三:图片压缩、解决旋转90度问题
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==Activity.DEFAULT_KEYS_DIALER&&resultCode==RESULT_OK){
bitmap=ImgUtils.compress(fileName.getAbsolutePath());
getIdCard.setBackground(new BitmapDrawable(bitmap));
}
}
public static Bitmap compress(String imagePath){
int degree=readPictureDegree(imagePath);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // 只获取图片的大小信息,而不是将整张图片载入在内存中,避免内存溢出
BitmapFactory.decodeFile(imagePath, options);
int height = options.outHeight;
int width= options.outWidth;
int inSampleSize = 2; // 默认像素压缩比例,压缩为原图的1/2
int minLen = Math.min(height, width); // 原图的最小边长
if(minLen > 300) { // 如果原始图像的最小边长大于100dp(此处单位我认为是dp,而非px)
float ratio = (float)minLen / 300.0f; // 计算像素压缩比例
inSampleSize = (int)ratio;
}
options.inJustDecodeBounds = false; // 计算好压缩比例后,这次可以去加载原图了
options.inSampleSize = inSampleSize; // 设置为刚才计算的压缩比例
Bitmap bm = BitmapFactory.decodeFile(imagePath, options); // 解码文件
Bitmap newbitmap = rotaingImageView(degree, bm);
return newbitmap;
}
public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
//旋转图片 动作
Matrix matrix = new Matrix();
;
matrix.postRotate(angle);
System.out.println("angle2=" + angle);
// 创建新的图片
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return resizedBitmap;
}