2017-06-19 2 views
0

Ich versuche, ein Stück Code, die Android-Berechtigungen behandelt refaktorieren. Es funktioniert gut, bis auf einen nervigen UI-Bug, der mir viele Kopfschmerzen bereitet hat. Hier ist der Code:Android-Berechtigungen UI-Problem mit mehreren Dialogen

private void getPermissions() { 

    if (Build.VERSION.SDK_INT >= 23) { 

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

     final List<String> permissionsList = new ArrayList<String>(); 
     if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_COARSE_LOCATION)) 
      permissionsNeeded.add(accessLocation); 
     if (!addPermission(permissionsList, android.Manifest.permission.READ_CONTACTS)) 
      permissionsNeeded.add(readContacts); 
     if (!addPermission(permissionsList, Manifest.permission.READ_EXTERNAL_STORAGE)) 
      permissionsNeeded.add(readStorage); 
     if (!addPermission(permissionsList, Manifest.permission.CAMERA)) 
      permissionsNeeded.add(accessCamera); 

     if (permissionsList.size() > 0) { 
      if (permissionsNeeded.size() > 0) { 
       requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
         REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
      } 
     } 
    } 
} 

private void showMessageOK (int message, final String perm) { 

    if (shouldShowRequestPermissionRationale(perm)) { 

     new AlertDialog.Builder(CreateSessionActivity.this) 
       .setMessage(message) 
       .setTitle("Permission required") 
       .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialog, int which) { 

         dialog.dismiss(); 
         requestPermissions(new String[] {perm}, 
           REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 

        } 
       }) 
       .create() 
       .show(); 
    } 
} 

private boolean addPermission(List<String> permissionsList, String permission) { 

    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { 

     permissionsList.add(permission); 

     //check for rationale 
     if (!shouldShowRequestPermissionRationale(permission)) 
      return false; 
    } 
    return true; 
} 

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

    Map<String, Integer> perms = new HashMap<>(); 

    perms.put(android.Manifest.permission.ACCESS_COARSE_LOCATION, PackageManager.PERMISSION_GRANTED); 
    perms.put(android.Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED); 
    perms.put(android.Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED); 
    perms.put(android.Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED); 
    // Fill with results 
    for (int i = 0; i < permissions.length; i++) 
     perms.put(permissions[i], grantResults[i]); 

    if (perms.get(accessLocation) != PackageManager.PERMISSION_GRANTED) { 

     showMessageOK(R.string.permdesc_access_location, 
       accessLocation); 
    } 

    if (perms.get(readContacts) != PackageManager.PERMISSION_GRANTED) { 

     showMessageOK(R.string.permdesc_read_contacts, 
       readContacts); 
    } 

    if (perms.get(readStorage) != PackageManager.PERMISSION_GRANTED) { 

     showMessageOK(R.string.permdesc_read_storage, 
       readStorage); 
    } 

    if (perms.get(accessCamera) != PackageManager.PERMISSION_GRANTED) { 

     showMessageOK(R.string.permdesc_access_camera, 
       accessCamera); 
    } 
} 

Es im Grunde eine Liste von Berechtigungen erhält, die vom Benutzer nicht bereits gewährt wird, durchläuft sie und fordert den Benutzer jeweils zu gewähren. Sobald es fertig ist, überprüft es alle verbleibenden Berechtigungen, die nicht gewährt wurden, und fordert den Benutzer erneut mit Informationen darüber auf, warum diese Berechtigung erforderlich ist und das Ergebnis nicht zulässt, bis er entweder "nicht erneut fragen" annimmt oder wählt.

Mein Problem tritt mit den verketteten "if" -Anweisungen in onRequestPermissionResult(). Wie Sie vielleicht vermuten, wenn mehrere Berechtigungsbedingungen wahr sind, dann öffnet jeder Dialog unter den aktuellen vorhandenen Dialog. Dies führt zu einem "Sprung" -Dialogeffekt zwischen dem Schließen eines Dialogs und dem nächsten Anzeigen. Ich habe case und if/elseif versucht, dies zu bekämpfen, aber es verursacht Probleme mit dem Rest meiner Berechtigungslogik.

Hat jemand eine saubere Lösung dafür? Ich wäre dankbar.

+0

IMHO, die sauberste Lösung ist aller 'showMessageOK()' Anrufe loszuwerden. Der Benutzer weiß, dass der Benutzer Ihnen die Berechtigung erteilt hat, weil * der Benutzer es gerade getan hat *. Danken Sie ihnen nicht für die Erteilung der Erlaubnis - tun Sie alles, was der Benutzer verlangte, dass die Erlaubnis benötigt. – CommonsWare

+0

Stellen Sie sicher, dass alle angeforderten Berechtigungen auch in Ihrer 'AndroidManifest'-Datei deklariert sind – Benny

Antwort

0

Nun, kann dies nicht der sauberste Code sein, aber

if (Build.VERSION.SDK_INT >= 23) { 

    List<String> permissionsNeeded = new ArrayList<String>();    
    for(int i=0; i<4;i++){ 
      checkAndAsk(i); 
    } 
    if (permissionsList.size() > 0) { 
     if (permissionsNeeded.size() > 0) { 
      requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), 
        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS); 
     } 
    } 
} 
//out of the get permissions method 
public void checkAndAsk(int i){ 
      switch(i){ 
       case 0: 
        if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_COARSE_LOCATION)) 
         permissionsNeeded.add(accessLocation); 
        break; 
       case 1: 
        if (!addPermission(permissionsList, android.Manifest.permission.READ_CONTACTS)) 
         permissionsNeeded.add(readContacts); 
        break; 
       //You get the idea 
      } 
    } 

Grundsätzlich durchlaufen Sie die Berechtigungen durch durch einen Parameter, von denen die Erlaubnis vorbei Sie fragen. Sobald eine Genehmigung gewährt/abgelehnt wird, bricht sie ab und wechselt zur zweiten Berechtigung, bis alle erledigt sind.

In der Theorie sollte dies funktionieren.

0

Verwenden Sie einfach diesen Code:

private void RequestAllPermissions() { 

     String[] PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.RECEIVE_SMS, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET, Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.WRITE_CONTACTS}; 

     if (!hasPermissions(this, PERMISSIONS)) { 
      ActivityCompat.requestPermissions(this, PERMISSIONS, REQUESTCODE_PERMISSION_ALL); 
     } else 

    } 

public static boolean hasPermissions(Context context, String... permissions) { 

     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) { 
      for (String permission : permissions) { 
       if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { 
        return false; 
       } 
      } 
     } 
     return true; 

    } 


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

    switch (requestCode) { 
     case REQUESTCODE_PERMISSION_ALL: { 

      boolean allpermissiongranted = true; 
      if (grantResults.length > 0) { 
       for (int i = 0; i < permissions.length; i++) { 
        if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { 
         allpermissiongranted = false; 
         break; 
        } 
       } 
      } else 
       allpermissiongranted = false; 

      if (allpermissiongranted) { 
       //do task 

      } else { 

       new SweetAlertDialog(mContext, SweetAlertDialog.WARNING_TYPE) 
         .setTitleText("Permission Not Granted") 
         .setContentText("Kindly grant all requested permission to proceed.") 
         .setConfirmText("Request") 
         .setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() { 
          @Override 
          public void onClick(SweetAlertDialog sDialog) { 
           sDialog.dismissWithAnimation(); 
           RequestAllPermissions(); 
          } 
         }) 
         .setCancelText("Exit") 
         .setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() { 
          @Override 
          public void onClick(SweetAlertDialog sweetAlertDialog) { 
           sweetAlertDialog.dismissWithAnimation(); 
           finish(); 
          } 
         }) 
         .show(); 
      } 

     } 
    } 

} 
Verwandte Themen