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资源,这个资源文件需要手动创建,以下操作如图
好了,下面贴一张 程序的 大致流程图,方便理解。
最后是 源码:
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 }
宾狗,今天就 记录 到这里啦😁
知道自己想要什么的人,每一步都在路上。