20 votos

Cómo evitar que Android pida permiso antes de permitir el acceso al dispositivo USB

Tengo una aplicación que corre en una tablet Android sin nombre que corre ICS 4.0.3 que controla un dispositivo USB a través de la interfaz de modo de anfitrión USB. El archivo Android.hardware.usb.host.xml está presente en /system/etc/permissions y todo funciona de maravilla. Excepto...

Cuando ejecuto la aplicación por primera vez después de un reinicio y luego conecto el dispositivo USB, aparece una ventana emergente que dice: "¿Permitir que la aplicación APPNAME acceda al dispositivo USB? [] Usar por defecto para este dispositivo USB. Cancelar OK" y tengo que pulsar OK antes de que pueda empezar a usar el dispositivo.

Necesito apagar la confirmación del usuario para que la aplicación pueda usar el dispositivo de inmediato. ¿Cómo hago esto? Tengo algunas sugerencias sobre el uso de un generador de pulsaciones de teclas para simular que el usuario pulsa el botón de la pantalla, pero prefiero evitar ese tipo de enfoque y configurar las cosas de manera que la solicitud de confirmación simplemente no se produzca.

Probablemente no pueda hacer que el proveedor me construya un kernel personalizado, pero debería poder obtener la clave de firma del firmware de ellos para poder firmar mi aplicación como una aplicación de sistema, si eso ayuda.

Un problema asociado: marcar la casilla "Usar por defecto para este dispositivo USB" no parece ayudar - si desenchufo y vuelvo a enchufar el dispositivo entonces obtengo el mensaje de confirmación de nuevo. He notado en esta situación que el número de dispositivo en /dev/bus/usb/001/ cambia cada vez que lo desconecto y lo vuelvo a conectar (001, 002, 003 etc.) lo que quizás explica este problema en particular.

10voto

GalacticCowboy Puntos 8185

Esta pregunta y respuesta es básicamente un duplicado de
http://stackoverflow.com/a/15151075/588476
Vea el enlace de arriba para un programa de ejemplo y una discusión más profunda.

Por lo que sé, hay dos maneras de obtener la ventana emergente de la caja de permisos del USB:

  1. Solicita permiso explícitamente de tu aplicación usando UsbManager.requestPermission(...)
  2. Registre un filtro de intención en su accesorio y deje que el sistema pida permiso cuando el dispositivo esté conectado.

En el caso de 1 he encontrado que la casilla de verificación en el popup para recordar el permiso no tiene ningún efecto.

Para mí, eliminé todo el código relacionado con los permisos de mi software y simplemente puse el filtro de intención en mi manifiesto. Cuando se conecta el dispositivo USB, si no se le ha concedido permiso, entonces aparecerá la caja de permisos del USB. Si el usuario hace clic en "OK" sin marcar la casilla de recordar, entonces la casilla aparecerá de nuevo la próxima vez que se conecte el dispositivo. Sin embargo, si el usuario marca la casilla y pulsa OK, entonces la casilla no debería volver a aparecer (a menos que el software se desinstale y luego se vuelva a instalar).

No estoy seguro de si hay un error en algún lugar relacionado con su dispositivo que aparezca como /dev/bus/usb/001 y luego 002 etc hágame saber si está usando el filtro de intención, ya que sin eso la casilla de verificación de recordar no hará nada.

No conozco ninguna forma de que puedas evitar el permiso de la ventana emergente por completo. Sospecho que no hay forma de hacerlo sin indagar en el código del Android como dijiste.

8voto

Rob Pridham Puntos 121

Después de mi comentario, eché un vistazo al código de Android subyacente.

Tengo una posible respuesta, pero con no menos de cuatro grandes advertencias y obstáculos:

  1. No lo he probado, porque no tengo ningún dispositivo USB adecuado a mano.
  2. Necesitas un nuevo permiso
  3. El permiso requiere que seas una aplicación de sistema
  4. El código requiere acceso a algo que no está en la API pública

¡Olvídese de esto si despliega aplicaciones ordinarias de postventa!

El primer prerrequisito es que tengas el MANAGE_USB permiso. Eso se describe aquí .

Sin embargo, a su vez, los requisitos para ello son que firmes con la llave del sistema e instales tu aplicación en /system/app.

De todos modos, si estás de acuerdo con eso, aquí tienes un código:

   IBinder b = ServiceManager.getService(USB_SERVICE);
   IUsbManager service = IUsbManager.Stub.asInterface(b);
   service.grantDevicePermission(mDevice, uid);

mDevice es el dispositivo de antes.

uid es el UID de tu propia aplicación y puedes buscarlo. Un ejemplo de cómo hacerlo es la primera respuesta aquí .

¿Todo bien? No. ServiceManager es android.os.ServiceManager y por lo tanto no es una API pública. Eso, en este ejemplo, es su manera de poner sus manos en el IUsbManager servicio (puede haber otras rutas). Ahora, para desplazarse que está fuera del alcance de mi respuesta; en los viejos tiempos se podía usar la reflexión, pero no sé si todavía se puede.

Después de todas esas travesuras, parece que ya no necesitas pedir permiso, y si lo haces, volverá inmediatamente sin diálogo.

PreguntAndroid.com

PreguntAndroid es una comunidad de usuarios de Android en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X