服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android工具类ImgUtil选择相机和系统相册

Android工具类ImgUtil选择相机和系统相册

2022-08-14 11:41zst1303939801 Android

这篇文章主要为大家详细介绍了Android工具类ImgUtil选择相机和系统相册,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android选择相机和系统相册的具体代码,供大家参考,具体内容如下

说明:

Android选择相机和系统相册

代码:

1、打开系统相机和系统相册工具类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package com.gxjl.pe.gxjlpesdk.util;
 
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.widget.Toast;
 
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 图片工具类
 * Created by xiaoshuai on 2018/8/17.
 */
 
public class ImgUtil {
 public static final int TAKE_PHOTO = 1;//拍照
 public static final int CHOOSE_PHOTO = 2;//选择相册
 public static final int REQUEST_CODE_CAMERA = 3;//相机权限请求
 public static final int REQUEST_CODE_ALBUM = 4;//相册权限请求
 public static Uri imageUri;//相机拍照图片保存地址
 
 /**
  * 选择图片,从图库、相机
  *
  * @param activity 上下文
  */
 public static void choicePhoto(final Activity activity) {
  //采用的是系统Dialog作为选择弹框
  new AlertDialog.Builder(activity).setTitle("上传头像")//设置对话框标题
    .setPositiveButton("拍照", new DialogInterface.OnClickListener() {//添加确定按钮
     @Override
     public void onClick(DialogInterface dialog, int which) {
      if (Build.VERSION.SDK_INT >= 23) {//检查相机权限
       ArrayList<String> permissions = new ArrayList<>();
       if (activity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        permissions.add(Manifest.permission.CAMERA);
       }
 
       if (permissions.size() == 0) {//有权限,跳转
        //打开相机-兼容7.0
        openCamera(activity);
       } else {
        activity.requestPermissions(permissions.toArray(new String[permissions.size()]), REQUEST_CODE_CAMERA);
       }
      } else {
       //打开相机-兼容7.0
       openCamera(activity);
      }
     }
    }).
    setNegativeButton("系统相册", new DialogInterface.OnClickListener() {
     @Override
     public void onClick(DialogInterface dialog, int which) {
      //如果有权限申请,请在Activity中onRequestPermissionsResult权限返回里面重新调用openAlbum()
      if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
       ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ALBUM);
      } else {
       openAlbum(activity);
      }
     }
    }).show();//在按键响应事件中显示此对话框
 }
 
 /**
  * 打开相机
  * 兼容7.0
  *
  * @param activity
  */
 public static void openCamera(Activity activity) {
  // 创建File对象,用于存储拍照后的图片
  File outputImage = new File(activity.getExternalCacheDir(), "output_image.jpg");
  try {
   if (outputImage.exists()) {
    outputImage.delete();
   }
   outputImage.createNewFile();
  } catch (IOException e) {
   e.printStackTrace();
  }
  if (Build.VERSION.SDK_INT < 24) {
   imageUri = Uri.fromFile(outputImage);
  } else {
   //Android 7.0系统开始 使用本地真实的Uri路径不安全,使用FileProvider封装共享Uri
   //参数二:fileprovider绝对路径 com.dyb.testcamerademo:项目包名
   imageUri = FileProvider.getUriForFile(activity, "com.mandaotech.ewallet.fileprovider", outputImage);
  }
  // 启动相机程序
  Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
  intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
  activity.startActivityForResult(intent, TAKE_PHOTO);
 }
 
 /**
  * 打开图库
  * @param activity
  */
 public static void openAlbum(Activity activity) {
  //调用系统图库的意图
  Intent choosePicIntent = new Intent(Intent.ACTION_PICK, null);
  choosePicIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
  activity.startActivityForResult(choosePicIntent, CHOOSE_PHOTO);
 
  //打开系统默认的软件
  //Intent intent = new Intent("android.intent.action.GET_CONTENT");
  //intent.setType("image/*");
  //activity.startActivityForResult(intent, CHOOSE_PHOTO); // 打开相册
 }
 
 /**
  * 得到byte[]
  * 这里对传入的图片Uri压缩到1M以内,并转换为byte[]后返回
  *
  * @param activity 上下文
  * @param uri  传入图片的Uri
  * @return byte[]
  */
 public static byte[] getImgByteFromUri(Activity activity, Uri uri) throws IOException {
  Bitmap bitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), uri);
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);//100表示不压缩,直接放到out里面
  int options = 90;//压缩比例
  while (out.toByteArray().length / 1024 > 200) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
   out.reset(); // 重置baos即清空baos
   bitmap.compress(Bitmap.CompressFormat.JPEG, options, out);// 这里压缩options%,把压缩后的数据存放到baos中
   options -= 10;// 每次都减少10
  }
  byte[] bs = out.toByteArray();
 
  return bs;
 }
 
}

相机选择:采用固定地址选择大图方式,上段代码块是适配7.0的,因为Android 7.0系统开始 使用本地真实的Uri路径不安全,使用FileProvider封装共享Uri。其中android:name、exported、 android:grantUriPermissions、取值固定,android:authorities取值为:“自己项目包名”.fileprovider。

2、申请权限确认

