Android拍照遇到的所有问题

先说说流程:拍照后将图片转为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;
    }

学习网站:http://www.itkzhan.com

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猴子学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值