Android-Runtime-Berechtigungsbeispiel

Willkommen zum Beispiel für Laufzeitberechtigungen bei Android. Mit der Einführung von Android 6.0 Marshmallow hat Google die Art und Weise geändert, wie Berechtigungen von der App gehandhabt werden. In diesem Tutorial werden wir uns die neuen Android-Laufzeitberechtigungen, die eingeführt wurden, und wie man mit ihnen umgeht, ansehen. Wenn sie nicht richtig gehandhabt werden, kann dies zu Abstürzen der Anwendung führen.

Was sind Android Laufzeitberechtigungen?

Mit der Einführung von Android 6.0 (SDK 23) werden Benutzer aufgefordert, bestimmte Berechtigungen bei Laufzeit zu erteilen, wenn diese für die Nutzung notwendig werden. Die erste Frage, die uns in den Sinn kommt, ist also – Werden ältere Apps auf Android Marshmallow laufen? Die Antwort ist ja, wenn die targetSdkVersion 22 oder weniger beträgt. Daher unterstützen Android-Laufzeitberechtigungen die Abwärtskompatibilität. Das bedeutet jedoch nicht, dass wir mit dem alten Modell der Berechtigungen arbeiten können, indem wir die SDK-Version auf 22 setzen. Ein Benutzer, der Marshmallow verwendet, kann die gefährlichen Berechtigungen (wir werden später die gefährlichen und normalen Berechtigungen diskutieren) in den Einstellungen->Apps->Berechtigungen widerrufen. In dem Fall, dass wir versuchen, eine Funktion aufzurufen, die eine Berechtigung erfordert, die der Benutzer noch nicht erteilt hat, wird die Funktion plötzlich eine Ausnahme(java.lang.SecurityException) auslösen, die zum Absturz der Anwendung führt. Daher müssen wir dieses neue Android-Berechtigungsmodell in unserer Anwendung implementieren.

Gefährliche und normale Android-Berechtigungen

Android definiert einige Berechtigungen als gefährlich und einige als normal. Das Gemeinsame an beiden Typen ist, dass sie im Manifest-Datei definiert werden müssen. Ab Android 6.0 werden nur gefährliche Berechtigungen zur Laufzeit überprüft, normale Berechtigungen nicht. Ein Beispiel für eine normale Berechtigung ist android.permission.INTERNET. Gefährliche Berechtigungen sind in Kategorien gruppiert, was es dem Benutzer erleichtert zu verstehen, was er der Anwendung erlaubt. Wenn der Benutzer eine Berechtigung in einer Gruppe/Kategorie akzeptiert, akzeptiert er die gesamte Gruppe. Ein Beispiel für eine gefährliche Berechtigung ist android.permission.FINE_LOCATION und android.permission.COARSE_LOCATION. Wenn eine der Standortberechtigungen aktiviert wird, werden alle aktiviert.

Anfordern von Android-Laufzeitberechtigungen

Die Methode requestPermissions(String[] permissions, int requestCode); ist eine öffentliche Methode, die verwendet wird, um gefährliche Berechtigungen anzufordern. Wir können mehrere gefährliche Berechtigungen anfordern, indem wir ein String-Array von Berechtigungen übergeben. Hinweis: Android-Berechtigungen, die zu zwei verschiedenen Gruppen gehören, würden den Benutzer mit einem individuellen Dialog für jede davon auffordern. Wenn sie zur selben Gruppe gehören, wird nur ein Dialogfeld zur Berechtigungsaufforderung angezeigt. Die Ergebnisse der Anfragen werden an die Methode onRequestPermissionResult übergeben. Beispiel: Angenommen, wir möchten in unserer App auf die Kamera und den Standort zugreifen. Beides sind gefährliche Berechtigungen. Wir zeigen eine Aufforderung an, um Zugriff auf diese Berechtigungen zu erhalten, wenn die Anwendung gestartet wird. Lassen Sie uns die Berechtigungen in ein String-Array einfügen und die requestPermissions-Methode wie folgt aufrufen:

String[] perms = {"android.permission.FINE_LOCATION", "android.permission.CAMERA"};

int permsRequestCode = 200; 
requestPermissions(perms, permsRequestCode);

@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){

    switch(permsRequestCode){

        case 200:

            boolean locationAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
            boolean cameraAccepted = grantResults[1]==PackageManager.PERMISSION_GRANTED;

            break;

    }

}

Jetzt möchten wir nicht, dass der Benutzer Berechtigungen akzeptiert, die er bereits akzeptiert hat. Selbst wenn die Berechtigung zuvor erteilt wurde, ist es erforderlich, erneut zu überprüfen, um sicherzustellen, dass der Benutzer diese Berechtigung nicht später widerrufen hat. Dafür muss die folgende Methode für jede Berechtigung aufgerufen werden.

checkSelfPermission(String perm);

