OSDN Git Service

Bluetoothのデバイスと接続する部分作りこみ途中。。
authorMRSa <mrsa@myad.jp>
Sat, 20 Feb 2021 13:46:32 +0000 (22:46 +0900)
committerMRSa <mrsa@myad.jp>
Sat, 20 Feb 2021 13:46:32 +0000 (22:46 +0900)
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/MainActivity.kt
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/ITextDataUpdater.kt [deleted file]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/MyBluetoothAdapter.kt [deleted file]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/connection/BluetoothDeviceFinder.kt
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/connection/IBluetoothScanResult.kt
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/connection/eeg/MindWaveConnection.kt
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/brainwave/BrainwaveDataHolder.kt

index 8374b50..dd572e9 100644 (file)
@@ -1,5 +1,6 @@
 package jp.osdn.gokigen.thetathoughtshutter
 
+import android.bluetooth.BluetoothDevice
 import android.os.Bundle
 import android.util.Log
 import android.view.KeyEvent
@@ -9,15 +10,21 @@ import com.theta360.pluginlibrary.receiver.KeyReceiver
 import com.theta360.pluginlibrary.values.LedColor
 import com.theta360.pluginlibrary.values.LedTarget
 import jp.osdn.gokigen.thetathoughtshutter.R.layout
+import jp.osdn.gokigen.thetathoughtshutter.bluetooth.connection.BluetoothDeviceFinder
+import jp.osdn.gokigen.thetathoughtshutter.bluetooth.connection.IBluetoothScanResult
+import jp.osdn.gokigen.thetathoughtshutter.bluetooth.connection.eeg.MindWaveConnection
+import jp.osdn.gokigen.thetathoughtshutter.brainwave.BrainwaveDataHolder
 import jp.osdn.gokigen.thetathoughtshutter.theta.ThetaHardwareControl
 import jp.osdn.gokigen.thetathoughtshutter.theta.ThetaSetupBluetoothSPP
 import jp.osdn.gokigen.thetathoughtshutter.theta.operation.IOperationCallback
 import java.lang.Exception
 
-class MainActivity : PluginActivity()
+class MainActivity : PluginActivity(), IBluetoothScanResult
 {
     private val thetaHardwareControl = ThetaHardwareControl(this)
     private val applicationStatus : MyApplicationStatus = MyApplicationStatus()
+    //private val bluetoothFinder = BluetoothDeviceFinder(this, this)
+    private val bluetoothConnection = MindWaveConnection(this, BrainwaveDataHolder())
 
     companion object
     {
@@ -62,7 +69,7 @@ class MainActivity : PluginActivity()
                     if (applicationStatus.status == MyApplicationStatus.Status.Initialized)
                     {
                         // Bluetooth SPPで EEGに接続する
-                        applicationStatus.status = MyApplicationStatus.Status.Searching
+                        connectToEEG()
                     }
                 }
                 if (keyCode == KeyReceiver.KEYCODE_MEDIA_RECORD) // Modeボタン
@@ -102,10 +109,33 @@ class MainActivity : PluginActivity()
 
             }
         })
-
         updateStatus(applicationStatus.status)
     }
 
+    // Bluetooth SPPで EEGに接続する
+    private fun connectToEEG()
+    {
+        try
+        {
+            val thread = Thread {
+                try
+                {
+                    bluetoothConnection.connect("MindWave Mobile")
+                }
+                catch (e: Exception)
+                {
+                    e.printStackTrace()
+                }
+            }
+            thread.start()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        applicationStatus.status = MyApplicationStatus.Status.Searching
+    }
+
     private fun updateStatus(currentStatus : MyApplicationStatus.Status)
     {
         try
@@ -210,6 +240,34 @@ class MainActivity : PluginActivity()
             e.printStackTrace()
         }
     }
+
+    override fun foundBluetoothDevice(device: BluetoothDevice)
+    {
+        try
+        {
+            // Bluetoothデバイスが見つかった!
+            applicationStatus.status = MyApplicationStatus.Status.Connected
+            updateStatus(applicationStatus.status)
+        }
+        catch (e : Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
+    override fun notFindBluetoothDevice()
+    {
+        try
+        {
+            // Bluetoothデバイスが見つからなかった...
+            applicationStatus.status = MyApplicationStatus.Status.Initialized
+            updateStatus(applicationStatus.status)
+        }
+        catch (e : Exception)
+        {
+            e.printStackTrace()
+        }
+    }
 }
 
 //
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/ITextDataUpdater.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/ITextDataUpdater.kt
deleted file mode 100644 (file)
index 9ba9e3e..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package jp.osdn.gokigen.thetathoughtshutter.bluetooth
-
-interface ITextDataUpdater
-{
-    fun setText(data: String?)
-    fun addText(data: String?)
-    fun showSnackBar(message: String?)
-    fun showSnackBar(rscId: Int)
-    fun enableOperation(isEnable: Boolean)
-}
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/MyBluetoothAdapter.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/bluetooth/MyBluetoothAdapter.kt
deleted file mode 100644 (file)
index 80d4e34..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package jp.osdn.gokigen.thetathoughtshutter.bluetooth
-
-import android.bluetooth.BluetoothAdapter
-
-
-class MyBluetoothAdapter
-{
-    fun getBondedDevices(): List<String>
-    {
-        val s: MutableList<String> = ArrayList()
-        try
-        {
-            val btAdapter = BluetoothAdapter.getDefaultAdapter()
-            val bondedDevices = btAdapter.bondedDevices
-            for (bt in bondedDevices)
-            {
-                s.add(bt.name)
-            }
-        }
-        catch (e: Exception)
-        {
-            e.printStackTrace()
-        }
-        return (s)
-    }
-}
index d893c3b..9a45116 100644 (file)
@@ -4,29 +4,74 @@ import android.app.Activity
 import android.bluetooth.BluetoothAdapter
 import android.bluetooth.BluetoothDevice
 import android.bluetooth.BluetoothManager
+import android.bluetooth.le.BluetoothLeScanner
+import android.bluetooth.le.ScanCallback
+import android.bluetooth.le.ScanResult
 import android.content.Context
 import android.util.Log
-import jp.osdn.gokigen.thetathoughtshutter.R
-import jp.osdn.gokigen.thetathoughtshutter.utils.SnackBarMessage
 
 class BluetoothDeviceFinder(private val context: Activity, private val scanResult: IBluetoothScanResult) : BluetoothAdapter.LeScanCallback
 {
 
     companion object
     {
-        private val TAG = toString()
-        private const val BLE_SCAN_TIMEOUT_MILLIS = 15 * 1000 // 15秒間
-        private const val BLE_WAIT_DURATION = 100 // 100ms間隔
+        private val TAG = BluetoothDeviceFinder::class.java.simpleName
     }
     private lateinit var targetDeviceName: String
-    private val messageToShow = SnackBarMessage(context, false)
     private var foundBleDevice = false
+    private var scanner : BluetoothLeScanner? = null
 
     fun reset()
     {
         foundBleDevice = false
     }
 
+    fun stopScan()
+    {
+        try
+        {
+            Log.v(TAG, " stopScan()")
+            val btMgr: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
+            btMgr.adapter.cancelDiscovery()
+            scanner?.flushPendingScanResults((object: ScanCallback() {
+                override fun onScanFailed(errorCode: Int)
+                {
+
+                }
+
+                override fun onScanResult(callbackType: Int, result: ScanResult?)
+                {
+
+                }
+
+                override fun onBatchScanResults(results: MutableList<ScanResult>?)
+                {
+
+                }
+            }))
+            scanner?.stopScan(object: ScanCallback() {
+                override fun onScanFailed(errorCode: Int)
+                {
+
+                }
+
+                override fun onScanResult(callbackType: Int, result: ScanResult?)
+                {
+
+                }
+
+                override fun onBatchScanResults(results: MutableList<ScanResult>?)
+                {
+
+                }
+            })
+        }
+        catch (e : Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
     fun startScan(targetDeviceName: String)
     {
         try
@@ -36,7 +81,9 @@ class BluetoothDeviceFinder(private val context: Activity, private val scanResul
             if (!btAdapter.isEnabled)
             {
                 // Bluetoothの設定がOFFだった
-                messageToShow.showMessage(R.string.bluetooth_setting_is_off)
+                Log.v(TAG, " BLUETOOTH SETTING IS OFF")
+                scanResult.notFindBluetoothDevice()
+                return
             }
             // Bluetooth のサービスを取得
             val btMgr: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
@@ -52,49 +99,74 @@ class BluetoothDeviceFinder(private val context: Activity, private val scanResul
     {
         try
         {
+            Log.v(TAG, " scanBluetoothDevice() ")
+
             // スキャン開始
             foundBleDevice = false
             val adapter = btMgr.adapter
-            if (!adapter.startLeScan(this))
+            if (adapter.isDiscovering)
             {
-                // Bluetooth LEのスキャンが開始できなかった場合...
-                Log.v(TAG, "Bluetooth LE SCAN START fail...")
-                messageToShow.showMessage(R.string.bluetooth_scan_start_failure)
-                return
+                adapter.cancelDiscovery()
             }
-            Log.v(TAG, " ----- BT SCAN STARTED ----- ")
-            var passed = 0
-            while (passed < BLE_SCAN_TIMEOUT_MILLIS)
-            {
-                if (foundBleDevice)
+            //adapter.startDiscovery()
+            scanner = adapter.bluetoothLeScanner
+            scanner?.startScan(object: ScanCallback() {
+                override fun onScanFailed(errorCode: Int)
                 {
-                    // デバイス発見
-                    Log.v(TAG, "FOUND DEVICE")
-                    break
+                    //super.onScanFailed(errorCode)
+                    Log.v(TAG, " onScanFailed : $errorCode")
                 }
 
-                // BLEのスキャンが終わるまで待つ
-                Thread.sleep(BLE_WAIT_DURATION.toLong())
-                passed += BLE_WAIT_DURATION
-            }
-            // スキャンを止める(500ms後に)
-            Thread.sleep(500)
-            adapter.stopLeScan(this)
-            Log.v(TAG, " ----- BT SCAN STOPPED ----- ")
+                override fun onScanResult(callbackType: Int, result: ScanResult?)
+                {
+                    //super.onScanResult(callbackType, result)
+                    val device = result?.device
+                    Log.v(TAG, " onScanResult($callbackType, ${device?.name}) ")
+                    val findDevice = (device?.name)?.contains(targetDeviceName)
+                    if ((findDevice != null)&&(findDevice))
+                    {
+                        Log.v(TAG, " FIND DEVICE : $targetDeviceName")
+                        scanResult.foundBluetoothDevice(device)
+                        scanner?.stopScan(object : ScanCallback() {
+                            override fun onScanFailed(errorCode: Int)
+                            {
+                                Log.v(TAG, " stopScan::onScanFailed : $errorCode")
+                            }
+                            override fun onScanResult(callbackType: Int, result: ScanResult?)
+                            {
+                                Log.v(TAG, " stopScan::onScanResult : $callbackType")
+                            }
+                            override fun onBatchScanResults(results: MutableList<ScanResult>?)
+                            {
+                                Log.v(TAG, " stopScan::onBatchScanResults ")
+                            }
+                        })
+                    }
+                }
+
+                override fun onBatchScanResults(results: MutableList<ScanResult>?)
+                {
+                    //super.onBatchScanResults(results)
+                    Log.v(TAG, " onBatchScanResults ")
+                }
+            })
         }
         catch (e: Exception)
         {
             e.printStackTrace()
             Log.v(TAG, "Bluetooth LE SCAN EXCEPTION...")
-            messageToShow.showMessage(R.string.scan_fail_via_bluetooth)
+            //messageToShow.showMessage(R.string.scan_fail_via_bluetooth)
         }
-        Log.v(TAG, "Bluetooth SCAN STOPPED.")
+        //Log.v(TAG, "Bluetooth SCAN STOPPED.")
+        //scanResult.notFindBluetoothDevice()
     }
 
     override fun onLeScan(device: BluetoothDevice, rssi: Int, scanRecord: ByteArray?)
     {
         try
         {
+            Log.v(TAG, " onLeScan() ")
+
             val btDeviceName = device.name
             if (btDeviceName != null && btDeviceName.matches(Regex(targetDeviceName)))
             {
index e07a173..4ffc78a 100644 (file)
@@ -13,15 +13,14 @@ import java.io.InputStream
 import java.util.*
 import kotlin.experimental.and
 
-
-class MindWaveConnection(private val context : Activity, private val dataReceiver: IBrainwaveDataReceiver) : IBluetoothScanResult
+class MindWaveConnection(context : Activity, private val dataReceiver: IBrainwaveDataReceiver, private val scanResult: IBluetoothScanResult? = null) : IBluetoothScanResult
 {
     companion object
     {
-        private val TAG = toString()
+        private val TAG = MindWaveConnection::class.java.simpleName
     }
 
-    private val deviceFinder: BluetoothDeviceFinder = BluetoothDeviceFinder(context, this)
+    private val deviceFinder = BluetoothDeviceFinder(context, this)
     private var fileLogger: BrainwaveFileLogger? = null
     private var foundDevice = false
     private var loggingFlag = false
@@ -83,6 +82,7 @@ class MindWaveConnection(private val context : Activity, private val dataReceive
 
     private fun serialCommunicationMain(btSocket: BluetoothSocket)
     {
+        Log.v(TAG, "serialCommunicationMain ")
         var inputStream: InputStream? = null
         try
         {
@@ -118,6 +118,7 @@ class MindWaveConnection(private val context : Activity, private val dataReceive
             try
             {
                 val data: Int = inputStream.read()
+                Log.v(TAG, " RECEIVED ")
                 val byteData = (data and 0xff).toByte()
                 if (previousData == byteData && byteData == 0xaa.toByte())
                 {
@@ -148,22 +149,81 @@ class MindWaveConnection(private val context : Activity, private val dataReceive
         }
     }
 
+
     override fun foundBluetoothDevice(device: BluetoothDevice)
     {
         try
         {
+            Log.v(TAG, " foundBluetoothDevice : ${device.name}")
+
+            deviceFinder.stopScan()
+
+            // TODO: 見つかったデバイスにペアリングする
+
+            device.setPin(byteArrayOf(0x30,0x30, 0x30, 0x30))
+
+            val result = device.createBond()
+            if (!result)
+            {
+                // ペアリング失敗
+            }
+
+
+        }
+        catch (e : Exception)
+        {
+            e.printStackTrace()
+        }
+        //return (device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")))
+    }
+
+
+/*
+    private fun prepareBluetoothDevice(device: BluetoothDevice) : BluetoothSocket?
+    {
+        try
+        {
+            device.setPin(byteArrayOf(0x30,0x30, 0x30, 0x30))
+
+            val result = device.createBond()
+            if (!result)
+            {
+                // ペアリング失敗
+                return (null)
+            }
+
+
+        }
+        catch (e : Exception)
+        {
+            e.printStackTrace()
+        }
+        return (device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")))
+    }
+
+    override fun foundBluetoothDevice(device: BluetoothDevice)
+    {
+        try
+        {
+            Log.v(TAG, " foundBluetoothDevice : ${device.name}")
             if (foundDevice)
             {
                 // デバイスがすでに見つかっている
                 Log.v(TAG, " ALREADY FIND BLUETOOTH DEVICE. : $device.name")
+                deviceFinder.stopScan()
                 return
             }
             foundDevice = true
-            val btSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
+            deviceFinder.stopScan()
+
+            val btSocket = prepareBluetoothDevice(device) // device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))
             val thread = Thread {
                 try
                 {
-                    serialCommunicationMain(btSocket)
+                    if (btSocket != null)
+                    {
+                        serialCommunicationMain(btSocket)
+                    }
                 }
                 catch (e: Exception)
                 {
@@ -174,10 +234,23 @@ class MindWaveConnection(private val context : Activity, private val dataReceive
             {
                 thread.start()
             }
+            else
+            {
+                Log.v(TAG, " btSocket is NULL.")
+            }
+            scanResult?.foundBluetoothDevice(device)
         }
         catch (e: Exception)
         {
             e.printStackTrace()
         }
     }
-}
\ No newline at end of file
+*/
+
+    override fun notFindBluetoothDevice()
+    {
+        Log.v(TAG, " notFindBluetoothDevice()")
+        scanResult?.notFindBluetoothDevice()
+        deviceFinder.stopScan()
+    }
+}
index 9eb53f6..47eb174 100644 (file)
@@ -3,8 +3,7 @@ package jp.osdn.gokigen.thetathoughtshutter.brainwave
 import android.util.Log
 import java.util.*
 
-
-class BrainwaveDataHolder(maxBufferSize: Int) : IBrainwaveDataReceiver
+class BrainwaveDataHolder(maxBufferSize: Int = 16000) : IBrainwaveDataReceiver
 {
     private val TAG = toString()
 
@@ -22,7 +21,7 @@ class BrainwaveDataHolder(maxBufferSize: Int) : IBrainwaveDataReceiver
 
     override fun receivedRawData(value: Int)
     {
-        //Log.v(TAG, " receivedRawData() : " + value);
+        Log.v(TAG, " receivedRawData() : $value");
         try {
             valueBuffer[currentPosition] = value
             currentPosition++