- java.lang.SecurityException:Need android.permission.BLUETOOTH_CONNECT permission for AttributionSource | 'onRequestPermissionsResult()' deprecated2022년 08월 22일 23시 26분 31초에 업로드 된 글입니다.작성자: 핀수728x90반응형
java.lang.SecurityException:Need android.permission.BLUETOOTH_CONNECT permission for AttributionSource
android 버전 12에서는 새로운 블루투스 권한이 도입되었다.
- BLUETOOTH_SCAN
- 앱이 저전력 (BLE) 블루투스 주변 기기와 같은 블루투스 기기를 검색하는 경우
- BLUETOOTH_ADVERTISE
- 현재 기기를 다른 디바이스에서 검색할 수 있도록 하는 경우
- BLUETOOTH_CONNECT
- 이미 페어링 된 기기와 통신하려는 경우
위 세가지 권한은 *런타임 권한이므로 앱에서 명시적으로 사용자 승인을 요청해야한다.
* 런타임 권한
위험한 권한이라고도 하며, 이 권한을 부여 받는 경우는 앱에서 제한된 데이터에 추가로 액세스를 하고 시스템과 다른 앱에 좀 더 큰 영향을 미치는 제한된 작업을 실행하도록 한다.
일반 권한
낮은 수준의 보호, 사용자의 개인정보 보호와 다른 앱의 작업에 거의 영향을 미치지 않기 때문에 앱 사용자에게 권한 부여 요청을 필요로 하지 않는다. 예시 : android.permission.INTERNET
서명 권한
앱에서 다른 앱이 정의한 서명 권한을 선언하고 두 앱이 동일한 인증서로 서명되었을 경우 시스템에서는 설치 시간에 첫번째 앱에 권한을 부여한다.
따라서 12버전에서 위 세가지 권한 중 해당하는 행위를 하기 위해서는
사용자의 권한 부여가 필요하다.
그렇지 않을 경우
java.lang.SecurityException:Need android.permission.BLUETOOTH_CONNECT permission for AttributionSource
와 같은 예외가 발생한다.
'onRequestPermissionsResult()' deprecated
위의 세 권한은 앞서 말했듯 런타임 권한이기 때문에 사용자의 승인을 받아야하고,
사용자는 이 권한을 해당 앱의 상세 설정에서 언제든지 취소하거나 승인할 수 있기 때문에
매번 확인을 해줘야한다.
// checkSelfPermission(해당 권한) if (checkSelfPermission(BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED) { // PERMISSION_GRANTED } else { // PERMISSION_DENIED }
권한이 부여되어있지 않을 경우 (PERMISSION_DENIED)
권한을 요청해준다.
requestPermissions(new String[]{BLUETOOTH_CONNECT}, PERMISSION_CODE);
그러면 아까의 예시 이미지 같은 다이얼로그가 뜨는 것을 확인할 수 있다.
이때 사용자가 선택한 결과를 받아와야 하는데
구글링을 해보면 대부분
onRequestPermissonsResult() 를 사용하고 있는 것을 알 수 있다. (제가 찾은 것들 기준입니다.)
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); }
그렇지만 해당 메서드는 deprecated 되었다.
문서가 설명하는 대로 코드를 작성해보자.
문서에서는 해당 결과를
registerForActivityResult 를 통해서 핸들링하라고 설명하고 있다.
형태는 아래와 같다.
private final ActivityResultLauncher<String > requestPermissionLauncher = registerForActivityResult( new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() { @Override public void onActivityResult(Boolean result) { } } );
해당 글과는 상관 없지만 조금 뜯어보자면
@NonNull @Override public final <I, O> ActivityResultLauncher<I> registerForActivityResult( @NonNull ActivityResultContract<I, O> contract, @NonNull ActivityResultCallback<O> callback) { return registerForActivityResult(contract, mActivityResultRegistry, callback); }
ActivityResultContract : 유형을 의미한다.
ActivityResultCallback : 유형에 대한 사용자의 입력이 주어지면 onActivityResult 가 실행된다.
다시 말해서
해당 권한에 대한 요청이 일어났을 때,
사용자는 권한을 부여하거나 거절하였을 것이고
그에 대한 결과를 받아와 처리를 해주는 것이다.
이러한 처리를 ActivityResultLauncher 가 혼자 알아서 하는 것은 아니다.
launch() 메서드를 호출해야 한다.
requestPermissionLauncher.launch(BLUETOOTH_CONNECT);
References
아래 글을 참고하여 작성 되었습니다.
728x90반응형'pinslog > Log.daily()' 카테고리의 다른 글
[Android] EditText를 TextView처럼 사용하기 (0) 2022.11.22 [etc] MacOS에 Mysql 설치하기 (+ MySQL Workbench) (0) 2022.10.01 [Android] Floating Action Button과 BadgeDrawable (0) 2022.08.16 [Android] 민감한 정보 숨기기 | local.properties에 api key저장하기 (0) 2022.08.15 [Android] 화면 전환 효과 | RecyclerView to fragment transition 적용하기 (0) 2022.08.14 다음글이 없습니다.이전글이 없습니다.댓글 - BLUETOOTH_SCAN