実現したいこと
- Raspberry Pi 4 で、Android 端末から発信されるビーコンを受信したい
前提
Raspberry Pi で Android から発信されるビーコンを受信するためのシステムを作っています。
現在、Android 端末で発信したビーコンを Raspberry Pi で受信することができずに困っています。
該当のソースコード
Raspberry Pi でビーコンを受信するためのプログラム
Python
1import time 2from beacontools import BeaconScanner, IBeaconFilter 3import sys 4bt_list={}5 6def callback(bt_addr, rssi, packet, additional_info):7 try:8 id="UUID:"+additional_info["uuid"]+" Major:"+str(additional_info["major"])+" Minor:"+str(additional_info["minor"])9 print("<Receive> %s " % (id))10 if not (id in bt_list):11 print("<IN> %s " % (id))12 currentCPUTime=time.perf_counter()13 bt_list[id]=currentCPUTime 14 except Exception as e: # 具体的な例外を指定して捕捉15 print(f"Error in callback: {e}")16 17 18# scan for all iBeacon advertisements from beacons with the specified uuid 19scanner = BeaconScanner(callback, 20 device_filter=IBeaconFilter(uuid="58cebe85-e7da-4c00-9c8e-54b200266795")21)22scanner.start()23 24try:25 while True:26 if(len(bt_list)==0):27 print("<No Listing>")28 for i in list(bt_list):29 #Wait 30s for detecting to exit beacon.30 if(time.perf_counter()-bt_list[i]>30):31 print("<OUT> %s " % (i))32 del bt_list[i]33 else:34 print("<Listing> %s %d" % (i,time.perf_counter()-bt_list[i]))35 time.sleep(1)36except KeyboardInterrupt:37 scanner.stop()
Android 端末でビーコンを発信するアプリケーションのプログラム
Kotlin
1package com.example.beacon 2 3import android.Manifest 4import android.bluetooth.BluetoothAdapter 5import android.bluetooth.le.AdvertiseCallback 6import android.bluetooth.le.AdvertiseSettings 7import android.content.Intent 8import android.content.pm.PackageManager 9import android.os.Build 10import android.os.Bundle 11import android.util.Log 12import androidx.appcompat.app.AppCompatActivity 13import androidx.core.app.ActivityCompat 14import androidx.core.content.ContextCompat 15import org.altbeacon.beacon.Beacon 16import org.altbeacon.beacon.BeaconParser 17import org.altbeacon.beacon.BeaconTransmitter 18 19class MainActivity : AppCompatActivity() {20 private val UUID = "58cebe85-e7da-4c00-9c8e-54b200266795"21 val IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"22 private val REQUEST_ENABLE_BT = 123 private val REQUEST_BLUETOOTH_PERMISSION = 224 25 // BLEの発信を制御するクラスのインスタンス26 private var _beaconTransmitter: BeaconTransmitter? = null27 28 override fun onCreate(savedInstanceState: Bundle?) {29 super.onCreate(savedInstanceState)30 setContentView(R.layout.activity_main)31 32 // Bluetoothが有効化されているか確認33 if (isBluetoothEnabled()) {34 // BLUETOOTH_ADVERTISEのパーミッションを確認し、リクエストする35 checkAndRequestBluetoothPermission()36 } else {37 // Bluetoothを有効化するためのリクエスト38 enableBluetooth()39 }40 }41 42 private fun isBluetoothEnabled(): Boolean {43 val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()44 return bluetoothAdapter != null && bluetoothAdapter.isEnabled 45 }46 47 private fun enableBluetooth() {48 val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)49 startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)50 }51 52 private fun checkAndRequestBluetoothPermission() {53 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {54 val permissionCheck = ContextCompat.checkSelfPermission(55 this,56 Manifest.permission.BLUETOOTH_ADVERTISE 57 )58 59 if (permissionCheck != PackageManager.PERMISSION_GRANTED) {60 ActivityCompat.requestPermissions(61 this,62 arrayOf(Manifest.permission.BLUETOOTH_ADVERTISE),63 REQUEST_BLUETOOTH_PERMISSION 64 )65 } else {66 // パーミッションがすでに許可されている場合、BLE広告を開始67 startAdvertising()68 }69 } else {70 // Android M未満のデバイスでは、インストール時に権限が許可されている71 startAdvertising()72 }73 }74 75 private fun startAdvertising() {76 val beacon = Beacon.Builder()77 .setId1(UUID)78 .setId2("1")79 .setId3("80")80 .setManufacturer(0x004C)81 .build()82 83 val beaconParser = BeaconParser().setBeaconLayout(IBEACON_FORMAT)84 val beaconTransmitter = BeaconTransmitter(applicationContext, beaconParser)85 86 beaconTransmitter.startAdvertising(beacon, object : AdvertiseCallback() {87 override fun onStartSuccess(settingsInEffect: AdvertiseSettings) {88 super.onStartSuccess(settingsInEffect)89 // BLE広告の開始に成功90 Log.d("success", "ENTER.")91 }92 93 override fun onStartFailure(errorCode: Int) {94 // BLE広告の開始に失敗95 Log.d("failed", "EXIT. ")96 }97 })98 }99 100 override fun onRequestPermissionsResult(101 requestCode: Int,102 permissions: Array<out String>,103 grantResults: IntArray 104 ) {105 when (requestCode) {106 REQUEST_BLUETOOTH_PERMISSION -> {107 if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {108 // パーミッションが許可された場合、BLE広告を開始109 startAdvertising()110 } else {111 // パーミッションが拒否された場合、適切に処理112 Log.d("permission", "Bluetooth Advertiseのパーミッションが拒否されました")113 }114 }115 }116 // スーパークラスのメソッドを呼び出す117 super.onRequestPermissionsResult(requestCode, permissions, grantResults)118 }119}
試したこと
ビーコンを用いて入退室をチェックする簡単なプログラムを参考にセットアップし、ビーコンを検知するプログラムを動かしています。
Android端末からBLEビーコンの発信をしたい。 の質問でAndroid 側のアプリケーションを作成し、 LogCat では BeaconTransmitter com.example.beacon I Advertisement start succeeded. と表示されるため、ぱっと見問題がないように思っています。が、こちら側に問題がある場合ご教授いただけると幸いです。
補足情報(FW/ツールのバージョンなど)
Python 3.11.2

0 コメント