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卡上获取图片,但获取到的图片未必能达到要求.所以要对 ...
随机推荐
- pc端常用导航
应为经常要写网站,导航部分基本一样,没必要每次都写一遍,下次直接来复制: HTML: <nav> <div class="clearfix container"& ...
- [编织消息框架][消息服务]rmi
RMI(即Remote Method Invoke 远程方法调用) 远程对象: 用于远程客户端调用 必需继承java.rmi.Remote,每个调用方法必须添加java.rmi.RemoteExcep ...
- WPF-控件(1)
小记:最近公司使用WPF开发一款新的产品,从零基础开始学习WPF,在看书的过程中,有些内容需要规整到一起,最终选择了博客园,希望对自己所掌握的知识有所规整. --------------------- ...
- 房上的猫:for循环,跳转语句与循环结构,跳转语句进阶
一.for循环 1.定义: for循环语句的主要作用是反复执行一段代码,直到满足一定条件为止 2.组成部分: (1)初始部分:设置循环的初始状态 (2)循环体:重复执行的代码 (3)迭代部分: ...
- UWP 手绘视频创作工具技术分享系列 - 有 AI 的手绘视频
AI(Artificial Intelligence)正在不断的改变着各个行业的形态和人们的生活方式,图像识别.语音识别.自然语言理解等 AI 技术正在自动驾驶.智能机器人.人脸识别.智能助理等领域中 ...
- c3p0使用记录
首先要导入c3p0包.c3p0下载解压后,lib目录下有三个包,使用mysql的话,只需要导入c3p0-0.9.5.2.jar,mchange-commons-java-0.2.11.jar. 要连接 ...
- 理解css伪类和伪元素
伪类就是可以通过直接添加一个类样式达到同等效果,而伪元素,则需要先添加一个元素,然后在元素上添加样式才能达到同等效果 伪类 :active 向被激活的元素添加样式. :focus 向拥有键盘输入焦点的 ...
- java 数据格式验证类
作为一个前端,懂一点java,php之类的,甚好. 我所在的项目前端采用的就是java的spring mvc框架,所以我们也写java,掐指一算,也快一年了. 前端而言,验证是一个坎,绕不过去的,前面 ...
- python基础(三)编码,深浅copy
编码,深浅copy encode,decode在python2中使用的一些迷糊,python3中更容易理解 要理解encode和decode,首先我们要明白编码,字符和二进制的相关概念,简单来说,计算 ...
- 【Manacher算法】求最长回文串的优秀算法
先贴一下代码~ //by 减维 #include<cstdio> #include<iostream> #include<cstring> #include< ...