회사에서 ble 연결을 통해 데이터를 주고받는 앱을 수정하는데 알 수 없는 버그가 발견되었다.
고객사 측에서는 ble연결 후에 앱 안에서의 음원이 자꾸 끊긴다는 이야기였다.
도통 무슨 소리인지 알 수가 없어서 이해가 안됐는데 안드로이드 공식문서를 보다가 실마리를 찾았다.
안드로이드 12가 나오면서 블루투스 권한이 변경되었다는 것이다.
https://developer.android.com/guide/topics/connectivity/bluetooth/permissions
지금부터 설명할 내용은 위 안드로이드 공식문서를 바탕으로 작성되었다.
1. Android 12 블루투스 권한
앱이 Android 12 (API level 31)이상을 타겟한다면 매니페스트 파일에 아래 권한 3개를 추가해주어야한다.
안드로이드 11 이하에서 블루투스 권한을 선언했을 때 필요한
은 선언시에 android:maxSdkVersion="30" 를 붙여준다.
스캔시에 장치의 물리적 위치를 가져오고싶다면 ACCESS_FINE_LOCATION
을 선언해주면 된다.
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30"/>
<!--android 12 new bluetooth permission-->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
위의 코드가 Android12에서 최종적인 manifest파일에서의 블루투스 권한 선언 내용이다.
이제, 런타임시에 BLUETOOTH_CONNECT, BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE 권한을 요청해주면 된다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.BLUETOOTH_CONNECT
),
Constants.Permission.REQ_CODE_BLE
)
}
이런식으로 요청해주면 된다.
원래는 권한이 거부상태이면, 요청하는게 맞지만 지금은 연습하는 과정이기때문에 생략한다.
2. Android 11이하에서의 블루투스 권한
-BLUETOOTH
권한은 필수적이다. (클래식 블루투스든 BLE든 간에)
-BLUETOOTH_ADMIN
권한도 거의 필수다.
(앱에서 블루투스 장치를 발견하여 블루투스 속성을 조작하고싶다면 추가해주자)
-ACCESS_FINE_LOCATION
권한도 필수적이다. (스캔 과정에서 위치정보를 획득해야하기 때문이다.)
안드로이드 9 (API 28)이하에서는 ACCESS_COARSE_LOCATION
을 ACCESS_FINE_LOCATION
대신 쓸 수 있다.
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
위의 코드는 안드로이드 11이하를 타겟팅할 때 매니페스트 파일에서의 블루투스 권한 선언이다.
안드로이드 11이하에서는 따로 블루투스 권한을 런타임시에 요청할 필요는 없고 기기자체가 블루투스를 사용할 수 있는지만 따져주면된다.
//기기가 블루투스를 사용 가능한지 체크
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
Toast.makeText(this, R.string.bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
// 기기가 BLE 사용 가능한지 체크
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
댓글 없음:
댓글 쓰기