BluetoothAdapter — その概要、メソッド、およびAndroidでのBluetooth管理

著者: IT Sectr 公開日: 2026-07-16 読了時間: 10 分

BluetoothAdapter は、デバイスのローカルBluetoothアダプターを表すシステムAndroidクラスです。BluetoothAdapterは、AndroidでのすべてのBluetooth操作のエントリポイントです:ラジオの有効化(enable)、デバイスのスキャン、可視性の管理(setScanMode)、アダプター情報の取得(getName、getAddress、getState)。このクラスは、BluetoothManager.getAdapter()(API 18+)またはBluetoothAdapter.getDefaultAdapter()を介して利用できます。Bluetoothモジュールのないデバイスでは、getDefaultAdapter()はnullを返します。Android Developers、2026によると、BluetoothAdapterは、API 5以降のAndroid上のBLEアプリケーションに必須のコンポーネントです。

重要ポイント

  • BluetoothAdapter は、デバイスのローカルBluetoothアダプターを管理するためのシステムAndroidクラスです
  • getDefaultAdapter() はインスタンスを取得する静的メソッドです。Bluetoothのないデバイスではnullを返します
  • getBluetoothLeScanner() は、最新のBLEスキャナー(API 21+)にアクセスするメソッドです
  • enable/disable は、Bluetoothラジオをオン/オフにするメソッドです(BLUETOOTH_ADMIN権限が必要)
  • startDiscovery/startLeScan は、クラシックおよびBLEスキャンメソッドです(LE Scanは非推奨、BluetoothLeScannerを使用)

BluetoothAdapterとは:本質とインスタンスの取得

BluetoothAdapter は、Androidデバイスの物理的なBluetoothアダプターを表します。各デバイスには正確に1つのアダプターがあります(複数のBluetoothチップを持つAndroid Automotiveは例外で、BluetoothManager.getAdapterList()を使用します)。BluetoothAdapterはラジオの状態をカプセル化します:STATE_OFF(0)、STATE_TURNING_ON(1)、STATE_ON(2)、STATE_TURNING_OFF(3)。状態はACTION_STATE_CHANGEDのBroadcastReceiverを介して追跡されます。

BluetoothAdapterインスタンスの取得は、Android上のBLEアプリケーションの最初のステップです。推奨される方法は、API 18+からBluetoothManager.getAdapter()を介するものです。代替方法は静的メソッドBluetoothAdapter.getDefaultAdapter()で、API 5から動作しますが、柔軟性に欠けます。どちらのメソッドも、デバイスにBluetoothモジュールがない場合(Wi-Fiのみのタブレット、エミュレーター)はnullを返します。nullチェックは必須です:アプリケーションは正常に終了するか、BLE機能を無効にする必要があります。

kotlin
// BluetoothAdapterの取得(推奨)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context

class BluetoothHelper(context: Context) {

    private val bluetoothAdapter: BluetoothAdapter?

    init {
        // 方法1:BluetoothManager経由(API 18+)
        val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
                as BluetoothManager?
        bluetoothAdapter = manager?.adapter

        // 方法2:静的メソッド経由(API 5+)
        // val adapter = BluetoothAdapter.getDefaultAdapter()

        // nullチェック
        if (bluetoothAdapter == null) {
            // デバイスがBluetoothをサポートしていません
        }
    }

    // Bluetooth状態を確認
    fun isBluetoothEnabled(): Boolean {
        return bluetoothAdapter?.isEnabled == true
    }

    // アダプター情報を取得
    fun getAdapterInfo(): Map<String, String> {
        return mapOf(
            "name" to (bluetoothAdapter?.name ?: "N/A"),
            "address" to (bluetoothAdapter?.address ?: "N/A"),
            "state" to (bluetoothAdapter?.state?.toString() ?: "N/A"),
            "scanMode" to (bluetoothAdapter?.scanMode?.toString() ?: "N/A")
        )
    }
}

BluetoothHelper クラスは、BluetoothManagerを介してBluetoothAdapterを取得し、その後にnullチェックを行う方法を示しています。isBluetoothEnabledはisEnabledをチェックします — BLE操作の前の必須条件です。getAdapterInfoはデバイス名、MACアドレス、状態、可視性モードを返します。重要:Android 10+(API 29+)では、アプリケーションにBLUETOOTH_ADMINとACCESS_FINE_LOCATIONの権限がない場合、システムサービスは偽のMACアドレス(02:00:00:00:00:00)を返します。

