Como parar o Android pedindo permissão antes de permitir o acesso ao dispositivo USB

19

Eu tenho um aplicativo em execução em um tablet Android sem nome enraizado executando o ICS 4.0.3 que controla um dispositivo USB por meio da interface do modo host USB. O arquivo android.hardware.usb.host.xml está presente em / system / etc / Permissions e tudo funciona maravilhosamente. Exceto...

Quando executo o aplicativo pela primeira vez após uma reinicialização e conecto o dispositivo USB, recebo uma janela pop-up dizendo "Permitir que o aplicativo APPNAME acesse o dispositivo USB? [] Use por padrão este dispositivo USB. Cancele OK" e Eu tenho que tocar em OK antes que ele possa começar a usar o dispositivo.

Preciso desativar a confirmação do usuário para que o aplicativo possa usar o dispositivo imediatamente. Como eu faço isso? Pareço algumas sugestões sobre o uso de um gerador de pressionamento de tecla para simular o usuário tocando no botão na tela, mas eu prefiro evitar esse tipo de abordagem e configurar as coisas para que a solicitação de confirmação simplesmente não aconteça.

Provavelmente, não consigo que o fornecedor faça uma compilação personalizada do kernel para mim, mas devo conseguir a chave de assinatura do firmware para poder assinar meu aplicativo como um aplicativo do sistema, se isso ajudar.

Um problema associado: marcar a caixa "Usar por padrão para este dispositivo USB" não parece ajudar - se eu desconectar e reconectar o dispositivo, receberei o prompt de confirmação novamente. Percebi nessa situação que o número do dispositivo em / dev / bus / usb / 001 / muda sempre que eu desconecto e reconecto (001, 002, 003 etc), o que talvez explique esse problema específico.

kbro
fonte
O que acontece se você implantar o aplicativo em / system / app? Você pode tentar isso com e sem assinatura do sistema. Escrevo isso como um comentário porque (a) não tentei e (b) não sei se esse modelo de implantação está disponível para você.
precisa

Respostas:

10

Esta pergunta e resposta é basicamente uma duplicata de
/programming//a/15151075/588476
Veja o link acima para um exemplo de programa e uma discussão mais aprofundada.

Até onde eu sei, existem duas maneiras de obter o pop-up da caixa de permissão USB:

  1. Solicite permissão explicitamente do seu aplicativo usando UsbManager.requestPermission (...)
  2. Registre um filtro de intenção no seu acessório e deixe o sistema solicitar permissão quando o dispositivo estiver conectado

No caso de 1, descobri que a caixa de seleção no pop-up para lembrar a permissão não tem efeito.

Para mim, removi todo o código relacionado às permissões do meu software e simplesmente coloquei o filtro de intenção no meu manifesto. Quando o dispositivo USB estiver conectado, se ele ainda não tiver recebido permissão, a caixa de permissão USB será exibida. Se o usuário clicar em OK sem marcar a caixa Lembrar, a caixa será exibida novamente na próxima vez que o dispositivo for conectado. No entanto, se o usuário marcar a caixa e pressionar OK, a caixa nunca deverá ser exibida novamente (a menos que o software seja desinstalado e reinstalado).

Não tenho certeza se há algum bug relacionado ao seu dispositivo aparecendo como / dev / bus / usb / 001 e 002 etc - informe-me se você estiver usando o filtro de intenção, pois sem isso a caixa de seleção lembrar fazer nada.

Não conheço nenhuma maneira de evitar completamente o pop-up de permissão. Eu suspeito que não há como fazer isso sem se aprofundar no código do Android, como você disse.

Wayne Uroda
fonte
1
Você tem certeza? Ainda estou vendo a solicitação de permissão quando o dispositivo é desconectado e reconectado. Esse comportamento é consistente com a documentação em developer.android.com/guide/topics/connectivity/usb/host.html . A seção "Usando um filtro de intenção", diz "Se os usuários aceitar, a sua aplicação tem automaticamente permissão para acessar o dispositivo até que o dispositivo é desconectado"
kbro
Só posso garantir o Nexus 7, Galaxy S3 e Galaxy Note; nesses dispositivos, só preciso aceitar a permissão uma vez (o dispositivo Android está sendo executado no modo host) - desde que eu ative a caixa de seleção para lembrar da decisão. Qual dispositivo / versão do Android você está usando, sinto que é um dispositivo personalizado / OEM?
Wayne Uroda
É um tablet OEM de 7 polegadas baseado no WonderMedia WM8850 de meados do SOM, com o sabor do Android 4.0.3.
kbro
Os filtros de intenção estão funcionando apenas para a sessão de inicialização atual. Sim, eu conecto um dispositivo USB ao meu telefone e ele concede permissão automaticamente
user924
7

Além do meu comentário, dei uma olhada no código Android subjacente.

Eu tenho uma resposta possível, mas com nada menos que quatro grandes ressalvas e obstáculos:

  1. Eu não tentei, porque não tenho nenhum dispositivo USB adequado em mãos.
  2. Você precisa de uma nova permissão
  3. A permissão requer que você seja um aplicativo do sistema
  4. O código requer acesso a algo que não está na API pública

Esqueça isso ao implantar aplicativos comuns de pós-venda!

O primeiro pré-requisito é que você tenha a MANAGE_USBpermissão. Isso é descrito aqui .

No entanto, por sua vez, os pré-requisitos para você assinar com a chave do sistema e instalar o aplicativo em / system / app.

De qualquer forma, se você estiver bem com isso, aqui está um código:

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

mDevice é o dispositivo de antes.

uidé o UID do seu próprio aplicativo e você pode pesquisar isso. Um exemplo de como fazer isso é a primeira resposta aqui .

Tudo bom? Não. ServiceManagerÉ android.os.ServiceManagere, portanto, não é uma API pública. Nesse exemplo, é o seu caminho para colocar as mãos no IUsbManagerserviço (pode haver outras rotas). Agora, contornar isso está além do escopo da minha resposta; antigamente, você poderia usar a reflexão, mas não sei se ainda pode.

Depois de todas essas travessuras, parece que você não precisa mais solicitar permissão e, se o fizer, retornará imediatamente sem nenhum diálogo.

Rob Pridham
fonte