学习使用安卓系统的相机和相册

概述

这里主要介绍如何调用系统的手机进行拍照,或者直接从相册中找图片。


学习使用系统自带的相机

权限

在Android4.4系统之前,访问SD卡的应用关联目录要声明权限,之后就可以不用声明了,为了兼容老版本,还是声明权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

代码一:准备工作

    public static final int TAKE_PHOTO =1; //表示打开相机的标识符,知己定义的
    private ImageView picture; //用来展示最后的图片
    private Uri imageUri; //表示图片文件的真实路径
    ---------------接下来是打开相机前的准备工作------------------
    File outputImage = new File(getExternalCacheDir(),"output_image.jpg");
    //创建File对象,用于存贮拍照后的照片
    //上述文件路径打印出来如下:
  // /storage/emulated/0/Android/data/com.yuyi.viewevent/cache/output_image.jpg
   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.yuyi.viewevent",outputImage);
           //参数一是:Context对象,参数二:任意的字符串,参数三:file对象
           //详细介绍,在最后面。
        }else {
           imageUri = Uri.fromFile(outputImage);
           /**前面那个版本判断如果运行低于7.0的就直接把file对象转换成Uri对象,
            得到一个本地真实路径,如果7.0以上,直接使用本地真实路径会认为不安全,
            所以使用了FileProvider这个特殊的内容提供器,可以选择性地将封装过得
            Uri共享给外部。
            */
         }
   //打印出imageUri的log如下:         file:///storage/emulated/0/Android/data/com.yuyi.viewevent/cache/output_image.jpg

      //隐世意图启动相机
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);//将uri传递进去
    startActivityForResult(intent,TAKE_PHOTO);

代码二:对于拍照结果的处理

 case TAKE_PHOTO:
    if (resultCode == RESULT_OK){
       try {
    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
    //将存在本地的图片进行读取成为bitmap
    picture.setImageBitmap(bitmap);
           } catch (FileNotFoundException e) {
                    e.printStackTrace();
           }
           }
     break;

学习读取相册中的图片

代码一

    public  static final int CHOOSE_PHOTO=2; //作为从相册选取的标识符
    private ImageView picture; //表示用于展示的图片
    private Uri imageUri; //表示文件的真实路径

代码二

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_DENIED){
                    ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);//动态获取权限
  }else {
         openAlbum();//此方法表示主动去打开相册
  }
  /**在这里面完成的是先进行运行时权限处理,动态去获取权限,因为相册中的照片都是存储
  在SD卡上,我们要从SD卡中读取照片就要这个权限,表示授予了程序对SD卡读和写的能力。*/

获取运行时权限之后,再走这个重写的方法:
 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull 
               String[] permissions, @NonNull int[] grantResults) {
      switch (requestCode){
                case 1:
                    if (grantResults.length > 0 &&grantResults[0] ==  
                    PackageManager.PERMISSION_GRANTED){
                        openAlbum();//表示用户最后给了权限,可以去打开相册
                    }else {
                    Toast.makeText(this,"未获取权限",Toast.LENGTH_SHORT).show();
                    }
                     break;
            }
    }

接下来会走打开相册的方法:
 private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,CHOOSE_PHOTO);
    }

当选择了照片之后,走下列方法:
case CHOOSE_PHOTO:
                if (resultCode == RESULT_OK){
                    if (Build.VERSION.SDK_INT >=19){
                        handleImageOnkitKat(data);
                        //上述方法表示:4.4及以上系统使用这个方法处理图片
                    }else {
                        handleImageBeforKitKat(data);
                        //上述方法表示:4.4及以下系统使用这个方法处理图片
                    }
                }
                break;
//因为4.4以上系统的手机,选中相册的图片不再返回图片真实的Uri了,而是一个封装过的Uri,因此要对于这个Uri进行解析才可以,

先看看在4.4以上系统使用时候,如何处理图片:
这里写图片描述


将从相册得到的数据进行解析结果进行转换
/**因为返回的Uri是doucument类型的话,得到doucument id,如过这个uri的authority是
media格式的话,还需通过字符串分割方式取出后半部分才能得到真的数字id,取出的id用于构建新的Uri的条件语句,然后将值传入getImagePath(),就可以得到真实路径,最后进行展示就可以,别的类型的比如file和content类型的可以直接进行解析。
*/
 private String getImagePath(Uri uri,String selection){
        String path = null;
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;
    }

针对与4.4一下的版本
private void handleImageBeforKitKat(Intent data) {
        Uri uri = data.getData();
        String imagepath = getImagePath(uri,null);
        displayImage(imagepath);
    }
   //由于没有封装过,可以直接进行解析。

展示图片的方法
private void displayImage(String imagePath){
        if (imagePath != null){
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            picture.setImageBitmap(bitmap);
        }else {
            Toast.makeText(this,"失败了",Toast.LENGTH_SHORT).show();
        }
    }
    //核心思想就是根据路径转换成为Bitmap图片

关于内容提供器的配置
首先:在清单文件中
<provider
    android:authorities="com.yuyi.viewevent.fileprocider"
    //authorities 属性的值必须和刚才FileProvider.getUriForFile()方法中的第二个参数一致
    android:name="android.support.v4.content.FileProvider"
    //name 的值是固定的
    android:exported="false"
    android:grantUriPermissions="true">
       <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"/>
     //内部使用的<mete_data>用来指定Uri的共享路径,并引用了一个@xml/file_paths的资源
</provider>

new->xml(文件夹名字)->file_paths.xml文件
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name = "my_images" path=""/>
</paths>

总结

这里只是讲了对于图片的获取,没有涉及对于图片裁剪的处理,内容主要是自学自《第一行代码》,感谢郭霖老师。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值