工具类中点击申请权限,可以在Activity中检测用户是否同意了权限

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  switch (requestCode) {
   case REQUEST_CODE_ALBUM://相册存储权限
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     ImgUtil.openAlbum(this);
    } else {
     UiUtil.showToast(this, "选择图库需要同意权限");
    }
    break;
   case REQUEST_CODE_CAMERA://相机拍照权限
    if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//允许
     ImgUtil.openCamera(OcrHandReviewActivity.this);
    } else {//拒绝
     UiUtil.showToast(this, "只有同意相机权限,才能使用扫码功能");
    }
    break;
   default:
  }
 }

3、相机和相册放回

在activity中得到拍照和选择的图片

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//相机、相册、剪切 返回
 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
 
  //正确返回
  if (resultCode == RESULT_OK) {
   switch (requestCode) {
    case ImgUtil.TAKE_PHOTO://相机返回
     Log.e("返回相机", ImgUtil.imageUri.toString());
  
  GlideApp.with(ElecIdPAActivity.this)
        .load(ImgUtil.imageUri)
        .skipMemoryCache(true)
        .diskCacheStrategy( DiskCacheStrategy.NONE )
        .into(iv_zhengmain_photo);
     break;
    case ImgUtil.CHOOSE_PHOTO://相册返回
     try {
      if (data != null) {
       //相册返回
       Uri uri = data.getData();
       Log.e("返回相册", uri.toString());
  
  GlideApp.with(ElecIdPAActivity.this)
   .load(uri)
   .skipMemoryCache(true)
   .diskCacheStrategy( DiskCacheStrategy.NONE )
   .into(iv_zhengmain_photo);
      }
     } catch (Exception e) {
      e.printStackTrace();
      UiUtil.showToast(this, "图片选择失败");
     }
     break;
   }
  } else {
   UiUtil.showToast(this, "图片选择失败");
  }
 }

4、AndroidManifest.xml权限声明

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!--获取sd卡写的权限,用于文件上传和下载-->
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
 <!--允许读取手机状态-->
 <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 <!-- 相机权限 -->
 <uses-permission android:name="android.permission.CAMERA"/>
 <uses-permission android:name="android.permission.VIBRATE"/>
 <uses-permission android:name="android.permission.FLASHLIGHT"/>
 
<application
 
 <!--7.0相机权限-->
  <provider
   android:name="android.support.v4.content.FileProvider"
   android:authorities="com.dyb.testcamerademo.fileprovider"
   android:exported="false"
   android:grantUriPermissions="true">
   <meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths"/>
  </provider>

5、file_paths.xml

android:resource=“@xml/file_paths”中@xml/的文件名字可以随便起,但一般规范化都用此名。
xml包下(在res下面新建包xml,然后在xml下面新建file_paths.xml文件)

* file_paths.xml源码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
 
 <!--
 name属性的值可以随便写,别名
 path属性的值表示共享的具体位置,设置空就表示将整个SD卡进行共享
  -->
 <paths>
  <external-path
   name="camera_photos"
   path=""/>
 </paths>
</paths>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/u012246458/article/details/79640980

延伸 · 阅读

精彩推荐
  • AndroidAndroid消息处理机制Looper和Handler详解

    Android消息处理机制Looper和Handler详解

    Android应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队例,应用程序的主线程不断地从这个消息队例中获取消息(Looper),然后对这些...

    Android开发网9672021-03-09
  • AndroidAndroid编程实现识别与挂载U盘的方法

    Android编程实现识别与挂载U盘的方法

    这篇文章主要介绍了Android编程实现识别与挂载U盘的方法,对比分析了Android针对U盘的识别与挂载技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    goleftgoright6952021-05-31
  • AndroidAndroid自定义ActionBar实例

    Android自定义ActionBar实例

    这篇文章主要介绍了Android自定义ActionBar的实现方法,以实例形式较为详细的分析了自定义ActionBar的原理与具体步骤,并附带完整实例代码供大家下载查看,需要...

    Android开发网7542021-03-11
  • AndroidAndroid实现自动播放图片功能

    Android实现自动播放图片功能

    这篇文章主要为大家详细介绍了Android实现自动播放图片功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    瘦子小姐6032022-03-02
  • AndroidAndroid4.0.x Home键事件拦截监听的方法

    Android4.0.x Home键事件拦截监听的方法

    这篇文章主要介绍了Android4.0.x Home键事件拦截监听的方法,对比分析了2.3.x的实现方法,分析了4.0.x实现Home键事件拦截监听的相关技巧,需要的朋友可以参考下...

    goleftgoright8512021-05-31
  • AndroidAndroid Metro菜单实现思路及代码

    Android Metro菜单实现思路及代码

    在安卓平台上实现一下Metro菜单效果,之前有介绍过了,相信大家对此不会陌生了吧,感兴趣的朋友可以了解下哈...

    Android开发网6512021-01-25
  • AndroidAndroid使用TransitionDrawable渐变切换多张图片

    Android使用TransitionDrawable渐变切换多张图片

    这篇文章主要为大家详细介绍了Android使用TransitionDrawable渐变切换多张图片,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    sinat_251123216842022-07-29
  • AndroidAndroid编程ViewPager回弹效果实例分析

    Android编程ViewPager回弹效果实例分析

    这篇文章主要介绍了Android编程ViewPager回弹效果,以实例形式较为详细的分析了ViewPager回弹效果的相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    freesonhp6372021-04-06