2017-06-19 46 views
0

我想重构一段代码,处理Android权限。它工作正常,除了一个令人讨厌的UI bug导致我很多头痛。下面的代码:Android权限用户界面问题与多个对话框

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

它基本上获得通过他们,是不是已经被用户授予的权限,周期的列表,并提示用户授予每个。一旦完成,它会检查尚未授予的任何剩余权限,并再次提示用户有关为什么需要该权限以及不允许该权限的结果的信息,直到他接受或选择“不再请求”为止。

我的问题与onRequestPermissionResult()中的链接“if”语句发生。您可能会猜到,如果多个权限条件为真,那么每个对话框将打开下面的当前现有的对话框。这导致一个对话框关闭和下一个显示之间的“跳跃”对话效果。我已经尝试过case和if/elseif语句来解决这个问题,但是这会导致我的其他许可权逻辑出现问题。

有没有人有这个清洁的解决方案?我会很感激。

+0

恕我直言,最干净的解决方案是摆脱所有的'showMessageOK()'调用。用户知道用户授予您权限,因为*用户只是做了*。不要感谢他们授予权限 - 无论用户要求什么,都需要获得许可。 – CommonsWare

+0

确保您要求的所有权限也在您的“AndroidManifest”文件中声明 – Benny

回答

0

好吧,这未必是最干净的代码,但是,

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

基本上你传递一个参数,它允许您将要求通过权限进行迭代。一旦许可被批准/拒绝,它就会中断,转移到第二个许可,直到全部完成。

理论上这应该起作用。

0

只需使用此代码:

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

     } 
    } 

}