android7.0 拍照以及图片剪辑--(再次修改)

如果你是在fragment里头调用的拍照,出了bug 可以查看 这篇文章 点我 不懂的可以留言。

这篇博客对于7.0的版本的修改。主要是在文件存储的处理。

6.0、8.0版本使用本文的存储文件会出现  java.io.FileNotFoundException: No such file or directory  找不到文件夹

至于怎么做版本适配大家可以度娘一下,我这个问题往后我处理好放在博客给大家看看还有什么不足的,还请指点。


本次修改的地方是使用了第三方的截图开源框架  uCrop,解决了一些机型剪辑图片时gg了。原因一个就是,Android自带的截图有点坑啊(应该是我用不好的原因)毕竟别人的框架也是基于系统的所提供嘛。 


这边先说明一下uCrop的使用,再往下看就是拍照功能的实现

1、添加依赖走起   -->app.gradle

implementation 'com.yalantis:ucrop:1.4.1'
-->build.gradle  (Project)

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }  //添加的是这句
    }
}

2、申请activity,这个并不是说你自己去创建一个,你看清楚他的包名,uCrop是作者的喔。

<activity
    android:name="com.yalantis.ucrop.UCropActivity"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

3、开搞啦。这里直接使用代码就可以,截图跳转到UCropActivity

        UCrop uCrop = UCrop.of(uri, cropUri);  //第一参数是处理图片你的文件的路径,第二个参数就是存放剪辑后的路径
        UCrop.Options options = new UCrop.Options();
        //设置裁剪图片可操作的手势
        options.setAllowedGestures(UCropActivity.SCALE, UCropActivity.ROTATE, UCropActivity.ALL);
        //是否隐藏底部容器,默认显示
        options.setHideBottomControls(true);
        //设置toolbar颜色
        options.setToolbarColor(ActivityCompat.getColor(activity, R.color.colorPrimary));
        //设置状态栏颜色
        options.setStatusBarColor(ActivityCompat.getColor(activity, R.color.colorPrimary));
//        //是否能调整裁剪框
//        options.setShowCropFrame(true); 
        options.setCompressionFormat(Bitmap.CompressFormat.JPEG);

        //UCrop配置
        //设置裁剪图片的宽高比,比如1:1  你自己随意
        uCrop.withAspectRatio(1, 1);
        uCrop.withMaxResultSize(250,250);
        uCrop.withOptions(options);
        //uCrop.useSourceImageAspectRatio();
        //跳转裁剪页面
        uCrop.start(getContext(),this,CODE_RESULT_REQUEST);
//start 方法中提供几种方式
             
        也就是说你在fragment、activity  都可以使用,其中fragment也做了一个适配
            你在fragment中调用也没有问题的。 参数使用的话,点击去看一下源码就知道怎么用了。

4、看下uCrop的效果

                                                                旋转

              

5、截图后的显示



然后进入我们的主题。

//拍照
private void showCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, REQUEST_CAMERA);

}
//保存图片路径
private void saveUrl() {
    file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/test/" + System.currentTimeMillis() + ".jpg");
    file.getParentFile().mkdirs();
   
    uri = FileProvider.getUriForFile(this, "com.example.cnb.cemera.fileprovider", file);
}
//权限申请以及开启  下面有一段新的权限申请,至于版本适配大家还是得自己去写
public void applyWritePermission() {
    String[] permissions = {android.Manifest.permission.WRITE_EXTERNAL_STORAGE};
    if (Build.VERSION.SDK_INT >= 23) {
        int check = ContextCompat.checkSelfPermission(this, permissions[0]);
        // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
        if (check == PackageManager.PERMISSION_GRANTED) {
            //调用相机
            showPhoto();
        } else {
            requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    } else {
        showPhoto();
    }
}

    //这一段新的权限申请/**

/**
 * 
 * @param selectFun 请求码,对应的功能,拍照 || 图库选取 
 */
public void applyWriteAndReadPermission(int selectFun) {
    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        //如果灭有权限
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, selectFun);
                                                                                                   //requestCode                 
    } else {
        showPhoto();
    }
}

