安卓操作相机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 使用相机或相册打开图片的更多相关文章

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

    Android相机.相册获取图片显示并保存到SD卡 [复制链接]   电梯直达 楼主    发表于 2013-3-13 19:51:43 | 只看该作者 |只看大图  本帖最后由 happy小妖同学 ...

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

    今天遇到一个用户头像上传的问题,需要从相册或者相机中读取图片.代码很简单,抽取关键部分,如下: //load user image - (void)UesrImageClicked { UIActio ...

  3. Android中使用OKHttp上传图片,从相机和相册中获取图片并剪切

    效果:注意:1:网络权限<;;;); intent.putExtra(); ); intent.putExtra(); intent.putExtra(, byteArrayOutputStre ...

  4. IOS研究院之打开照相机与本地相册选择图片(六)

    原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:IOS研究院之打开照相机与本地相册选择图片(六) Hello 大家好 IOS的文章好久都木有更新了,今天更新一篇哈. 这篇文章主要学习 ...

  5. android 开发 实现一个进入相机拍照后裁剪图片或者进入相册选中裁剪图片的功能

    实现思维路径: 以进入相机拍照的思维路线为例子: 1.进入app 2.判断之前是否保存头像,如果有就显示历史图像 (下面代码中在getOldAvatar();方法中执行这个逻辑) 3.点击更换图像的B ...

  6. 微信小程序:从本地相册选择图片或使用相机拍照。

    wx.chooseImage(OBJECT) 从本地相册选择图片或使用相机拍照. OBJECT参数说明: 示例代码: wx.chooseImage({ count: 1, // 默认9 sizeTyp ...

  7. 微信小程序chooseImage(从本地相册选择图片或使用相机拍照)

    一.使用API wx.chooseImage(OBJECT) var util = require('../../utils/util.js') Page({ data:{ src:"../ ...

  8. Android 从相机或相册或获取图片(转)

    参考: https://github.com/ASDbobo/GetPhotoDemo Android 8.0 调取系统摄像头和相册选择图片 9.3 使用Camera拍照

  9. android 照相或从相册获取图片并裁剪

    照相或从相册获取图片并裁剪 在android应用中很多时候都要获取图片(例如获取用户的头像)就需要从用户手机上获取图片.可以直接照,也可以从用户SD卡上获取图片,但获取到的图片未必能达到要求.所以要对 ...

随机推荐

  1. C# Log4net记录日志

    前言 1.需求 需求很简单,就是在C#开发中高速写日志.比如在高并发,高流量的地方需要写日志.我们知道程序在操作磁盘时是比较耗时的,所以我们把日志写到磁盘上会有一定的时间耗在上面,这些并不是我们想看到 ...

  2. Git 进阶 —— 远程仓库

    一.远程仓库怎么玩 1. 自己搭建一个运行Git的服务器 Git是分布式版本控制系统,同一个Git仓库,可以分布到不同的机器上,但肯定有一台机器有着最原始的版本库,然后别的机器来克隆这个原始版本库,这 ...

  3. C# 多线程传递多个参数

    http://www.cnblogs.com/lvdongjie/p/5416883.html 3. 方式三:采用lambda表达式 对于lambda表达式不熟悉的可以查看微软MSDN上的说明文档.此 ...

  4. C# Excel数据导入到数据库

    http://www.jb51.net/article/44743.htm 假如Excel中的数据如下: 数据库建表如下: 其中Id为自增字段: 代码: 复制代码 代码如下: using System ...

  5. 如何复制Google浏览器的控制台内容

    今天在调用第三方的接口,对着文档,传参数,老是报参数错误,没办法只能把参数打印出来看看,在Google控制台上看,费劲,就想复制出来,格式化一下,然后对着文档进行对比. console.info(JS ...

  6. Ajax同源和跨域

    ajax跨域访问 客户端页面 var url = "http://172.16.91.121:81/FellIn/FellIn.aspx?Action=WXSave&WX_Store ...

  7. Intellij idea破解办法

    最开始的时候intellij用得是社区版,专业版是要钱的.但是社区版的功能确实弱了很多:比如Diagrams功能就没有,比如社区版不支持web项目,想起个tomcat跑个web项目都没法搞.于是,重新 ...

  8. Python day 7(2) 类和实例(1)

    一:面向对象编程 1  面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 2 ...

  9. 每天学一点Docker(5)——了解Docker架构

    Docker的核心组件: 1.Docker客户端 - Client 2.Docker服务器 - Docker deamon 3.Docker镜像 - Image 4.仓库 - Registry 5.D ...

  10. rpc之thrift

    rpc之thrift 一.介绍 thrift是一个rpc(remove procedure call)框架,可以实现不同的语言(java.c++.js.python.ruby.c#等)之间的相互调用. ...