Suche…


Einführung

Android Marshmallow führte das Runtime Permission- Modell ein. Berechtigungen werden in zwei Kategorien unterteilt, nämlich normale und gefährliche Berechtigungen . wo gefährliche Berechtigungen jetzt vom Benutzer zur Laufzeit erteilt werden.

Bemerkungen

Ab sdk 23 benötigt Android Laufzeitberechtigungen für Berechtigungen auf Geräten, auf denen Android 6.0 oder höher ausgeführt wird, innerhalb der als gefährlich eingestuften Berechtigungsgruppen. Gefährliche Berechtigungsgruppen sind Personengruppen, die die Privatsphäre und / oder Sicherheit des Benutzers gefährden.

Im Folgenden finden Sie eine Liste gefährlicher Berechtigungsgruppen:

Gefährliche Berechtigungsgruppen

Berechtigungsgruppe
KALENDER
KAMERA
KONTAKTE
STANDORT
MIKROFON
TELEFON
SENSOREN
SMS
LAGER

Alle Berechtigungen dieser Gruppen erfordern die Verwaltung von Laufzeitberechtigungen für Geräte ab Android 6.0 mit einem Ziel-SDK von 23 oder höher.

Normale Berechtigungen

Im Folgenden finden Sie eine Liste normaler Berechtigungen. Diese werden nicht als gefährlich für die Privatsphäre oder Sicherheit des Benutzers angesehen und erfordern daher keine Laufzeitberechtigungen für SDK 23 und höher.

ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
REQUEST_INSTALL_PACKAGES
WECKER STELLEN
SET_TIME_ZONE
HINTERGRUNDBILD FESTLEGEN
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRIEREN
WAKE_LOCK
WRITE_SYNC_SETTINGS

Android 6.0 mehrere Berechtigungen

Dieses Beispiel zeigt, wie Berechtigungen zur Laufzeit in Android 6 und höher geprüft werden.

public static final int MULTIPLE_PERMISSIONS = 10; // code you want.

String[] permissions = new String[] {
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
    Manifest.permission.CAMERA,
    Manifest.permission.ACCESS_COARSE_LOCATION,
    Manifest.permission.ACCESS_FINE_LOCATION
};

@Override
void onStart() {
    if (checkPermissions()){
        // permissions granted.    
    } else {
        // show dialog informing them that we lack certain permissions
    }
}

private boolean checkPermissions() {
    int result;
    List<String> listPermissionsNeeded = new ArrayList<>();
    for (String p:permissions) {
        result = ContextCompat.checkSelfPermission(getActivity(),p);
        if (result != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(p);
        }
    }
    if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MULTIPLE_PERMISSIONS);
        return false;
    }
    return true;
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MULTIPLE_PERMISSIONS:{
            if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                // permissions granted.
            } else {
                // no permissions granted.
            }
            return;
        }
    }
}

Erzwingen von Berechtigungen in Broadcasts, URI

Sie können eine Berechtigungsprüfung durchführen, wenn Sie eine Absicht an einen registrierten Rundfunkempfänger senden. Die Berechtigungen, die Sie senden, werden mit den unter dem Tag registrierten Berechtigungen abgeglichen. Sie schränken ein, wer Broadcasts an den zugehörigen Empfänger senden darf.

Um eine Broadcast-Anforderung mit Berechtigungen zu senden, geben Sie die Berechtigung als Zeichenfolge im Context.sendBroadcast(Intent intent, String permission) jedoch, dass die Empfänger-App diese Berechtigung haben MUSS , um Ihre Rundsendung zu empfangen. Der Empfänger sollte zuerst vor dem Absender installiert werden.

Die Methodensignatur lautet:

 void sendBroadcast (Intent intent, String receiverPermission)
 //for example to send a broadcast to Bcastreceiver receiver
 Intent broadcast = new Intent(this, Bcastreceiver.class);
 sendBroadcast(broadcast, "org.quadcore.mypermission");

und Sie können in Ihrem Manifest angeben, dass der Broadcast-Sender die angeforderte Berechtigung enthalten muss, die über sendBroadcast gesendet wird:

 <!--  Your special permission -->
 <permission android:name="org.quadcore.mypermission" 
    android:label="my_permission" 
    android:protectionLevel="dangerous"></permission>

