2015-10-29 8 views
28

"CheckSelfPermission" -Methode funktioniert nicht wie erwartet und es gibt immer Null in Android 6.0 (Marshmallow) zurück. Weil das Ziel sdk 22 ist und ich HTTP-Client für die Netzwerkverbindung verwende. Im Folgenden ist das Code-Snippet.checkSelfPermission-Methode funktioniert nicht in targetSdkVersion 22

"private void insertDummyContactWrapper() { Liste permissionsNeeded = new Arraylist();

final List<String> permissionsList = new ArrayList<String>(); 
    if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) 
     permissionsNeeded.add("GPS"); 
    if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS)) 
     permissionsNeeded.add("Read Contacts"); 
    if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS)) 
     permissionsNeeded.add("Write Contacts"); 

    if (permissionsList.size() > 0) { 
     if (permissionsNeeded.size() > 0) { 
      // Need Rationale 
      String message = "You need to grant access to " + permissionsNeeded.get(0); 
      for (int i = 1; i < permissionsNeeded.size(); i++) 
       message = message + ", " + permissionsNeeded.get(i); 
      showMessageOKCancel(message, 
        new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
         } 
        }); 
      return; 
     } 
     requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
       REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
     return; 
    } 

    insertDummyContact(); 
} 

@TargetApi(Build.VERSION_CODES.M) 
private boolean addPermission(List<String> permissionsList, String permission) { 
    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { 
     permissionsList.add(permission); 
     // Check for Rationale Option 
     if (!shouldShowRequestPermissionRationale(permission)) return false; 
    } 
    return true; 
} 

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

@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(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED); 
      perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED); 
      perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED); 
      // Fill with results 
      for (int i = 0; i < permissions.length; i++) 
       perms.put(permissions[i], grantResults[i]); 
      // Check for ACCESS_FINE_LOCATION 
      if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) { 
       // All Permissions Granted 
       insertDummyContact(); 
      } else { 
       // Permission Denied 
       Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     } 
     break; 
     default: 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    } 
}" 
+0

Mögliche Duplikat [Marshmallow-Berechtigungen funktionieren nicht für TargetVersion unter 23] (http: // stackoverflow.com/questions/33232865/Marshmallow-Berechtigungen-nicht-Working-for-Target-Version-unter-23) –

Antwort

9

Verfahren Context#checkSelfPermission(String) wurde 23. Auch auf die API hinzugefügt unter API 23 es sinnlos ist, als die Erlaubnis immer gewährt wird. machen Sie einen Scheck für die API-Version vor

private void insertDummyContactWrapper() { 
    // the only way we insert the dummy contact if if we are below M. 
    // Else we continue on and prompt the user for permissions 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
     insertDummyContact(); 
     return; 
    } 

    List<String> permissionsNeeded = new ArrayList<String>(); 

    final List<String> permissionsList = new ArrayList<String>(); 
    if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION)) 
     permissionsNeeded.add("GPS"); 
    if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS)) 
     permissionsNeeded.add("Read Contacts"); 
    if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS)) 
     permissionsNeeded.add("Write Contacts"); 
    if (permissionsList.size() > 0) { 
     if (permissionsNeeded.size() > 0) { 
      // Need Rationale 
      String message = "You need to grant access to " + permissionsNeeded.get(0); 
      for (int i = 1; i < permissionsNeeded.size(); i++) 
       message = message + ", " + permissionsNeeded.get(i); 
      showMessageOKCancel(message, 
        new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
         } 
        }); 
      return; 
     } 
     requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
       REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
    } 
} 

Referenz die Berechtigungen Handhabung: http://developer.android.com/reference/android/content/Context.html#checkSelfPermission(java.lang.String)

+0

Nun, der Link, den Sie angeben, nicht angeben, dass es nicht auf API <23 funktionieren sollte. Tatsächlich kettet es wahrscheinlich einfach auf 'checkPermission (String-Berechtigung, int pid, int uid)', die seit API 1 vorhanden ist. –

+0

Der Link zeigt, dass "checkSelfPermission" vor API 23 nicht existierte. Es ist nicht relevant, wenn es als ketten Die Methode wird unter API 23 nie etwas tun. Unabhängig davon, was Sie tun, werden die Laufzeitberechtigungen unterhalb von 23 nicht funktionieren. Überprüfen Sie vor einer Berechtigungsbehandlung die API auf mindestens 23. Sie werden nie die Laufzeitberechtigungen erhalten, um unter 23 zu arbeiten. – JBirdVegas

