拍照和选择相册(兼容高版本)
来源:互联网 发布:淘宝安能物流被禁用 编辑:程序博客网 时间:2024/05/22 02:08
拍照
打开相机准备工作
申请权限,需要下面两个权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.CAMERA"/> 在Android 6.0系统下,可以选择在清单文件中静态注册,在Android 6.0以上需要代码中动态申请,关于代 码中动态申请,可以参照: http://blog.csdn.net/thanksforandroid/article/details/75105002
打开相机
File tempFile = new File(MineStudentFragment.this.getContext().getExternalCacheDir() , PHOTO_FILE_NAME);/**生成一个文件,放在内置SD卡上,PHOTO_FILE_NAME是自己取的名字。*/ if (Build.VERSION.SDK_INT >= 24) { uriP = FileProvider.getUriForFile(MineStudentFragment.this.getContext() , "mooc.zhihuiyuyi.com.mooc.provider" , tempFile); } else { uriP = Uri.fromFile(tempFile); }/**http://blog.csdn.net/thanksforandroid/article/details/76512616*/ if (uriP != null) { ForOpenCamera(uriP, REQUEST_PERMISSION_GALLERY_FIRST,Manifest.permission.WRITE_EXTERNAL_STORAGE); } else { ToastUtils.showShort(MineStudentFragment.this.getContext(), "未找到可用文件路径"); }/**下面这个if - else 是为了给6.0网上系统动态申请写SD卡权限,ForOpenCamera()方法是自己写的*/
ForOpenCamera()方法
private void ForOpenCamera(Uri uriP, int permissionCode, String permission) { if (Build.VERSION.SDK_INT >= 23) { if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED) { MineStudentFragment.this.requestPermissions(new String[]{permission}, permissionCode);//没有就去申请,这里是因为当时是在Fragment中使用的, return; } else { startCamera(uriP); } } else { startCamera(uriP); } } /**参数说明,这里传进来一个Uri,是为了有权限时候直接去调用startCamera,permissionCode是权限 申请码,方便动态申请权限之后,在权限回调中判断,permission,是你要申请的权限*/
假设用户没有权限,那么就回去申请,申请结果的回调如下:
@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch(requestCode){ case REQUEST_PERMISSION_GALLERY_FIRST: /**这里之展示了一种case*/ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //表示给了权限了 startCamera(uriP); } else { //表示没有权限,不能下一步ToastUtils.showLong(MineStudentFragment.this.getContext(), "您把数据访问禁止了,你将不能享受服务。修改权限可以去设置中修改!"); } break; } }
接下来看看startCamera()方法
public void startCamera(Uri uriP) { // 激活相机 mIntent1 = new Intent("android.media.action.IMAGE_CAPTURE"); mIntent1.putExtra(MediaStore.EXTRA_OUTPUT, uriP); requestPermissions(mIntent1, REQUEST_PERMISSION_CAREMA, Manifest.permission.CAMERA, PHOTO_REQUEST_CAREMA); } /**在这里获取打开相机的intent,然后调用自定义的requestPermissions()这个自定义方法*/
requestPermissions()方法:
private void requestPermissions(Intent intent, int permissionCode, String permission, int requestCode) {if (Build.VERSION.SDK_INT >= 23) { if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED) { MineStudentFragment.this.requestPermissions(new String[]{permission}, permissionCode); return; } else { startActivityForResult(intent, requestCode); } } else { startActivityForResult(intent, requestCode); } }/***也是检查有没有打开相机权限,如果没有的话,就去申请,有的话,就去打开相机了,requestCode是为了得到相机的返回值*/
假设用户也没有打开相机权限,那么权限回调如下,这里也只取关于相机权限部分:
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_PERMISSION_CAREMA: /**这里只截取了一部分*/ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { startActivityForResult(mIntent1, PHOTO_REQUEST_CAREMA); } else { ToastUtils.showLong(MineStudentFragment.this.getContext(), "您把相机权限禁止了,您将不能享受服务。修改权限可以去设置中修改!"); } break; }}
正常走到现在,用户会进行拍照,当结果返回的时候:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); /**这里为了理解,只展示相机结果的回调*/ if (requestCode == PHOTO_REQUEST_CAREMA) { tempFile = new File(MineStudentFragment.this.getContext().getExternalCacheDir() , PHOTO_FILE_NAME); if (Build.VERSION.SDK_INT >= 24) { if (getImageContentUri(MineStudentFragment.this.getContext(), tempFile) != null) { crop(getImageContentUri(MineStudentFragment.this.getContext(), tempFile)); } else { ToastUtils.showShort(MineStudentFragment.this.getContext(), "拍照失败,稍后重试!"); } } else { if (Uri.fromFile(tempFile) != null) { crop(Uri.fromFile(tempFile)); } else { ToastUtils.showShort(MineStudentFragment.this.getContext(), "拍照失败,稍后重试!"); } }}/**这里加了这么多层的嵌套,是为了避免空指针。下一步进行剪切,调用自定义的crop方法,它需要传一个Uri路径,但是这里又存在问题,在Android 7.0网上版本,所需要的路径,不能直接同过Uri.fromFile来获得,所以这里又多了一个判断*/
看看图片剪切的方法:
private void crop(Uri uri) { // 裁剪图片意图 Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); // 裁剪框的比例,1:1 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // 裁剪后输出图片的尺寸大小 intent.putExtra("outputX", 250); intent.putExtra("outputY", 250); intent.putExtra("outputFormat", "JPEG");// 图片格式 intent.putExtra("noFaceDetection", true);// 取消人脸识别 intent.putExtra("return-data", true); // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT startActivityForResult(intent, PHOTO_REQUEST_CUT); }
这里也是有一个startActivityForResult,接下来看看裁剪图片的返回结果的处理
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PHOTO_REQUEST_CUT) { // 返回剪切后的数据,这里为了展示,也只是保留一部分需要的一部分 if (data != null && data.getParcelableExtra("data") != null) { mStream = new ByteArrayOutputStream(); mBitmap = data.getParcelableExtra("data"); mBitmap.compress(Bitmap.CompressFormat.PNG, 100, mStream); /**图片可以应用了*/ /**接下来就是上传到服务器*/ File files = creatFile(mBitmap);//变成文件 putNET_Photo(files); } else { ToastUtils.showShort(MineStudentFragment.this.getContext(), "未知的错误发生了"); } } }
createFile()方法是将Bitmap转换成文件的方法,这里多说一下,其实到这里拍照已经结束了
private File creatFile(Bitmap bitmap) { File cache = new File(getActivity().getCacheDir() + File.separator + CACHE_DIR); BufferedOutputStream bos = null; File file = null; if (!cache.exists()) { cache.mkdirs(); } try { file = new File(cache, USER_ICON_NAME); bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); bos.flush(); bos.close(); } catch (IOException e) { e.printStackTrace(); } return file; }
相册
准备工作
需要权限如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
打开系统相册
mIntent2 = new Intent(Intent.ACTION_PICK); mIntent2.setType("image/*"); requestPermissions(mIntent2, REQUEST_PERMISSION_GALLERY, Manifest.permission.WRITE_EXTERNAL_STORAGE, PHOTO_REQUEST_GALLERY);
针对于7.0以上,所以还是有动态获取权限,requestPermissions方法,
private void requestPermissions(Intent intent, int permissionCode, String permission, int requestCode) { if (Build.VERSION.SDK_INT >= 23) {if(ContextCompat.checkSelfPermission(getContext(), permission)!= PackageManager.PERMISSION_GRANTED) { MineStudentFragment.this.requestPermissions(new String[]{permission}, permissionCode); return; } else { startActivityForResult(intent, requestCode); } } else { startActivityForResult(intent, requestCode); } } /**此方法和上述相机哪里申请第二个权限的时候一样,不需要重写,只需要调用即可*/
权限申请结果
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_PERMISSION_GALLERY: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { startActivityForResult(mIntent2, PHOTO_REQUEST_GALLERY); } else { ToastUtils.showLong(MineStudentFragment.this.getContext(), "您把数据访问禁止了,你将不能享受服务。修改权限可以去设置中修改!"); } break; } }/**这里直截取了一部分。*/
用户选完相片之后,看看对于结果的处理:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PHOTO_REQUEST_GALLERY) { // 从相册返回的数据 if (data != null && data.getData() != null) { // 获取图片的全路径 Uri uri_1 = data.getData(); LogUtils.d("MineStudentFragment", "得到图片的全路径是:" + uri_1.toString()); crop(uri_1); } else { ToastUtils.showShort(MineStudentFragment.this.getContext(), "选择相册失败,稍后重试!"); } } }/**接下来就是调用crop方法,然后的处理就是和前面拍照一样了*/
说明:
前面的权限结果回调方法还有Activity结果的回调方法,其实是在一块的,这里为了好理解,而分开了,这里也涉及到了权限动态申请还有FileProvider,这些 可以参考博客,
http://blog.csdn.net/thanksforandroid/article/details/75105002
http://blog.csdn.net/thanksforandroid/article/details/76512616
阅读全文
0 0
- 拍照和选择相册(兼容高版本)
- Android 拍照和相册选图 版本兼容
- Android全兼容版本的拍照和获取相册功能
- Android 拍照和相册选择
- Android图片裁剪(拍照和从相册选择)
- android拍照或相册获取头像(兼容4.4以下,4.4,5.0,6.0版本)
- 调用系统相机拍照和选择相册
- Android 从相册和拍照选择图片
- 拍照和从相册选择图片 截图
- 拍照和从相册选择图片
- android 拍照和选择相册图片剪切
- 拍照和从相册选择图片
- 调用摄像头拍照和选择相册
- 调用摄像头和相册(调用摄像头拍照和从相册中选择图片)
- android头像选择(拍照,相册,裁剪)
- android头像选择(拍照,相册,裁剪)
- Android拍照、相册选择
- android 选择图片 剪裁 拍照 兼容所有版本的代码
- LeetCode 387. First Unique Character in a String
- RN版本项目实战升级,工程化相关技术tips,实用, mark.
- JS Math.sin() 与 Math.cos() 用法
- 浏览器中User-Agent的来龙去脉
- React native 常用第三方件总结
- 拍照和选择相册(兼容高版本)
- 【全解析】屏幕尺寸/分辨率/像素/PPI之间到底什么关系?
- JS中Math.ceil()和Math.floor(x)的使用
- 【python】lambda表达式、filter()、map()
- Android 界面的模板化设计
- 使用HttpURLConnection通过post请求服务器时,URLEncode编码的必要性
- ubuntu14.04安装caffe+cuda7.5+cudnn5.0+opencv3.0(亲测有效)
- Mysql查询最近30天的数据(每天的业绩总和数据)
- Linux系统文件I/O编程(一)---open()等基本函数