Cómo solicitar permisos de un servicio en Android Marshmallow

En Android Marshmallow, los permisos deben solicitarse en tiempo de ejecución cuando se necesiten, en lugar de todos a la vez cuando se instala una aplicación. Sin embargo, solo puedo solicitar permisos de una actividad, lo cual es un problema, ya que mi aplicación solo contiene servicios. (¿Por qué es eso, podría preguntar? La aplicación tiene una cara del reloj Android Wear incluida, y todo lo que hace el teléfono es buscar fotos cercanas para enviar al reloj, no se necesita actividad. Pero sí requiere permisos de ubicación).

Entonces, ¿hay alguna forma de solicitar permisos de un Servicio? ¿O de algún modo obligar a otorgar los permisos en el momento de la instalación como en el pasado?

    requestPermission() solo se puede requestPermission() desde una Activity y no desde un Service (a diferencia de checkPermission() que solo requiere PackageManager ). Entonces necesitas hacer un trabajo extra para evitar eso; debe proporcionar una Activity en su aplicación y, por ejemplo, su Service puede verificar los permisos que necesita y si todavía no se han otorgado, puede crear una notificación y puede informar al usuario con un breve mensaje descriptivo de por qué hay una notificación y lo que debe suceder cuando hacen clic en la notificación, etc.

    Estoy de acuerdo, esto es muy problemático para los servicios, creo que deberías informar un problema en la página de Android Developer Preview para esto.

    Por el momento, creo que la mejor solución es verificar el permiso del servicio y mostrar una notificación si falta el permiso. Aún mejor, cree una DialogActivity para solicitar permiso cuando los usuarios presionen en la notificación.

    Eche un vistazo a la biblioteca PermissionEverywhere . Le permite solicitar permiso desde cualquier contexto.

    Crea una notificación haciendo clic en la cual se abre una actividad que solicita un permiso.

    Código de muestra de la página github de la biblioteca: –

     @Override protected Boolean doInBackground(Void... params) { PermissionResponse response = PermissionEverywhere.getPermission(getApplicationContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQ_CODE, "Notification title", "This app needs a write permission", R.mipmap.ic_launcher) .call(); //waits.. boolean isGranted = response.isGranted(); if(isGranted){ //changed from isGrante to isGranted // Do stuff } } 

    Hay una biblioteca muy simple que permite hacer exactamente esto. Puede verificar los permisos desde cualquier lugar (incluso desde un servicio), en función de si la aplicación está en primer plano o en segundo plano, muestra un cuadro de diálogo normal o genera una notificación que solicita permisos. El código es realmente fácil de entender y también es muy fácil de usar.

    Pruébalo: Permisos de Android

     @SuppressLint("NewApi") public void checkPerm() { locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if ( checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) { return; } locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {....} } 

    Puede usar ResultReceiver para crear un receptor de la respuesta de los usuarios, luego pasarlo como callback a la Actividad, a través de PendingIntent de notificación. Referencia