android 拍照图片压缩第三方,Android调用系统相机、图库、裁剪图片并压缩上传(适配7.0)...

阅读: 评论:0

android 拍照图片压缩第三方,Android调用系统相机、图库、裁剪图片并压缩上传(适配7.0)...

android 拍照图片压缩第三方,Android调用系统相机、图库、裁剪图片并压缩上传(适配7.0)...

最近在开发中遇到了一个比较棘手的问题,由于在之前使用的版本-targetSdkVersion小于24也就是小于7.0所以在使用相机拍照的时候不会出现问题,但是当targetSdkVersion版本大于或者等于7.0的时候用原来的方法调用相机就会抛出一个SecurityException安全异常

通过搜索发现是出于对系统安全的考虑,在sdk24及以上,对相机的操作需要使用FileProvider才行。

虽然有些麻烦,但除非用第三方框架,不然也只能自己动手去解决了。

二、操作流程

1、定义全局标识

用于接收图库选择或拍照完成后的结果回调

//图库

private static final int PHOTO_TK = 0; //拍照

private static final int PHOTO_PZ = 1; //裁剪

private static final int PHOTO_CLIP = 2;

定义全局的uri

private Uri contentUri;

2、图库操作

这里用的是一个自定义的dialog

update_dialog_TK.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) { //调用系统图库,选择图片

Intent intent = new Intent(Intent.ACTION_PICK, null);

intent.setDataAndType(

MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*"); //返回结果和标识

startActivityForResult(intent, PHOTO_TK);

dialog.dismiss();

}

});

3、相机操作

3.1 Android7.0以下版本

直接调用系统相机,通过日志可以看到会返回一个类似

file:///storage/emulated/0/temp.jpg的文件

update_dialog_PZ.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) { // 启动系统相机

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //

获取拍完后的uri

Uri mImageCaptureUri = Uri.fromFile(new

ExternalStorageDirectory(), "temp.jpg"));

intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri); // 返回结果和标识

startActivityForResult(intent, PHOTO_PZ);

dialog.dismiss();

}

});

3.2 兼容Android7.0以上版本

在新的版本中,Android对内容提供者做了限制,返回的不再是uri,而需要一个FileProvider

使用 content://代替了 file:///

所以如果直接使用原来的方法就会报错。

所以在之前我们要给AndroidManifest文件中application标签添加权限

android:name="android.t.FileProvider"

android:authorities="你的包名.fileProvider"

android:exported="false"

android:grantUriPermissions="true">

android:name="android.support.FILE_PROVIDER_PATHS"

android:resource="@xml/provider_paths" />

并且需要创建一个xml

(可以在上面android:resource="@xml/provider_paths"直接使用快捷键alt+enter创建,然后将代码拷贝进去)

external-path标签用来指定Uri共享,name属性的值可以自定义,path属性的值表示共享的具体位置

xmlns:android="">

然后在调用系统相机的时候判断

update_dialog_PZ.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) { // 启动系统相机

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Uri mImageCaptureUri; // 判断7.0android系统

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //临时添加一个拍照权限

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

//通过FileProvider获取uri

contentUri = UriForFile(UpdatePhotoActivity.this,

"你的包名.fileProvider", new ExternalStorageDirectory(),

"temp.jpg"));

intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);

} else {

mImageCaptureUri = Uri.fromFile(new

ExternalStorageDirectory(), "temp.jpg"));

intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

}

startActivityForResult(intent, PHOTO_PZ);

dialog.dismiss();

}

});

4、 onActivityResult

使用onActivityResult接收操作完成的回调

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent

data) { ActivityResult(requestCode, resultCode, data); if (resultCode ==

Activity.RESULT_OK) { switch (requestCode) { case PHOTO_PZ: //获取拍照结果,执行裁剪

Uri pictur; //如果是7.0android系统,直接获取uri

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

pictur = contentUri;

} else {

pictur = Uri.fromFile(new File(

}

startPhotoZoom(pictur); break; case PHOTO_TK: //获取图库结果,执行裁剪

Data()); break;

case PHOTO_CLIP: //裁剪完成后的操作,上传至服务器或者本地设置

break;

}

}

}

5、裁剪

当拍照完成后或者本地选择图片完毕之后会执行该方法。同时也做了7.0适配

/**

* 裁剪图片的方法.

* 用于拍照完成或者选择本地图片之后

*/

private Uri uritempFile; public void startPhotoZoom(Uri uri) {

Log.e("uri=====", "" + uri);

Intent intent = new Intent("com.android.camera.action.CROP");

intent.setDataAndType(uri, "image/*");

intent.putExtra("crop", "true");

intent.putExtra("aspectX", 1);

intent.putExtra("aspectY", 1);

intent.putExtra("outputX", 60);

intent.putExtra("outputY", 60); //uritempFile为Uri类变量,实例化uritempFile

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //开启临时权限

intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION |

Intent.FLAG_GRANT_READ_URI_PERMISSION); //重点:针对7.0以上的操作

intent.wRawUri(MediaStore.EXTRA_OUTPUT, uri));

uritempFile = uri;

} else {

uritempFile = Uri.parse("file://" + "/" +

}

intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);

intent.putExtra("return-data", false);

intent.putExtra("outputFormat", Bitmap.String());

intent.putExtra("noFaceDetection", true);

startActivityForResult(intent, PHOTO_CLIP);

}

三、裁剪后的处理

在onActivityResult方法还有一个最后的处理,前面只是在给图片做操作,下面是将完成后的图片选择加载到本地或者上传到项目的服务端,一般在实际开发中用的比较多

1、加载至本地

使用Picasso加载,因为Picasso支持Uri、File、Stirng类型,不需要做进一步的转换就可以直接用。

Picasso.with(this)

.load(uritempFile)

.into(cardviewImg);

2、转成File并压缩、上传

在实际开发中有时候需要对图片进行进一步的处理,比如传到服务器需要File类型的文件,所以就需要进行再一次的转换。

具体可以根据需求来进行相应的操作

//裁剪后的图像转成BitMapphoto1 =

BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));//创建路径String

path = ExternalStorageDirectory()

.getPath() + "/Pic";//获取外部储存目录file = new File(path);Log.e("file",

System.currentTimeMillis(); //生成新的文件file = new String() + "/" + i +

".png");

Log.e("fileNew", Path()); //创建输出流

OutputStream out = new Path()); //压缩文件,返回结果boolean

flag = photo1press(Bitmap.CompressFormat.JPEG, 100, out);

项目demo地址:

本文发布于:2024-01-31 05:02:51,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170664857425738.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图片   第三方   图库   相机   上传
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23