关注Honeycomb或更高版本Android版本的外部USB存储器的更改

Sun*_*ker 20 usb android usb-drive android-intent mtp

我有一台运行Android Honeycomb的数码单反相机和三星Galaxy Tab.使用USB电缆将DSLR连接到平板电脑(通过USB套件在平板电脑上启用主机功能).我希望在用户使用此外置摄像头拍照时收到通知,以便将此图像下载到平板电脑或使用它做其他事情,例如显示包含从图像中获取的元信息的Toast通知.

至于我获得允许监视更改的所有现有工具(如FileObserver使用底层inotify机制MediaContentProvider等),需要查看特定文件或文件系统路径.这很好,直到我们在2.x和更早版本的Android版本中获得了块层协议支持 - 当你连接设备时,它已被安装在设备文件系统的某个地方,你可以使用这个挂载点作为这些工具的观察点.

由于Honeycomb Google已经将访问外部USB设备的方式改为Media Transfer Protocol其中PTP的一部分.现在,当我将外部USB设备连接到Android设备时,我将看不到任何挂载点(我正在使用adb shell和后续mount命令获取它们).此外,MTP实现使用存储ID,它显然充当更高级别的抽象,并且只是普通的整数值.我希望有一种方法能够以某种方式将这些存储ID转换为真正的路径/ mountpoint /但是显然似乎没有.

考虑到MediaScanner已经在我的设备上运行的Android ,我猜想Intent当设备可以访问的媒体文件发生变化时,可以通过特殊的广播来管理这个问题,所以我开始寻找已经存在且适合Intents被通知但没有运气-我只找到ACTION_MEDIA_MOUNTED并且ACTION_MEDIA_REMOVED当设备被连接和断开分别被仅广播.这意味着MediaScanner在重新安装之前无法注意到设备上的任何更改(我使用库存应用程序对其进行了双重检查 - 在您拔下插头并将其插入Android设备之前,它不会在相机上看到任何新创建的图像再次).

试图获得外部SD卡的这个挂载路径,我使用了Environment.getExternalStorageDirectory()API调用,但它产生了模拟Galaxy的sdcard路径,而/mnt/sdcard不是相机的路径.所以它对我也不起作用.

我设法解决这个问题,只是发起了定期Timer活动,AsyncTask并作为一个TimerTask.此任务会初始化USB连接,打开设备,扫描整个设备内存,仅获取最后拍摄的照片,然后关闭设备描述符和USB连接.

它看起来并不像做,考虑到它需要做的所有这些行动每一个可能是很经常的时间的最好的和有效的方式,说每5秒或10秒.它肯定会很快耗尽电池并产生不必要的系统I/O,仅用于拍摄最后拍摄的照片并将其与之前拍摄的照片进行比较(99%是相同的图像),但我没有找到任何更好的工作解决方案这样做.拥有基于事件的通知的观察者机制会好得多.

所以我的问题是有更有效的方式来通知Honeycomb或更高版本的Android版本的外部USB存储器的更改,而不是上面描述的那些?

Sun*_*nic 2

如果您想要一种更有效的方式,相机必须通过 USB 发出某种信号,表明它已拍摄照片。我想它并没有这样做。

因此,您必须按照您描述的方式手动检查:

安装存储 --> 检查更改 --> 根据检测到的更改执行您的操作。

我不知道你以前读过什么“MTP 方式”,但这里有一个示例应用程序:

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

为了不每次都扫描整个存储,您可以保存读出文件名的结果,例如每次检查和比较它以找到新文件时。通常,文件的命名也以与相机上相同的编号开头。因此,如果您使用空 SD 卡启动会话,您就已经知道照片的文件名。比如说img0001.jpg。所以你只需要编写一个函数来抓取该文件,直到成功为止。如果您想要下一个 img0002.jpg,您可以编写一个任务/服务/函数来获取该文件,直到成功,依此类推。

如果您想节省电池,您可以在中间添加一个额外的电池/电源来为 USB 端口供电。

您可以尝试使用 ScheduledExecutorService 来代替异步任务或计时器任务,看看它是否使用更少的电量。

希望能给你一些新的想法