2012-04-27 5 views
20

Tengo una cámara DSLR y Samsung Galaxy Tab con Android Honeycomb. DSLR conectado a una tableta mediante un cable USB (a través de un kit USB que permite la funcionalidad del host en una tableta). Me gustaría recibir una notificación cuando el usuario tome una fotografía con esta cámara externa, para descargar esta imagen a la tableta o hacer algo más con ella, como mostrar la notificación de Toast que contiene información meta tomada de la imagen.Esté atento a los cambios en el almacenamiento USB externo para Honeycomb o versiones posteriores de Android

Por lo que yo entiendo todas las herramientas existentes (como FileObserver usando subyacente inotify mecanismo, MediaContentProvider etc) que permite observar los cambios, exigen un determinado archivo o una ruta de sistema de archivos para ser observados. Esto fue lo suficientemente bueno hasta que tuvimos soporte de protocolo de capa de bloque en las versiones 2.x y anteriores de Android: cuando conectabas el dispositivo, lo montabas en algún lugar del sistema de archivos del dispositivo y pudiste utilizar este punto de montaje como punto de observación para esas herramientas .

Desde Honeycomb Google ha cambiado la forma de acceder a los dispositivos USB externos a Media Transfer Protocol con PTP como un subconjunto de esto. Ahora cuando conecto un dispositivo USB externo a un dispositivo Android, no veo ningún punto de montaje (estoy usando adb shell y el siguiente comando mount para obtenerlos). Además, la implementación de MTP usa identificadores de almacenamiento que aparentemente actúan como un nivel más alto de abstracción y son simplemente valores enteros. Esperaba que hubiera una manera de traducir de alguna manera estos identificadores de almacenamiento a las rutas reales/punto de montaje/lo que sea, pero aparentemente no parece ser así.

Pensando en Android MediaScanner que ya se está ejecutando en el dispositivo supuse que podría manejar este problema con un especial Intent emiten cuando hay cambios en los medios de comunicación los archivos accesibles desde el dispositivo, por lo que comenzó a buscar ya existente y adecuado Intents para recibir una notificación, pero no hubo suerte: solo encontré ACTION_MEDIA_MOUNTED y ACTION_MEDIA_REMOVED que se emiten solo cuando el dispositivo está conectado y desconectado, respectivamente. Eso significa que MediaScanner no puede notar ningún cambio en el dispositivo hasta que lo vuelva a montar (lo he comprobado por duplicado con la aplicación Gallery, no ve imágenes recién creadas en la cámara hasta que lo desenchufa y luego lo conecta al Android dispositivo de nuevo).

Tratando de conseguir esta ruta de montaje de la tarjeta sd externa, solía Environment.getExternalStorageDirectory() llamada a la API pero los rendimientos emulado ruta sdcard del Galaxy que es /mnt/sdcard, ninguno de la cámara. Entonces tampoco funciona para mí.

Logré resolver este problema solo habiendo lanzado el evento Timer periódico con AsyncTask actuando como TimerTask. Esta tarea inicializa la conexión USB, abre el dispositivo, escanea toda la memoria del dispositivo, obtiene solo la última foto tomada y luego cierra el descriptor del dispositivo y la conexión USB.

No parece la forma mejor y más eficiente de hacerlo teniendo en cuenta que tiene que hacer todas estas acciones cada vez, lo que podría ser bastante frecuente, por ejemplo, cada 5 o 10 segundos. Definitivamente agota rápidamente la batería y produce E/S innecesarias del sistema solo para tomar la última foto tomada y compararla con la última foto tomada anteriormente (en el 99% tenía la misma imagen), pero no encontré ninguna solución de trabajo mejor para hacer esto Sería mucho mejor tener un mecanismo de observación con notificaciones basadas en eventos.

Así que mi pregunta es ¿hay alguna forma más eficiente de recibir notificaciones sobre cambios en el almacenamiento USB externo para Honeycomb o versiones posteriores de Android en lugar de uno descrito anteriormente?

Respuesta

2

Si desea una forma más eficiente, la cámara debería enviar algún tipo de señal a través del usb que haya tomado una foto. Supongo que no está haciendo eso.

Por lo tanto, tendrá que comprobar manualmente haciendo el camino su están discribing:

montaje de almacenamiento -> comprobar si hay cambios -> hacer lo suyo con los cambios detectados.

I no sabe lo que se utiliza para leer "la forma MTP" pero aquí un ejemplo de aplicación:

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

Para no escanear todo el almacenamiento cada vez que usted podría ahorrar el resultado de la lectura a los nombres de archivo por ejemplo, cada vez que revisas y lo comparas para encontrar los nuevos. Por lo general, el nombre del archivo también comienza con el mismo número en una cámara. Entonces, si comienzas una sesión con una tarjeta sd vacía, ya sabes el nombre del archivo que tendrá la foto. digamos img0001.jpg. Entonces solo necesita escribir una función para tomar ese archivo hasta que tenga éxito. si quiere la siguiente img0002.jpg puede escribir una tarea/servicio/función para tomar ese archivo hasta que tenga éxito, y así sucesivamente.

Si desea ahorrar batería, podría implementar una batería/fuente de alimentación adicional entre ellas para alimentar el puerto usb.

En lugar de una tarea Async o timerTask, puede probar un ScheduledExecutorService y ver si usa menos energía.

Espero que le haya dado algunas nuevas ideas

Cuestiones relacionadas