Anndroid 使用相机或相册打开图片
安卓操作相机or相册
笔者做这方面测试的时候,没遇到什么大坑基本上,需要注意的有两点
1. 使用相册打开读取图片需要使用运行时权限,而且还是要在AndroidManifest.xml中进行权限声明,权限声明如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
2. 使用相机拍照获取图片的方式,平台版本API >= 24的时候,从文件转型成Uri格式 需要使用FileProvider.getUriForFile()这个方法(ps:此方法接受三个参数,1.Context 2.一个任意字符串 3.File对象),看到了Provider你也该想到了内容提供器,那么使用了内容提供器,相应的就需要到AndroidManifest.xml文件中对内容提供器注册了,编辑如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lichangxin.call_camera_and_photos_test"> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity> <provider
android:exported="false"
android:grantUriPermissions="true"
android:authorities="com.example.lichangxin.call_camera_and_photos_test"
android:name="android.support.v4.content.FileProvider">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/> </provider> </application> </manifest>
这里 需要注意的就是 <provider>标签内的android:authorities属性的值必须要同FileProvider.getUriForFile()方法的第二个参数值相同。
另外,这里使用了<me-data>标签来指定Uri的共享路径,并引用了一个@xml/file_paths资源,这个资源文件需要手动创建,以下操作如图
好了,下面贴一张 程序的 大致流程图,方便理解。
最后是 源码:
package com.example.lichangxin.call_camera_and_photos_test; import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView; import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.jar.Manifest; public class MainActivity extends AppCompatActivity { private static final int TAKE_PHOTO = 1;
private static final int CHOOSE_PHOTO = 2;
private ImageView image;
private Uri imageUri; private void ls(String tishi){
Log.d("enen",tishi);
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button open_camera = (Button)findViewById(R.id.open_camera);
final Button open_album = (Button)findViewById(R.id.open_photo_album);
image = (ImageView)findViewById(R.id.image1);
open_camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 创建File 对象,用于存储拍摄后的照片
File outputImage = new File(getExternalCacheDir(),"output_image.jpg"); //getExternalCacheDir 获取外部存储目录
try{
if(outputImage.exists()){ // 这里进行一级过滤 若文件存在 则删除文件
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e){
e.printStackTrace();
} if(Build.VERSION.SDK_INT >= 24){
imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.lichangxin.call_" +
"camera_and_photos_test",outputImage);
}else{
imageUri = Uri.fromFile(outputImage); //从文件转为uri
} // 此 if - else 用来判断 平台版本,>=24 用新的API 旧的版本直接用Uri.fromFile Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
startActivityForResult(intent,TAKE_PHOTO); } }); open_album.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
},1);
ls("111111111");
}else{
//执行打开 相册操作
openAlbum();
}
}
});
} //打开相册
private void openAlbum(){
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent,CHOOSE_PHOTO);
} @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode){
case 1:
ls("2222222222");
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
ls("333333333333");
openAlbum();
}else {
Log.d("enen","没有获得权限");
}
break;
default:
break;
}
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case TAKE_PHOTO: if(resultCode == RESULT_OK){ try{
Log.d("enen","jiasi");
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(imageUri));
image.setImageBitmap(bitmap);
Log.d("enen","jiasi wancheng");
}catch (FileNotFoundException e){
Log.d("enen","yichang");
e.printStackTrace();
} }
break; case CHOOSE_PHOTO:
if(resultCode == RESULT_OK){ if(Build.VERSION.SDK_INT >= 19){
//4.4以上使用此方法处理图片
handleImageOnkitKat(data);
}else{
//4.4一下 用此方法处理
handleImageBeforeKitKat(data);
} } default:
break;
}
} @TargetApi(19)
private void handleImageOnkitKat(Intent data){
String imagePath = null;
Uri uri = data.getData(); //取得 系统封装过的Uri 进行解析
if(DocumentsContract.isDocumentUri(this,uri)){
//如果是document类型的Uri 通过document id处理
String docId = DocumentsContract.getDocumentId(uri);
ls(docId); // 这里输出格式 为 image:26 证明上行代码 取出了id部分 // @***
if("com.android.providers.media.documents".equals(uri.getAuthority())){
//
String id = docId.split(":")[1]; // 字符串分割,解析出 数字格式的id 这里存在疑问 为什么以:为分隔符 (从@***行 解决疑问)
String selection = MediaStore.Images.Media._ID + "=" + id;
imagePath = getImagePath(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));
imagePath = getImagePath(contentUri,null);
}
}else if("content".equalsIgnoreCase(uri.getScheme())){ //getScheme() 方法 用于获取该uri的协议比如 content://...中的 content
//如果是content类型的Uri 则使用普通方式处理
imagePath = getImagePath(uri,null); }else if("file".equalsIgnoreCase(uri.getScheme())){
//如果是 file 类型的 Uri 则直接获取图片路径
imagePath = uri.getPath();
} //通过 上面的 判断解析,下面来跟进图片路径显示 图片
dispalyImage(imagePath); } private void handleImageBeforeKitKat(Intent data){
Uri uri = data.getData();
String imagepath = getImagePath(uri,null);
dispalyImage(imagepath);
} private String getImagePath(Uri uri,String selection){
String path = null;
// 通过 uri和selection 来获取 真实的 图片路径
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;
} private void dispalyImage(String imagepath){
if(imagepath != null){
Bitmap bitmap = BitmapFactory.decodeFile(imagepath);
image.setImageBitmap(bitmap);
}else{
ls("5555555555");
}
} }
宾狗,今天就 记录 到这里啦
Anndroid 使用相机或相册打开图片的更多相关文章
- Android相机、相册获取图片显示并保存到SD卡
Android相机.相册获取图片显示并保存到SD卡 [复制链接] 电梯直达 楼主 发表于 2013-3-13 19:51:43 | 只看该作者 |只看大图 本帖最后由 happy小妖同学 ...
- iOS 从相机或相册获取图片并裁剪
今天遇到一个用户头像上传的问题,需要从相册或者相机中读取图片.代码很简单,抽取关键部分,如下: //load user image - (void)UesrImageClicked { UIActio ...
- Android中使用OKHttp上传图片,从相机和相册中获取图片并剪切
效果:注意:1:网络权限<;;;); intent.putExtra(); ); intent.putExtra(); intent.putExtra(, byteArrayOutputStre ...
- IOS研究院之打开照相机与本地相册选择图片(六)
原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:IOS研究院之打开照相机与本地相册选择图片(六) Hello 大家好 IOS的文章好久都木有更新了,今天更新一篇哈. 这篇文章主要学习 ...
- android 开发 实现一个进入相机拍照后裁剪图片或者进入相册选中裁剪图片的功能
实现思维路径: 以进入相机拍照的思维路线为例子: 1.进入app 2.判断之前是否保存头像,如果有就显示历史图像 (下面代码中在getOldAvatar();方法中执行这个逻辑) 3.点击更换图像的B ...
- 微信小程序:从本地相册选择图片或使用相机拍照。
wx.chooseImage(OBJECT) 从本地相册选择图片或使用相机拍照. OBJECT参数说明: 示例代码: wx.chooseImage({ count: 1, // 默认9 sizeTyp ...
- 微信小程序chooseImage(从本地相册选择图片或使用相机拍照)
一.使用API wx.chooseImage(OBJECT) var util = require('../../utils/util.js') Page({ data:{ src:"../ ...
- Android 从相机或相册或获取图片(转)
参考: https://github.com/ASDbobo/GetPhotoDemo Android 8.0 调取系统摄像头和相册选择图片 9.3 使用Camera拍照
- android 照相或从相册获取图片并裁剪
照相或从相册获取图片并裁剪 在android应用中很多时候都要获取图片(例如获取用户的头像)就需要从用户手机上获取图片.可以直接照,也可以从用户SD卡上获取图片,但获取到的图片未必能达到要求.所以要对 ...
随机推荐
- 微信小程序部署问题总结
1.微信小程序免费SSL证书Https 申请(阿里云申请) 进入阿里云控制台后,选择CA证书服务 选择购买证书 但是阿里云的免费SSL证书藏得比较深,得这样操作才能显示出免费证书 点击Symantec ...
- 【原创】java NIO selector 学习笔记 一
能力有限,仅仅是自己看源码的一些笔记. 主要介绍 可选通道 和 选择器 选择键(SelectableChannel 和 Selector SelectionKey) 选择器(Selector) 选择 ...
- DM企业建站系统v201710 sql注入漏洞分析 | 新版v201712依旧存在sql注入
0x00 前言 本来呢,这套CMS都不想审的了.下载下来打开一看,各种debug注释,排版烂的不行. 贴几个页面看看 感觉像是新手练手的,没有审下去的欲望了. 但想了想,我tm就是新手啊,然后就继续看 ...
- Linux下用ls和du命令查看文件以及文件夹大小
ls的用法 ls -l |grep "^-"|wc -l或find ./company -type f | wc -l 查看某文件夹下文件的个数,包括子文件夹里的. ls -lR ...
- Java学习笔记14(面向对象七:final、static)
final:意为最终,不可变,是一个修饰词 有时候一个类地功能被开发好了,不想让子类重写,修改,这里就会用到final关键字 final修饰类: 不可以被继承,但是可以继承其他类 示例: public ...
- linux 实时同步inotify
#实时同步inotify 1.inotify简介inotify是一种强大的,细腻度的,异步的文件系统事件监控机制,linux内核从2.6.13起,加入了inotify支持,通过INOTIFY可以监控文 ...
- (5编译使用最新opencv)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练 1综述http://www.cnblogs.com/jsxyhelu/p/7907241.html 2环境架设http://www.c ...
- 关于new Date()
1. 将时间戳转换成日期格式 // 简单的一句代码 var date = new Date(时间戳); //获取一个时间对象 /** 1. 下面是获取时间日期的方法,需要什么样的格式自己拼接起来就好了 ...
- webpack构建本地服务器
webpack构建本地服务器 想不想让你的浏览器监测你的代码的修改,并自动刷新修改后的结果,其实Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建, 可以实现你想要的这些 ...
- MYSQL:python 3.x连接数据库的方式
我们想要在我们的mython程序中使用mysql,首先需要安装pymysql模块,安装方式可以使用cmd命令安装, pip3.x install pymysql 首先在我们连接数据库之前先创建一个us ...