今回は、以下の挙動をするアプリを作成する
- アプリが起動すると、画面には「スキャン」というボタンが表示される
- 「スキャン」ボタンが押されると、Bluetoothの許可を求めるダイアログが表示される
- ユーザーがBluetoothの許可を与えた場合、Bluetooth機能が有効かどうかをチェックする
- Bluetooth機能が無効であれば、ユーザーにBluetoothを有効にするように促すダイアログを表示する
- Bluetoothが有効であれば、「BT接続できます」というメッセージが表示される
実装
AndroidManifest.xml に以下を追加
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
MainActivity
Bluetoothをスキャン(Bluetoothを使用して通信可能な近くのBluetoothデバイスを検索すること)するために必要な許可をユーザーに求め、許可された場合にBluetoothの機能を有効にする処理を行う
class MainActivity : AppCompatActivity() {
private var btPermission = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun scanBt(view: View) {
val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java)
val bluetoothAdapter: BluetoothAdapter? = bluetoothManager.adapter
if (bluetoothAdapter == null) {
Toast.makeText(this, "BT接続が許可されていません", Toast.LENGTH_LONG).show()
} else {
if (VERSION.SDK_INT >= Build.VERSION_CODES.S) {
blueToothPermissionLauncher.launch(android.Manifest.permission.BLUETOOTH_CONNECT)
} else {
blueToothPermissionLauncher.launch(android.Manifest.permission.BLUETOOTH)
}
}
}
private val blueToothPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java)
val bluetoothAdapter: BluetoothAdapter? = bluetoothManager.adapter
btPermission = true
if (bluetoothAdapter?.isEnabled == false) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
btActivityResultLauncher.launch(enableBtIntent)
} else {
btScan()
}
} else {
btPermission = false
}
}
private val btActivityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == RESULT_OK) {
btScan()
}
}
private fun btScan() = Toast.makeText(this, "BT接続できます", Toast.LENGTH_LONG).show()
}
ひとつづつ解説していく
private var btPermission = false
- Bluetoothアクセスの許可があるかどうかを示すブール変数
- 初期値は
false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
-
onCreate
関数はアクティビティが最初に作成されたときに呼び出される - ここではレイアウトを設定しているだけ
-
R.layout.activity_main
を紐づけている
fun scanBt(view: View) {
val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java)
val bluetoothAdapter: BluetoothAdapter? = bluetoothManager.adapter
if (bluetoothAdapter == null) {
Toast.makeText(this, "BT接続が許可されていません", Toast.LENGTH_LONG).show()
} else {
if (VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Manifestはandroidの方
blueToothPermissionLauncher.launch(android.Manifest.permission.BLUETOOTH_CONNECT)
} else {
blueToothPermissionLauncher.launch(android.Manifest.permission.BLUETOOTH)
}
}
}
このメソッドがおこなっていること
- Bluetoothが有効になっている場合はBluetoothスキャンを開始し、それ以外の場合はBluetoothアクセスの許可をリクエストする
ひとつひとつ説明する
-
BluetoothManager
オブジェクトを取得する -
BluetoothManager
は、Bluetooth関連の機能を提供するAndroidのAPIの一部で、Bluetoothデバイスとの通信を行うために必要 -
BluetoothManager
は、Bluetoothデバイスの検出を管理するのに使用する -
bluetoothAdapter
オブジェクトをBluetoothManager
から取得する -
bluetoothAdapter
は、Bluetoothデバイスとの通信を管理するクラスで、Bluetooth接続の許可を確認するために必要 - もし
BluetoothAdapter
がnull
であれば、「BT接続が許可されていません」というトーストメッセージが表示する -
BluetoothAdapter
がnull
である場合、Bluetoothにアクセスするために必要な許可がユーザーに与えられていないことを意味する -
BluetoothAdapter
がnull
でなければ、SDKのバージョンに応じてBluetooth接続の許可を確認するための許可要求を送信する - Android APIバージョンが11以上であれば
BLUETOOTH_CONNECT
パーミッションをリクエストし、それ以外の場合はBLUETOOTH
パーミッションをリクエストする(APIバージョンによって、サポートされているパーミッションが異なるため) - それぞれの要求は、
blueToothPermissionLauncher.launch()
メソッドを介して行われる
private val blueToothPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
val bluetoothManager: BluetoothManager = getSystemService(BluetoothManager::class.java)
val bluetoothAdapter: BluetoothAdapter? = bluetoothManager.adapter
btPermission = true
if (bluetoothAdapter?.isEnabled == false) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
btActivityResultLauncher.launch(enableBtIntent)
} else {
btScan()
}
} else {
btPermission = false
}
}
このメソッドがおこなっていること
- Bluetooth接続のために必要なパーミッションのリクエストを処理する
ひとつひとつ説明する
-
registerForActivityResult
は、アクティビティでアクティビティ結果を受信するためのコールバックが含まれる - このコールバックは、ユーザーがパーミッションリクエストを許可または拒否した場合に呼び出される
-
isGranted
パラメータはBluetoothアクセスが許可されたかどうかを示し、Bluetoothアクセスが許可されている場合は、Bluetoothアダプタが有効になっているかどうかを確認し、有効であればBluetoothスキャンを開始する -
BluetoothManager
とBluetoothAdapter
のインスタンスを取得し、isEnabled
メソッドを使用してBluetoothが有効になっているかどうかを確認する - Bluetoothが無効になっている場合は、
ACTION_REQUEST_ENABLE
というBluetoothを有効にするためのIntentを作成し、btActivityResultLauncher
に対して送信する - Bluetoothが有効になっている場合、
btScan
関数が呼び出される - Bluetoothへのアクセスを許可された場合は、
btPermission
フラグをtrue
に設定する - パーミッションが拒否された場合は、
btPermission
フラグをfalse
に設定する
private fun btScan() = Toast.makeText(this, "BT接続できます", Toast.LENGTH_LONG).show()
-
btScan
関数は、Bluetoothスキャンが完了したときに表示されるメッセージを定義する
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="スキャン"
android:onClick="scanBt"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
おわりに
Bluethoothを仕事で使用することがありそうな予感がしたので、勉強してみました。
Bluethoothの接続を促すという初歩の初歩ができるようになりました。
がんばるぞい!