如何获得关于画廊应用程序可见的每个新图像的通知?

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 ...我认为这可能是矫枉过正...

以上是关于如何获得关于画廊应用程序可见的每个新图像的通知?的主要内容,如果未能解决你的问题,请参考以下文章

如何显示具有相关标题的背景图像

Swift导航栏中图像的动画变化

OpenCV 图像处理:白化(whitening)

SwiftUI - 在当前视图中为新图像设置动画

MATLAB中图像的对角线像素

将 UIImage 剪辑到 UIBezierPath(不屏蔽)