Zoeken…


Invoering

Android Marshmallow introduceerde het Runtime Permission- model. Machtigingen zijn onderverdeeld in twee categorieën, namelijk normale en gevaarlijke machtigingen . waar gevaarlijke toestemmingen nu door de gebruiker worden verleend tijdens runtime.

Opmerkingen

Vanaf sdk 23 vereist Android runtime-machtigingen voor machtigingen op apparaten met Android 6.0 en hoger, binnen wat wordt geclassificeerd als de Dangerous Permission Groups. Gevaarlijke machtigingsgroepen zijn groepen waarvan wordt aangenomen dat deze de privacy en / of veiligheid van de gebruiker in gevaar brengen.

Het volgende is een lijst met gevaarlijke machtigingsgroepen:

Gevaarlijke machtigingsgroepen

Toestemmingsgroep
KALENDER
CAMERA
CONTACTEN
PLAATS
MICROFOON
TELEFOON
SENSORS
sms
OPSLAG

Elke machtiging van deze groepen vereist beheer van runtime-machtigingen voor apparaten op Android 6.0 en hoger met een doelskd van 23 of hoger.

Normale machtigingen

Het volgende is een lijst met normale machtigingen. Deze worden niet beschouwd als gevaarlijk voor de privacy of beveiliging van de gebruiker en vereisen dus geen runtime-machtigingen voor SDK 23 en hoger.

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
ZET ALARM
SET_TIME_ZONE
STEL IN ALS ACHTERGROND
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
TRILLEN
WAKE_LOCK
WRITE_SYNC_SETTINGS

Android 6.0 meerdere machtigingen

Dit voorbeeld laat zien hoe u tijdens runtime machtigingen kunt controleren in Android 6 en hoger.

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;
        }
    }
}

Machtigingen afdwingen in uitzendingen, URI

U kunt een machtigingscontrole uitvoeren wanneer u een intentie naar een geregistreerde uitzendontvanger verzendt. De machtigingen die u verzendt, worden gecontroleerd met de machtigingen die onder de tag zijn geregistreerd. Ze beperken wie uitzendingen naar de bijbehorende ontvanger kan verzenden.

Om een uitzendverzoek met machtigingen te verzenden, geeft u de toestemming op als een tekenreeks in de Context.sendBroadcast(Intent intent, String permission) , maar houd er rekening mee dat de app van de ontvanger die toestemming MOET hebben om uw uitzending te ontvangen. De ontvanger moet eerst vóór de afzender worden geïnstalleerd.

De methode handtekening is:

 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");

en u kunt in uw manifest opgeven dat de afzender van de uitzending de gevraagde toestemming moet opnemen die via de sendBroadcast is verzonden:

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

Verklaar ook de toestemming in het manifest van de toepassing die deze uitzending zou moeten ontvangen:

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

Opmerking: zowel een ontvanger als een uitzender kunnen een toestemming nodig hebben, en wanneer dit gebeurt, moeten beide machtigingscontroles slagen voordat de intentie aan het bijbehorende doel kan worden afgeleverd. De app die de toestemming definieert, moet eerst worden geïnstalleerd.

Vind de volledige documentatie hier over machtigingen.

Meerdere runtime-machtigingen van dezelfde machtigingsgroepen

In het manifest hebben we vier gevaarlijke runtime-machtigingen van twee groepen.

<!-- 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 de activiteit waarvoor de machtigingen zijn vereist. Let op: het is belangrijk om te controleren op machtigingen voor elke activiteit waarvoor machtigingen vereist zijn, omdat de machtigingen kunnen worden ingetrokken terwijl de app op de achtergrond staat en de app crasht.

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();
    }

We hoeven voor elke groep slechts om toestemming te vragen en alle andere machtigingen van deze groep worden verleend, tenzij de toestemming door de gebruiker wordt ingetrokken.

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;
}

Dit gaat over het resultaat van het al dan niet toestaan van toestemmingen door de gebruiker. In dit voorbeeld wordt de app gedood als de machtigingen niet zijn toegestaan.

@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);
    }
}

Meer informatie https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

PermissionUtil gebruiken

PermissionUtil is een eenvoudige en handige manier om in context context om machtigingen te vragen. U kunt eenvoudig onAllGranted() wat er moet gebeuren in het geval van alle gevraagde machtigingen ( onAllGranted() ), elk verzoek is geweigerd ( onAnyDenied() ) of in het geval dat een rationeel nodig is ( onRational() ).

Overal in uw AppCompatActivity of Fragment dat u om toestemming van de gebruiker wilt vragen

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);

En voeg dit toe aan onRequestPermissionsResult

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

Voeg de gevraagde toestemming ook toe aan uw AndroidManifest.xml

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

Neem alle machtigingsgerelateerde code op in een abstracte basisklasse en breid de activiteit van deze basisklasse uit om schonere / herbruikbare code te bereiken

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);
    }
}

Voorbeeldgebruik in de activiteit

De activiteit moet de hierboven gedefinieerde abstracte basisklasse als volgt uitbreiden:

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow