- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在为 Android 开发一个“照片库”类型的应用程序。它最初是 Udacity 开发 Android 应用程序的最终项目,因此它的整体结构( Activity 、内容提供者等)应该非常健全,并且被 Udacity/Google 接受认证。
然而,它还没有 100% 完成,我仍在努力改进它。
我想做的事情应该非常简单;将设备上的所有图像(作为缩略图)加载到 MainActivity 中的 GridView,DetailActivity 显示全尺寸图像 + 一些元数据(标题、大小、日期等)。
类(class)要求我们编写一个 ContentProvider,所以我有一个 query() 函数,它基本上从 MediaStore 获取数据,并将游标返回到 MainActivity 的 GridView。至少在我的设备(Sony Xperia Z1、Android 5.1.1)上,这几乎可以完美运行。有一些错误和怪癖,但总的来说,我可以始终在我的应用程序中找到我手机上的所有图像,然后单击它们以查看详细信息。
但是,当我尝试在我 friend 的 Sony Xperia Z3 上安装该应用程序时,一切都失败了。没有图像出现,虽然我显然检查过他手机上实际上有大约 100 张照片。在另一位 friend 的手机(全新的三星 S6)上也一样:-(
这是主要问题。在我的手机上,东西正常,“次要”错误涉及相机拍摄新照片时,它不会自动加载到我的应用程序中(作为缩略图)。看来我需要弄清楚如何触发扫描,或者加载/生成新拇指所需的任何东西。这在我的愿望 list 上也很靠前。
正如我所说,我相信所有这一切真的应该非常简单,所以也许我所有的困难都表明我正在以完全错误的方式解决问题? 这是我的 query() 函数正在执行的操作:
获取所有缩略图的光标,来自 MediaStore.Media.Thumbnails.EXTERNAL_CONTENT_URI
获取所有图像的光标,来自 MediaStore.Media.Images.EXTERNAL_CONTENT_URI
加入这些,在 MediaStore.Media.Thumbnails.IMAGE_ID = MediaStore.Media.Images._ID
使用 CursorJoiner
返回结果 retCursor
(在连接中生成)
-- 请查找完整代码 in this previous post.
虽然这看起来(对我来说)是正确的,但也许这真的不是解决这个问题的方法?顺便说一下,我加入了缩略图和图像,这样我就可以在 GridView 中显示一些元数据(例如拍摄日期)和缩略图。我已经确定了加入的问题,特别是因为如果我将其简化为仅将拇指加载到 GridView 中,那么这一切都可以正常工作——在我 friend 的手机上也是如此。 (加载新照片除外。)
不知何故,我关于 IMAGE_ID
和 _ID
始终一致的假设是不正确的?我见过 post on AirPair ,描述了一个类似的图库应用程序,而教程实际上在这方面略有不同。他没有尝试连接游标,而是获取缩略图游标并对其进行迭代,adding data from Images using individual queries to the MediaStore ... 但这是最有效的方法吗?- 然而,他的解决方案确实将缩略图加入了 ID 上的相应图像:
Cursor imagesCursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
filePathColumn,
MediaStore.Images.Media._ID + "=?", new String[]{imageId}, // NB!
null);
总而言之,我需要以下方面的帮助:
最佳答案
好吧,看来我终于想通了这一切。我想我会在这里分享给任何可能感兴趣的人。
我想达到什么目的?
经过大量试验和错误,并尝试使用 MediaStore,我了解到缩略图表 (MediaStore.Images.Thumbnails) 不能期望在任何给定时间都是最新的。 将缺少缩略图的图像,反之亦然(孤立的缩略图)。特别是当相机应用程序拍摄新照片时,显然它不会立即创建缩略图。直到图库应用程序(或等效应用程序)打开,缩略图表才会更新。
关于如何解决这个问题,我得到了各种有用的建议,主要集中在查询图像表 (MediaStore.Images.Media) 上,然后以某种方式一次一行地使用缩略图扩展光标。虽然这确实有效,但它导致应用程序非常慢,并且在我的设备上为大约 2000 张图像消耗了大量内存。
确实应该可以简单地 JOIN(左外连接)缩略图表和图像表,这样我们就可以获得所有图像和缩略图(当它们存在时)。否则,我们将缩略图 DATA 列保留为 null
,并自行生成那些特定的缺失缩略图。真正酷的是将这些缩略图插入到 MediaStore 中,但我还没有研究过。
所有这一切的主要问题是使用 CursorJoiner .出于某种原因,它要求两个游标都按升序排序,比方说按 ID。然而,这意味着最旧的图像优先,这确实是一个蹩脚的画廊应用程序。然而,我发现 CursorJoiner 可以被“愚弄”,通过简单地按 ID*(-1)
排序来允许降序:
Cursor c_thumbs = getContext().getContentResolver().query(
MediaStore.Images.Thumnails.EXTERNAL_CONTENT_URI,
null, null, null,
"(" + MediaStore.Images.Thumnails.IMAGE_ID + "*(-1))");
Cursor c_images= getContext().getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, null, null,
"(" + MediaStore.Images.Media._ID + "*(-1))");
不过,只要行匹配,就可以正常工作(BOTH
情况)。但是,当您遇到游标唯一的行(LEFT
或 RIGHT
情况)时,反向排序会扰乱 CursorJoiner 类的内部工作。但是,对左右游标进行简单的补偿就足以“重新对齐”连接,使其回到正轨。请注意 moveToNext()
和 moveToPrevious()
调用。
// join these and return
// the join is on images._ID = thumbnails.IMAGE_ID
CursorJoiner joiner = new CursorJoiner(
c_thumbs, new String[] { MediaStore.Images.Thumnails.IMAGE_ID }, // left = thumbnails
c_images, new String[] { MediaStore.Images.Media._ID } // right = images
);
String[] projection = new String{"thumb_path", "ID", "title", "desc", "datetaken", "filename", "image_path"};
MatrixCursor retCursor = new MatrixCursor(projection);
try {
for (CursorJoiner.Result joinerResult : joiner) {
switch (joinerResult) {
case LEFT:
// handle case where a row in cursorA is unique
// images is unique (missing thumbnail)
// we want to show ALL images, even (new) ones without thumbnail!
// data = null will cause a temporary thumbnail to be generated in PhotoAdapter.bindView()
retCursor.addRow(new Object[]{
null, // data
c_images.getLong(1), // image id
c_images.getString(2), // title
c_images.getString(3), // desc
c_images.getLong(4), // date
c_images.getString(5), // filename
c_images.getString(6)
});
// compensate for CursorJoiner expecting cursors ordered ascending...
c_images.moveToNext();
c_thumbs.moveToPrevious();
break;
case RIGHT:
// handle case where a row in cursorB is unique
// thumbs is unique (missing image)
// compensate for CursorJoiner expecting cursors ordered ascending...
c_thumbs.moveToNext();
c_images.moveToPrevious();
break;
case BOTH:
// handle case where a row with the same key is in both cursors
retCursor.addRow(new Object[]{
c_thumbs.getString(1), // data
c_images.getLong(1), // image id
c_images.getString(2), // title
c_images.getString(3), // desc
c_images.getLong(4), // date
c_images.getString(5), // filename
c_images.getString(6)
});
break;
}
}
} catch (Exception e) {
Log.e("myapp", "JOIN FAILED: " + e);
}
c_thumbs.close();
c_images.close();
return retCursor;
然后,在“PhotoAdapter”类中,它为我的 GridView
创建元素并将数据从 ContentProvider(上面的 retCursor
)返回的游标绑定(bind)到这些元素中,我按以下方式创建缩略图(当 thumb_path
字段为 null
时):
String thumbData = cursor.getString(0); // thumb_path
if (thumbData != null) {
Bitmap thumbBitmap;
try {
thumbBitmap = BitmapFactory.decodeFile(thumbData);
viewHolder.iconView.setImageBitmap(thumbBitmap);
} catch (Exception e) {
Log.e("myapp", "PhotoAdapter.bindView() can't find thumbnail (file) on disk (thumbdata = " + thumbData + ")");
return;
}
} else {
String imgPath = cursor.getString(6); // image_path
String imgId = cursor.getString(1); // ID
Log.v("myapp", "PhotoAdapter.bindView() thumb path for image ID " + imgId + " is null. Trying to generate, with path = " + imgPath);
try {
Bitmap thumbBitmap = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imgPath), 512, 384);
viewHolder.iconView.setImageBitmap(thumbBitmap);
} catch (Exception e) {
Log.e("myapp", "PhotoAdapter.bindView() can't generate thumbnail for image path: " + imgPath);
return;
}
}
关于android - 查询 MediaStore : Joining thumbnails and images (on ID),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32782085/
我正在测试设置SQLAlchemy以映射现有数据库。这个数据库是很久以前自动建立的,它是由我们不再使用的先前的第三方应用程序创建的,因此 undefined 某些预期的事情,例如外键约束。该软件将管理
这个问题在这里已经有了答案: What is the difference between "INNER JOIN" and "OUTER JOIN"? (28 个答案) 关闭 7 年前。 INNE
这个问题在这里已经有了答案: What is the difference between "INNER JOIN" and "OUTER JOIN"? (29 个回答) 关闭7年前. INNER J
假设有两个表: table1.c1 table1.c2 1 1 A 2 1 B 3 1 C 4 2
假设有两个表: table1.c1 table1.c2 1 1 A 2 1 B 3 1 C 4 2
一.先看一些最简单的例子 例子 Table A aid adate 1 a1 2&nb
数据库操作语句 7. 外连接——交叉查询 7.1 查询 7.2 等值连接 7.3 右外
我有两个表 'users' 和 'lms_users' class LmsUser belongs_to :user end class User has_one :lms_user
我试图避免在 Rails 中对我的 joins 进行字符串插值,因为我注意到将查询器链接在一起时灵活性会降低。 也就是说,我觉得 joins(:table1) 比 joins('inner join
我有这个代码 User.find(:all, :limit => 10, :joins => :user_points, :select => "users.*, co
我刚刚开始探索 Symfony2,我很惊讶它拥有如此多的强大功能。我开始做博客教程在: http://tutorial.symblog.co.uk/ 但使用的是 2.1 版而不是 2.0 我的问题是我
什么是 SQL JOIN什么是不同的类型? 最佳答案 插图来自 W3schools : 关于SQL JOIN 和不同类型的 JOIN,我们在Stack Overflow上找到一个类似的问题: http
我有两个 Hive 表,我正在尝试加入它们。这些表没有被任何字段聚集或分区。尽管表包含公共(public)键字段的记录,但连接查询始终返回 0 条记录。所有数据类型都是“字符串”数据类型。 连接查询很
我正在使用 Solr 的(4.0.0-beta)连接功能来查询包含具有父/子关系的文档的索引。连接查询效果很好,但我只能在搜索结果中获得父文档。我相信这是预期的行为。 但是,是否有可能在搜索结果中同时
我正在使用可用的指南/api/书籍自学 Rails,但我无法理解通过三种方式/嵌套 has_many :through 关联进行的连接。 我有用户与组相关联:通过成员(member)资格。 我在多对多
什么是 SQL JOIN,有哪些不同的类型? 最佳答案 插图来自 W3schools : 关于SQL JOIN 和不同类型的 JOIN,我们在Stack Overflow上找到一个类似的问题: htt
我正在尝试访问数据库的两个表。在商店里,我保留了一个事件列表,其中包含 Table Event id, name,datei,houri, dateF,Hourf ,capacity, age ,de
我有 4 个表:booking、address、search_address 和 search_address_log 表:(相关列) 预订:(pickup_address_id, dropoff_a
我在YML中有以下结构:。我正试着创造一个这样的结构:。作业名称和脚本用~分隔,作业用;分隔。。我可以使用以下命令使其正常工作。然而,我想知道是否可以用一个yq表达式来完成,而不是通过管道再次使用yq
我在YML中有以下结构:。我正试着创造一个这样的结构:。作业名称和脚本用~分隔,作业用;分隔。。我可以使用以下命令使其正常工作。然而,我想知道是否可以用一个yq表达式来完成,而不是通过管道再次使用yq
我是一名优秀的程序员,十分优秀!