ParkSangGwon / TedPermission

Easy check permission library for Android Marshmallow
1.74k stars 238 forks source link

android.permission.SYSTEM_ALERT_WINDOW 권한 설정 방법 추가 #18

Closed babosamo closed 7 years ago

babosamo commented 8 years ago

권한 설정에서 android.permission.SYSTEM_ALERT_WINDOW 도 설정할 수 있도록 기능 추가하였습니다.

ParkSangGwon commented 8 years ago

@babosamo 권한을 거부한경우 사용자가 설정에서 허용할 수있도록 마지막에 띄워주는 showPermissionDenyDialog()함수가 있습니다. SYSTEM_ALERT_WINDOW가 거부된 경우와 다른 권한이 거부된 경우 띄워주어야 하는 Setting화면이 각기 다릅니다. 이부분을 구분해서 사용자에게 마지막 권한허용을 할수있는 설정창을 띄우는 부분이 있으면 좋을것 같습니다.

babosamo commented 8 years ago

@ParkSangGwon 불필요한 코드 제거, Rational 메시지 추가, 확인 부탁 드려요 ^^

ParkSangGwon commented 8 years ago

@babosamo 수정 감사드립니다. 확인해보니 그리기권한을 요청하기전에 Rationale메세지를 띄워주는 방식이 잘 적용되어 있는것 같습니다. 좀더 완벽한 '그리기권한 대응' 기능 추가를 위해 아래와 같은 내용을 추가해주시면 좋을것 같습니다.

현재 사용자가 권한을 거부하는경우 Deny메세지와 함께 다이어로그를 띄워서 권한을 설정할수있는 기능을 제공하고 있습니다. '그리기 권한'이 추가되는경우는 사용자가 권한을 거부하는경우, 기존의 권한설정화면으로의 이동이 아니라 그리기 권한설정화면으로 이동시켜야 합니다. 즉, showPermissionDenyDialog()에서도 '그리기 권한' 이 허용되지 않은경우에는 해당 설정화면으로 보내줄 수 있어야 합니다.

사용자가 권한을 거부하는경우의 예상되는 사용 시나리오는 아래와 같습니다.

  1. 그리기외의 권한만 거부되는경우 앱권한 설정화면 이동 및 onActivityResult()에서 권한허용여부 검사
  2. 그리기 권한만 거부되는 경우 '그리기 권한' 설정화면 이동 및 onActivityResult()에서 권한허용여부 검사
  3. 그리기권한과 그외의 권한 모두 거부되는 경우 1,2번의 화면이동및 검사 모두 적용
babosamo commented 8 years ago

@ParkSangGwon denyMessage 가 있는 경우의 처리 동선을 추가하였습니다.

ParkSangGwon commented 8 years ago

@babosamo (RationaleDenyActivity.class에서 확인가능) 일반 권한과 SYSTEM_ALERT_WINDOW 권한을 함께 요청하는경우, SYSTEM_ALERT_WINDOW권한을 거부하면 일반권한들은 권한요청을 하지도 않고 permissionDenied()를 호출하고 있습니다.

소스코드상으로 살펴보니 onActivityResult()에서 해당 부분과 관련된 경우의수가 고려되지 않은것 같습니다.

최종 정리해보자면 SYSTEM_ALERT_WINDOW 권한을 체크하는것과 그외의 권한을 체크하는것은 별도로 요청하든 함께 요청하든 각각의 권한 허용여부가 상대에게 영향을 미치지 않는 방식으로 구현되면 좋을것 같습니다.

이부분에 대한 경우의수를 조금만 더 추가해주시면 완벽히 추가될것 같습니다~

ParkSangGwon commented 8 years ago

@babosamo 변경하신 사항들 테스트 완료하였습니다. 동작방식은 이제 거의다 완료된것 같습니다. 다만 소스코드상으로 나중에 이해하기 어려울만한 여지가 있는 부분들이 있어서 이부분을 수정하면 좋을것 같습니다.

TedPermissionActivity.java:347

 case REQ_CODE_SYSTEM_ALERT_WINDOW_PERMISSION_REQUEST:
                if(!hasWindowPermission() && !TextUtils.isEmpty(denyMessage)){  // 권한이 거부되고 denyMessage 가 있는 경우
                    if(!hasCheckWindowPermissionRequest) {      // 최초 거부에서만 dialog 를 뛰운다
                        showWindowPermissionDenyDialog();
                        hasCheckWindowPermissionRequest = true;
                    }else{
                        checkPermissions(false);
                    }
                }else {     // 권한있거나 또는 denyMessage가 없는 경우는 일반 permission 을 확인한다.
                    hasCheckWindowPermissionRequest = true;
                    checkPermissions(false);
                }
                break;

이부분에서 REQ_CODE_SYSTEM_ALERT_WINDOW_PERMISSION_REQUEST로 intent를 시작하는경우는 2가지 경우인것 같습니다.

  1. 처음에 화면그리기 권한을 요청하고 돌아온경우
  2. 화면그리기 권한요청이 거부되었을때 다이어로그를 띄워서 다시한번 해당 설정화면으로 간뒤 돌아온 경우

case REQ_CODE_SYSTEM_ALERT_WINDOW_PERMISSION_REQUEST:에서 복잡한 코드가 생기는 이유는 위의 2가지 경우 모두 같은 함수를 사용하기때문인것 같습니다.

기존의 권한요청은 이 2가지가 나뉘어서 구현되어있습니다.

  1. requestPermissions(ArrayList<String> needPermissions) (line:206)
  2. startActivityForResult(intent, REQ_CODE_REQUEST_SETTING); (line:296)

정리해서 말씀드리자면 Window permission 권한을 처음 요청할때와 거부한뒤 [설정]버튼을 통해 들어갈때를 구분해서 요청하면 깔끔하게 코드를 작성할 수 있을것 같습니다. 위와같은 경우는 startActivityForResult() 하실때 requestCode를 2가지 경우로 나누어서 호출하시고 onActivityResult()에서 각각으로 case를 나누어서 처리하신다면 좀더 명확하고 보기쉬운 코드가 될것 같습니다.

계속 성실하게 pull request해주시고 계신데 수정요청사항이 많네요.. 진짜진짜 거의다 오셨습니다. 감사합니다.

ParkSangGwon commented 8 years ago

@babosamo 코드에 표기한대로 isShownRationalDilaog 변수 오타 수정해주시면 좋을것 같습니다. 테스트해보니 이상없이 동작하는것 같습니다.

최종 적용을 위해서 demo프로젝트에 Manifest.permission.SYSTEM_ALERT_WINDOW을 위한 Activity한개를 추가해주시면 좋을것 같습니다. (현재는 DenyActivity, RationaleActivity, RationaleDenyActivity, NoDialogActivity 로 이루어져 있습니다.) WindowPermissionActivity정도로 하나 만드셔서 예제로 추가해주시면 좋을것 같습니다.