De acuerdo con esto: http://developer.android.com/preview/features/runtime-permissions.html#coding una aplicación puede verificar los permisos de tiempo de ejecución y solicitar permisos si aún no se ha otorgado. Entonces se mostrará el siguiente cuadro de diálogo:
En caso de que el usuario rechace un permiso importante, una aplicación debería mostrar una explicación de por qué se necesita el permiso y qué impacto tiene la disminución. Ese diálogo tiene dos opciones:
- vuelva a intentarlo nuevamente (se solicita permiso nuevamente)
- negar (la aplicación funcionará sin ese permiso).
Never ask again
Sin embargo, si el usuario verifica , el segundo diálogo con la explicación no debería mostrarse, especialmente si el usuario ya lo rechazó una vez. Ahora la pregunta es: ¿cómo sabe mi aplicación si el usuario ha verificado el Never ask again
? La OMI onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
no me da esa información.
Una segunda pregunta sería: ¿Google tiene planes de incorporar un mensaje personalizado en el diálogo de permiso que explique por qué la aplicación necesita el permiso? De esa manera nunca habría un segundo diálogo que sin duda mejoraría la experiencia de usuario.
fuente
Respuestas:
Developer Preview 2 trae algunos cambios en la forma en que la aplicación solicita los permisos (consulte también http://developer.android.com/preview/support.html#preview2-notes ).
El primer diálogo ahora se ve así:
No hay una casilla de verificación "Nunca volver a mostrar" (a diferencia de la vista previa del desarrollador 1). Si el usuario niega el permiso y si el permiso es esencial para la aplicación, podría presentar otro cuadro de diálogo para explicar la razón por la cual la aplicación solicita ese permiso, por ejemplo:
Si el usuario rechaza nuevamente, la aplicación debería cerrarse si necesita absolutamente ese permiso o seguir ejecutándose con una funcionalidad limitada. Si el usuario reconsidera (y selecciona volver a intentarlo), se solicita nuevamente el permiso. Esta vez el aviso se ve así:
La segunda vez se muestra la casilla de verificación "Nunca preguntar de nuevo". Si el usuario niega nuevamente y la casilla de verificación está marcada, no debería suceder nada más. Se puede determinar si la casilla de verificación está marcada o no mediante Activity.shouldShowRequestPermissionRationale (String), por ejemplo, así:
Eso es lo que dice la documentación de Android ( https://developer.android.com/training/permissions/requesting.html ):
Para saber si el usuario negó con "nunca preguntar de nuevo", puede verificar nuevamente el método shouldShowRequestPermissionRationale en su onRequestPermissionsResult cuando el usuario no otorgó el permiso.
Puede abrir la configuración de su aplicación con este código:
No hay forma de enviar al usuario directamente a la página de Autorización.
fuente
Puedes revisar
shouldShowRequestPermissionRationale()
tuonRequestPermissionsResult()
.https://youtu.be/C8lUdPVSzDk?t=2m23s
Compruebe si se otorgó el permiso o no
onRequestPermissionsResult()
. Si no, entonces verifiqueshouldShowRequestPermissionRationale()
.true
, muestre una explicación de por qué se necesita este permiso en particular. Luego, dependiendo de la elección del usuario nuevamenterequestPermissions()
.false
, muestre un mensaje de error que indique que no se otorgó el permiso y que la aplicación no puede continuar o que una función en particular está deshabilitada.A continuación se muestra el código de muestra.
Aparentemente, Google Maps hace exactamente esto para obtener permiso de ubicación.
fuente
Aquí hay un método agradable y fácil para verificar el estado actual de los permisos:
Advertencia: devuelve BLOCKED_OR_NEVER_ASKED el primer inicio de la aplicación, antes de que el usuario haya aceptado / denegado el permiso a través de la solicitud del usuario (en dispositivos SDK 23+)
Actualizar:
La biblioteca de soporte de Android ahora también parece tener una clase muy similar
android.support.v4.content.PermissionChecker
que contiene unacheckSelfPermission()
que devuelve:fuente
BLOCKED_OR_NEVER_ASKED
si el permiso aún no se ha solicitado.android.content.pm
ya definePERMISSION_GRANTED = 0
yPERMISSION_DENIED = -1
. Tal vez conjuntoBLOCKED_OR_NEVER_ASKED = PERMISSION_DENIED - 1
o algo?Una vez que el usuario ha marcado "No volver a preguntar", la pregunta no se puede volver a mostrar. Pero puede explicarse al usuario que previamente ha denegado el permiso y debe otorgarlo en la configuración. Y refiéralo a la configuración, con el siguiente código:
fuente
Puede ser útil para alguien: -
Lo que he notado es que si marcamos el indicador shouldShowRequestPermissionRationale () en el método de devolución de llamada onRequestPermissionsResult (), solo muestra dos estados .
Estado 1: -Return true: - Cada vez que el usuario hace clic en Denegar permisos (incluida la primera vez).
Estado 2: - Devuelve falso: - si el usuario selecciona "nunca pregunta de nuevo".
Enlace de ejemplo de trabajo detallado
fuente
onRequestPermissionsResult
, no cuando realmente solicitas el permiso.Puede determinarlo verificando si la justificación del permiso se mostrará dentro del
onRequestPermissionsResult()
método de devolución de llamada. Y si encuentra algún permiso configurado para no volver a preguntar nunca más , puede solicitar a los usuarios que otorguen permisos desde la configuración.Mi implementación completa sería como a continuación. Funciona para solicitudes de permisos simples o múltiples . Use lo siguiente o use directamente mi biblioteca.
fuente
Si desea detectar todos los "estados" (primera vez denegado, solo denegado, solo denegado con "Nunca preguntar de nuevo" o denegado permanentemente), puede hacer lo siguiente:
Crea 2 booleanos
Establezca el primero antes de pedir permiso:
Establezca el segundo dentro de su método onRequestPermissionsResult:
Use la siguiente "tabla" para hacer lo que necesite en onRequestPermissionsResult () (después de verificar que todavía no tiene el permiso):
fuente
// TRUE FALSE
También ocurre cuando el usuario permite un permiso después de denegarlo previamente.Tuve el mismo problema y lo resolví. Para simplificar la vida, escribí una clase util para manejar los permisos de tiempo de ejecución.
Y los métodos PreferenceUtil son los siguientes.
Ahora, todo lo que necesita es usar el método * checkPermission * con los argumentos adecuados.
Aquí hay un ejemplo,
Si el usuario marcó No preguntar nunca más , recibirá una devolución de llamada en onPermissionDisabled .
Feliz codificación :)
fuente
shouldShowRequestPermissionRationale
, guardando de preferencia la solicitud enviada al usuario. Tuve la misma idea y encontré tu respuesta. Buen trabajo hombreExplicación completa de cada caso de permiso.
fuente
Una función útil para determinar si se ha bloqueado la solicitud de un permiso arbitrario (en Kotlin):
El uso de esto requiere establecer un booleano de preferencia compartida con el nombre de su permiso deseado (por ejemplo
android.Manifest.permission.READ_PHONE_STATE
)true
cuando solicite un permiso por primera vez.Explicación:
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
ya que parte del código solo se puede ejecutar en el nivel de API 23+.ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED
para verificar que aún no tenemos el permiso.!activity.shouldShowRequestPermissionRationale(permission)
para verificar si el usuario ha denegado la aplicación preguntando nuevamente. Debido a las peculiaridades de esta función , también se requiere la siguiente línea.PreferenceManager.getDefaultSharedPreferences(activity).getBoolean(permission, false)
esto se usa (junto con establecer el valor en verdadero en la primera solicitud de permiso) para distinguir entre los estados "Nunca preguntado" y "Nunca preguntar de nuevo", ya que la línea anterior no devuelve esta información.fuente
El método shouldShowRequestPermissionRationale () se puede usar para verificar si el usuario seleccionó la opción 'nunca más se preguntó' y denegó el permiso. Hay muchos ejemplos de código, por lo que preferiría explicar cómo usarlo para tal propósito, porque creo que su nombre y su implementación hacen que esto sea más complicado de lo que realmente es.
Como se explica en Solicitud de permisos en tiempo de ejecución , ese método devuelve verdadero si la opción 'nunca preguntar de nuevo' es visible, de lo contrario, falso; Por lo tanto, devuelve falso la primera vez que se muestra un cuadro de diálogo, luego, a partir de la segunda vez, devuelve verdadero, y solo si el usuario niega el permiso para seleccionar la opción, en ese punto vuelve a ser falso nuevamente.
Para detectar este caso, puede detectar la secuencia falso-verdadero-falso, o (más simple) puede tener un indicador que haga un seguimiento de la hora inicial en que se muestra el diálogo. Después de eso, ese método devuelve verdadero o falso, donde el falso le permitirá detectar cuándo se selecciona la opción.
fuente
Por favor no me arrojes piedras por esta solución.
Esto funciona pero es un poco "hacky".
Cuando llame
requestPermissions
, registre la hora actual.Entonces en
onRequestPermissionsResult
Si no se otorga el resultado, verifique la hora nuevamente.
Como el usuario no puede hacer clic tan rápido en el botón denegar, sabemos que seleccionó "nunca preguntar de nuevo" porque la devolución de llamada es instantánea.
Úselo bajo su propio riesgo.
fuente
Escribí una taquigrafía para solicitar permiso en Android M. Este código también maneja la compatibilidad con versiones anteriores de Android.
Todo el código feo se extrae en un Fragmento que se adjunta y se separa a la Actividad que solicita los permisos. Puede usar
PermissionRequestManager
lo siguiente:Echa un vistazo: https://gist.github.com/crysxd/385b57d74045a8bd67c4110c34ab74aa
fuente
fuente
Pruebe esta sencilla biblioteca de permisos. Manejará todas las operaciones relacionadas con el permiso en 3 sencillos pasos. Me salvó el tiempo. Puede finalizar todo el trabajo relacionado con los permisos en 15 minutos .
Puede manejar Denegar, Puede manejar Nunca preguntar de nuevo, Puede llamar a la configuración de la aplicación para obtener permiso, Puede dar un mensaje Racional, Puede dar un mensaje de Denegación, Puede dar una lista de permisos aceptados, Puede dar una lista de denegados permisos y etc.
https://github.com/ParkSangGwon/TedPermission
Paso 1: agrega tu dependencia
Paso 2: pide permisos
Paso 3: manejar la respuesta de permiso
fuente
Puedes escuchar bonita.
Oyente
MainClass para permiso
Usado de esta manera
anular onRequestPermissionsResult en actividad o fragmnet
fuente
En su lugar, recibirá una devolución de llamada
onRequestPermissionsResult()
como PERMISSION_DENIED cuando solicite permiso nuevamente mientras cae en condición falsa deshouldShowRequestPermissionRationale()
Desde el documento de Android:
Cuando el sistema le pide al usuario que otorgue un permiso, el usuario tiene la opción de decirle al sistema que no solicite ese permiso nuevamente. En ese caso, cada vez que una aplicación utiliza
requestPermissions()
para pedir ese permiso nuevamente, el sistema inmediatamente rechaza la solicitud. El sistema llama a suonRequestPermissionsResult()
método de devolución de llamada y pasaPERMISSION_DENIED
, de la misma manera que lo haría si el usuario hubiera rechazado explícitamente su solicitud nuevamente. Esto significa que cuando llamarequestPermissions()
, no puede asumir que ha tenido lugar una interacción directa con el usuario.fuente
Puede usar el
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
método para detectar si nunca preguntar está marcado o no.Para más referencia: marque esto
Para verificar los permisos múltiples, use:
método de explicar ()
El código anterior también mostrará un cuadro de diálogo, que redirigirá al usuario a la pantalla de configuración de la aplicación desde donde puede otorgar permiso si ha marcado el botón Nunca preguntar de nuevo.
fuente
Puedes usar
dentro
Vea el siguiente ejemplo:
Compruebe si tiene permiso cuando el usuario hace clic en el botón:
Cuando el usuario responda al cuadro de diálogo de permiso, iremos a onRequestPermissionResult:
fuente
También me gustaría obtener la información de si el usuario ha seleccionado "nunca preguntar de nuevo". He logrado una 'solución casi' con una bandera de aspecto feo, pero antes de decirte cómo, te contaré sobre mi motivación:
Me gustaría ofrecer la funcionalidad de referencia de permisos inicialmente. Si el usuario lo usa y no tiene derechos, obtiene el primer cuadro de diálogo de arriba o el segundo y el tercero. Cuando el usuario ha elegido 'Nunca preguntar de nuevo', me gustaría deshabilitar la funcionalidad y mostrarla de manera diferente. - Mi acción se desencadena por una entrada de texto giratoria, también me gustaría agregar '(Permiso revocado)' al texto de la etiqueta que se muestra. Esto le muestra al usuario: 'Hay funcionalidad pero no puedo usarla, debido a mi configuración de permisos'. Sin embargo, esto no parece posible, ya que no puedo comprobar si se ha elegido o no "Nunca preguntar de nuevo".
Llegué a una solución con la que puedo vivir al tener mi funcionalidad siempre habilitada con una verificación de permiso activa. Estoy mostrando un mensaje Toast en onRequestPermissionsResult () en caso de una respuesta negativa, pero solo si no he mostrado mi ventana emergente de justificación personalizada. Entonces, si el usuario ha elegido 'Nunca preguntar de nuevo', solo recibe un mensaje de brindis. Si el usuario es reacio a elegir 'nunca preguntar de nuevo', solo obtiene la justificación personalizada y la ventana emergente de solicitud de permiso por parte del sistema operativo, pero no brinda, ya que tres notificaciones seguidas serían demasiado dolorosas.
fuente
Tengo que implementar un permiso dinámico para la cámara. Donde ocurren 3 casos posibles: 1. Permitir, 2. Denegado, 3. No volver a preguntar.
fuente
Ampliando la respuesta anterior de mVck , la siguiente lógica determina si "Nunca preguntar de nuevo" se ha verificado para una solicitud de permiso dada:
que se extrae de abajo (para ver el ejemplo completo, vea esta respuesta )
fuente
puedes leer el documento oficial de Android Solicitar permisos de aplicación
o puedes encontrar muchas bibliotecas de permisos de Android populares en Github
fuente
Para responder la pregunta con precisión, ¿qué sucede cuando el usuario presiona "Nunca preguntar de nuevo"?
El método / función anulada
La matriz grantResult resulta estar vacía, ¿entonces puede hacer algo allí? Pero no es la mejor práctica.
¿Cómo manejar "Nunca preguntar de nuevo"?
Estoy trabajando con Fragment, que requería el permiso READ_EXTERNAL_STORAGE.
Las otras funciones son triviales.
fuente