安卓操作相机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资源,这个资源文件需要手动创建,以下操作如图
好了,下面贴一张 程序的 大致流程图,方便理解。
最后是 源码:
1 package com.example.lichangxin.call_camera_and_photos_test;
2
3 import android.annotation.TargetApi;
4 import android.content.ContentUris;
5 import android.content.Intent;
6 import android.content.pm.PackageManager;
7 import android.database.Cursor;
8 import android.graphics.Bitmap;
9 import android.graphics.BitmapFactory;
10 import android.net.Uri;
11 import android.os.Build;
12 import android.provider.DocumentsContract;
13 import android.provider.MediaStore;
14 import android.support.annotation.NonNull;
15 import android.support.v4.app.ActivityCompat;
16 import android.support.v4.content.ContextCompat;
17 import android.support.v4.content.FileProvider;
18 import android.support.v7.app.AppCompatActivity;
19 import android.os.Bundle;
20 import android.util.Log;
21 import android.view.View;
22 import android.widget.Button;
23 import android.widget.ImageView;
24
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.util.jar.Manifest;
29
30 public class MainActivity extends AppCompatActivity {
31
32 private static final int TAKE_PHOTO = 1;
33 private static final int CHOOSE_PHOTO = 2;
34 private ImageView image;
35 private Uri imageUri;
36
37
38 private void ls(String tishi){
39 Log.d("enen",tishi);
40 }
41
42 @Override
43 protected void onCreate(Bundle savedInstanceState) {
44 super.onCreate(savedInstanceState);
45 setContentView(R.layout.activity_main);
46 final Button open_camera = (Button)findViewById(R.id.open_camera);
47 final Button open_album = (Button)findViewById(R.id.open_photo_album);
48 image = (ImageView)findViewById(R.id.image1);
49 open_camera.setOnClickListener(new View.OnClickListener() {
50 @Override
51 public void onClick(View v) {
52 // 创建File 对象,用于存储拍摄后的照片
53 File outputImage = new File(getExternalCacheDir(),"output_image.jpg"); //getExternalCacheDir 获取外部存储目录
54 try{
55 if(outputImage.exists()){ // 这里进行一级过滤 若文件存在 则删除文件
56 outputImage.delete();
57 }
58 outputImage.createNewFile();
59 } catch (IOException e){
60 e.printStackTrace();
61 }
62
63 if(Build.VERSION.SDK_INT >= 24){
64 imageUri = FileProvider.getUriForFile(MainActivity.this,"com.example.lichangxin.call_" +
65 "camera_and_photos_test",outputImage);
66 }else{
67 imageUri = Uri.fromFile(outputImage); //从文件转为uri
68 }
69
70 // 此 if - else 用来判断 平台版本,>=24 用新的API 旧的版本直接用Uri.fromFile
71
72 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
73 intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
74 startActivityForResult(intent,TAKE_PHOTO);
75
76 }
77
78
79 });
80
81 open_album.setOnClickListener(new View.OnClickListener() {
82 @Override
83 public void onClick(View v) {
84 if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
85 != PackageManager.PERMISSION_GRANTED){
86 ActivityCompat.requestPermissions(MainActivity.this,new String[]{
87 android.Manifest.permission.WRITE_EXTERNAL_STORAGE
88 },1);
89 ls("111111111");
90 }else{
91 //执行打开 相册操作
92 openAlbum();
93 }
94 }
95 });
96 }
97
98 //打开相册
99 private void openAlbum(){
100 Intent intent = new Intent("android.intent.action.GET_CONTENT");
101 intent.setType("image/*");
102 startActivityForResult(intent,CHOOSE_PHOTO);
103 }
104
105
106 @Override
107 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
108 switch (requestCode){
109 case 1:
110 ls("2222222222");
111 if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
112 ls("333333333333");
113 openAlbum();
114 }else {
115 Log.d("enen","没有获得权限");
116 }
117 break;
118 default:
119 break;
120 }
121 }
122
123
124 @Override
125 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
126 switch (requestCode){
127 case TAKE_PHOTO:
128
129 if(resultCode == RESULT_OK){
130
131 try{
132 Log.d("enen","jiasi");
133 Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
134 .openInputStream(imageUri));
135 image.setImageBitmap(bitmap);
136 Log.d("enen","jiasi wancheng");
137 }catch (FileNotFoundException e){
138 Log.d("enen","yichang");
139 e.printStackTrace();
140 }
141
142 }
143 break;
144
145 case CHOOSE_PHOTO:
146 if(resultCode == RESULT_OK){
147
148 if(Build.VERSION.SDK_INT >= 19){
149 //4.4以上使用此方法处理图片
150 handleImageOnkitKat(data);
151 }else{
152 //4.4一下 用此方法处理
153 handleImageBeforeKitKat(data);
154 }
155
156 }
157
158
159 default:
160 break;
161 }
162 }
163
164 @TargetApi(19)
165 private void handleImageOnkitKat(Intent data){
166 String imagePath = null;
167 Uri uri = data.getData(); //取得 系统封装过的Uri 进行解析
168 if(DocumentsContract.isDocumentUri(this,uri)){
169 //如果是document类型的Uri 通过document id处理
170 String docId = DocumentsContract.getDocumentId(uri);
171 ls(docId); // 这里输出格式 为 image:26 证明上行代码 取出了id部分 // @***
172 if("com.android.providers.media.documents".equals(uri.getAuthority())){
173 //
174 String id = docId.split(":")[1]; // 字符串分割,解析出 数字格式的id 这里存在疑问 为什么以:为分隔符 (从@***行 解决疑问)
175 String selection = MediaStore.Images.Media._ID + "=" + id;
176 imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
177 }else if("com.android.providers.downloads.documents".equals(uri.getAuthority())){
178 //
179 Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public" +
180 "_downloads"),Long.valueOf(docId));
181 imagePath = getImagePath(contentUri,null);
182 }
183 }else if("content".equalsIgnoreCase(uri.getScheme())){ //getScheme() 方法 用于获取该uri的协议比如 content://...中的 content
184 //如果是content类型的Uri 则使用普通方式处理
185 imagePath = getImagePath(uri,null);
186
187 }else if("file".equalsIgnoreCase(uri.getScheme())){
188 //如果是 file 类型的 Uri 则直接获取图片路径
189 imagePath = uri.getPath();
190 }
191
192 //通过 上面的 判断解析,下面来跟进图片路径显示 图片
193 dispalyImage(imagePath);
194
195 }
196
197 private void handleImageBeforeKitKat(Intent data){
198 Uri uri = data.getData();
199 String imagepath = getImagePath(uri,null);
200 dispalyImage(imagepath);
201 }
202
203 private String getImagePath(Uri uri,String selection){
204 String path = null;
205 // 通过 uri和selection 来获取 真实的 图片路径
206 Cursor cursor = getContentResolver().query(uri,null,selection,null,null);
207 if(cursor!=null){
208 if(cursor.moveToFirst()){
209 path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
210 }
211 cursor.close();
212 }
213 return path;
214 }
215
216 private void dispalyImage(String imagepath){
217 if(imagepath != null){
218 Bitmap bitmap = BitmapFactory.decodeFile(imagepath);
219 image.setImageBitmap(bitmap);
220 }else{
221 ls("5555555555");
222 }
223 }
224
225
226 }
宾狗,今天就 记录 到这里啦😁
知道自己想要什么的人,每一步都在路上。