Android – Como solicitar los permisos en Android 6 y superiores

Las aplicaciones que desarrollas en Android que requieren permisos necesitan la declaración de estos en el archivo manifiest de tu proyecto. Veamos como se piden los permisos en Android 6 y superior.

Por ejemplo  para acceder a la Camara de Fotos debemos incluir un  <uses-permission> en nuestro manifiest. de este modo.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.gustavopeiretti.app" >
    <uses-permission android:name="android.permission.CAMERA" />
    ...
</manifest>

android-permissions

Si tu proyecto esta definido para para versiones anteriores targetSdkVersion 22 o menor solo basta con incluir en el “manifiest” los permisos que necesitas. En estas versiones, al instalar la aplicación, Android requiere al usuario la aceptación de los permisos que hemos declarado en nuestro archivo manifiest.

Sin embargo a partir de targetSdkVersion 23 Android 6.0 (API level 23) esto ha cambiado y es necesario que nosotros nos encarguemos de requerir estos permisos para aquellos que son ‘peligrosos’. Android los llama “Dangerous permissions”

    .. archivo build.gradle de nuestra app.. 
    ....
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
    
        defaultConfig {
            applicationId "com.example.examplepermission"
            minSdkVersion 23
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        ...
    }

¿Cómo requerir los permisos para Android 6 o superior?

Podemos hacer uso de este metodo “PermissionChecker.checkSelfPermission(..)” que nos dira el estado del permiso. Luego usaremos requestPermissions(..) para solicitar los permisos que nos faltan.

Por ejemplo, para saber si tenemos permisos a la Camara y requerirlos en caso negativo:

private final int REQUEST_CODE_ASK_PERMISSIONS = 123;
        ...

         int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);
            if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {

                // request permission

                requestPermissions(new String[] {Manifest.permission.CAMERA},
                        REQUEST_CODE_ASK_PERMISSIONS);

            }else if (hasWriteContactsPermission == PackageManager.PERMISSION_GRANTED){

                // do something

            }

¿Cómo obtener el resultado del permiso?

El resultado de nuestra solicitud de permisos la podemos evaluar sobreescribiendo “onRequestPermissionsResult(…)”

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if(REQUEST_CODE_ASK_PERMISSIONS == requestCode) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // OK Do something with..
            } else {
                // The user does not grant permissions 
            }
        }else{
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

Si intentas abrir la Camara (o lo que necesites) sin permisos otorgados por el usuario, recibiras esta excepción

    Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=android/com.android.internal.app.ResolverActivity } 

Permisos que necesitan ser verificados

Puedes solicitar permisos ya sea para el grupo o para un elemento individual del grupo. En el caso de CONTACTS, este tiene tres elementos.

Permission Group: CONTACTS

Permissions: READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS

Si tu App solicita permisos para un item en particular del grupo de permisos, por ejemplo READ_CONTACTS, Android solicitara permisos al usuario indicándole que necesita permisos para CONTACTS (el grupo) sin detallar el permiso particular que requeriste.

Si tu app ya tiene permisos a READ_CONTACTS otorgados por el usuario y luego tu app solicita permisos para otro item especifico del mismo grupo, ej. WRITE_CONTACTS, el sistema inmediatamente otorgará permisos sin preguntarle al usuario.

Es decir, si ya recibiste permisos para READ_CONTACTS y luego solicitas para WRITE_CONTACTS inmediatamente recibiras este segundo permiso porque estan en el mismo grupo.

Los permisos se agrupan acorde a la columna “Permission Group” que pueden consultar en este enlace

El codigo completo de ejemplo quedaría así

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE_ASK_PERMISSIONS = 123;

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
    }

    public void examplePermission(View view) {
        checkPermission();
    }

    private void checkPermission() {

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {

            Toast.makeText(this, "This version is not Android 6 or later " + Build.VERSION.SDK_INT, Toast.LENGTH_LONG).show();

        } else {

            int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.CAMERA);

            if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {

                requestPermissions(new String[] {Manifest.permission.CAMERA},
                        REQUEST_CODE_ASK_PERMISSIONS);

                Toast.makeText(this, "Requesting permissions", Toast.LENGTH_LONG).show();

            }else if (hasWriteContactsPermission == PackageManager.PERMISSION_GRANTED){

                Toast.makeText(this, "The permissions are already granted ", Toast.LENGTH_LONG).show();
                openCamera();

            }

        }

        return;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if(REQUEST_CODE_ASK_PERMISSIONS == requestCode) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "OK Permissions granted ! " + Build.VERSION.SDK_INT, Toast.LENGTH_LONG).show();
                openCamera();
            } else {
                Toast.makeText(this, "Permissions are not granted ! " + Build.VERSION.SDK_INT, Toast.LENGTH_LONG).show();
            }
        }else{
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private void openCamera() {

        textView.setText("Thanks !!!");

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivity(intent);

    }

}

Descarga este codigo completo

Referencias:

Android Permissions

Requesting Permissions at Run Time

Hi! If you find my posts helpful, please support me by inviting me for a coffee :)

Ver también