BluetoothAdapterの主要メソッド:enable、disable、getState、getAddress

BluetoothAdapter はBluetoothラジオを制御するメソッドを提供します。enable()とdisable()はBluetoothをオン/オフにします。どちらのメソッドもBLUETOOTH_ADMIN権限が必要で、非同期に実行されます:enable()を呼び出した後、システムはラジオの有効化プロセスを開始し、状態はBluetoothAdapter.ACTION_STATE_CHANGEDアクションのBroadcastReceiverを介して追跡されます。Android 10+では、enable()とdisable()には追加のシステム特権が必要です — 通常のアプリケーションはユーザーダイアログなしでプログラムによってBluetoothを制御できません。

getState() は現在のアダプター状態を返します:STATE_OFF(10)、STATE_TURNING_ON(11)、STATE_ON(12)、STATE_TURNING_OFF(13)。getAddress() はBluetoothアダプターのMACアドレスを返します。Android 6+では、MACアドレスを要求するためにACCESS_FINE_LOCATION(またはAPI 31+の場合はACCESS_COARSE_LOCATION)が必要です。Android 10+では、getAddress()は定数アドレス02:00:00:00:00:00を返します — 実際のアドレスは公開APIを介して利用できません。

getScanMode() はアダプターの可視性モードを決定します:SCAN_MODE_NONE(不可視)、SCAN_MODE_CONNECTABLE(接続済みデバイスに可視)、SCAN_MODE_CONNECTABLE_DISCOVERABLE(すべてに可視)。可視性モードはセキュリティのために時間制限があります(通常60~300秒)。setScanMode()を介してモードを設定するには、Android 10+でBLUETOOTH_ADMINとシステム権限が必要です。

メソッド説明必要な権限
enable()BluetoothラジオをオンにするBLUETOOTH_ADMIN
disable()BluetoothラジオをオフにするBLUETOOTH_ADMIN
getState()現在のアダプター状態BLUETOOTH
getAddress()アダプターのMACアドレスBLUETOOTH + ACCESS_FINE_LOCATION(API 23+)
getScanMode()デバイスの可視性モードBLUETOOTH
setScanMode()可視性モードの設定BLUETOOTH_ADMIN

デバイススキャン:startDiscoveryとBluetoothLeScanner

BluetoothAdapter は2種類のスキャンをサポートしています。クラシックBluetoothスキャン(BR/EDR)はstartDiscovery()を介して起動します — 電話やヘッドセットを含むすべてのタイプのBluetoothデバイスを検出します。結果はBluetoothDevice.ACTION_FOUNDアクションのBroadcastReceiverを介して返されます。startDiscovery()は12秒間動作し、cancelDiscovery()を呼び出すことでキャンセルできます。このメソッドはBLEでは非推奨です — BluetoothLeScannerを使用してください。

BluetoothAdapterを介したBLEスキャンは、非推奨のメソッドstartLeScan(LeScanCallback)を使用します。API 21以降、GoogleはBluetoothAdapter.getBluetoothLeScanner()を介して取得されるBluetoothLeScannerの使用を推奨しています。BluetoothLeScannerはより柔軟なAPIを提供します:ScanSettingsを介したスキャン設定(モード、コールバックタイプ、マッチモード)、ScanFilterを介したフィルタリング(サービスUUID、デバイス名、MACアドレスによる)、およびバックグラウンドスキャンのためのPendingIntentのサポート。

kotlin
// 古い(非推奨)BLEスキャンAPI vs 新しいAPI
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*

class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {

    // 非推奨:startLeScan(API 18+、API 21)
    @Suppress("DEPRECATION")
    fun legacyScan() {
        bluetoothAdapter?.startLeScan { device, rssi, scanRecord ->
            print("Found (LE Scan): $device.name, RSSI: $rssi")
        }
    }

