分享实现Android图片选择的两种方式
作者:hebedich 发布时间:2023-06-28 05:09:27
标签:Android,图片选择
Android选择图片的两种方式:
第一种:单张选取
通过隐式启动activity,跳转到相册选择一张返回结果
关键代码如下:
发送请求:
private static final int PICTURE = 10086; //requestcode
Intent intent = new Intent();
if (Build.VERSION.SDK_INT < 19) {//因为Android SDK在4.4版本后图片action变化了 所以在这里先判断一下
intent.setAction(Intent.ACTION_GET_CONTENT);
} else {
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
}
intent.setType("image/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, PICTURE);
接收结果:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
this.finish();
return;
}
Uri uri = data.getData();
switch (requestCode) {
case PICTURE:
image = FileUtils.getUriPath(this, uri); //(因为4.4以后图片uri发生了变化)通过文件工具类 对uri进行解析得到图片路径
break;
default:
break;
}
this.finish();
}
文件工具类:
public class FileUtils {
private static final String TAG = "FileUtils";
private static final boolean DEBUG = false;
/**
* 获取可读的文件大小
*/
public static String getReadableFileSize(int size) {
final int BYTES_IN_KILOBYTES = 1024;
final DecimalFormat dec = new DecimalFormat("###.#");
final String KILOBYTES = " KB";
final String MEGABYTES = " MB";
final String GIGABYTES = " GB";
float fileSize = 0;
String suffix = KILOBYTES;
if(size > BYTES_IN_KILOBYTES) {
fileSize = size / BYTES_IN_KILOBYTES;
if(fileSize > BYTES_IN_KILOBYTES) {
fileSize = fileSize / BYTES_IN_KILOBYTES;
if(fileSize > BYTES_IN_KILOBYTES) {
fileSize = fileSize / BYTES_IN_KILOBYTES;
suffix = GIGABYTES;
} else {
suffix = MEGABYTES;
}
}
}
return String.valueOf(dec.format(fileSize) + suffix);
}
/**
* 获取文件的文件名(不包括扩展名)
*/
public static String getFileNameWithoutExtension(String path) {
if(path == null) {
return null;
}
int separatorIndex = path.lastIndexOf(File.separator);
if(separatorIndex < 0) {
separatorIndex = 0;
}
int dotIndex = path.lastIndexOf(".");
if(dotIndex < 0) {
dotIndex = path.length();
} else if(dotIndex < separatorIndex) {
dotIndex = path.length();
}
return path.substring(separatorIndex + 1, dotIndex);
}
/**
* 获取文件名
*/
public static String getFileName(String path) {
if(path == null) {
return null;
}
int separatorIndex = path.lastIndexOf(File.separator);
return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length());
}
/**
* 获取扩展名
*/
public static String getExtension(String path) {
if(path == null) {
return null;
}
int dot = path.lastIndexOf(".");
if(dot >= 0) {
return path.substring(dot);
} else {
return "";
}
}
public static File getUriFile(Context context, Uri uri) {
String path = getUriPath(context, uri);
if(path == null) {
return null;
}
return new File(path);
}
public static String getUriPath(Context context, Uri uri) {
if(uri == null) {
return null;
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
if("com.android.externalstorage.documents".equals(uri.getAuthority())) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
} else if("com.android.providers.media.documents".equals(uri.getAuthority())) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
} else if("content".equalsIgnoreCase(uri.getScheme())) {
if("com.google.android.apps.photos.content".equals(uri.getAuthority())) {
return uri.getLastPathSegment();
}
return getDataColumn(context, uri, null, null);
} else if("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if(cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if(cursor != null) cursor.close();
}
return null;
}
}
第二种方式 批量选择图片
如果我们需要类似于微信那样的一次选取多张图片,很明显第一种方式是不能满足需求,那么怎么才能批量选取呢?andorid并提供像单张选取似的批量选取的直接方法,所以我们只能自己从数据库中获得。
首先我们要认识一个类mediastore android中所有的多媒体文件都存储在这个数据库中,例如图片 视频 音频 等等,他通过contentprovider 向其他进程提供数据的接口
想要从mediastore中获得数据,我们可以使用与ContentProvider 对应的ContentResolver
关键代码:
final String[] projectionPhotos = {
MediaStore.Images.Media._ID,//每一列的ID 图片的ID
MediaStore.Images.Media.BUCKET_ID,//图片所在文件夹ID
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,//图片所在文件夹名称
MediaStore.Images.Media.DATA,//图片路径
MediaStore.Images.Media.DATE_TAKEN,//图片创建时间
};
cursor = MediaStore.Images.Media.query(context.getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI
, projectionPhotos, "", null, MediaStore.Images.Media.DATE_TAKEN + " DESC");
所有图片都在cursor里了 再从cursor中取出即可


