分享实现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中取出即可
相关文章
Android使用Jetpack Compose开发零基础起步教程
Jetpack Compose是用于构建原生Android UI的现代工具包。Jetpack Compose使用更少的代码,强大的工具和直观的Kotlin API,简化并加速了Android上的UI开发2023-04-04
最新评论