观察Honeycomb或更高版本的安卓系统中外部USB存储设备的变化

20

我有一台DSLR相机和运行Android Honeycomb的三星Galaxy Tab平板电脑。使用USB线将DSLR相机连接到平板电脑(通过启用平板电脑主机功能的USB套件)。我想在用户使用这个外部相机拍照时得到通知,以便将其图像下载到平板电脑上或者做其他事情,比如显示包含从图像中提取的元信息的提示通知。

就我所知,所有现有的工具(例如使用底层inotify机制的FileObserver,MediaContentProvider等)都允许监视更改,需要监视特定文件或文件系统路径。在2.x和早期的Android版本中支持块层协议时,这足够好 - 当您连接设备时,它会挂载在设备的文件系统中的某个位置,并且您可以将此挂载点用作那些工具的观察点。

自Honeycomb以来,Google已更改了访问外部USB设备的方式,采用PTP作为Media Transfer Protocol的子集。现在当我将外部USB设备连接到Android设备时,我看不到任何挂载点(我正在使用adb shell和随后的mount命令获取它们)。此外,MTP实现使用存储ID,显然作为抽象级别较高的纯整数值。我希望有一种方法可以将这些存储ID转换为实际路径/挂载点/任何其他东西,但显然似乎没有。

考虑到我的设备上已经运行了 Android 的 MediaScanner,我猜测它可以通过特殊的Intent来处理从设备访问的媒体文件发生更改的问题,因此我开始寻找现有且适合被通知的Intents,但没有找到任何符合要求的 - 我只找到了ACTION_MEDIA_MOUNTEDACTION_MEDIA_REMOVED,分别在设备连接和断开连接时广播。这意味着MediaScanner直到重新挂载之前都无法注意到设备上的任何更改(我使用原始的相册应用程序进行了双重检查-它不会看到相机上新创建的图像,直到您将其从 Android 设备上拔下并再次插入)。
尝试获取外部SD卡的挂载路径,我使用了Environment.getExternalStorageDirectory() API调用,但它得到了模拟 Galaxy 的SD卡路径,即/mnt/sdcard,而不是相机的路径。因此,对我也没用。
我只能通过启动定期的Timer事件并使用AsyncTask作为TimerTask来解决此问题。该任务初始化USB连接,打开设备,扫描整个设备内存,仅获取最新拍摄的照片,然后关闭设备描述符和USB连接。
考虑到要频繁进行所有这些操作,例如每5或10秒钟,这显然不是最佳和高效的方法。它会快速耗尽电池,并为仅获取最新拍摄的照片并将其与上一个最新拍摄的照片进行比较(在99%的情况下,是相同的照片)而产生不必要的系统I/O负载。但我没有找到更好的解决方案。因此,我的问题是,是否有更有效的通知外部USB存储中更改的方法适用于 Honeycomb 或更高版本的 Android?
1个回答

2
如果您想要更有效率的方式,相机就必须通过 USB 发送某种信号来表示它已经拍摄了一张照片。我猜它没有这么做。
因此,您将不得不手动检查,按照您所描述的方式进行:
挂载存储 --> 检查更改 --> 对检测到的更改进行操作。
我不知道您用什么方法来读取“MTP 方式”,但以下是一个示例应用程序:

https://github.com/ynakanishi/Honeycomb-MTP-sample

为了避免每次扫描整个存储空间,您可以保存读取文件名的结果,例如每次检查并比较它以找到新文件。通常,相机上的文件命名也以相同的数字开头。因此,如果您使用空SD卡开始会话,则已知照片的文件名。假设是img0001.jpg。因此,您只需要编写一个函数来获取该文件,直到成功。如果您想要下一个img0002.jpg,您可以编写一个任务/服务/函数来获取该文件,直到成功,依此类推。
如果您想要节省电池电量,可以在USB端口之间实现另外的电池/电源。
您可以尝试使用ScheduledExecutorService而不是Async Task或TimerTask,并查看它是否使用更少的电力。
希望这给您带来了一些新的思路。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接