Android读书笔记(五)使用摄像头、从相册获取图片
来源:互联网 发布:电脑印章的软件 编辑:程序博客网 时间:2024/05/17 01:50
1.使用摄像头拍照
代码中getExternalCacheDir()方法,获取的是应用关联缓存目录。我们要使用此目录来存放图片,为什么不用SD卡的其他目录,因为从Android 6.0开始,读写sd卡为危险权限,使用其他目录则需要运行时权限。代码中有一处判断系统版本,是因为从Android 7.0系统开始,直接使用本地真实路径Uri被认为是不安全的,为了解决这个问题我们需要使用FileProvider。
take_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //用来存放拍摄的照片 File outputImage = new File(getExternalCacheDir(), "output_image.jpg"); //文件存在就删除 if (outputImage.exists()) { outputImage.delete(); } try { outputImage.createNewFile(); } catch (IOException e) { e.printStackTrace(); } //判断系统版本是否高于7.0 if (Build.VERSION.SDK_INT >= 24) { //getUriForFile(),参数一:context、参数二:任意的唯一字符、参数三:file对象 imageUri = FileProvider.getUriForFile(Main6Activity.this ,"cn.xd.study.a6", outputImage); } else { //获取uri imageUri = Uri.fromFile(outputImage); } //进行拍照 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //设置输出路径 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, TAKE_PHOTO); } });
拍完照片后,我们在onActivityResult()中进行处理。
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK) { try { //读取刚拍的照片,显示出来 Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver() .openInputStream(imageUri)); picture.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
实现拍照功能的代码已经写完了,接下来还需要配置一下provider。编辑AndroidManifest.xml文件,在application下添加provider。
<provider <!--name为固定值--> android:name="android.support.v4.content.FileProvider" <!--authorities的值要与FileProvider.getUriForFile()中参数二相同--> android:authorities="cn.xd.study.a6" android:exported="false" android:grantUriPermissions="true"> <meta-data <!--name为固定值--> android:name="android.support.FILE_PROVIDER_PATHS" <!--resource引用了a.xml文件,a.xml中设置了共享的路径--> android:resource="@xml/a" /> </provider>
创建a.xml文件,在project目录方式下,项目名→app→src→main→res,在res文件下创建xml文件目录和a.xml文件。a.xml文件如下:
<?xml version="1.0" encoding="utf-8"?><paths> <!--name 任意,path 共享的具体路径,path为空表示共享整个sd卡--> <external-path name="my_images" path=""/></paths>
基本完成了,还有个小尾巴,兼容android 4.4系统之前的版本,访问sd卡需要声明权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2.从相册中选择照片
为了更好的兼容性,下面的程序运行之前,需要使用运行时权限,运行时权限就不展示了(读写权限)。
//打开相册 private void openAlbum() { Intent intent = new Intent("android.intent.action.GET_CONTENT"); intent.setType("image/*"); startActivityForResult(intent, CHOOSE_PHOTO);//CHOOSE_PHOTO=2 }
选择照片完成后,需要使用onActivityResult()方法来处理。
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == CHOOSE_PHOTO) { //判断版本是否大于4.4并且是否选择了照片,从而执行不同的方法 //这是由于从4.4版本开始,选取相册中的图片不再返回真实的uri,需要对uri进行解析 if (Build.VERSION.SDK_INT >= 19 && resultCode != 0) { handleImageOnKitKat(data); } else if (resultCode != 0) { handleImageBeforeKitKat(data); } } }
//4.4及版本以上,要对uri进行处理,才能获取到真实的路径 @TargetApi(19)//指定该方法用于4.4版本及以上版本 private void handleImageOnKitKat(Intent data) { String imagesPath = null; Uri uri = data.getData(); if (DocumentsContract.isDocumentUri(Main7Activity.this, uri)) { //从android 7.0操作, //content://com.android.providers.media.documents/document/image:40 //getDocumentId()获取的是ID,40 String docId = DocumentsContract.getDocumentId(uri); //从相册选取图片,uri中的Authority为com.android.providers.media.documents。 if ("com.android.providers.media.documents".equals(uri.getAuthority())) { String id = docId.split(":")[1]; String selection = MediaStore.Images.Media._ID + "=" + id; imagesPath = getImagesPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI , selection); //没能测试 } else if ("com.android.providers.downloads.documents".equals( uri.getAuthority())) { Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads") , Long.valueOf(docId)); imagesPath = getImagesPath(contentUri, null); } //4.4模拟器选择图片,content://media/external/images/media/12 } else if ("content".equalsIgnoreCase(uri.getScheme())) { imagesPath = getImagesPath(uri, null); //在4.4系统红米1s选择图片的uri //file:///storage/sdcard1/DCIM/Camera/IMG_20170623_105806.jpg } else if ("file".equalsIgnoreCase(uri.getScheme())) { imagesPath = uri.getPath(); } displayImage(imagesPath); }
private void handleImageBeforeKitKat(Intent data) { Uri uri = data.getData(); String imagePath = getImagesPath(uri, null); displayImage(imagePath); }
//获取真实的路径 private String getImagesPath(Uri uri, String selection) { String path = null; Cursor cursor = getContentResolver().query(uri, null, selection, null, null); if (cursor != null) { if (cursor.moveToFirst()) { path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)); } cursor.close(); } return path; }
displayImage()方法用来展示图片。选取照片所需权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
阅读全文
0 0
- Android读书笔记(五)使用摄像头、从相册获取图片
- 从摄像头/相册获取图片
- 从摄像头/相册获取图片,压缩图片,上传服务器小结
- Android-->相册,摄像头获取图片,图片路径,以及剪裁图片
- Android从相册选择图片和调用系统摄像头拍照
- Android 如何从相册(gallery)获取一张图片?
- Android 从相机或相册获取图片
- android 从系统相册获取一张图片
- android从相册中获取图片
- Android从相册和照相机获取图片
- android 从相册中获取图片
- Android从摄像头或相册中获取照片
- Android调用手机摄像头和相册获取图片
- 从相册获取图片
- 调用摄像头和相册(调用摄像头拍照和从相册中选择图片)
- Android中使用OKHttp上传图片,从相机和相册中获取图片并剪切
- iphone开发]从摄像头/相册获取图片,压缩图片,上传服务器小结
- 【iphone开发】ios 从摄像头/相册获取图片,压缩图片,上传服务器小结
- c语音代码及注释“俄罗斯方块”
- C#中HttpWebRequest的用法详解
- Java转义字符详细、Eclipse快捷键详细、Eclipse的javadoc文档操作
- ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'information_schema
- JAVA连接Orcale数据库
- Android读书笔记(五)使用摄像头、从相册获取图片
- QT编写树莓派的Nokia5110显示屏显示
- Go语言中数组和slice的区别
- Properties工具类
- moment.js 日期和时间管理 24小时制
- bzoj 1978(dp)
- 线性表
- group by用法
- 总结一个人工智能(AI)产品设计框架