Android で BLE(checkPermission)
AndroidKotlin
2022-7-17 17:54 JST

Android で BLE やっと SCAN できました。そしてソースも整理もつきました。

ACCESS_FINE_LOCATION とパーミッション

ACCESS_FINE_LOCATION が AndroidManifest に必要であったのは前に書きました。Intent は隠蔽されて requestPermissions を直接使うのは deprecated になりました。内部的に使っているみたいね。そのため、 registerForActivityResultをつかって、コールバックルーチンをつくる。このコールバックはview を作る前に作らないといけないみたいなので、class の変数(?)で val で予め作っておきます。

private val requestPermission =
    registerForActivityResult(ActivityResultContracts.RequestPermission())
        { result ->
            if (result) {
                checkPermission()
            } else {
                Toast.makeText(this.requireContext(), 
                    "Permission Denied."
                    Toast.LENGTH_SHORT).show()
            }
        }

checkPermission は class 内の private なメソッドで、次のようにしました。こうすることによって、次々とパーミッションのチェックをしていき最後に startScanning (これも private なメソッド) を呼びます。

private fun checkPermission() {
    if (checkSelfPermission( this.requireContext(), 
                Manifest.permission.ACCESS_FINE_LOCATION) 
            != PackageManager.PERMISSION_GRANTED) {
        requestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
        return
    }
    if (checkSelfPermission( this.requireContext(), 
                Manifest.permission.BLUETOOTH_SCAN) 
            != PackageManager.PERMISSION_GRANTED) {
        requestPermission.launch(Manifest.permission.BLUETOOTH_SCAN)
        return
    }
    if (checkSelfPermission( this.requireContext(), 
                Manifest.permission.BLUETOOTH_CONNECT) 
            != PackageManager.PERMISSION_GRANTED) {
        requestPermission.launch(Manifest.permission.BLUETOOTH_CONNECT)
        return
    }
    startScanning()
}

checkSelfPermission は一回どこからか呼ばないといけないのでonCreateView から呼びます。onViewCreated からだとなぜか複数回呼ばれることがあったので。

startScanning の stopScanning は @Synchoronized で排他しました。

リンク集