注意蜂窝或更高版本Android的外部USB存储的变化
我有一个单反相机和三星Galaxy Tab运行Android蜂巢。DSLR使用USB电缆连接到平板电脑(通过USB套件启用平板电脑上的主机功能)。当用户使用此外置摄像头拍照时,我希望收到通知,以便将此图像下载到平板电脑,或使用它执行其他操作,例如显示包含从图像中获取的元信息的Toast通知 只要我获得了所有允许监视更改的现有工具(如使用底层注意蜂窝或更高版本Android的外部USB存储的变化,android,android-intent,usb,usb-drive,mtp,Android,Android Intent,Usb,Usb Drive,Mtp,我有一个单反相机和三星Galaxy Tab运行Android蜂巢。DSLR使用USB电缆连接到平板电脑(通过USB套件启用平板电脑上的主机功能)。当用户使用此外置摄像头拍照时,我希望收到通知,以便将此图像下载到平板电脑,或使用它执行其他操作,例如显示包含从图像中获取的元信息的Toast通知 只要我获得了所有允许监视更改的现有工具(如使用底层inotify机制的FileObserver,MediaContentProvider等),就需要监视特定的文件或文件系统路径。这已经足够好了,直到我们在2.
inotify
机制的FileObserver
,MediaContentProvider
等),就需要监视特定的文件或文件系统路径。这已经足够好了,直到我们在2.x和更早的Android版本中有了块层协议支持——当您连接设备时,它已经安装在设备的文件系统的某个地方,并且您能够使用这个挂载点作为这些工具的监视点
自从蜂巢公司以来,谷歌已经将访问外部USB设备的方式改为媒体传输协议
,并将PTP
作为其中的一个子集。现在,当我将外部USB设备连接到Android设备时,我不会看到它的任何挂载点(我正在使用adb shell
和后续的mount
命令来获取它们)。此外,MTP
实现使用了存储ID,它显然是一个更高级别的抽象,只是简单的整数值。我希望有一种方法能够以某种方式将这些存储ID转换为真正的路径/挂载点/任何东西,但显然没有
想到已经在我的设备上运行的AndroidMediaScanner
,我猜它可以通过一种特殊的Intent
来处理这个问题,当可以从设备访问的媒体文件发生变化时,它会广播,所以我开始寻找已经存在的和合适的Intent
,以便得到通知,但没有运气-我发现只有ACTION\u MEDIA\u挂载了和ACTION\u MEDIA\u删除了,只有在设备连接和断开连接时才会播放。这意味着MediaScanner
在重新安装之前无法注意到设备上的任何更改(我已使用stock Gallery应用程序对其进行了双重检查-在您拔下并再次将其插入Android设备之前,它不会在相机上看到任何新创建的图像)
为了获取外部SD卡的挂载路径,我使用了Environment.getExternalStorageDirectory()
API调用,但它会生成模拟的Galaxy SD卡路径
这是/mnt/sdcard
,而不是相机的。所以这对我也不起作用
我只在启动了周期性的Timer
事件,并将AsyncTask
作为TimerTask
时才设法解决了这个问题。此任务不初始化usb连接,打开设备,
扫描整个设备内存,仅获取上次拍摄的照片,然后关闭设备描述符和usb连接
考虑到每次都要做所有这些动作,这看起来并不是最好、最有效的方法,这可能是非常常见的,比如说每5秒或10秒。它肯定会很快耗尽电池电量,并产生不必要的系统I/O,仅用于拍摄最后一张照片,并将其与之前的最后一张照片进行比较(99%的照片都是相同的图像),但我还没有找到更好的解决方案。最好有一个带有基于事件的通知的观察者机制
因此,我的问题是,有没有比上述更有效的方式来通知蜂窝或更高版本的Android外部USB存储的更改 如果您想要一种更有效的方式,相机必须通过usb发送某种信号,表明它已经拍摄了照片。我想不是这样的
因此,您必须按照描述的方式手动检查:
装载存储-->检查更改-->处理检测到的更改
我不知道你以前读过什么“MTP方式”,但这里有一个示例应用程序:
为了避免每次都扫描整个存储,您可以保存读取文件名的结果,例如每次检查并比较文件名以查找新文件名时。通常,文件的命名也从相机上的相同编号开始。因此,如果您使用空sd卡启动会话,您就已经知道照片的文件名。比方说img001.jpg。因此,您只需要编写一个函数来获取该文件,直到它成功。如果您想要下一个img002.jpg,您可以编写一个任务/服务/函数来获取该文件,直到成功,依此类推
如果你想节省电池,你可以在两者之间安装一个额外的电池/电源,为usb端口供电
您可以尝试ScheduledExecutorService,而不是异步任务或timerTask,并查看它是否耗电较少
希望给你一些新的想法