    // 新:BluetoothLeScanner(API 21+)
    fun modernScan() {
        val scanner = bluetoothAdapter?.bluetoothLeScanner
            ?: return

        // スキャン設定
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
            .build()

        // サービスでフィルタリング(心拍数UUID)
        val filters = listOf(
            ScanFilter.Builder()
                .setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
                .build()
        )

        // スキャン開始
        scanner.startScan(filters, settings, object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                val device = result.device
                val rssi = result.rssi
                print("Found (BLE Scanner): ${device.name}, RSSI: $rssi, address: ${device.address}")
            }

            override fun onScanFailed(errorCode: Int) {
                print("Scan error: $errorCode")
            }
        })
    }
}

BLEScanner クラスは、非推奨のstartLeScanと最新のBluetoothLeScannerを比較しています。legacyScanでは、LeScanCallbackはBluetoothDevice、RSSI、および生のscanRecordを受け取ります。modernScanでは、LOW_LATENCYモード(最大検出速度)のScanSettingsと、心拍数サービスUUID(0x180D)でフィルタリングするScanFilterが使用されます。ScanCallbackは、拡張情報を含むScanResultオブジェクトを提供します:名前、RSSI、アドバタイズデータ、接続タイプ。

BluetoothManager:BluetoothAdapterにアクセスする最新API

BluetoothManager は、Bluetooth操作を管理するためにAPI 18(Android 4.3)で導入されたシステムAndroidサービスです。API 18より前は、BluetoothAdapterを取得する唯一の方法は静的メソッドgetDefaultAdapter()でした。BluetoothManagerは以下を提供します:adapter — BluetoothAdapterインスタンス、getConnectedDevices() — 接続済みデバイスのリスト、getDevicesMatchingConnectionStates() — 状態によるフィルタリング。BluetoothManagerは、古いAPIでBluetoothLeScannerを取得するためにも使用されます。

BluetoothManagerの利点 BluetoothAdapter.getDefaultAdapter()を直接呼び出す場合と比較して:アプリケーションは静的シングルトンに依存せず、マネージャーはコンテキスト(Activity/Application)を尊重します。これはAndroid Enterpriseのマルチアカウントシナリオにとって重要です。複数のBluetoothチップを備えたAndroid Automotiveでは、BluetoothManager.getAdapterList()はすべての利用可能なアダプターを返します — BluetoothAdapter.getDefaultAdapter()は最初のもののみを返します。

kotlin
// BLEにBluetoothManagerを使用
class BLEConnection(context: Context) {

    private val bluetoothManager: BluetoothManager =
        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager

    private val adapter: BluetoothAdapter? = bluetoothManager.adapter

    // 接続済みBLEデバイスリストを取得
    fun getConnectedDevices(): List<BluetoothDevice> {
        return bluetoothManager.getConnectedDevices(
            BluetoothProfile.GATT
        )
    }

    // 状態でデバイスをフィルタリング
    fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
        return bluetoothManager.getDevicesMatchingConnectionStates(
            BluetoothProfile.GATT, states
        )
    }

    // デバイスのBLEサポートを確認
    fun isBLESupported(): Boolean {
        return adapter != null && context.packageManager
            .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
    }

    // システムダイアログ経由でBluetooth有効化を要求
    fun requestEnableBluetooth(activity: MainActivity) {
        if (adapter?.isEnabled == false) {
            val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            activity.startActivityForResult(intent, REQUEST_ENABLE_BT)
        }
    }

    companion object {
        const val REQUEST_ENABLE_BT = 1001
    }
}

BLEConnection クラスは、BluetoothManagerを使用してBluetoothAdapterにアクセスし、接続済みのGATTデバイスのリストを取得します。isBLESupportedは、PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE)を介してBLEラジオの存在をチェックします — BLEなしのBluetooth Classicデバイスにとって重要なチェックです。requestEnableBluetoothは、Bluetoothを有効にするシステムダイアログ(ACTION_REQUEST_ENABLE)を表示し、BLUETOOTH_ADMIN権限は必要ありません — これはシステムアプリなしでAndroid 10+でBluetoothを有効にする唯一の合法的な方法です。

BluetoothAdapterを使用するためのAndroid権限

権限 BluetoothAdapterの権限は、Androidのバージョンごとに進化してきました。Android 6〜11(API 23〜30)では、BLEスキャンにBLUETOOTH、BLUETOOTH_ADMIN、およびACCESS_FINE_LOCATIONが必須です。Android 12+(API 31+)では、Googleは権限を分割しました:ACCESS_FINE_LOCATIONはBLUETOOTH_SCAN(スキャン)、BLUETOOTH_CONNECT(接続)、BLUETOOTH_ADVERTISE(アドバタイズ)に置き換えられました。BLEデバイスの検出には、BLUETOOTH_SCANで十分で、位置情報は必要ありません。