Es gibt einen Integer-Wert von PERMISSION_GRANTED oder PERMISSION_DENIED zurück. Hinweis: Wenn ein Benutzer eine Berechtigung ablehnt, die in der App kritisch ist, wird shouldShowRequestPermissionRationale(String permission); verwendet, um dem Benutzer die Notwendigkeit der Berechtigung zu erläutern. Lassen Sie uns eine Anwendung entwickeln, die überprüft, ob die Berechtigung bereits vorhanden ist. Wenn nicht, wird sie zur Laufzeit angefordert.

Android-Berechtigungen zur Laufzeit Projektstruktur

Android-Berechtigungen zur LaufzeitCode

Die content_main.xml enthält die beiden Schaltflächen zum Überprüfen und Anfordern von Berechtigungen.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.journaldev.runtimepermissions.MainActivity"
    tools:showIn="@layout/activity_main">
    <Button
        android:id="@+id/check_permission"
        android:layout_width="match_parent"
        android:layout_centerInParent="true"
        android:layout_height="wrap_content"
        android:text="Check Permission"/>
    <Button
        android:id="@+id/request_permission"
        android:layout_below="@+id/check_permission"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Request Permission"/>
</RelativeLayout>

Die MainActivity.java ist wie folgt definiert.

package com.journaldev.runtimepermissions;

import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import android.view.View;
import android.widget.Button;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.CAMERA;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int PERMISSION_REQUEST_CODE = 200;
    private View view;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Button check_permission = (Button) findViewById(R.id.check_permission);
        Button request_permission = (Button) findViewById(R.id.request_permission);
        check_permission.setOnClickListener(this);
        request_permission.setOnClickListener(this);


    }


    @Override
    public void onClick(View v) {

        view = v;

        int id = v.getId();
        switch (id) {
            case R.id.check_permission:
                if (checkPermission()) {

                    Snackbar.make(view, "Permission already granted.", Snackbar.LENGTH_LONG).show();

                } else {

                    Snackbar.make(view, "Please request permission.", Snackbar.LENGTH_LONG).show();
                }
                break;
            case R.id.request_permission:
                if (!checkPermission()) {

                    requestPermission();

                } else {

                    Snackbar.make(view, "Permission already granted.", Snackbar.LENGTH_LONG).show();

                }
                break;
        }

    }

    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
        int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);

        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }

    private void requestPermission() {

        ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION, CAMERA}, PERMISSION_REQUEST_CODE);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0) {

                    boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                    if (locationAccepted && cameraAccepted)
                        Snackbar.make(view, "Permission Granted, Now you can access location data and camera.", Snackbar.LENGTH_LONG).show();
                    else {

                        Snackbar.make(view, "Permission Denied, You cannot access location data and camera.", Snackbar.LENGTH_LONG).show();

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
                                showMessageOKCancel("You need to allow access to both the permissions",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                                    requestPermissions(new String[]{ACCESS_FINE_LOCATION, CAMERA},
                                                            PERMISSION_REQUEST_CODE);
                                                }
                                            }
                                        });
                                return;
                            }
                        }

                    }
                }


                break;
        }
    }


    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(MainActivity.this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }

}

Hinweis: Fügen Sie die Berechtigungen, die zur Laufzeit überprüft werden sollen, in der Manifestdatei über dem Anwendungstag wie folgt hinzu;

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Im obigen Code werden die beiden Berechtigungen CAMERA und LOCATION überprüft und angefordert. Das Importieren des vollständigen Klassennamens der statischen Berechtigung ermöglicht es uns, nur das PERMISSION-Objekt anstelle des vollqualifizierten Pfads zu schreiben. checkPermission() ruft die Methode checkSelfPermission für jede Berechtigung auf. requestPermission() ruft ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION, CAMERA}, PERMISSION_REQUEST_CODE); auf. onRequestPermissionsResult überprüft, ob die Berechtigungen gewährt wurden oder nicht. In unserem Code wird, wenn beide Berechtigungen nicht gewährt wurden, ein Alert-Dialog angezeigt, der die obligatorische Notwendigkeit zum Anfordern der Berechtigungen anzeigt. Dazu wird shouldShowRequestPermissionRationale(String permission) aufgerufen, was einen Alert-Dialog anzeigt, der die Notwendigkeit der Berechtigungen erklärt. Sie können die Berechtigungen manuell über Einstellungen->Apps->Berechtigungen widerrufen. Hinweis: Die Laufzeitberechtigungsmethoden sind erst ab API 23 verfügbar. Daher wird bei jeder der Methoden die folgende Bedingung überprüft:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)

Das Ergebnis der Anwendungsbeispiel für Android-Runtime-Berechtigungen ist unten dargestellt. Damit endet dieses Tutorial. Sie können das endgültige Android-Runtime-Berechtigungsprojekt über den folgenden Link herunterladen.

Laden Sie das Beispielprojekt für Android-Runtime-Berechtigungen herunter

Referenz: https://developer.android.com/training/permissions/requesting.html

Source:
https://www.digitalocean.com/community/tutorials/android-runtime-permissions-example