//权限返回  
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        showPhoto();
    } else {
        // 没有获取 到权限,从新请求,或者关闭app
        Toast.makeText(this, "需要存储权限", Toast.LENGTH_SHORT).show();
    }
}
    //activity返回
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {

            Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri contentUri = Uri.fromFile(file);
            mediaScanIntent.setData(contentUri);
            sendBroadcast(mediaScanIntent);
            String path = this.getExternalCacheDir().getPath();

            cropRawPhoto(uri);
        } else if (requestCode == CODE_RESULT_REQUEST) {
            //在手机相册中显示刚拍摄的图片

            if (data == null) {
                return;
            }
            Bundle extras = data.getExtras();
            if (extras != null) {
                bm = extras.getParcelable("data");
            }
//            sendImage(bm);
            img.setImageBitmap(bm);
        }

    }


    //裁剪图片  使用第三方框架uCrop 进行编辑,
    public void cropRawPhoto(Uri uri) {  //这个uri是拍照后保存下来的图片文件路径
        Log.e("url", uri + "-------");
        File cropFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/test/crop_" + System.currentTimeMillis() + ".jpg");
        cropFile.getParentFile().mkdirs();
        Uri cropUri = FileProvider.getUriForFile(getContext(), "com.example.cnb.superschool.fileprovider", cropFile);
        UCrop uCrop = UCrop.of(uri, cropUri);
        UCrop.Options options = new UCrop.Options();
        //设置裁剪图片可操作的手势
        options.setAllowedGestures(UCropActivity.SCALE, UCropActivity.ROTATE, UCropActivity.ALL);
        //是否隐藏底部容器,默认显示
        options.setHideBottomControls(true);
        //设置toolbar颜色
        options.setToolbarColor(ActivityCompat.getColor(activity, R.color.colorPrimary));
        //设置状态栏颜色
        options.setStatusBarColor(ActivityCompat.getColor(activity, R.color.colorPrimary));
//        //是否能调整裁剪框
//        options.setShowCropFrame(true);
        options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
        //UCrop配置
        //设置裁剪图片的宽高比,比如1:1  你自己随意
        uCrop.withAspectRatio(1, 1);
        uCrop.withMaxResultSize(250, 250);
        uCrop.withOptions(options);
        //uCrop.useSourceImageAspectRatio();
        //跳转裁剪页面
        uCrop.start(getContext(), this, CODE_RESULT_REQUEST);

    }




//裁剪图片  系统自带的图片剪辑  
public void cropRawPhoto(Uri uri) {
    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");

    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    intent.putExtra("outputX", 200);
    intent.putExtra("outputY", 200);
    intent.putExtra("return-data", true);
    intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    startActivityForResult(intent, CODE_RESULT_REQUEST);
}
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.cnb.cemera.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/filepaths"/>
</provider>


<?xml version="1.0" encoding="utf-8"?>
<resources>
  
<external-path
    name="external_files"
    path="." />
</resources>

复制以上的代码一般就可以运行了啦。

捋一捋处理思路

首先android6.0 以上 都需要 权限申请,

如果权限已经开启,那么执行拍照功能。否则判断用户是否要开启该权限

开启/关闭 权限都后会有一个权限返回结果,那么,返回中去判断权限是否开启,开启则进行拍照

接着,拍照功能开启,确定后保存图片路径,返回到onActivityResult 根据requestCode 来判定

是哪一个功能的返回,在判断为拍照功能里头添加剪辑。

最后轮到剪辑功能,跳转到剪辑页面,需要的设置他们的参数,也就是截取的比例,完成后返回到onActivityResult 

判断是不是剪辑功能的返回值,设置图片显示。

这个图片显示需要转换成bitmap,获取data之后转成bitmap

Bundle extras = data.getExtras();
if (extras != null) {             
     bm = extras.getParcelable("data");
}
img.setImageBitmap(bm)

android7.0以后 需要通过获取路径来获取图片。

新建一个xml文件夹,然后新建一个xml文件,名字随意。可以返回上面代码看一下











猜你喜欢

转载自blog.csdn.net/qq_36099573/article/details/79937324