猜你喜欢
- C# 的类型转换有显式转型 和 隐式转型 两种方式。显式转型:有可能引发异常、精确度丢失及其他问题的转换方式。需要使用手段进行转换操作。隐式
- 简介之前在项目中遇到了一个新需求,领导让我使用本地缓存,来缓存数据库查出的用户信息,经过一番资料查阅和实验,最终确定了使用Caffeine来
- 概要应同学邀请,演示如何使用 PyQt5 内嵌浏览器浏览网页,并注入 Javascript 脚本实现自动化操作。下面测试的是一个廉价机票预订
- analyzer的使用规则查询只能查找倒排索引表中真实存在的项, 所以保证文档在索引时与查询字符串在搜索时应用相同的分析过程非常重要,这样查
- 引言在前两篇文章中,我们了解了ReentrantLock内部公平锁和非公平锁的实现原理,可以知道其底层基于AQS,使用双向链表实现,同时在线
- Mybatis与Ibatis的区别: 1、Mybatis实现了接口绑定,使用更加方便 在ibatis2.x中我们需要在DAO的实现类中指定具
- Android EditText密码的隐藏和显示功能实现效果图:实现代码:首先在xml里创建两个控件 EditText和CheckBox然后
- 一、简介编写手机App时,有时需要使用文字转语音(Text to Speech)的功能,比如开车时阅读收到的短信、导航语音提示、界面中比较重
- 本文主要介绍了C# WinForm状态栏实时显示当前时间(窗体状态栏StatusStrip示例),分享给大家,具体如下:实现效果:通过Sta
- 需求:有些时候,我们需要连接多个数据库,但是,在方法调用前并不知道到底是调用哪个。即同时保持多个数据库的连接,在方法中根据传入的参数来确定。
- 一、线程异常我们在单线程中,捕获异常可以使用try-catch,代码如下所示:using System;namespace Multithr
- Android图片的处理工具类BitmapUtils,供大家参考,具体内容如下项目中经常会用到图片,所以在这先简单的总结一下。闲言少叙,上代
- 前言1.Map里面只能存放对象,不能存放基本类型,例如int,需要使用Integer2.Map集合取出时,如果变量声明了类型,会先进行拆箱,
- 前言我们经常会被问到这么一个问题:SpringBoot相对于spring有哪些优势呢?其中有一条答案就是SpringBoot自动注入。那么自
- 最近正在学习使用Android Studio,发现默认的Hello World程序界面和我们
- 介绍无论是在WPF中还是WinForm中,都有用户控件(UserControl)和自定义控件(CustomControl),这两种控件都是对
- 在项目开发中,我们经常会遇到表中的字段名和表对应实体类的属性名称不一定都是完全相同的情况,下面小编给大家演示一下这种情况下的如何解决字段名与
- Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecim
- 先利用jsoup将得到的html代码“标准化”(Jsoup.parse(String html))方法,然后利用FileWiter将此htm
- Android Service是分为两种:本地服务(Local Service): 同一个apk内被调用远程服务(Remote Servic