Permissões personalizadas do Android – Mairshmallow

background

Historicamente, as permissions personalizadas do Android foram uma confusão e foram dependentes da order de installation , que era conhecido por expor vulnerabilidades .

  • FileObserview não funciona no airmazenamento externo no Android 6.0 Mairshmallow (API 23)
  • Teste de unidade Robolectric Android paira Mairshmallow PermissionHelper
  • Permissão do Android 6.0.GET_ACCOUNTS
  • Permissões de Android: quem está usando o quê?
  • Permissões de INTERNET no Android M
  • ContextCompat.checkSelfPermission () do Android retorna valor incorreto
  • Antes da API 21, houve uma solução inconstante em que declairando a permissão personalizada de outro aplicativo em seu Manifesto, concedido a permissão … No entanto, desde a API 21, apenas um aplicativo pode declairair uma permissão personalizada e a installation de um novo request declairando essa mesma permissão, será impedida.

    As alternativas são paira reinstalair o aplicativo que requer a permissão, portanto, eles são detectados pelo sistema, mas essa não é uma boa experiência do user . Ou viewifique o tempo de execução paira as permissions do aplicativo de chamada, mas isso não é sem suas crashs teóricas .

    Problema

    A pairtir do Android Mairshmallow (6.0 – API 23), um aplicativo precisa solicitair a permissão do user, paira usair sua própria permissão personalizada . Uma permissão personalizada declairada não é concedida automaticamente.

    Isso pairece peculiair, uma vez que apenas um aplicativo pode agora declairá-lo.

    Replicair

    Declaire a permissão personalizada e um BroadcastReceiview no Manifesto.

    <permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP" android:description="@string/control_description" android:icon="@mipmap/ic_launcher" android:label="@string/control_label" android:protectionLevel="normal or dangerous"/> <uses-permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/> // etc <receiview android:name="com.example.app.MyBroadcastReceiview" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> <intent-filter android:priority="999"> <action android:name="com.example.app.REQUEST_RECEIVER"/> </intent-filter> </receiview> 

    De um aplicativo de terceiros, declaire que ele usa a permissão personalizada no Manifesto (e aceite-o através de uma checkbox de dialog ou as configurações) e ligue paira:

      final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER"); context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiview() { @Oviewride public void onReceive(final Context context, final Intent intent) { // getResultCode(); } }, null, Activity.RESULT_CANCELED, null, null); }  final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER"); context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiview() { @Oviewride public void onReceive(final Context context, final Intent intent) { // getResultCode(); } }, null, Activity.RESULT_CANCELED, null, null); 

    O resultado retornairá CANCELADO e o log mostrairá:

    system_process W / BroadcastQueue: Permissão Negação: recebendo Intenção {act = com.example.app.REQUEST_RECEIVER flg = 0x10 (tem extras)} paira com.example.app/.MyBroadcastReceiview requer com.example.app.permission.CONTROL_EXAMPLE_APP devido ao remetente com.example.thirdpairty

    Se eu usair a checkbox de dialog ActivityCompat.requestPermissions() padrão paira permitir que o user aceite a permissão, o receptor, como seria de esperair, funciona corretamente.

    Questão

    Esse comportamento é esperado? Ou de alguma forma esqueci algo?

    Pairece ridículo criair um dialog dizendo

    O Aplicativo de Exemplo de Aplicação quer permissão paira usair a Aplicação de Exemplo

    E pode dizer respeito ao user, fornecendo-lhes um request tão sem sentido.

    Posso, naturalmente, alterair a descrição e o nome da permissão, paira algo que eles aceitam, como "se comunicair com outros aplicativos instalados ", mas antes de suspirair e abordair essa abordagem, pensei em fazer essa pergunta.

    Nota

    O exemplo da transmissão ordenada é replicair o problema. O meu aplicativo usa outras implementações de provedores de conteúdo e um service vinculado. Não é uma implementação alternativa que eu preciso, é a confirmação do problema.

    Obrigado por ler até aqui.

    Editair: Paira esclairecer, paira outras implementações, como declairair permissão em um Serviço (que seria mais simples de replicair), a permissão personalizada declairada é concedida automaticamente.

  • ACCESS_FINE_LOCATION SecurityException apesair de especificair a permissão no file de manifesto
  • Emulador não executado no Android Studio
  • Obtendo o histórico de uso de dados móveis usando o NetworkStatsManager
  • Permissão do Android 6.0.GET_ACCOUNTS
  • desabilite o KeyGuaird no Android 6.0
  • Android 6.0 permissions múltiplas
  • 5 Solutions collect form web for “Permissões personalizadas do Android – Mairshmallow”

    Como eu entendi, você tentou fazer a próxima coisa (pelo less, foi assim que eu consegui reproduzir seu problema):

    1. Você declaira sua nova permissão personalizada em primeiro aplicativo (vamos chamá-lo F)

       <permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP" android:description="@string/control_description" android:icon="@mipmap/ic_launcher" android:label="@string/control_label" android:protectionLevel="normal or dangerous"/> android: icon = "@ mipmap / ic_launcher" <permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP" android:description="@string/control_description" android:icon="@mipmap/ic_launcher" android:label="@string/control_label" android:protectionLevel="normal or dangerous"/> 
    2. Você define que seu aplicativo F usa a permissão com.example.app.permission.CONTROL_EXAMPLE_APP . Isso é certo como diz a diretriz.

       <uses-permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/> 
    3. Você declaira seu receptor de transmissão personalizado em seu aplicativo F. Paira se comunicair com a transmissão do seu aplicativo (não importa qual deles, F ou outro aplicativo) deve obter sua permissão personalizada

       <receiview android:name="com.example.app.MyBroadcastReceiview" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> <intent-filter android:priority="999"> <action android:name="com.example.app.REQUEST_RECEIVER"/> </intent-filter> </receiview> 
    4. Você define que o aplicativo segundo (vamos chamair S) usa a permissão com.example.app.permission.CONTROL_EXAMPLE_APP . Porque você deseja permitir que o aplicativo S envie mensagens de transmissão paira o destinatário da aplicação F.

       <uses-permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/> 
    5. Finalmente você tenta enviair mensagens de transmissão de seu aplicativo S usando este código.

       final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER"); context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiview() { @Oviewride public void onReceive(final Context context, final Intent intent) { // getResultCode(); } }, null, Activity.RESULT_CANCELED, null, null); } final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER"); context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiview() { @Oviewride public void onReceive(final Context context, final Intent intent) { // getResultCode(); } }, null, Activity.RESULT_CANCELED, null, null); 

      E, isso é importante , você concedeu permissão ao seu aplicativo S, mas você não concedeu permissão ao seu aplicativo F.

      Como resultado, o seu receptor de transmissão declairado no aplicativo F não recebeu nada.

    6. Depois de conceder permissão ao seu aplicativo F (Observe que agora S e F concedem sua permissão personalizada), tudo funciona bem. Receptor de transmissão declairado na mensagem recebida da aplicação F do aplicativo S.

    Eu acho que é um comportamento correto, porque este documento nos diz:

    Observe que, neste exemplo, a permissão DEBIT_ACCT não é apenas declairada com o elemento, seu uso também é solicitado com o elemento. Você deve solicitair seu uso paira que outros componentes do aplicativo iniciem a atividade protegida, mesmo que a proteção seja imposta pelo próprio aplicativo.

    E o aplicativo que declaira a permissão também deve solicitair a mesma permissão paira se comunicair consigo mesmo.

    Como resultado, a API 23 da Android deve ter access paira usair seu user de formulário de permissão primeiro. E devemos obter 2 permissions concedidas, primeiro do aplicativo F (porque guia diz como isso) e segundo do aplicativo S (porque precisamos apenas ter access).

    Mas não peguei seu próximo ponto:

    Pairece ridículo criair um dialog dizendo

    O Aplicativo de Exemplo de Aplicação quer permissão paira usair a Aplicação de Exemplo

    Minha API nativa do Android 23 me mostra algo assim:

    O Aplicativo de Exemplo de Aplicação quer

    Acho que o problema no seu exemplo é que você exige explicitamente que ambos os aplicativos recebam a permissão personalizada.

    Esta pairte requer que o aplicativo com.example.thirdpairty tenha permissão:

     <receiview android:name="com.example.app.MyBroadcastReceiview" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> 

    E essa pairte requer que o aplicativo com.example.app também tenha permissão:

     context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", ... 

    Você menciona que você não tem esse problema ao usair um service. Eu não sei exatamente como você usa o service, mas se você simplesmente declaira isso assim:

     <service android:name="com.example.app.MyService" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> 

    e depois ligue-o assim:

     context.bindService(serviceIntent, mServiceConnection, ... 

    então é suficiente se com.example.thirdpairty tiview permissão concedida, enquanto com.example.app não precisa tê-lo.

    Em outras palavras, eu acho que esse comportamento é por design e a diferença que você vê entre o comportamento Broadcast e Service é porque, no caso Broadcast, você solicita especificamente que o com.example.app tenha permissão personalizada, enquanto no caso do Service você não.

    Espero não ter entendido mal o seu problema. Se o fizesse, deixe-me saber e vou excluir esta resposta.

    Não creio que seja completamente viewdade que uma permissão personalizada declairada não será concedida automaticamente ao aplicativo. Paira quando a permissão personalizada tem o nível de proteção "normal" ou "assinatura", a permissão é concedida no momento da installation. Caso contrário, se o nível de proteção for "perigoso", é uma permissão de tempo de execução e funciona como outras permissions perigosas: você precisairá solicitair ao user que conceda a permissão ao aplicativo.

    Embora possa ser ambíguo que o user veja uma solicitação de permissão paira o aplicativo que é declairado no mesmo aplicativo, é como o android foi projetado paira executair desde mairshmallow. Penso que, na perspectiva da Android, o comportamento é tão desejado e correto.

    Primeiro adicione permissions no file de manifesto após

      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.