随着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相关推荐

  1. Android相机、相册获取图片显示并保存到SD卡

    如题,这个需求本不是一个很复杂的过程,但是却存在一些隐患,我也是最近在项目中碰到这个问题,将Android通过相机或相册获取图片并最终显示在界面上做了一个小研究,现将一些结果和附上的一个Demo叙述如 ...

  2. 从相机相册获取图片裁剪后用于评论晒图或更换背景图

    这是我人生中写的第一篇博客,是否要纪念一下这一刻(2016.09.01 16:52).其实关于写博客,老早就有这种写法,首先觉得他能够帮我总结我学到的和用过的技术,其次还能帮助那些和我有一样需求的人, ...

  3. iOS 从相机或相册获取图片并裁剪

    /load user image - (void)UesrImageClicked { UIActionSheet *sheet; // 判断是否支持相机 if([UIImagePickerContr ...

  4. android相册路径地址,Android拍照和相册获取图片路径

    /** *调用系统相机 */ public voidstartCamera() { Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE); ...

  5. android通过访问相册获取图片并展示在ImageView中

    第一步:添加相应的权限以及属性: ①在manifest中设置权限 <uses-feature android:name="android.hardware.camera" / ...

  6. android访问图库,android通过访问相册获取图片并展示在ImageView中

    第一步:添加相应的权限以及属性: ①在manifest中设置权限 ②在中设置相应属性,这一步很关键,解决了我在这一方面最后的一个有关deny的权限问题 android:requestLegacyExt ...

  7. android从本地相册获取图片uri三星手机适配问题

    启动系统相册intent Intent intentFromGallery = new Intent(); if (android.os.Build.VERSION.SDK_INT >= and ...

  8. Android 调用系统打开相机,打开相册获取图片路径

    我们在开发中经常遇到一些功能需要调取系统相机拍照获取图片,或者有的时候直接打开图库获取图片,那我们怎么获取呢,今天分享下, 第一步,打开相机 public static final int CAMER ...

  9. android开发 获取相册名称_android通过拍照、相册获取图片并显示 实例完整源码下载(亲测通过)...

    [实例简介]其中也包含了 将图片保存至 sd卡功能 [实例截图] [核心代码] public class MainActivity extends Activity{ private static f ...

最新文章

  1. RH124 章1 访问命令行 笔记
  2. 一个 TCP 连接可以发多少个 HTTP 请求?
  3. boost::hana::cycle用法的测试程序
  4. [HNOI2011]XOR和路径
  5. LookAheadEnumerator:在解析器中实现回溯
  6. 软件工程-读书笔记(第4章)
  7. 日期插件(jedate)
  8. QImage、QPainter绘图
  9. 台达plc控制伺服电机编程实例_三菱Q系列PLC控制伺服电机编程实例
  10. Visual Odometry
  11. ictclas4j java_ictclas4j 分词工具包 安装流程
  12. 计算机组装与维护考试题a卷,计算机组装与维护考试题A卷.docx
  13. 【别墅装修】—婚房装修成今年家居市场消费热点
  14. 5分钟读懂UML类图
  15. Servlet中关于Session数据存储遇到的数据转换问题
  16. flex布局(flex容器,flex属性)
  17. Python数据结构之二——tuple(元组)
  18. Delphi基本数据类型(内置数据类型)
  19. Spring Security多种登录方式
  20. 怎样记住“和差化积 积化和差”公式?

热门文章

  1. linux中内存管理方法的总结,Linux系统内存总结.docx
  2. 淘宝上付款后接到电话要账号 警方不排除卖家倒卖信息
  3. 2024年408 计算机考研 学习视频集
  4. 2021 前端面试(杭州)
  5. office_handwriting 手写字体生成脚本 手写文章 打印手写效果 windows office word 宏脚本 模仿手写 模拟手写 一键生成 代码生成 任意文本 多种字体 手写字体
  6. 平安ETL开发面试积累
  7. 企业怎样管理问题职工?
  8. Maya的一些实用插件——记录分享篇
  9. 新开普生产实习【智能家居灯控系统】
  10. android 实现 3d 文字,android 3d 游戏 开发 基础 第10课-2D文字显示.ppt