権限テーブル Androidバージョン別:

操作API 23–30API 31+
BLEスキャンACCESS_FINE_LOCATIONBLUETOOTH_SCAN(位置情報なし)
BLE接続ACCESS_FINE_LOCATIONBLUETOOTH_CONNECT
BLEアドバタイズACCESS_FINE_LOCATIONBLUETOOTH_ADVERTISE
有効化/無効化BLUETOOTH_ADMINBLUETOOTH_ADMIN(システム)
MACアドレス取得ACCESS_FINE_LOCATIONBLUETOOTH_CONNECT(偽のアドレス)

Android 12+では、すべてのBluetooth権限はランタイム権限です — ActivityResultContracts.RequestMultiplePermissionsを介してランタイムで要求する必要があります。BLUETOOTH_SCANとBLUETOOTH_ADVERTISEはNEARBY_DEVICESグループに属し、BLUETOOTH_CONNECTは同じグループに属します。BLUETOOTHとBLUETOOTH_ADMINの権限はAPI < 31との互換性のためにマニフェストに残りますが、API 31+では無視されます — Googleは新しい権限を明示的に指定する必要があります。

kotlin
// Android 12+でBluetooth権限を要求
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.content.ContextCompat

class PermissionHelper(context: Context) {

    fun getRequiredPermissions(): Array<String> {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // Android 12+:BLE-
            arrayOf(
                Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.BLUETOOTH_ADVERTISE
            )
        } else {
            // Android 6-11:BLE
            arrayOf(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN
            )
        }
    }

    // すべての権限を確認
    fun hasPermissions(context: Context): Boolean {
        return getRequiredPermissions().all { permission ->
            ContextCompat.checkSelfPermission(context, permission)
                    == PackageManager.PERMISSION_GRANTED
        }
    }
}

PermissionHelper クラスは、APIレベルに応じて正しい権限セットを返します。Android 12+では、位置情報なしのBLUETOOTH_SCAN、BLUETOOTH_CONNECT、BLUETOOTH_ADVERTISEが使用されます。Android 6〜11では、BLEスキャンにまだACCESS_FINE_LOCATIONが必要です。開発者は、ActivityResultContractsまたはRxPermissionsを介して権限を要求する際に、両方のシナリオを考慮する必要があります。

KotlinでのBluetoothAdapterの完全な例

完全な例 BluetoothAdapterを使用してBLEデバイスをスキャン、接続、データ読み取りを行うKotlinのBLEアプリケーションの例です。この例では、権限チェック、アダプターの取得、BluetoothLeScannerを介したスキャン、BluetoothDevice.connectGattを介した接続をカバーしています。

kotlin
// Kotlinの完全なBLEマネージャー
class BLEManager(private val context: Context) {

    private val bluetoothManager: BluetoothManager =
        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    private val adapter: BluetoothAdapter? = bluetoothManager.adapter
    private var scanner: BluetoothLeScanner? = adapter?.bluetoothLeScanner
    private var gatt: BluetoothGatt? = null

    // 1. サービス検出
    fun canScan(): Boolean {
        return adapter?.isEnabled == true
                && scanner != null
                && PermissionHelper(context).hasPermissions(context)
    }

    // 2. フィルター付き
    fun startScanning(callback: (BluetoothDevice, Int) -> Unit) {
        if (!canScan()) return

        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setReportDelay(0)
            .build()

        scanner?.startScan(null, settings, object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                callback(result.device, result.rssi)
            }
        })
    }

    // 3. スキャン停止
    fun stopScanning() {
        scanner?.stopScan(object : ScanCallback() {})
    }

    // 4. BLEデバイスに接続
    fun connectToDevice(device: BluetoothDevice) {
        if (adapter?.isEnabled != true) return

        gatt = device.connectGatt(
            context,
            false,
            object : BluetoothGattCallback() {
                override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        gatt.discoverServices()
                    }
                }

                override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
                    // サービスが見つかりました、特性を読み取れます
                }
            },
            BluetoothDevice.TRANSPORT_LE
        )
    }

    // 5. リソースを解放
    fun disconnect() {
        gatt?.disconnect()
        gatt?.close()
        gatt = null
    }
}

