如果开发一个自定义相册功能. 一般而言,顶部会有3个tab,分别是"全部", "照片"和"视频", 但是如果产品在文档上随手加上了一个"喜欢"列,就会非常的麻烦. 因为根本没法从媒体库中获取到类似这样的一个字段.
解决思路
获取媒体库数据, 肯定是用ContentResolver
来操作的. 这个步骤就不提.
在debug查看了Cursor
返回的所有数据列以后, 发现了一个字段tag
, 他虽然不是我们要的favorite
(喜欢)功能,但是可以用上.
就是将这个tag
的值写上我们自定义的一个值, 比如favorite
, 然后下次查询的时候, 直接查询这个tag
的值, 如果它的值为null
就表示没有被用户点击"喜欢", 如果等于我们自定义的字段favorite
, 则表示被标记了喜欢.
实现
我们先定义一个字段,用来标记喜欢
public static final String TAG_FAVORITE = "favorite";
再假设有一个Model类代表我们的相册类, 定义为Album
, 然后结构如下
public class Album {
public int id;
public boolean favorite;
public long addDate;
public String path;
public int width;
public int height;
public String mime;
public long duration;
public String displayName;
public int orientation;
public boolean isVideo;
public boolean isChecked;
// .... 省略其他的equals, 序列化之类的代码
}
接着就可以实现标记为相册为喜欢和不喜欢的方法了. 为了支持批量操作. 所以使用了applyBatch
方法.
/**
* 标记资源为[喜欢]或者移除此标记
*
* @param albums 被操作的数据
* @param favorite true标记为喜欢, false清除标记
*/
public void markAlbumsFavorite(List<Album> albums, boolean favorite) {
final Uri queryUri = MediaStore.Files.getContentUri("external");
ContentResolver resolver = ContextProvider.get().getContext().getContentResolver();
String selection = MediaStore.Files.FileColumns._ID + " = ?";
ArrayList<ContentProviderOperation> operations =
albums.stream()
.map(album ->
ContentProviderOperation.newUpdate(queryUri)
.withSelection(
selection,
new String[] {String.valueOf(album.id)})
.withValue(
MediaStore.Video.VideoColumns.TAGS,
favorite ? TAG_FAVORITE : null)
.build())
.collect(Collectors.toCollection(ArrayList::new));
try {
resolver.applyBatch(queryUri.getAuthority(), operations);
} catch (Exception e) {
e.printStackTrace();
}
}
里面使用了Java8
的流式操作Stream
, 如果看不懂, 我觉得可以学习一波这个东西. 学完了以后, 根本不想再用for
循环了...
然后就是查询的部分了.
在查询数据的代码中, 加上如下这么一段:
// ... 省略了查询的字段设置等...
Cursor cursor =
context.getContentResolver()
.query(queryUri, projection, selection, selectionArgs, sortOrder + limit);
if (cursor == null) {
return new LinkedHashMap<>();
}
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Album album = new Album();
album.id = cursor.getInt(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID));
String favorite = null;
try {
// 个别手机在第一次设置tags之前获取的话会出错
favorite =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TAGS));
} catch (Exception ignored) {
}
album.favorite = TextUtils.equals(TAG_FAVORITE, favorite);
// ... 省略后续的字段设置 ...
}
大概就是这样.
网友评论