首页 技术 正文
技术 2022年11月10日
0 收藏 452 点赞 4,287 浏览 6905 个字

安卓操作相机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资源,这个资源文件需要手动创建,以下操作如图

Anndroid 使用相机或相册打开图片

好了,下面贴一张 程序的 大致流程图,方便理解。

Anndroid 使用相机或相册打开图片

最后是 源码:

 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");
}
} }

宾狗,今天就 记录 到这里啦

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,493
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,907
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,740
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,495
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,133
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,297