BLEManager クラスは、Androidでの完全なBLEサイクルを統合します:アダプターと権限のチェック(canScan)、ScanSettingsを使用したBluetoothLeScannerを介したスキャン(startScanning)、TRANSPORT_LEを使用したBluetoothDevice.connectGattを介した接続(connectToDevice)、リソースの解放(disconnect)。すべてのBLE操作はUIスレッドで実行されます — AndroidはメインスレッドでBluetoothGattCallbackを呼び出します。パフォーマンスが重要なBLEタスクでは、GATT操作をバックグラウンドのHandlerThreadにオフロードすることをお勧めします。

よくある質問

AndroidのBluetoothAdapterとは何ですか?

BluetoothAdapter は、AndroidデバイスのローカルBluetoothアダプターを表すクラスです。BluetoothManager.getAdapter()(API 18+)またはBluetoothAdapter.getDefaultAdapter()を介して取得されます。Bluetoothの有効化/無効化、デバイスのスキャン、可視性の管理、アダプター情報の取得のメソッドを提供します。Bluetoothモジュールのないデバイスではnullを返します。

なぜBluetoothAdapter.getDefaultAdapter()がnullを返すのですか?

理由はデバイスにBluetoothラジオがないことです。Wi-Fiのみのタブレット、Androidエミュレーター、BluetoothなしのAndroid TVに典型的です。アプリ起動時にgetDefaultAdapter()がnullかどうかをチェックし、アダプターがない場合はBLE機能を無効にします。より正確な検出のためには、PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE)を介したチェックが代替手段です。

BluetoothLeScannerとstartLeScanの違いは何ですか?

BluetoothLeScanner(API 21+)は、ScanFilter、ScanSettings、PendingIntentをサポートするBLEスキャンの最新APIです。startLeScan(API 18+)は、限られたデータセットでLeScanCallbackを受け入れる非推奨のBluetoothAdapterメソッドです。Googleはすべての新しいプロジェクトでBluetoothLeScannerを推奨しており、UUIDによるフィルタリング、消費電力モードの設定、PendingIntentによるバックグラウンド操作が可能です。

Android 12+でBLEに必要な権限は?

Android 12+(API 31)では、BLEスキャンにはBLUETOOTH_SCAN、接続にはBLUETOOTH_CONNECT、アドバタイズにはBLUETOOTH_ADVERTISEが必要です。位置情報権限ACCESS_FINE_LOCATIONはBLEには不要になりました。Android 6〜11では、ACCESS_FINE_LOCATIONが必要です。すべての権限はActivityResultContractsを介してランタイムで要求されます。

ダイアログなしでプログラムによってBluetoothを有効にできますか?

Android 10+では、システムダイアログなしのプログラムによるBluetooth有効化は、BLUETOOTH_PRIVILEGED権限を持つシステムアプリのみ利用可能です。通常のアプリはIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE)とstartActivityForResultを使用する必要があります — ユーザーがシステムダイアログで有効化を確認します。マニフェストのBLUETOOTH_ADMINはAndroid 10+でenable()権限を付与しません。

まとめ

  • BluetoothAdapter はAndroidでのすべてのBluetooth操作のエントリポイントであり、BluetoothManagerまたはgetDefaultAdapter()を介して取得されます
  • getState()isEnabled は、BLE操作前のBluetoothラジオ状態の基本的なチェックです
  • BluetoothLeScanner(API 21+)は、ScanFilter、ScanSettings、PendingIntentのサポートで非推奨のstartLeScanを置き換えます
  • BluetoothManager は、マルチアカウントシナリオとAutomotiveをサポートするBluetoothAdapter取得の最新の方法です
  • 権限 は進化しました:ACCESS_FINE_LOCATION(API 23-30)→ BLUETOOTH_SCAN/CONNECT/ADVERTISE(API 31+)
  • enable()/disable() — Android 10+では通常のアプリの場合、システムダイアログACTION_REQUEST_ENABLEを介してのみ
  • connectGatt は、BluetoothGattCallbackを介してBLEペリフェラルとGATT接続を確立するBluetoothDeviceのメソッドです

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください