Advertisement
Guest User

Untitled

a guest
Apr 16th, 2017
566
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 14.37 KB | None | 0 0
  1. package family.emotion.emtracker
  2.  
  3. import android.annotation.TargetApi
  4. import android.app.Service
  5. import android.bluetooth.*
  6. import android.content.Context
  7. import android.content.Intent
  8. import android.os.Binder
  9. import android.os.Build
  10. import android.os.DeadObjectException
  11. import android.os.IBinder
  12. import android.util.Log
  13. import family.emotion.emtracker.SupportedGattAttributes
  14. import java.util.*
  15.  
  16.  
  17. /**
  18.  * Created by Ruslan Kishai aka creageek on 29.03.16.
  19.  * Copyright FORCE, LLC (2016)
  20.  */
  21.  
  22. @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
  23. class BluetoothService : Service() {
  24.  
  25.     private var mBluetoothGatt: BluetoothGatt? = null
  26.  
  27.     private val serviceStack = Stack<UUID>()
  28.     private val charStack = Stack<UUID>()
  29.  
  30.     /**
  31.      * Variable that defines interaction with Bluetooth device: gets data from and sends broadcasts
  32.      * notifications about new data; checks connection state and looks for Bluetooth services that
  33.      * can be discovered
  34.      */
  35.  
  36.     private val STATE_DISCONNECTED = 0
  37.     private val STATE_CONNECTING = 1
  38.     private val STATE_CONNECTED = 2
  39.  
  40.     private val mGattCallback = object : BluetoothGattCallback() {
  41.         override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
  42.  
  43.             var intentAction: String
  44.  
  45.             if (newState == BluetoothProfile.STATE_CONNECTED) {
  46.                 intentAction = ACTION_GATT_CONNECTED
  47.                 connectionState = STATE_CONNECTED
  48.                 sendBroadcast(Intent(ACTION_GATT_CONNECTED))
  49.  
  50.               //  broadcastUpdate(intentAction)
  51.                 Log.i("BLE Service", "Connected to GATT server.")
  52.                 Log.i("BLE Service", "Attempting to start service discovery:"+
  53.                  mBluetoothGatt?.discoverServices())
  54.             } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
  55.                 intentAction = ACTION_GATT_DISCONNECTED
  56.                 connectionState = STATE_DISCONNECTED
  57.                // bleGatt!!.connect()
  58.  
  59.                 sendBroadcast(Intent(ACTION_GATT_DISCONNECTED))
  60.                 Log.i("BLE Service", "Disconnected from GATT server.")
  61.                // broadcastUpdate(intentAction)
  62.             } else {
  63.                 intentAction = ACTION_GATT_CONNECTING
  64.                 connectionState = STATE_CONNECTING
  65.                 sendBroadcast(Intent(ACTION_GATT_CONNECTING))
  66.                 mBluetoothGatt?.discoverServices()
  67.                 Log.i("BLE Service", "Connecting to GATT server.")
  68.             }
  69.         }
  70.  
  71.                 override fun onCharacteristicRead(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
  72.             super.onCharacteristicRead(gatt, characteristic, status)
  73.         }
  74.  
  75.         override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
  76.             super.onCharacteristicWrite(gatt, characteristic, status)
  77.         }
  78.  
  79.         override fun onDescriptorRead(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
  80.             super.onDescriptorRead(gatt, descriptor, status)
  81.         }
  82.  
  83.         override fun onReliableWriteCompleted(gatt: BluetoothGatt, status: Int) {
  84.             super.onReliableWriteCompleted(gatt, status)
  85.         }
  86.  
  87.         override fun onReadRemoteRssi(gatt: BluetoothGatt, rssi: Int, status: Int) {
  88.             super.onReadRemoteRssi(gatt, rssi, status)
  89.         }
  90.  
  91.         override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) {
  92.             super.onMtuChanged(gatt, mtu, status)
  93.         }
  94.  
  95.         override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
  96.             val value: Int
  97.             val type: String
  98.             try {
  99.                 if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.Heartrate)) {
  100.                     // Heartrate
  101.                     value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1)!!
  102.                     type = TYPE_HEARTRATE
  103.                     //if (BuildConfig.DEBUG)
  104.                     Log.i(LOG_TAG, String.format("Heartrate is %d", value))
  105.                 } else if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.EDA)) {
  106.                     // EDA
  107.                     value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, 0)!!
  108.                     type = TYPE_EDA
  109.                     //if (BuildConfig.DEBUG)
  110.                     Log.i(LOG_TAG, String.format("Eda is %d", value))
  111.                 } else if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.Oxi)) {
  112.                     // Oxi
  113.                     value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0)!!
  114.                     type = TYPE_OXY
  115.                     //if (BuildConfig.DEBUG)
  116.                     Log.i(LOG_TAG, String.format("Oxy is %d", value))
  117.                 } else if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.Battery)) {
  118.                     // Battery
  119.                     value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)!!
  120.                     type = TYPE_BATTERY
  121.                     //if (BuildConfig.DEBUG)
  122.                     Log.i(LOG_TAG, String.format("Battery is %d", value))
  123.                 } else if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.FallSensor)) {
  124.                     // Fall Sensor
  125.                     value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)!!
  126.                     if (value != 0xAA)
  127.                         return
  128.                     type = TYPE_FALLEN
  129.                     //if (BuildConfig.DEBUG)
  130.                     Log.i(LOG_TAG, "Fallen")
  131.                 } else if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.AlertButton)) {
  132.                     // Alarm Button
  133.                     value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)!!
  134.                     type = TYPE_ALARM_BUTTON
  135.                     //if (BuildConfig.DEBUG)
  136.                     Log.i(LOG_TAG, "Button pressed")
  137.                 } else
  138.  
  139.                 //NEW API
  140.                     if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.HRV)) {
  141.                         //HRV
  142.                         value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)!!
  143.                         type = TYPE_HRV
  144.                         //if (BuildConfig.DEBUG)
  145.                         Log.i(LOG_TAG, String.format("HRV is %d", value))
  146.                     } else if (characteristic.uuid.equals(SupportedGattAttributes.Characteristics.SI)) {
  147.                         //SI
  148.                         value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0)!!
  149.                         type = TYPE_SI
  150.                         // if(BuildConfig.DEBUG)
  151.                         Log.i(LOG_TAG, String.format("SI is %d", value))
  152.  
  153.  
  154.                     } else {
  155.                         Log.wtf(LOG_TAG, "Unsupported characteristic")
  156.                         return
  157.                     }
  158.  
  159.                 val broadcast = Intent(ACTION_GATT_EXTRA_DATA)
  160.                 broadcast.putExtra("value", value)
  161.                 broadcast.putExtra("type", type)
  162.                 sendBroadcast(broadcast)
  163.             } catch (e: NullPointerException) {
  164.                 Log.wtf(LOG_TAG, "NullPointerException with characteristic UUID " + characteristic.uuid.toString())
  165.                 e.printStackTrace()
  166.             }
  167.  
  168.         }
  169.  
  170.         override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
  171.             if (status == BluetoothGatt.GATT_SUCCESS) {
  172.                 val serviceUuidList = arrayOf<UUID>(
  173.                         SupportedGattAttributes.Services.Heartrate,
  174.                         SupportedGattAttributes.Services.EDA,
  175.                         SupportedGattAttributes.Services.Oxi,
  176.                         SupportedGattAttributes.Services.Battery,
  177.                         SupportedGattAttributes.Services.HRV,
  178.                         SupportedGattAttributes.Services.SI,
  179.                         SupportedGattAttributes.Services.AlertButton,
  180.                         SupportedGattAttributes.Services.ForceAlert)
  181.                 val charUuidList = arrayOf<UUID>(
  182.                         SupportedGattAttributes.Characteristics.Heartrate,
  183.                         SupportedGattAttributes.Characteristics.EDA,
  184.                         SupportedGattAttributes.Characteristics.Oxi,
  185.                         SupportedGattAttributes.Characteristics.Battery,
  186.                         SupportedGattAttributes.Characteristics.HRV,
  187.                         SupportedGattAttributes.Characteristics.SI,
  188.                         SupportedGattAttributes.Characteristics.AlertButton,
  189.                         SupportedGattAttributes.Characteristics.FallSensor)
  190.  
  191.                 val services = gatt.services
  192.  
  193.                 for (i in services.indices) {
  194.                     var knownService = false
  195.                     var position = 0
  196.                     //if (BuildConfig.DEBUG)
  197.                     Log.i(LOG_TAG, "Found service with UUID " + services[i].uuid.toString())
  198.                     for (knownServices in serviceUuidList) {
  199.                         knownService = knownServices == services[i].uuid
  200.                         if (knownService)
  201.                             break
  202.                         ++position
  203.                     }
  204.                     if (knownService) {
  205.                         serviceStack.add(serviceUuidList[position])
  206.                         charStack.add(charUuidList[position])
  207.                     }
  208.                 }
  209.                 if (serviceStack.size > 0 && charStack.size > 0)
  210.                     performSubscribing(gatt)
  211.             } else {
  212.                 Log.e(LOG_TAG, "onServicesDiscovered received: " + status)
  213.             }
  214.         }
  215.  
  216.         private fun performSubscribing(gatt: BluetoothGatt) {
  217.             val pop = serviceStack.pop()
  218.             val service = gatt.getService(pop)
  219.             val characteristic = service.getCharacteristic(charStack.pop())
  220.             gatt.setCharacteristicNotification(characteristic, true)
  221.             val descriptor = characteristic.getDescriptor(SupportedGattAttributes.DEFAULT)
  222.             descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
  223.             if (gatt.writeDescriptor(descriptor))
  224.                 Log.i(LOG_TAG, "Started " + pop.toString())
  225.         }
  226.  
  227.         override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
  228.             super.onDescriptorWrite(gatt, descriptor, status)
  229.             if (serviceStack.size > 0 && charStack.size > 0) {
  230.                 performSubscribing(gatt)
  231.             }
  232.         }
  233.     }
  234.  
  235.     var connectionState = STATE_DISCONNECTED
  236.  
  237.     override fun onDestroy() {
  238.         super.onDestroy()
  239.         Log.wtf(LOG_TAG, "Service stopped")
  240.  
  241.         if (mBluetoothGatt == null)
  242.             return
  243.         try {
  244.             mBluetoothGatt!!.disconnect()
  245.             mBluetoothGatt!!.close()
  246.             mBluetoothGatt = null
  247.             this@BluetoothService.stopSelf()
  248.         } catch (e: DeadObjectException) {
  249.         }
  250.     }
  251.  
  252.     private val mLocalBinder = LocalBinder()
  253.  
  254.     inner class LocalBinder : Binder() {
  255.         val service: BluetoothService
  256.             get() = this@BluetoothService
  257.     }
  258.  
  259.     override fun onBind(intent: Intent): IBinder? {
  260.         return mLocalBinder
  261.     }
  262.  
  263.     var device: BluetoothDevice? = null
  264.     //    override fun onStartCommand(intent: Intent?
  265. //                                , flags: Int, startId: Int): Int {
  266. //        //   if (BuildConfig.DEBUG)
  267. //        Log.wtf(LOG_TAG, "Started service")
  268. //        if (LocalStorage(this).getDeviceAddress() == null) {
  269. //            Log.wtf(LOG_TAG, "Device address == null :(")
  270. //            return Service.START_NOT_STICKY
  271. //        }
  272. //
  273. //        if (mBluetoothGatt == null || !mBluetoothGatt!!.device.address.equals(LocalStorage(this).getDeviceAddress())) {
  274. //            val mBluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
  275. //            val mBluetoothAdapter = mBluetoothManager.adapter
  276. //            device = mBluetoothAdapter.getRemoteDevice(LocalStorage(this).getDeviceAddress())
  277. //
  278. //            mBluetoothGatt = device?.connectGatt(this, true, mGattCallback)
  279. //            sendBroadcast(Intent(ACTION_GATT_CONNECTING))
  280. //        } else
  281. //            mBluetoothGatt!!.connect()
  282. //        return Service.START_STICKY_COMPATIBILITY
  283. //    }
  284.     fun getFromPrefs(key: String): String = getSharedPreferences("ble", Context.MODE_PRIVATE).getString(key, "")
  285.  
  286.     override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
  287.         val mng = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
  288.         val adapter = BluetoothAdapter.getDefaultAdapter()//.adapter
  289.         val device = adapter!!.getRemoteDevice(getFromPrefs("device-address")) ?: return START_NOT_STICKY
  290.  
  291.         if (mBluetoothGatt == null) {
  292.             mBluetoothGatt = device.connectGatt(this, true, mGattCallback)
  293.             sendBroadcast(Intent(ACTION_GATT_CONNECTING))
  294.         } else mBluetoothGatt!!.connect()
  295.         return START_STICKY_COMPATIBILITY
  296.     }
  297.  
  298.  
  299.     companion object {
  300.         private val LOG_TAG = BluetoothService::class.java.name
  301.  
  302.         val AUTHORITY = "family.emotion.emtracker"
  303.         val ACTION_GATT_CONNECTED = AUTHORITY + ".ACTION_GATT_CONNECTED"
  304.         val ACTION_GATT_CONNECTING = AUTHORITY + ".ACTION_GATT_CONNECTING"
  305.         val ACTION_GATT_DISCONNECTED = AUTHORITY + ".ACTION_GATT_DISCONNECTED"
  306.         val ACTION_GATT_DATA_AVAILABLE = AUTHORITY + ".ACTION_GATT_DATA_AVAILABLE"
  307.         val ACTION_GATT_EXTRA_DATA = AUTHORITY + ".ACTION_GATT_EXTRA_DATA"
  308.         val ACTION_FORGET_DEVICE = AUTHORITY + ".FORGET"
  309.  
  310.  
  311.         val TYPE_HEARTRATE = AUTHORITY + ".TYPE_HEARTRATE"
  312.         val TYPE_EDA = AUTHORITY + ".TYPE_EDA"
  313.         val TYPE_OXY = AUTHORITY + ".TYPE_OXY"
  314.         val TYPE_BATTERY = AUTHORITY + ".TYPE_BATTERY"
  315.         val TYPE_FALLEN = AUTHORITY + ".TYPE_FALLEN"
  316.         val TYPE_ALARM_BUTTON = AUTHORITY + ".TYPE_ALARM_BUTTON"
  317.  
  318.         val TYPE_HRV = AUTHORITY + ".TYPE_HRV"
  319.         val TYPE_SI = AUTHORITY + ".TYPE_SI"
  320.  
  321.         val HEARTRATE = 1
  322.         val OXI = 2
  323.         val EDA = 3
  324.         val BATTERY = 4
  325.     }
  326.  
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement