我有一台数码单反相机和一台运行 Android Honeycomb 的三星 Galaxy Tab。DSLR 使用 USB 电缆连接到平板电脑(通过 USB 套件在平板电脑上启用主机功能)。我希望在用户使用此外部相机拍照时收到通知,以便将此图像下载到平板电脑或对其执行其他操作,例如显示包含从图像中获取的元信息的 Toast 通知。
据我所知,所有现有工具(例如FileObserver
使用底层inotify
机制MediaContentProvider
等)都允许监视更改,要求监视特定文件或文件系统路径。这已经足够好了,直到我们在 2.x 和更早的 Android 版本中获得块层协议支持 - 当您连接设备时,它已安装在设备文件系统的某个位置,您可以将此安装点用作这些工具的观察点.
由于 Honeycomb Google 已将访问外部 USB 设备的方式更改为Media Transfer Protocol
withPTP
作为其子集。现在,当我将外部 USB 设备连接到 Android 设备时,我不会看到它的任何挂载点(我正在使用adb shell
后续mount
命令来获取它们)。此外,MTP
实现使用的存储 id 显然充当更高级别的抽象,并且只是普通的整数值。我希望有一种方法可以以某种方式将这些存储 id 转换为真实路径/挂载点/任何东西,但显然似乎没有。
考虑到MediaScanner
已经在我的设备上运行的 Android,我猜想它可以Intent
在设备可访问的媒体文件发生变化时通过特殊广播来解决这个问题,所以我开始寻找已经存在并适合Intents
被通知的问题,但没有运气- 我发现只有在分别连接和断开设备时才广播ACTION_MEDIA_MOUNTED
。ACTION_MEDIA_REMOVED
这意味着MediaScanner
在您重新安装之前无法注意到设备上的任何更改(我已经使用股票图库应用程序仔细检查了它 - 在您拔下然后将其插入 Android 设备之前,它不会在相机上看到任何新创建的图像再次)。
试图为外部 sdcard 获取这个挂载路径,我使用Environment.getExternalStorageDirectory()
了 API 调用,但它产生了模拟 Galaxy 的 sdcard 路径,而/mnt/sdcard
不是相机的路径。所以它对我也不起作用。
我设法解决了这个问题,只是在启动定期Timer
事件并AsyncTask
充当TimerTask
. 此任务确实初始化 USB 连接,打开设备,扫描整个设备内存,仅获取最后拍摄的照片,然后关闭设备描述符和 USB 连接。
考虑到它必须每次都执行所有这些操作,这看起来不是最好和最有效的方法,这可能非常频繁,比如每 5 或 10 秒。它肯定会很快耗尽电池电量并产生不必要的系统 I/O,仅用于拍摄最后一张照片并将其与上一张照片进行比较(99% 是相同的图像),但我还没有找到更好的工作解决方案这样做。最好有一个带有基于事件的通知的观察者机制。
所以我的问题是,有没有更有效的方式来通知 Honeycomb 或更高版本的 Android 的外部 USB 存储的变化,而不是上面描述的?