Android 相机 或者 相册 获取图片裁剪 适用6.0/7.0
随着Android 的版本更新迭代。本来以前代码很简单的打开相册或者相机 获取图片裁剪 给Unity3D 使用的过程 挺简单的。但是随着 Android 版本的 更新 和 安全 的加强 。有几点 和以前不一样的地方。在这里和大家分享下。
首先呢。在Unity3D 里面是 无法判断 手机摄像头 权限是否打开的, Android 原生是可以的。而6.0 和7.0 有是 有区别的。
package photos.john.com;import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.net.Uri;
import android.view.View.OnClickListener;
import android.support.v4.content.ContextCompat;
import android.support.v4.app.ActivityCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.widget.Toast;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;public class MainActivity extends AppCompatActivity {private Button buttonCamera;private Button buttonPhoto;private ImageView imageView;private static final int TAKE_PHOTO_PERMISSION_REQUEST_CODE = 0; // 拍照的权限处理返回码private static final int WRITE_SDCARD_PERMISSION_REQUEST_CODE = 1; // 读储存卡内容的权限处理返回码private static final int TAKE_PHOTOSDCARD_PERMISSION_REQUEST_CODE = 2; // 拍照 存储权限private static final int TAKE_PHOTO_REQUEST_CODE = 3; // 拍照返回的 requestCodeprivate static final int CHOICE_FROM_ALBUM_REQUEST_CODE = 4; // 相册选取返回的 requestCodeprivate static final int CROP_PHOTO_REQUEST_CODE = 5; // 裁剪图片返回的 requestCodeprivate Uri photoUri = null;private Uri photoOutputUri = null; // 图片最终的输出文件的 Uri@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);buttonCamera = (Button)findViewById(R.id.buttonCamera);buttonPhoto = (Button)findViewById(R.id.buttonPhoto);imageView = (ImageView)findViewById(R.id.imageView);buttonCamera.setOnClickListener( new ButtonListener());buttonPhoto.setOnClickListener( new ButtonListener());}private class ButtonListener implements View.OnClickListener {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.buttonCamera:// 同上面的权限申请逻辑OnCamera();break;case R.id.buttonPhoto:OnPhotos();break;default:break;}}}//相机权限检查private boolean OnCameraPermission(){boolean isPass = true;if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {isPass = false;// 申请相机权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CAMERA}, TAKE_PHOTO_PERMISSION_REQUEST_CODE);}return isPass;}//相机权限检查.- 存储private boolean OnCameraPermissionSTORAGE(){boolean isPass = true;if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {isPass = false;// 申请读写内存卡内容的权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, TAKE_PHOTOSDCARD_PERMISSION_REQUEST_CODE);}return isPass;}//相册权限检查 //实际是读取内存卡的权限private boolean OnPhotosPermission(){boolean isPass = true;if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {isPass = false;// 申请读写内存卡内容的权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_SDCARD_PERMISSION_REQUEST_CODE);}return isPass;}private void OnCamera(){if( !OnCameraPermission() || !OnCameraPermissionSTORAGE())//这里不光需要相机权限 还需要 读取储存卡{return;}/*** 设置拍照得到的照片的储存目录,因为我们访问应用的缓存路径并不需要读写内存卡的申请权限,* 因此,这里为了方便,将拍照得到的照片存在这个缓存目录中*/File file = new File(getExternalCacheDir(), "image.jpg");try {if(file.exists()) {file.delete();}file.createNewFile();} catch (IOException e) {e.printStackTrace();}/*** 因 Android 7.0 开始,不能使用 file:// 类型的 Uri 访问跨应用文件,否则报异常,* 因此我们这里需要使用内容提供器,FileProvider 是 ContentProvider 的一个子类,* 我们可以轻松的使用 FileProvider 来在不同程序之间分享数据(相对于 ContentProvider 来说)*/if(Build.VERSION.SDK_INT >= 24) {photoUri = FileProvider.getUriForFile(this, this.getPackageName()+".provider", file);} else {photoUri = Uri.fromFile(file); // Android 7.0 以前使用原来的方法来获取文件的 Uri}// 打开系统相机的 Action,等同于:"android.media.action.IMAGE_CAPTURE"Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 设置拍照所得照片的输出目录takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST_CODE);}private void OnPhotos(){if( !OnPhotosPermission() ){return;}// 打开系统图库的 Action,等同于: "android.intent.action.GET_CONTENT"Intent choiceFromAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);// 设置数据类型为图片类型choiceFromAlbumIntent.setType("image/*");startActivityForResult(choiceFromAlbumIntent, CHOICE_FROM_ALBUM_REQUEST_CODE);}/*** 裁剪图片*/private void cropPhoto(Uri inputUri) {// 调用系统裁剪图片的 ActionIntent cropPhotoIntent = new Intent("com.android.camera.action.CROP");// 设置数据Uri 和类型cropPhotoIntent.setDataAndType(inputUri, "image/*");// 授权应用读取 Uri,这一步要有,不然裁剪程序会崩溃cropPhotoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 设置图片的最终输出目录cropPhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoOutputUri = Uri.parse("file:sdcard/image_output.jpg"));cropPhotoIntent.putExtra("noFaceDetection", false);cropPhotoIntent.putExtra("scale", true);//裁剪框比例cropPhotoIntent.putExtra("aspectX", 1);cropPhotoIntent.putExtra("aspectY", 1);//输出图片大小cropPhotoIntent.putExtra("outputX", 512);cropPhotoIntent.putExtra("outputY", 512);cropPhotoIntent.putExtra("return-data", false);cropPhotoIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());startActivityForResult(cropPhotoIntent, CROP_PHOTO_REQUEST_CODE);}/*** 在这里进行用户权限授予结果处理* @param requestCode 权限要求码,即我们申请权限时传入的常量* @param permissions 保存权限名称的 String 数组,可以同时申请一个以上的权限* @param grantResults 每一个申请的权限的用户处理结果数组(是否授权)*/@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {switch (requestCode) {// 调用相机拍照:case TAKE_PHOTO_PERMISSION_REQUEST_CODE:// 如果用户授予权限,那么打开相机拍照if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {OnCamera();} else {Toast.makeText(this, "拍照权限被拒绝", Toast.LENGTH_SHORT).show();}break;// 调用相机拍照: 存储case TAKE_PHOTOSDCARD_PERMISSION_REQUEST_CODE:// 如果用户授予权限,那么打开相机拍照if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {OnCamera();} else {Toast.makeText(this, "读写内存卡内容权限被拒绝", Toast.LENGTH_SHORT).show();}break;// 打开相册选取:case WRITE_SDCARD_PERMISSION_REQUEST_CODE:if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){OnPhotos();} else {Toast.makeText(this, "读写内存卡内容权限被拒绝", Toast.LENGTH_SHORT).show();}break;}}/*** 通过这个 activity 启动的其他 Activity 返回的结果在这个方法进行处理* @param requestCode 返回码,用于确定是哪个 Activity 返回的数据* @param resultCode 返回结果,一般如果操作成功返回的是 RESULT_OK* @param data 返回对应 activity 返回的数据*/@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(resultCode == RESULT_OK) {// 通过返回码判断是哪个应用返回的数据switch (requestCode) {// 拍照case TAKE_PHOTO_REQUEST_CODE:cropPhoto(photoUri);break;// 相册选择case CHOICE_FROM_ALBUM_REQUEST_CODE:cropPhoto(data.getData());break;// 裁剪图片case CROP_PHOTO_REQUEST_CODE:File file = new File(photoOutputUri.getPath());if(file.exists()) {Bitmap bitmap = BitmapFactory.decodeFile(photoOutputUri.getPath());imageView.setImageBitmap(bitmap);//file.delete(); // 选取完后删除照片} else {Toast.makeText(this, "找不到照片", Toast.LENGTH_SHORT).show();}break;}}}
}
这里有点特殊 需要添加一些东西
资源下载 源码下载
过两天有空 我会把它 嵌入 Unity3d 中使用
Android 相机 或者 相册 获取图片裁剪 适用6.0/7.0相关推荐
- Android相机、相册获取图片显示并保存到SD卡
如题,这个需求本不是一个很复杂的过程,但是却存在一些隐患,我也是最近在项目中碰到这个问题,将Android通过相机或相册获取图片并最终显示在界面上做了一个小研究,现将一些结果和附上的一个Demo叙述如 ...
- 从相机相册获取图片裁剪后用于评论晒图或更换背景图
这是我人生中写的第一篇博客,是否要纪念一下这一刻(2016.09.01 16:52).其实关于写博客,老早就有这种写法,首先觉得他能够帮我总结我学到的和用过的技术,其次还能帮助那些和我有一样需求的人, ...
- iOS 从相机或相册获取图片并裁剪
/load user image - (void)UesrImageClicked { UIActionSheet *sheet; // 判断是否支持相机 if([UIImagePickerContr ...
- android相册路径地址,Android拍照和相册获取图片路径
/** *调用系统相机 */ public voidstartCamera() { Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE); ...
- android通过访问相册获取图片并展示在ImageView中
第一步:添加相应的权限以及属性: ①在manifest中设置权限 <uses-feature android:name="android.hardware.camera" / ...
- android访问图库,android通过访问相册获取图片并展示在ImageView中
第一步:添加相应的权限以及属性: ①在manifest中设置权限 ②在中设置相应属性,这一步很关键,解决了我在这一方面最后的一个有关deny的权限问题 android:requestLegacyExt ...
- android从本地相册获取图片uri三星手机适配问题
启动系统相册intent Intent intentFromGallery = new Intent(); if (android.os.Build.VERSION.SDK_INT >= and ...
- Android 调用系统打开相机,打开相册获取图片路径
我们在开发中经常遇到一些功能需要调取系统相机拍照获取图片,或者有的时候直接打开图库获取图片,那我们怎么获取呢,今天分享下, 第一步,打开相机 public static final int CAMER ...
- android开发 获取相册名称_android通过拍照、相册获取图片并显示 实例完整源码下载(亲测通过)...
[实例简介]其中也包含了 将图片保存至 sd卡功能 [实例截图] [核心代码] public class MainActivity extends Activity{ private static f ...
最新文章
- RH124 章1 访问命令行 笔记
- 一个 TCP 连接可以发多少个 HTTP 请求?
- boost::hana::cycle用法的测试程序
- [HNOI2011]XOR和路径
- LookAheadEnumerator:在解析器中实现回溯
- 软件工程-读书笔记(第4章)
- 日期插件(jedate)
- QImage、QPainter绘图
- 台达plc控制伺服电机编程实例_三菱Q系列PLC控制伺服电机编程实例
- Visual Odometry
- ictclas4j java_ictclas4j 分词工具包 安装流程
- 计算机组装与维护考试题a卷,计算机组装与维护考试题A卷.docx
- 【别墅装修】—婚房装修成今年家居市场消费热点
- 5分钟读懂UML类图
- Servlet中关于Session数据存储遇到的数据转换问题
- flex布局(flex容器,flex属性)
- Python数据结构之二——tuple(元组)
- Delphi基本数据类型(内置数据类型)
- Spring Security多种登录方式
- 怎样记住“和差化积 积化和差”公式?
热门文章
- linux中内存管理方法的总结,Linux系统内存总结.docx
- 淘宝上付款后接到电话要账号 警方不排除卖家倒卖信息
- 2024年408 计算机考研 学习视频集
- 2021 前端面试(杭州)
- office_handwriting 手写字体生成脚本 手写文章 打印手写效果 windows office word 宏脚本 模仿手写 模拟手写 一键生成 代码生成 任意文本 多种字体 手写字体
- 平安ETL开发面试积累
- 企业怎样管理问题职工?
- Maya的一些实用插件——记录分享篇
- 新开普生产实习【智能家居灯控系统】
- android 实现 3d 文字,android 3d 游戏 开发 基础 第10课-2D文字显示.ppt