如何获得关于画廊应用程序可见的每个新图像的通知?
Posted
技术标签:
【中文标题】如何获得关于画廊应用程序可见的每个新图像的通知?【英文标题】:How to get notified of each new image being visible to the gallery app? 【发布时间】:2014-02-14 04:19:24 【问题描述】:背景
当用户下载一张新图片或使用相机拍摄一张图片时,图库应用会更新以显示新图片。
我需要在每张新图片创建后立即收到通知,无论它是如何创建的(相机、浏览器等),就像图库应用程序显示的那样。
问题
事实证明,有一个 mediaScanner android 组件负责扫描所有类型的媒体文件,当它完成时,它应该发送一个意图“MEDIA_SCANNER_FINISHED”(如this example 所示)。
所以我添加了下一个代码,希望每次用户从相机应用中拍照时它都会显示一个祝酒词:
清单:
...
<receiver android:name="com.example.newgalleryimagereceivertest.MediaScannerBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.MEDIA_SCANNER_FINISHED" />
<data android:scheme="file" />
</intent-filter>
</receiver>
...
java 文件:
package com.example.newgalleryimagereceivertest;
...
public class MediaScannerBroadcastReceiver extends BroadcastReceiver
@Override
public void onReceive(final Context context, final Intent intent)
android.util.Log.d("AppLog", "gallery has new images");
由于某种原因,此代码不起作用...
问题
代码有什么问题?
在拍照后会调用 broadcastReceiver 吗?
正确的做法是什么?
我真的需要使用 contentObserver 并监控它的变化(使用 this 之类的东西),并为此保持应用程序运行吗?我真的希望不会……
【问题讨论】:
我知道 Toast 的工作存在一些限制。 UI 线程和活动上下文。所以,在说代码不起作用之前。你可以做一个日志并仔细检查Log.d("toast", "gallery have new images");
是的,使用日志也显示它不起作用。现在也将在这里更新代码。在这里的清单上还发现了一个奇怪的东西,我已经修复了。
只是猜测,可能是"android.hardware.action.NEW_PICTURE"
或者"com.android.camera.NEW_PICTURE"
被调用了
@a.ch.这只会被本机相机应用程序调用,并且只能从某个 API 调用。我希望收到画廊可以显示的任何图像的通知,并且不受特定应用程序的限制。拍摄新照片时,第三方相机不会使用此意图。
您好,您有解决办法吗?我被困在同一点上。
【参考方案1】:
ACTION_MEDIA_SCANNER_FINISHED 用于向图库添加新的目录:
广播操作:媒体扫描仪已完成对目录的扫描。 扫描目录的路径包含在 Intent.mData 中 字段。
常量值:“android.intent.action.MEDIA_SCANNER_FINISHED”
您应该使用ACTION_MEDIA_SCANNER_SCAN_FILE,它用于添加新的文件——不仅仅是目录:
广播操作:请求媒体扫描仪扫描文件并添加它 到媒体数据库。文件的路径包含在 Intent.mData 字段。
常量值:“android.intent.action.MEDIA_SCANNER_SCAN_FILE”
您可以使用here 讨论的代码测试此Intent
。
此外,据报道some 需要包含 mime 类型 和文件扩展名,例如:
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.png" />
【讨论】:
遗憾的是,我仍然一无所获。它对你有用吗?你有没有运行你的应用程序,当你用相机拍照时,你有没有得到一个意图? @androiddeveloper 我在关于 mime 类型和文件扩展名的答案中添加了更多内容。这行得通吗? 还是什么都没有。我也试过 android:pathPattern=".*\\.jpg" 和 android:pathPattern=".*\\.jpeg" 。我想知道它是正则表达式还是通配符。 我认为这两个选项不像答案中所述的那样相似。如文档中所述,_SCAN_FILE 用于请求扫描,而 _SCANNER_FINISHED 用于通知媒体扫描器已完成。 _SCANNER_FINISHED 广播通知您有新数据,但随后您需要查询媒体存储以查找新数据,AFAIK。【参考方案2】:您可能还想考虑将这些添加到您的过滤器中:
com.android.camera.NEW_PICTURE
com.android.camera.NEW_VIDEO
android.hardware.action.NEW_PICTURE
android.hardware.action.NEW_VIDEO
android.hardware.x 动作是“官方”当前广播,但 com.android.x 是由三星设备和旧版 Android 发送的。
【讨论】:
这个问题太老了,所以我不再需要它了。然而,这很有趣。其他 OEM 的设备会发生什么情况?它们运作良好吗? @androiddeveloper 那么你是如何解决你的问题的呢?你能告诉我们你的方法吗? @HendraWijayaDjiono 我没有解决它,因为我没有它了。【参考方案3】:我认为您可以使用 FileObserver 来实现这一点。
如文档中所述:
监控文件以在设备上的任何进程访问或更改文件后触发事件。 每个 FileObserver 实例监视单个文件或目录。如果某个目录被监控,那么被监控目录内的所有文件和子目录都会触发事件。
但你必须记住:
如果 FileObserver 被垃圾回收,它将停止发送事件。为确保您继续接收事件,您必须保留对其他活动对象的 FileObserver 实例的引用。
请给我一些反馈。 希望这会有所帮助。
【讨论】:
我怎么知道要听哪些文件?只应监视为 mediaStore 存储的文件...您尝试过吗?你如何监控一个特定的进程,它应该用于 mediaStore 的哪个进程?您如何让 fileObserver 观察所有目录中的所有文件,而不是单个文件(它似乎不是递归的)?您必须为设备上的每个文件夹以及每个新文件夹创建一个实例... 例如:你可以像下面这样收听你的图片目录: Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES);等等为您的目录。不,我没试过。您不想监视哪个进程创建了文件,您将监视设备中任何进程创建的任何文件。 但我不想监控创建的每个文件,因为有些文件不会进入 mediaStore(可能是大多数文件)。我也不想只监视您编写的单个文件夹,因为用户可以安装将图像文件(如第三方相机)放在其他文件夹中的应用程序,这仍然使图库应用程序知道这些文件...... 你不能监控SD卡吗?我不知道我说的对不对。 我已经读过它了。它似乎无法递归工作-您必须自己创建很多 FileObservers-每个目录一个,甚至对于新目录...对于每个文件,您都必须检查它是否进入 mediaStore ...我认为这可能是矫枉过正...以上是关于如何获得关于画廊应用程序可见的每个新图像的通知?的主要内容,如果未能解决你的问题,请参考以下文章