+1

Nun, ich lese gerade meinen Kommentar noch einmal, ich war heute Morgen * nicht * wach. In der Tat stürzt die Methode in API <23 ab ... Aber es gibt immer die Möglichkeit, die support-v4-Bibliothek zu verwenden, die 'checkSelfPermission' bereitstellt (http://developer.android.com/reference/android/support/v4/content) /ContextCompat.html#checkSelfPermission%28android.content.Context,%20java.lang.String%29). Dieser funktioniert (und gibt immer 'PERMISSION_GRANTED' auf API <23) zurück. –

3

Wenn eine API-Ebene vor 23 ausgewählt wird, gilt ein Kompatibilitätsmodus. Das alte Berechtigungsverhalten wird auch auf Geräten mit Android 6 ausgeführt. Um das neue Berechtigungssystem zu verwenden, müssen Sie API 23 (oder höher in der Zukunft) verwenden.

Das vollständige Verhalten wird auf der Dokumentation angegeben: https://developer.android.com/training/permissions/requesting.html

69
  1. Wenn Ihre Anwendung vor 23 (Android M) eine API-Ebene zielt dann beide: ContextCompat#checkSelfPermission und Context#checkSelfPermission nicht funktioniert und immer gibt 0 zurück (PERMISSION_GRANTED). Selbst wenn Sie die Anwendung unter Android 6.0 (API 23) ausführen.

  2. Es ist nicht vollständig richtig, dass Sie sich nicht um Berechtigungen kümmern müssen, wenn Sie vor 23 auf eine API-Ebene ausgerichtet sind. Wenn Sie eine API-Ebene vor dem 23. Targeting dann:

    • Android < 6.0: Alles wird in Ordnung sein.
    • Android 6.0: Anwendung der Laufzeitberechtigungen werden standardmäßig gewährt werden (Kompatibilitätsmodus gilt), aber kann der Benutzer Laufzeitberechtigungen in Android-Einstellungen ändern, dann können Sie ein Problem haben.
  3. Wie ich im ersten Punkt, wenn Sie vor dem 23. auf Android eine API-Level-Targeting 6.0 dann ContextCompat#checkSelfPermission und Context#checkSelfPermission funktionieren nicht. Glücklicherweise können Sie PermissionChecker#checkSelfPermission verwenden, um Laufzeitberechtigungen zu überprüfen.

Beispielcode:

public boolean selfPermissionGranted(String permission) { 
     // For Android < Android M, self permissions are always granted. 
     boolean result = true; 

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

      if (targetSdkVersion >= Build.VERSION_CODES.M) { 
       // targetSdkVersion >= Android M, we can 
       // use Context#checkSelfPermission 
       result = context.checkSelfPermission(permission) 
         == PackageManager.PERMISSION_GRANTED; 
      } else { 
       // targetSdkVersion < Android M, we have to use PermissionChecker 
       result = PermissionChecker.checkSelfPermission(context, permission) 
         == PermissionChecker.PERMISSION_GRANTED; 
      } 
     } 

     return result; 
    } 

Um Ziel Sdk Version zu erhalten, können Sie:

try { 
     final PackageInfo info = context.getPackageManager().getPackageInfo(
       context.getPackageName(), 0); 
     targetSdkVersion = info.applicationInfo.targetSdkVersion; 
    } catch (PackageManager.NameNotFoundException e) { 
     e.printStackTrace(); 
    } 

es auf Nexus 5 mit Android M. arbeitet

+0

Die beste Antwort, die ich finden konnte. –

+1

Was ist der Sinn der Verwendung von 'PermissionChecker # checkSelfPermission', wenn du es bist Ziel nicht mindestens SDK 23? Berechtigungen werden * immer * erteilt, selbst auf einem SDK 23-Gerät, wenn das SDK 22 oder niedriger ausgerichtet ist. –

+4

Berechtigungen werden nach der Installation automatisch gewährt, aber ein Benutzer kann die Laufzeitberechtigungen nach der Installation deaktivieren. Aus diesem Grund möchten wir überprüfen, ob Berechtigungen gewährt werden. – MikePtr

Verwandte Themen