Erklären Sie auch die Erlaubnis im Manifest der Anwendung, die diese Sendung empfangen soll:

 <!--  I use the permission ! -->
 <uses-permission android:name="org.quadcore.mypermission"/>
 <!-- along with the receiver -->
 <receiver android:name="Bcastreceiver" android:exported="true" />

Hinweis: Sowohl ein Empfänger als auch ein Sender können eine Berechtigung erfordern. In diesem Fall müssen beide Berechtigungsprüfungen bestanden werden, damit die Absicht an das zugeordnete Ziel übermittelt werden kann. Die App, die die Berechtigung definiert, sollte zuerst installiert werden.

Die vollständige Dokumentation finden Sie hier unter Berechtigungen.

Mehrere Laufzeitberechtigungen aus denselben Berechtigungsgruppen

Im Manifest haben wir vier gefährliche Laufzeitberechtigungen aus zwei Gruppen.

<!-- Required to read and write to shredPref file. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<!-- Required to get location of device. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

In der Aktivität, für die die Berechtigungen erforderlich sind. Beachten Sie, dass bei jeder Aktivität, die Berechtigungen erfordert, nach Berechtigungen gesucht werden muss, da die Berechtigungen widerrufen werden können, während sich die App im Hintergrund befindet und die App dann abstürzt.

final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.act_layout);
    
    // A simple check of whether runtime permissions need to be managed 
    if (Build.VERSION.SDK_INT >= 23) {
        checkMultiplePermissions();
    }

Wir müssen nur für jede dieser Gruppen eine Erlaubnis einholen, und alle anderen Berechtigungen dieser Gruppe werden erteilt, es sei denn, der Benutzer widerruft die Berechtigung.

private void checkMultiplePermissions() {

    if (Build.VERSION.SDK_INT >= 23) {
        List<String> permissionsNeeded = new ArrayList<String>();
        List<String> permissionsList = new ArrayList<String>();
        
        if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
            permissionsNeeded.add("GPS");
        }

        if (!addPermission(permissionsList, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
            permissionsNeeded.add("Read Storage");
        }
        
        if (permissionsList.size() > 0) {
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
            return;
        }
    }
}



private boolean addPermission(List<String> permissionsList, String permission) {
    if (Build.VERSION.SDK_INT >= 23)

        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);

            // Check for Rationale Option
            if (!shouldShowRequestPermissionRationale(permission))
                return false;
        }
    return true;
}

Hierbei handelt es sich um das Ergebnis, dass der Benutzer Berechtigungen zulässt oder nicht. Wenn in diesem Beispiel keine Berechtigungen zulässig sind, wird die App beendet.

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
        
            Map<String, Integer> perms = new HashMap<String, Integer>();
            // Initial
            perms.put(android.Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
            perms.put(android.Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
            
            // Fill with results
            for (int i = 0; i < permissions.length; i++)
                perms.put(permissions[i], grantResults[i]);
            if (perms.get(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                    && perms.get(android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                // All Permissions Granted
                return;
            } else {
                // Permission Denied
                if (Build.VERSION.SDK_INT >= 23) {
                    Toast.makeText(
                            getApplicationContext(),
                            "My App cannot run without Location and Storage " +
                                    "Permissions.\nRelaunch My App or allow permissions" +
                                    " in Applications Settings",
                            Toast.LENGTH_LONG).show();
                    finish();
                }
            }
        }
        break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Weitere Informationen https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/de

PermissionUtil verwenden

PermissionUtil ist eine einfache und bequeme Methode, um Berechtigungen im Kontext abzufragen. Sie können problemlos onAllGranted() , was geschehen soll, wenn alle angeforderten Berechtigungen erteilt wurden ( onAllGranted() ), jede Anforderung abgelehnt wurde ( onAnyDenied() ) oder falls ein rationaler onRational() erforderlich ist ( onRational() ).

Überall in Ihrer AppCompatActivity oder Ihrem Fragment, an dem Sie die Erlaubnis des Benutzers anfordern möchten

mRequestObject = PermissionUtil.with(this).request(Manifest.permission.WRITE_EXTERNAL_STORAGE).onAllGranted(
                new Func() {
                    @Override protected void call() {
                        //Happy Path
                    }
                }).onAnyDenied(
                new Func() {
                    @Override protected void call() {
                        //Sad Path
                    }
                }).ask(REQUEST_CODE_STORAGE);

Und fügen Sie dies zu onRequestPermissionsResult

if(mRequestObject!=null){
    mRequestObject.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

Fügen Sie die angeforderte Berechtigung auch zu Ihrer AndroidManifest.xml hinzu

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

Fügen Sie allen berechtigungsbezogenen Code einer abstrakten Basisklasse hinzu und erweitern Sie die Aktivität dieser Basisklasse, um saubereren / wiederverwendbaren Code zu erhalten

public abstract class BaseActivity extends AppCompatActivity {
    private Map<Integer, PermissionCallback> permissionCallbackMap = new HashMap<>();

    @Override
    protected void onStart() {
        super.onStart();
        ...
    }

    @Override
    public void setContentView(int layoutResId) {
        super.setContentView(layoutResId);
        bindViews();
    }

    ...

    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionCallback callback = permissionCallbackMap.get(requestCode);

        if (callback == null) return;

        // Check whether the permission request was rejected.
        if (grantResults.length < 0 && permissions.length > 0) {
            callback.onPermissionDenied(permissions);
            return;
        }

        List<String> grantedPermissions = new ArrayList<>();
        List<String> blockedPermissions = new ArrayList<>();
        List<String> deniedPermissions = new ArrayList<>();
        int index = 0;

        for (String permission : permissions) {
            List<String> permissionList = grantResults[index] == PackageManager.PERMISSION_GRANTED
                    ? grantedPermissions
                    : ! ActivityCompat.shouldShowRequestPermissionRationale(this, permission)
                        ? blockedPermissions
                        : deniedPermissions;
            permissionList.add(permission);
            index ++;
        }

        if (grantedPermissions.size() > 0) {
            callback.onPermissionGranted(
                    grantedPermissions.toArray(new String[grantedPermissions.size()]));
        }

        if (deniedPermissions.size() > 0) {
            callback.onPermissionDenied(
                    deniedPermissions.toArray(new String[deniedPermissions.size()]));
        }

        if (blockedPermissions.size() > 0) {
            callback.onPermissionBlocked(
                    blockedPermissions.toArray(new String[blockedPermissions.size()]));
        }

        permissionCallbackMap.remove(requestCode);
    }

    /**
     * Check whether a permission is granted or not.
     *
     * @param permission
     * @return
     */
    public boolean hasPermission(String permission) {
        return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * Request permissions and get the result on callback.
     *
     * @param permissions
     * @param callback
     */
    public void requestPermission(String [] permissions, @NonNull PermissionCallback callback) {
        int requestCode = permissionCallbackMap.size() + 1;
        permissionCallbackMap.put(requestCode, callback);
        ActivityCompat.requestPermissions(this, permissions, requestCode);
    }

    /**
     * Request permission and get the result on callback.
     *
     * @param permission
     * @param callback
     */
    public void requestPermission(String permission, @NonNull PermissionCallback callback) {
        int requestCode = permissionCallbackMap.size() + 1;
        permissionCallbackMap.put(requestCode, callback);
        ActivityCompat.requestPermissions(this, new String[] { permission }, requestCode);
    }
}

Verwendungsbeispiel in der Aktivität

Die Aktivität sollte die oben definierte abstrakte Basisklasse wie folgt erweitern:

private void requestLocationAfterPermissionCheck() {
    if (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
        requestLocation();
        return;
    }

    // Call the base class method.
    requestPermission(Manifest.permission.ACCESS_FINE_LOCATION, new PermissionCallback() {
        @Override
        public void onPermissionGranted(String[] grantedPermissions) {
            requestLocation();
        }

        @Override
        public void onPermissionDenied(String[] deniedPermissions) {
            // Do something.
        }

        @Override
        public void onPermissionBlocked(String[] blockedPermissions) {
            // Do something.
        }
    });
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow