앱에서 블루투스 기능을 사용하려면 여러 권한을 선언해야 합니다. 또한 앱에 기존 블루투스 또는 저전력 블루투스 (BLE) 지원이 필요한지 지정해야 합니다. 앱에 블루투스 기본 또는 BLE가 필요하지 않지만 이러한 기술의 이점을 누릴 수 있는 경우 런타임에 사용 가능 여부를 확인할 수 있습니다.
권한 선언
앱에서 선언하는 권한 집합은 앱의 타겟 SDK 버전에 따라 다릅니다.
Android 12 이상 타겟팅
참고: Android 8.0 (API 수준 26) 이상에서는 부속 기기 관리도구 (CDM)가 이 섹션에 설명된 권한에 비해 부속 기기에 연결하는 더 간소화된 메서드를 제공합니다. CDM 시스템은 앱을 대신해 페어링 UI를 제공하고 위치 정보 액세스 권한이 필요하지 않습니다.
페어링 및 연결 환경을 더 세부적으로 제어하려면 이 섹션에 설명된 권한을 사용하세요.
앱이 Android 12 (API 수준 31) 이상을 타겟팅하는 경우 앱의 매니페스트 파일에서 다음 권한을 선언합니다.
- 앱이 BLE 주변기기와 같은 블루투스 기기를 검색하는 경우
BLUETOOTH_SCAN
권한을 선언합니다. - 앱이 현재 기기를 다른 블루투스 기기에서 검색할 수 있도록 하려는 경우
BLUETOOTH_ADVERTISE
권한을 선언합니다. - 앱이 이미 페어링된 블루투스 기기와 통신한다면
BLUETOOTH_CONNECT
권한을 선언합니다. - 기존 블루투스 관련 권한 선언의 경우
android:maxSdkVersion
을 30으로 설정합니다. 이 앱 호환성 단계를 통해 시스템은 Android 12 이상을 실행하는 기기에 설치할 때 필요한 블루투스 권한만 앱에 부여할 수 있습니다. - 앱이 블루투스 검색 결과를 사용하여 실제 위치를 파생하는 경우
ACCESS_FINE_LOCATION
권한을 선언합니다. 또는 앱이 실제 위치를 파생하지 않는다고 강력하게 어설션하고ACCESS_FINE_LOCATION
권한의android:maxSdkVersion
를 30으로 설정할 수 있습니다.
BLUETOOTH_ADVERTISE
, BLUETOOTH_CONNECT
, BLUETOOTH_SCAN
권한은 런타임 권한입니다.
따라서 블루투스 기기를 찾거나 기기를 다른 기기에서 검색할 수 있게 하거나 이미 페어링된 블루투스 기기와 통신하려면 앱에서 명시적으로 사용자 승인을 요청해야 합니다. 앱이 이러한 권한 중 하나 이상을 요청하면 시스템은 그림 1과 같이 앱이 근처 기기에 액세스하도록 허용하라는 메시지를 사용자에게 표시합니다.
다음 코드 스니펫은 앱이 Android 12 이상을 타겟팅하는 경우 앱에서 블루투스 관련 권한을 선언하는 방법을 보여줍니다.
<manifest>
<!-- 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" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can
<a href="#assert-never-for-location">strongly assert that your app
doesn't derive physical location</a>. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Needed only if your app uses Bluetooth scan results to derive
physical location. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
앱이 물리적 위치를 얻지 않는다고 강력하게 어설션합니다
앱이 블루투스 검색 결과를 사용하여 실제 위치를 파생하지 않으면 앱이 블루투스 권한을 사용하여 실제 위치를 파생하지 않는다는 강력한 어설션을 만들 수 있습니다. 그러려면 다음 단계를 완료하세요.
android:usesPermissionFlags
속성을BLUETOOTH_SCAN
권한 선언에 추가하고 이 속성 값을neverForLocation
으로 설정합니다.위치가 앱에 달리 필요하지 않으면 앱의 매니페스트에서
ACCESS_FINE_LOCATION
권한을 삭제합니다.
다음 코드 스니펫은 앱의 매니페스트 파일을 업데이트하는 방법을 보여줍니다.
<manifest>
<!-- Include "neverForLocation" only if you can strongly assert that
your app never derives physical location from Bluetooth scan results. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!-- Set maxSdkVersion to 30 if you can strongly assert that, on
Android 12 and higher, your app never derives physical location from
Bluetooth scan results and doesn't need location access for any other
purpose. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30" />
...
</manifest>
Android 11 이하 타겟팅
앱이 Android 11 (API 수준 30) 이하를 타겟팅하는 경우 앱의 매니페스트 파일에서 다음 권한을 선언합니다.
BLUETOOTH
는 연결 요청, 연결 수락, 데이터 전송과 같은 블루투스 클래식 또는 BLE 통신을 실행하는 데 필요합니다.- Android 11 이하에서는 블루투스 스캔을 사용하여 사용자의 위치에 관한 정보를 수집할 수 있으므로
ACCESS_FINE_LOCATION
가 필요합니다.
위치 정보 액세스 권한은 런타임 권한이므로 매니페스트에서 선언하는 것과 함께 런타임 시 이러한 권한을 요청해야 합니다.
근처 블루투스 기기 찾기
앱에서 기기 검색을 시작하거나 블루투스 설정을 조작하려면 BLUETOOTH_ADMIN
권한을 선언해야 합니다. 대부분의 앱은 로컬 블루투스 기기를 검색하기 위한 용도로만 이 권한이 필요합니다. 앱이 사용자 요청에 따라 블루투스 설정을 수정하는 '전원 관리자'가 아닌 한 이 권한으로 부여된 다른 기능을 사용하지 마세요. 앱 매니페스트 파일에서 권한을 선언합니다. 예를 들면 다음과 같습니다.
<manifest>
...
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
...
</manifest>
앱이 서비스를 지원하고 Android 10 (API 수준 29) 또는 Android 11에서 실행할 수 있는 경우 블루투스 기기를 검색하는 ACCESS_BACKGROUND_LOCATION
권한도 선언해야 합니다. 이 요구사항에 관한 자세한 내용은 백그라운드에서 위치 정보 액세스를 참고하세요.
다음 코드 스니펫은 ACCESS_BACKGROUND_LOCATION
권한을 선언하는 방법을 보여줍니다.
<manifest>
...
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
</manifest>
앱 권한 선언에 관한 자세한 내용은 <uses-permission>
참조를 참고하세요.
블루투스 기능 사용 지정
블루투스가 앱의 핵심적인 부분인 경우 매니페스트 파일에 이 요구사항을 나타내는 플래그를 추가할 수 있습니다. <uses-feature>
요소를 사용하면 앱에서 사용하는 하드웨어 유형과 필수 여부를 지정할 수 있습니다.
이 예에서는 앱에 블루투스 클래식이 필요하다고 표시하는 방법을 보여줍니다.
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
앱에서 저전력 블루투스를 사용하는 경우 다음을 사용할 수 있습니다.
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
앱에 이 기능이 필요하다고 선언하면 Google Play 스토어에서는 이러한 기능이 없는 기기의 사용자에게 앱을 숨깁니다. 따라서 앱이 이 기능 없이 작동할 수 없는 경우에만 required 속성을 true
로 설정해야 합니다.
런타임에 기능 사용 가능 여부 확인
블루투스 클래식 또는 BLE를 지원하지 않는 기기에서 앱을 사용할 수 있도록 하려면 앱의 매니페스트에 <uses-feature>
요소를 계속 포함하되 required="false"
를 설정해야 합니다. 그런 다음 런타임 시 PackageManager.hasSystemFeature()
를 사용하여 기능 사용 가능 여부를 확인할 수 있습니다.
Kotlin
// Check to see if the Bluetooth classic feature is available. val bluetoothAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH) // Check to see if the BLE feature is available. val bluetoothLEAvailable = packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
Java
// Use this check to determine whether Bluetooth classic is supported on the device. // Then you can selectively disable BLE-related features. boolean bluetoothAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH); // Use this check to determine whether BLE is supported on the device. Then // you can selectively disable BLE-related features. boolean bluetoothLEAvailable = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);