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 }

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

 

posted @ 2017-06-20 18:02  昕无旁骛  阅读(1004)  评论(0编辑  收藏  举报