Unify bluetooth, Android 12 permissions

This commit is contained in:
Milos Kozak 2021-12-13 01:01:16 +01:00
parent 0307796ecf
commit 201a04bfbf
29 changed files with 231 additions and 237 deletions

View file

@ -1,7 +1,7 @@
package info.nightscout.androidaps.plugins.general.maintenance package info.nightscout.androidaps.plugins.general.maintenance
import android.Manifest import android.Manifest
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
@ -24,8 +24,6 @@ import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ImportExportPrefs import info.nightscout.androidaps.interfaces.ImportExportPrefs
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.maintenance.formats.* import info.nightscout.androidaps.plugins.general.maintenance.formats.*
@ -41,9 +39,11 @@ import info.nightscout.androidaps.utils.alertDialogs.WarningDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.protection.PasswordCheck
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.storage.Storage
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
@ -81,17 +81,13 @@ class ImportExportPrefsImpl @Inject constructor(
override fun verifyStoragePermissions(fragment: Fragment, onGranted: Runnable) { override fun verifyStoragePermissions(fragment: Fragment, onGranted: Runnable) {
fragment.context?.let { ctx -> fragment.context?.let { ctx ->
val permission = ContextCompat.checkSelfPermission(ctx, val permission = ContextCompat.checkSelfPermission(ctx, Manifest.permission.WRITE_EXTERNAL_STORAGE)
Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (permission != PackageManager.PERMISSION_GRANTED) { if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user // We don't have permission so prompt the user
fragment.activity?.let { fragment.activity?.let {
androidPermission.askForPermission(it, androidPermission.askForPermission(it, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE))
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE))
}
} else {
onGranted.run()
} }
} else onGranted.run()
} }
} }
@ -114,7 +110,7 @@ class ImportExportPrefsImpl @Inject constructor(
// based on https://medium.com/@pribble88/how-to-get-an-android-device-nickname-4b4700b3068c // based on https://medium.com/@pribble88/how-to-get-an-android-device-nickname-4b4700b3068c
val n1 = Settings.System.getString(context.contentResolver, "bluetooth_name") val n1 = Settings.System.getString(context.contentResolver, "bluetooth_name")
val n2 = Settings.Secure.getString(context.contentResolver, "bluetooth_name") val n2 = Settings.Secure.getString(context.contentResolver, "bluetooth_name")
val n3 = BluetoothAdapter.getDefaultAdapter()?.name val n3 = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter?.name
val n4 = Settings.System.getString(context.contentResolver, "device_name") val n4 = Settings.System.getString(context.contentResolver, "device_name")
val n5 = Settings.Secure.getString(context.contentResolver, "lock_screen_owner_info") val n5 = Settings.Secure.getString(context.contentResolver, "lock_screen_owner_info")
val n6 = Settings.Global.getString(context.contentResolver, "device_name") val n6 = Settings.Global.getString(context.contentResolver, "device_name")
@ -137,8 +133,10 @@ class ImportExportPrefsImpl @Inject constructor(
} }
@Suppress("SameParameterValue") @Suppress("SameParameterValue")
private fun askForEncryptionPass(activity: FragmentActivity, @StringRes canceledMsg: Int, @StringRes passwordName: Int, @StringRes passwordExplanation: Int?, private fun askForEncryptionPass(
@StringRes passwordWarning: Int?, then: ((password: String) -> Unit)) { activity: FragmentActivity, @StringRes canceledMsg: Int, @StringRes passwordName: Int, @StringRes passwordExplanation: Int?,
@StringRes passwordWarning: Int?, then: ((password: String) -> Unit)
) {
passwordCheck.queryAnyPassword(activity, passwordName, R.string.key_master_password, passwordExplanation, passwordWarning, { password -> passwordCheck.queryAnyPassword(activity, passwordName, R.string.key_master_password, passwordExplanation, passwordWarning, { password ->
then(password) then(password)
}, { }, {
@ -170,29 +168,37 @@ class ImportExportPrefsImpl @Inject constructor(
private fun askToConfirmExport(activity: FragmentActivity, fileToExport: File, then: ((password: String) -> Unit)) { private fun askToConfirmExport(activity: FragmentActivity, fileToExport: File, then: ((password: String) -> Unit)) {
if (!assureMasterPasswordSet(activity, R.string.nav_export)) return if (!assureMasterPasswordSet(activity, R.string.nav_export)) return
TwoMessagesAlertDialog.showAlert(activity, rh.gs(R.string.nav_export), TwoMessagesAlertDialog.showAlert(
activity, rh.gs(R.string.nav_export),
rh.gs(R.string.export_to) + " " + fileToExport.name + " ?", rh.gs(R.string.export_to) + " " + fileToExport.name + " ?",
rh.gs(R.string.password_preferences_encrypt_prompt), { rh.gs(R.string.password_preferences_encrypt_prompt), {
askForMasterPassIfNeeded(activity, R.string.preferences_export_canceled, then) askForMasterPassIfNeeded(activity, R.string.preferences_export_canceled, then)
}, null, R.drawable.ic_header_export) }, null, R.drawable.ic_header_export
)
} }
private fun askToConfirmImport(activity: FragmentActivity, fileToImport: PrefsFile, then: ((password: String) -> Unit)) { private fun askToConfirmImport(activity: FragmentActivity, fileToImport: PrefsFile, then: ((password: String) -> Unit)) {
if (!assureMasterPasswordSet(activity, R.string.nav_import)) return if (!assureMasterPasswordSet(activity, R.string.nav_import)) return
TwoMessagesAlertDialog.showAlert(activity, rh.gs(R.string.nav_import), TwoMessagesAlertDialog.showAlert(
activity, rh.gs(R.string.nav_import),
rh.gs(R.string.import_from) + " " + fileToImport.name + " ?", rh.gs(R.string.import_from) + " " + fileToImport.name + " ?",
rh.gs(R.string.password_preferences_decrypt_prompt), { rh.gs(R.string.password_preferences_decrypt_prompt), {
askForMasterPass(activity, R.string.preferences_import_canceled, then) askForMasterPass(activity, R.string.preferences_import_canceled, then)
}, null, R.drawable.ic_header_import) }, null, R.drawable.ic_header_import
)
} }
private fun promptForDecryptionPasswordIfNeeded(activity: FragmentActivity, prefs: Prefs, importOk: Boolean, private fun promptForDecryptionPasswordIfNeeded(
format: PrefsFormat, importFile: PrefsFile, then: ((prefs: Prefs, importOk: Boolean) -> Unit)) { activity: FragmentActivity, prefs: Prefs, importOk: Boolean,
format: PrefsFormat, importFile: PrefsFile, then: ((prefs: Prefs, importOk: Boolean) -> Unit)
) {
// current master password was not the one used for decryption, so we prompt for old password... // current master password was not the one used for decryption, so we prompt for old password...
if (!importOk && (prefs.metadata[PrefsMetadataKey.ENCRYPTION]?.status == PrefsStatus.ERROR)) { if (!importOk && (prefs.metadata[PrefsMetadataKey.ENCRYPTION]?.status == PrefsStatus.ERROR)) {
askForEncryptionPass(activity, R.string.preferences_import_canceled, R.string.old_master_password, askForEncryptionPass(
R.string.different_password_used, R.string.master_password_will_be_replaced) { password -> activity, R.string.preferences_import_canceled, R.string.old_master_password,
R.string.different_password_used, R.string.master_password_will_be_replaced
) { password ->
// ...and use it to load & decrypt file again // ...and use it to load & decrypt file again
val prefsReloaded = format.loadPreferences(importFile.file, password) val prefsReloaded = format.loadPreferences(importFile.file, password)
@ -232,15 +238,19 @@ class ImportExportPrefsImpl @Inject constructor(
ToastUtils.errorToast(activity, e.message) ToastUtils.errorToast(activity, e.message)
log.error(LTag.CORE, "Unhandled exception", e) log.error(LTag.CORE, "Unhandled exception", e)
} catch (e: PrefFileNotFoundError) { } catch (e: PrefFileNotFoundError) {
ToastUtils.Long.errorToast(activity, rh.gs(R.string.preferences_export_canceled) ToastUtils.Long.errorToast(
activity, rh.gs(R.string.preferences_export_canceled)
+ "\n\n" + rh.gs(R.string.filenotfound) + "\n\n" + rh.gs(R.string.filenotfound)
+ ": " + e.message + ": " + e.message
+ "\n\n" + rh.gs(R.string.needstoragepermission)) + "\n\n" + rh.gs(R.string.needstoragepermission)
)
log.error(LTag.CORE, "File system exception", e) log.error(LTag.CORE, "File system exception", e)
} catch (e: PrefIOError) { } catch (e: PrefIOError) {
ToastUtils.Long.errorToast(activity, rh.gs(R.string.preferences_export_canceled) ToastUtils.Long.errorToast(
activity, rh.gs(R.string.preferences_export_canceled)
+ "\n\n" + rh.gs(R.string.needstoragepermission) + "\n\n" + rh.gs(R.string.needstoragepermission)
+ ": " + e.message) + ": " + e.message
)
log.error(LTag.CORE, "File system exception", e) log.error(LTag.CORE, "File system exception", e)
} }
} }

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.queue package info.nightscout.androidaps.queue
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothManager
import android.content.Context import android.content.Context
import android.os.PowerManager import android.os.PowerManager
import android.os.SystemClock import android.os.SystemClock
@ -9,18 +9,18 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning
import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.queue.events.EventQueueChanged
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
class QueueThread internal constructor( class QueueThread internal constructor(
private val queue: CommandQueue, private val queue: CommandQueue,
context: Context, private val context: Context,
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val rxBus: RxBus, private val rxBus: RxBus,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
@ -63,8 +63,7 @@ class QueueThread internal constructor(
//toggle BT //toggle BT
pump.disconnect("watchdog") pump.disconnect("watchdog")
SystemClock.sleep(1000) SystemClock.sleep(1000)
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter?.let { bluetoothAdapter ->
if (bluetoothAdapter != null) {
bluetoothAdapter.disable() bluetoothAdapter.disable()
SystemClock.sleep(1000) SystemClock.sleep(1000)
bluetoothAdapter.enable() bluetoothAdapter.enable()

View file

@ -74,7 +74,7 @@ class TriggerBTDevice(injector: HasAndroidInjector) : Trigger(injector) {
// Get the list of paired BT devices to use in dropdown menu // Get the list of paired BT devices to use in dropdown menu
private fun devicesPaired(): ArrayList<CharSequence> { private fun devicesPaired(): ArrayList<CharSequence> {
val s = ArrayList<CharSequence>() val s = ArrayList<CharSequence>()
(context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter?.bondedDevices?.forEach { s.add(it.name) } (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter?.bondedDevices?.forEach { s.add(it.name) }
return s return s
} }

View file

@ -7,6 +7,8 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application> <application>
<activity android:name="info.nightscout.androidaps.activities.TDDStatsActivity" /> <activity android:name="info.nightscout.androidaps.activities.TDDStatsActivity" />
<activity <activity

View file

@ -130,6 +130,7 @@ class BolusProgressDialog : DaggerDialogFragment() {
.toObservable(EventDismissBolusProgressIfRunning::class.java) .toObservable(EventDismissBolusProgressIfRunning::class.java)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ .subscribe({
aapsLogger.debug(LTag.PUMP, "Running timestamp $timestamp. Close request timestamp ${it.bolusTimestamp}")
if (it.bolusTimestamp == null || it.bolusTimestamp == timestamp) if (it.bolusTimestamp == null || it.bolusTimestamp == timestamp)
if (running) dismiss() if (running) dismiss()
}, fabricPrivacy::logException) }, fabricPrivacy::logException)

View file

@ -6,6 +6,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.location.LocationManager import android.location.LocationManager
import android.os.Build
import android.os.SystemClock
import android.provider.Settings import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
@ -23,7 +25,9 @@ class BlePreCheck @Inject constructor(
) { ) {
companion object { companion object {
private const val PERMISSION_REQUEST_COARSE_LOCATION = 30241 // arbitrary. private const val PERMISSION_REQUEST_COARSE_LOCATION = 30241 // arbitrary.
private const val PERMISSION_REQUEST_BLUETOOTH = 30242 // arbitrary.
} }
fun prerequisitesCheck(activity: AppCompatActivity): Boolean { fun prerequisitesCheck(activity: AppCompatActivity): Boolean {
@ -37,11 +41,20 @@ class BlePreCheck @Inject constructor(
// your code that requires permission // your code that requires permission
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSION_REQUEST_COARSE_LOCATION) ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSION_REQUEST_COARSE_LOCATION)
} }
// change after SDK = 31+
if (Build.VERSION.SDK_INT >= /*Build.VERSION_CODES.S*/31) {
//ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT), PERMISSION_REQUEST_BLUETOOTH)
ActivityCompat.requestPermissions(activity, arrayOf("android.permission.BLUETOOTH_SCAN", "android.permission.BLUETOOTH_CONNECT"), PERMISSION_REQUEST_BLUETOOTH)
}
val bluetoothAdapter = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter val bluetoothAdapter = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
// Ensures Bluetooth is available on the device and it is enabled. If not, // Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth. // displays a dialog requesting user permission to enable Bluetooth.
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled) { if (bluetoothAdapter?.isEnabled != true) {
bluetoothAdapter?.enable()
SystemClock.sleep(3000)
}
if (bluetoothAdapter?.isEnabled != true) {
OKDialog.show(activity, rh.gs(R.string.message), rh.gs(R.string.ble_not_enabled)) OKDialog.show(activity, rh.gs(R.string.message), rh.gs(R.string.ble_not_enabled))
return false return false
} else { } else {

View file

@ -3,6 +3,8 @@
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<application> <application>
<service <service
android:name="info.nightscout.androidaps.danar.services.DanaRExecutionService" android:name="info.nightscout.androidaps.danar.services.DanaRExecutionService"

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.danar.services;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -190,7 +191,7 @@ public abstract class AbstractDanaRExecutionService extends DaggerService {
protected void getBTSocketForSelectedPump() { protected void getBTSocketForSelectedPump() {
mDevName = sp.getString(R.string.key_danar_bt_name, ""); mDevName = sp.getString(R.string.key_danar_bt_name, "");
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothAdapter bluetoothAdapter = ((BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
if (bluetoothAdapter != null) { if (bluetoothAdapter != null) {
Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices(); Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();

View file

@ -3,9 +3,11 @@ package info.nightscout.androidaps.danars.activities
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult import android.bluetooth.le.ScanResult
import android.content.Context
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -30,10 +32,12 @@ class BLEScanActivity : NoSplashAppCompatActivity() {
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var blePreCheck: BlePreCheck @Inject lateinit var blePreCheck: BlePreCheck
@Inject lateinit var context: Context
private var listAdapter: ListAdapter? = null private var listAdapter: ListAdapter? = null
private val devices = ArrayList<BluetoothDeviceItem>() private val devices = ArrayList<BluetoothDeviceItem>()
private var bluetoothLeScanner: BluetoothLeScanner? = null private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private val bluetoothLeScanner: BluetoothLeScanner? get() = bluetoothAdapter?.bluetoothLeScanner
private lateinit var binding: DanarsBlescannerActivityBinding private lateinit var binding: DanarsBlescannerActivityBinding
@ -55,12 +59,9 @@ class BLEScanActivity : NoSplashAppCompatActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
BluetoothAdapter.getDefaultAdapter()?.let { bluetoothAdapter -> if (bluetoothAdapter?.isEnabled != true) bluetoothAdapter?.enable()
if (!bluetoothAdapter.isEnabled) bluetoothAdapter.enable()
bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
startScan() startScan()
} }
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()

View file

@ -21,8 +21,6 @@ import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.extensions.notify import info.nightscout.androidaps.extensions.notify
import info.nightscout.androidaps.extensions.waitMillis import info.nightscout.androidaps.extensions.waitMillis
import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
@ -31,6 +29,8 @@ import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import java.util.* import java.util.*
import java.util.concurrent.ScheduledFuture import java.util.concurrent.ScheduledFuture
@ -69,8 +69,7 @@ class BLEComm @Inject internal constructor(
private var scheduledDisconnection: ScheduledFuture<*>? = null private var scheduledDisconnection: ScheduledFuture<*>? = null
private var processedMessage: DanaRSPacket? = null private var processedMessage: DanaRSPacket? = null
private val mSendQueue = ArrayList<ByteArray>() private val mSendQueue = ArrayList<ByteArray>()
private var bluetoothManager: BluetoothManager? = null private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private var bluetoothAdapter: BluetoothAdapter? = null
private var connectDeviceName: String? = null private var connectDeviceName: String? = null
private var bluetoothGatt: BluetoothGatt? = null private var bluetoothGatt: BluetoothGatt? = null
@ -92,14 +91,6 @@ class BLEComm @Inject internal constructor(
@Synchronized @Synchronized
fun connect(from: String, address: String?): Boolean { fun connect(from: String, address: String?): Boolean {
aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing BLEComm.") aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing BLEComm.")
if (bluetoothManager == null) {
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
if (bluetoothManager == null) {
aapsLogger.error("Unable to initialize BluetoothManager.")
return false
}
}
bluetoothAdapter = bluetoothManager?.adapter
if (bluetoothAdapter == null) { if (bluetoothAdapter == null) {
aapsLogger.error("Unable to obtain a BluetoothAdapter.") aapsLogger.error("Unable to obtain a BluetoothAdapter.")
return false return false
@ -411,7 +402,8 @@ class BLEComm @Inject internal constructor(
if (bufferLength >= 6) { if (bufferLength >= 6) {
for (idxStartByte in 0 until bufferLength - 2) { for (idxStartByte in 0 until bufferLength - 2) {
if (readBuffer[idxStartByte] == PACKET_START_BYTE && readBuffer[idxStartByte + 1] == PACKET_START_BYTE || if (readBuffer[idxStartByte] == PACKET_START_BYTE && readBuffer[idxStartByte + 1] == PACKET_START_BYTE ||
readBuffer[idxStartByte] == BLE5_PACKET_START_BYTE && readBuffer[idxStartByte + 1] == BLE5_PACKET_START_BYTE) { readBuffer[idxStartByte] == BLE5_PACKET_START_BYTE && readBuffer[idxStartByte + 1] == BLE5_PACKET_START_BYTE
) {
if (idxStartByte > 0) { if (idxStartByte > 0) {
// if buffer doesn't start with signature remove the leading trash // if buffer doesn't start with signature remove the leading trash
aapsLogger.debug(LTag.PUMPBTCOMM, "Shifting the input buffer by $idxStartByte bytes") aapsLogger.debug(LTag.PUMPBTCOMM, "Shifting the input buffer by $idxStartByte bytes")
@ -429,7 +421,8 @@ class BLEComm @Inject internal constructor(
return return
// Verify packed end [5A 5A] // Verify packed end [5A 5A]
if (readBuffer[length + 5] == PACKET_END_BYTE && readBuffer[length + 6] == PACKET_END_BYTE || if (readBuffer[length + 5] == PACKET_END_BYTE && readBuffer[length + 6] == PACKET_END_BYTE ||
readBuffer[length + 5] == BLE5_PACKET_END_BYTE && readBuffer[length + 6] == BLE5_PACKET_END_BYTE) { readBuffer[length + 5] == BLE5_PACKET_END_BYTE && readBuffer[length + 6] == BLE5_PACKET_END_BYTE
) {
packetIsValid = true packetIsValid = true
} else { } else {
aapsLogger.error(LTag.PUMPBTCOMM, "Error in input data. Resetting buffer.") aapsLogger.error(LTag.PUMPBTCOMM, "Error in input data. Resetting buffer.")

View file

@ -5,6 +5,10 @@
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<application> <application>
<activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8HistoryActivity" /> <activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8HistoryActivity" />
<activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8UserOptionsActivity" /> <activity android:name="info.nightscout.androidaps.diaconn.activities.DiaconnG8UserOptionsActivity" />

View file

@ -3,11 +3,13 @@ package info.nightscout.androidaps.diaconn.activities
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanFilter import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanResult import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings import android.bluetooth.le.ScanSettings
import android.content.Context
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -32,7 +34,9 @@ class DiaconnG8BLEScanActivity : NoSplashAppCompatActivity() {
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBus @Inject lateinit var rxBus: RxBus
@Inject lateinit var blePreCheck: BlePreCheck @Inject lateinit var blePreCheck: BlePreCheck
@Inject lateinit var context: Context
private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private var listAdapter: ListAdapter? = null private var listAdapter: ListAdapter? = null
private val devices = ArrayList<BluetoothDeviceItem>() private val devices = ArrayList<BluetoothDeviceItem>()
private var bluetoothLeScanner: BluetoothLeScanner? = null private var bluetoothLeScanner: BluetoothLeScanner? = null
@ -58,7 +62,7 @@ class DiaconnG8BLEScanActivity : NoSplashAppCompatActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
BluetoothAdapter.getDefaultAdapter()?.let { bluetoothAdapter -> bluetoothAdapter?.let { bluetoothAdapter ->
if (!bluetoothAdapter.isEnabled) bluetoothAdapter.enable() if (!bluetoothAdapter.isEnabled) bluetoothAdapter.enable()
bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
startScan() startScan()

View file

@ -44,8 +44,7 @@ class BLECommonService @Inject internal constructor(
private var processedMessage: DiaconnG8Packet? = null private var processedMessage: DiaconnG8Packet? = null
private var processedMessageByte: ByteArray? = null private var processedMessageByte: ByteArray? = null
private val mSendQueue = ArrayList<ByteArray>() private val mSendQueue = ArrayList<ByteArray>()
private var bluetoothManager: BluetoothManager? = null private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private var bluetoothAdapter: BluetoothAdapter? = null
private var connectDeviceName: String? = null private var connectDeviceName: String? = null
private var bluetoothGatt: BluetoothGatt? = null private var bluetoothGatt: BluetoothGatt? = null
@ -69,14 +68,6 @@ class BLECommonService @Inject internal constructor(
@Synchronized @Synchronized
fun connect(from: String, address: String?): Boolean { fun connect(from: String, address: String?): Boolean {
aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing Bluetooth ") aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing Bluetooth ")
if (bluetoothManager == null) {
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
if (bluetoothManager == null) {
aapsLogger.error("Unable to initialize BluetoothManager.")
return false
}
}
bluetoothAdapter = bluetoothManager?.adapter
if (bluetoothAdapter == null) { if (bluetoothAdapter == null) {
aapsLogger.error("Unable to obtain a BluetoothAdapter.") aapsLogger.error("Unable to obtain a BluetoothAdapter.")
return false return false

View file

@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.nightscout.androidaps.insight"> package="info.nightscout.androidaps.insight">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<application> <application>
<activity <activity

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.pump.insight.activities;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@ -25,14 +26,20 @@ import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.inject.Inject;
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity; import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
import info.nightscout.androidaps.insight.R; import info.nightscout.androidaps.insight.R;
import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck;
import info.nightscout.androidaps.plugins.pump.insight.connection_service.InsightConnectionService; import info.nightscout.androidaps.plugins.pump.insight.connection_service.InsightConnectionService;
import info.nightscout.androidaps.plugins.pump.insight.descriptors.InsightState; import info.nightscout.androidaps.plugins.pump.insight.descriptors.InsightState;
import info.nightscout.androidaps.plugins.pump.insight.utils.ExceptionTranslator; import info.nightscout.androidaps.plugins.pump.insight.utils.ExceptionTranslator;
public class InsightPairingActivity extends NoSplashAppCompatActivity implements InsightConnectionService.StateCallback, View.OnClickListener, InsightConnectionService.ExceptionCallback { public class InsightPairingActivity extends NoSplashAppCompatActivity implements InsightConnectionService.StateCallback, View.OnClickListener, InsightConnectionService.ExceptionCallback {
@Inject BlePreCheck blePreCheck;
@Inject Context context;
private boolean scanning; private boolean scanning;
private LinearLayout deviceSearchSection; private LinearLayout deviceSearchSection;
private TextView pleaseWaitSection; private TextView pleaseWaitSection;
@ -71,6 +78,8 @@ public class InsightPairingActivity extends NoSplashAppCompatActivity implements
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insight_pairing); setContentView(R.layout.activity_insight_pairing);
blePreCheck.prerequisitesCheck(this);
deviceSearchSection = findViewById(R.id.device_search_section); deviceSearchSection = findViewById(R.id.device_search_section);
pleaseWaitSection = findViewById(R.id.please_wait_section); pleaseWaitSection = findViewById(R.id.please_wait_section);
codeCompareSection = findViewById(R.id.code_compare_section); codeCompareSection = findViewById(R.id.code_compare_section);
@ -160,7 +169,7 @@ public class InsightPairingActivity extends NoSplashAppCompatActivity implements
private void startBLScan() { private void startBLScan() {
if (!scanning) { if (!scanning) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothAdapter bluetoothAdapter = ((BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
if (bluetoothAdapter != null) { if (bluetoothAdapter != null) {
if (!bluetoothAdapter.isEnabled()) bluetoothAdapter.enable(); if (!bluetoothAdapter.isEnabled()) bluetoothAdapter.enable();
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
@ -176,7 +185,7 @@ public class InsightPairingActivity extends NoSplashAppCompatActivity implements
private void stopBLScan() { private void stopBLScan() {
if (scanning) { if (scanning) {
unregisterReceiver(broadcastReceiver); unregisterReceiver(broadcastReceiver);
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothAdapter bluetoothAdapter = ((BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
if (bluetoothAdapter != null) { if (bluetoothAdapter != null) {
bluetoothAdapter.cancelDiscovery(); bluetoothAdapter.cancelDiscovery();
} }
@ -204,7 +213,7 @@ public class InsightPairingActivity extends NoSplashAppCompatActivity implements
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED))
BluetoothAdapter.getDefaultAdapter().startDiscovery(); ((BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter().startDiscovery();
else if (action.equals(BluetoothDevice.ACTION_FOUND)) { else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
deviceAdapter.addDevice(bluetoothDevice); deviceAdapter.addDevice(bluetoothDevice);

View file

@ -2,7 +2,9 @@ package info.nightscout.androidaps.plugins.pump.insight.connection_service;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
@ -106,7 +108,8 @@ public class InsightConnectionService extends DaggerService implements Connectio
private DelayedActionThread disconnectTimer; private DelayedActionThread disconnectTimer;
private DelayedActionThread recoveryTimer; private DelayedActionThread recoveryTimer;
private DelayedActionThread timeoutTimer; private DelayedActionThread timeoutTimer;
private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); private final BluetoothAdapter bluetoothAdapter =
((BluetoothManager)getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter();
private BluetoothDevice bluetoothDevice; private BluetoothDevice bluetoothDevice;
private BluetoothSocket bluetoothSocket; private BluetoothSocket bluetoothSocket;
private ConnectionEstablisher connectionEstablisher; private ConnectionEstablisher connectionEstablisher;

View file

@ -97,7 +97,7 @@ class MedtronicFragment : DaggerFragment() {
binding.pumpStatusIcon.text = "{fa-bed}" binding.pumpStatusIcon.text = "{fa-bed}"
binding.history.setOnClickListener { binding.history.setOnClickListener {
if (medtronicPumpPlugin.rileyLinkService.verifyConfiguration()) { if (medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() == true) {
startActivity(Intent(context, MedtronicHistoryActivity::class.java)) startActivity(Intent(context, MedtronicHistoryActivity::class.java))
} else { } else {
displayNotConfiguredDialog() displayNotConfiguredDialog()
@ -105,7 +105,7 @@ class MedtronicFragment : DaggerFragment() {
} }
binding.refresh.setOnClickListener { binding.refresh.setOnClickListener {
if (!medtronicPumpPlugin.rileyLinkService.verifyConfiguration()) { if (medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() != true) {
displayNotConfiguredDialog() displayNotConfiguredDialog()
} else { } else {
binding.refresh.isEnabled = false binding.refresh.isEnabled = false
@ -119,7 +119,7 @@ class MedtronicFragment : DaggerFragment() {
} }
binding.stats.setOnClickListener { binding.stats.setOnClickListener {
if (medtronicPumpPlugin.rileyLinkService.verifyConfiguration()) { if (medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() == true) {
startActivity(Intent(context, RileyLinkStatusActivity::class.java)) startActivity(Intent(context, RileyLinkStatusActivity::class.java))
} else { } else {
displayNotConfiguredDialog() displayNotConfiguredDialog()
@ -159,7 +159,7 @@ class MedtronicFragment : DaggerFragment() {
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)
.subscribe({ .subscribe({
aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered") aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered")
medtronicPumpPlugin.rileyLinkService.verifyConfiguration() medtronicPumpPlugin.rileyLinkService?.verifyConfiguration()
updateGUI() updateGUI()
}, fabricPrivacy::logException) }, fabricPrivacy::logException)
disposable += rxBus disposable += rxBus
@ -191,7 +191,7 @@ class MedtronicFragment : DaggerFragment() {
@Synchronized @Synchronized
private fun setDeviceStatus() { private fun setDeviceStatus() {
val resourceId = rileyLinkServiceData.rileyLinkServiceState.resourceId val resourceId = rileyLinkServiceData.rileyLinkServiceState.resourceId
val rileyLinkError = medtronicPumpPlugin.rileyLinkService.error val rileyLinkError = medtronicPumpPlugin.rileyLinkService?.error
binding.rlStatus.text = binding.rlStatus.text =
when { when {
rileyLinkServiceData.rileyLinkServiceState == RileyLinkServiceState.NotStarted -> rh.gs(resourceId) rileyLinkServiceData.rileyLinkServiceState == RileyLinkServiceState.NotStarted -> rh.gs(resourceId)
@ -337,7 +337,7 @@ class MedtronicFragment : DaggerFragment() {
binding.reservoir.text = rh.gs(R.string.reservoirvalue, medtronicPumpStatus.reservoirRemainingUnits, medtronicPumpStatus.reservoirFullUnits) binding.reservoir.text = rh.gs(R.string.reservoirvalue, medtronicPumpStatus.reservoirRemainingUnits, medtronicPumpStatus.reservoirFullUnits)
warnColors.setColorInverse(binding.reservoir, medtronicPumpStatus.reservoirRemainingUnits, 50.0, 20.0) warnColors.setColorInverse(binding.reservoir, medtronicPumpStatus.reservoirRemainingUnits, 50.0, 20.0)
medtronicPumpPlugin.rileyLinkService.verifyConfiguration() medtronicPumpPlugin.rileyLinkService?.verifyConfiguration()
binding.errors.text = medtronicPumpStatus.errorInfo binding.errors.text = medtronicPumpStatus.errorInfo
val showRileyLinkBatteryLevel: Boolean = rileyLinkServiceData.showBatteryLevel val showRileyLinkBatteryLevel: Boolean = rileyLinkServiceData.showBatteryLevel

View file

@ -13,14 +13,13 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventRefreshOverview import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.PumpSync.TemporaryBasalType import info.nightscout.androidaps.interfaces.PumpSync.TemporaryBasalType
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState
@ -33,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.ServiceTaskExecutor
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.tasks.WakeAndTuneTask
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryTBR
import info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncEntriesCreator
import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil
import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil import info.nightscout.androidaps.plugins.pump.common.utils.ProfileUtil
import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry import info.nightscout.androidaps.plugins.pump.medtronic.comm.history.pump.PumpHistoryEntry
@ -56,6 +56,8 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.TimeChangeType
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.joda.time.LocalDateTime import org.joda.time.LocalDateTime
import java.util.* import java.util.*
@ -89,7 +91,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsSchedulers: AapsSchedulers, aapsSchedulers: AapsSchedulers,
pumpSync: PumpSync, pumpSync: PumpSync,
pumpSyncStorage: info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage pumpSyncStorage: info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage
) : info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract(PluginDescription() // ) : PumpPluginAbstract(PluginDescription() //
.mainType(PluginType.PUMP) // .mainType(PluginType.PUMP) //
.fragmentClass(MedtronicFragment::class.java.name) // .fragmentClass(MedtronicFragment::class.java.name) //
.pluginIcon(R.drawable.ic_veo_128) .pluginIcon(R.drawable.ic_veo_128)
@ -99,9 +101,9 @@ class MedtronicPumpPlugin @Inject constructor(
.description(R.string.description_pump_medtronic), // .description(R.string.description_pump_medtronic), //
PumpType.MEDTRONIC_522_722, // we default to most basic model, correct model from config is loaded later PumpType.MEDTRONIC_522_722, // we default to most basic model, correct model from config is loaded later
injector, rh, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil, aapsSchedulers, pumpSync, pumpSyncStorage injector, rh, aapsLogger, commandQueue, rxBus, activePlugin, sp, context, fabricPrivacy, dateUtil, aapsSchedulers, pumpSync, pumpSyncStorage
), Pump, RileyLinkPumpDevice, info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncEntriesCreator { ), Pump, RileyLinkPumpDevice, PumpSyncEntriesCreator {
private lateinit var rileyLinkMedtronicService: RileyLinkMedtronicService private var rileyLinkMedtronicService: RileyLinkMedtronicService? = null
// variables for handling statuses and history // variables for handling statuses and history
private var firstRun = true private var firstRun = true
@ -126,12 +128,12 @@ class MedtronicPumpPlugin @Inject constructor(
val mLocalBinder = service as RileyLinkMedtronicService.LocalBinder val mLocalBinder = service as RileyLinkMedtronicService.LocalBinder
rileyLinkMedtronicService = mLocalBinder.serviceInstance rileyLinkMedtronicService = mLocalBinder.serviceInstance
isServiceSet = true isServiceSet = true
rileyLinkMedtronicService.verifyConfiguration() rileyLinkMedtronicService?.verifyConfiguration()
Thread { Thread {
for (i in 0..19) { for (i in 0..19) {
SystemClock.sleep(5000) SystemClock.sleep(5000)
aapsLogger.debug(LTag.PUMP, "Starting Medtronic-RileyLink service") aapsLogger.debug(LTag.PUMP, "Starting Medtronic-RileyLink service")
if (rileyLinkMedtronicService.setNotInPreInit()) { if (rileyLinkMedtronicService?.setNotInPreInit() == true) {
break break
} }
} }
@ -232,9 +234,7 @@ class MedtronicPumpPlugin @Inject constructor(
// Pump Plugin // Pump Plugin
private var isServiceSet: Boolean = false private var isServiceSet: Boolean = false
override fun getRileyLinkService(): RileyLinkMedtronicService { override fun getRileyLinkService(): RileyLinkMedtronicService? = rileyLinkMedtronicService
return rileyLinkMedtronicService
}
override fun getPumpInfo(): RileyLinkPumpInfo { override fun getPumpInfo(): RileyLinkPumpInfo {
val frequency = rh.gs(if (medtronicPumpStatus.pumpFrequency == "medtronic_pump_frequency_us_ca") R.string.medtronic_pump_frequency_us_ca else R.string.medtronic_pump_frequency_worldwide) val frequency = rh.gs(if (medtronicPumpStatus.pumpFrequency == "medtronic_pump_frequency_us_ca") R.string.medtronic_pump_frequency_us_ca else R.string.medtronic_pump_frequency_worldwide)
@ -294,12 +294,12 @@ class MedtronicPumpPlugin @Inject constructor(
override fun isConnected(): Boolean { override fun isConnected(): Boolean {
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnected") if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnected")
return isServiceSet && rileyLinkMedtronicService.isInitialized return isServiceSet && rileyLinkMedtronicService?.isInitialized == true
} }
override fun isConnecting(): Boolean { override fun isConnecting(): Boolean {
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnecting") if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "MedtronicPumpPlugin::isConnecting")
return !isServiceSet || !rileyLinkMedtronicService.isInitialized return !isServiceSet || rileyLinkMedtronicService?.isInitialized != true
} }
override fun getPumpStatus(reason: String) { override fun getPumpStatus(reason: String) {
@ -330,7 +330,7 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.") aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.")
return false return false
} }
return !rileyLinkMedtronicService.deviceCommunicationManager.isDeviceReachable return rileyLinkMedtronicService?.deviceCommunicationManager?.isDeviceReachable != true
} }
private fun refreshAnyStatusThatNeedsToBeRefreshed() { private fun refreshAnyStatusThatNeedsToBeRefreshed() {
@ -369,13 +369,13 @@ class MedtronicPumpPlugin @Inject constructor(
} }
MedtronicStatusRefreshType.BatteryStatus, MedtronicStatusRefreshType.RemainingInsulin -> { MedtronicStatusRefreshType.BatteryStatus, MedtronicStatusRefreshType.RemainingInsulin -> {
rileyLinkMedtronicService.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
refreshTypesNeededToReschedule.add(key) refreshTypesNeededToReschedule.add(key)
resetTime = true resetTime = true
} }
MedtronicStatusRefreshType.Configuration -> { MedtronicStatusRefreshType.Configuration -> {
rileyLinkMedtronicService.medtronicUIComm.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(key.getCommandType(medtronicUtil.medtronicPumpModel)!!)
resetTime = true resetTime = true
} }
} }
@ -406,7 +406,7 @@ class MedtronicPumpPlugin @Inject constructor(
private fun initializePump(): Boolean { private fun initializePump(): Boolean {
if (!isServiceSet) return false if (!isServiceSet) return false
aapsLogger.info(LTag.PUMP, logPrefix + "initializePump - start") aapsLogger.info(LTag.PUMP, logPrefix + "initializePump - start")
rileyLinkMedtronicService.deviceCommunicationManager.setDoWakeUpBeforeCommand(false) rileyLinkMedtronicService?.deviceCommunicationManager?.setDoWakeUpBeforeCommand(false)
setRefreshButtonEnabled(false) setRefreshButtonEnabled(false)
if (isRefresh) { if (isRefresh) {
if (isPumpNotReachable) { if (isPumpNotReachable) {
@ -420,7 +420,7 @@ class MedtronicPumpPlugin @Inject constructor(
// model (once) // model (once)
if (!medtronicUtil.isModelSet) { if (!medtronicUtil.isModelSet) {
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.PumpModel) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.PumpModel)
} else { } else {
if (medtronicPumpStatus.medtronicDeviceType !== medtronicUtil.medtronicPumpModel) { if (medtronicPumpStatus.medtronicDeviceType !== medtronicUtil.medtronicPumpModel) {
aapsLogger.warn(LTag.PUMP, logPrefix + "Configured pump is not the same as one detected.") aapsLogger.warn(LTag.PUMP, logPrefix + "Configured pump is not the same as one detected.")
@ -434,19 +434,19 @@ class MedtronicPumpPlugin @Inject constructor(
readPumpHistory() readPumpHistory()
// remaining insulin (>50 = 4h; 50-20 = 1h; 15m) // remaining insulin (>50 = 4h; 50-20 = 1h; 15m)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetRemainingInsulin) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetRemainingInsulin)
scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10) scheduleNextRefresh(MedtronicStatusRefreshType.RemainingInsulin, 10)
// remaining power (1h) // remaining power (1h)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetBatteryStatus) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetBatteryStatus)
scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20) scheduleNextRefresh(MedtronicStatusRefreshType.BatteryStatus, 20)
// configuration (once and then if history shows config changes) // configuration (once and then if history shows config changes)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(getSettings(medtronicUtil.medtronicPumpModel)) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(getSettings(medtronicUtil.medtronicPumpModel))
// read profile (once, later its controlled by isThisProfileSet method) // read profile (once, later its controlled by isThisProfileSet method)
basalProfiles basalProfiles
val errorCount = rileyLinkMedtronicService.medtronicUIComm.invalidResponsesCount val errorCount = rileyLinkMedtronicService?.medtronicUIComm?.invalidResponsesCount ?: 0
if (errorCount >= 5) { if (errorCount >= 5) {
aapsLogger.error("Number of error counts was 5 or more. Starting tuning.") aapsLogger.error("Number of error counts was 5 or more. Starting tuning.")
setRefreshButtonEnabled(true) setRefreshButtonEnabled(true)
@ -466,9 +466,9 @@ class MedtronicPumpPlugin @Inject constructor(
private val basalProfiles: Unit private val basalProfiles: Unit
get() { get() {
val medtronicUITask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD) val medtronicUITask = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
if (medtronicUITask.responseType === MedtronicUIResponseType.Error) { if (medtronicUITask?.responseType === MedtronicUIResponseType.Error) {
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetBasalProfileSTD) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetBasalProfileSTD)
} }
} }
@ -558,10 +558,10 @@ class MedtronicPumpPlugin @Inject constructor(
return return
} }
medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus) medtronicUtil.dismissNotification(MedtronicNotificationType.PumpUnreachable, rxBus)
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetRealTimeClock)
var clock = medtronicUtil.pumpTime var clock = medtronicUtil.pumpTime
if (clock == null) { // retry if (clock == null) { // retry
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetRealTimeClock)
clock = medtronicUtil.pumpTime clock = medtronicUtil.pumpTime
} }
if (clock == null) return if (clock == null) return
@ -569,7 +569,7 @@ class MedtronicPumpPlugin @Inject constructor(
if (timeDiff > 20) { if (timeDiff > 20) {
if (clock.localDeviceTime.year <= 2015 || timeDiff <= 24 * 60 * 60) { if (clock.localDeviceTime.year <= 2015 || timeDiff <= 24 * 60 * 60) {
aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is %d s. Set time on pump.", timeDiff)) aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "MedtronicPumpPlugin::checkTimeAndOptionallySetTime - Time difference is %d s. Set time on pump.", timeDiff))
rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetRealTimeClock) rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.SetRealTimeClock)
if (clock.timeDifference == 0) { if (clock.timeDifference == 0) {
val notification = Notification(Notification.INSIGHT_DATE_TIME_UPDATED, rh.gs(R.string.pump_time_updated), Notification.INFO, 60) val notification = Notification(Notification.INSIGHT_DATE_TIME_UPDATED, rh.gs(R.string.pump_time_updated), Notification.INFO, 60)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
@ -619,9 +619,9 @@ class MedtronicPumpPlugin @Inject constructor(
bolusDeliveryType = BolusDeliveryType.Delivering bolusDeliveryType = BolusDeliveryType.Delivering
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery"); // LOG.debug("MedtronicPumpPlugin::deliverBolus - Start delivery");
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetBolus, val responseTask = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.SetBolus,
arrayListOf(detailedBolusInfo.insulin)) arrayListOf(detailedBolusInfo.insulin))
val response = responseTask.result as Boolean? val response = responseTask?.result as Boolean?
setRefreshButtonEnabled(true) setRefreshButtonEnabled(true)
// LOG.debug("MedtronicPumpPlugin::deliverBolus - Response: {}", response); // LOG.debug("MedtronicPumpPlugin::deliverBolus - Response: {}", response);
@ -639,8 +639,6 @@ class MedtronicPumpPlugin @Inject constructor(
}.start() }.start()
} }
val now = System.currentTimeMillis() val now = System.currentTimeMillis()
detailedBolusInfo.timestamp = now
detailedBolusInfo.deliverAtTheLatest = now // not sure about that one
pumpSyncStorage.addBolusWithTempId(detailedBolusInfo, true, this) pumpSyncStorage.addBolusWithTempId(detailedBolusInfo, true, this)
@ -743,8 +741,8 @@ class MedtronicPumpPlugin @Inject constructor(
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - TBR running - so canceling it.") aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - TBR running - so canceling it.")
// CANCEL // CANCEL
val responseTask2 = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR) val responseTask2 = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.CancelTBR)
val response = responseTask2.result as Boolean? val response = responseTask2?.result as Boolean?
if (response == null || !response) { if (response == null || !response) {
aapsLogger.error(logPrefix + "setTempBasalAbsolute - Cancel TBR failed.") aapsLogger.error(logPrefix + "setTempBasalAbsolute - Cancel TBR failed.")
finishAction("TBR") finishAction("TBR")
@ -757,9 +755,9 @@ class MedtronicPumpPlugin @Inject constructor(
} }
// now start new TBR // now start new TBR
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetTemporaryBasal, val responseTask = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.SetTemporaryBasal,
arrayListOf(absoluteRate, durationInMinutes)) arrayListOf(absoluteRate, durationInMinutes))
val response = responseTask.result as Boolean? val response = responseTask?.result as Boolean?
aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - setTBR. Response: " + response) aapsLogger.info(LTag.PUMP, logPrefix + "setTempBasalAbsolute - setTBR. Response: " + response)
return if (response == null || !response) { return if (response == null || !response) {
finishAction("TBR") finishAction("TBR")
@ -922,10 +920,10 @@ class MedtronicPumpPlugin @Inject constructor(
//aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate); //aapsLogger.debug(LTag.PUMP, "HST: Target Date: " + targetDate);
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val responseTask2 = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.GetHistoryData, val responseTask2 = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.GetHistoryData,
arrayListOf(/*lastPumpHistoryEntry*/ null, targetDate) as? ArrayList<Any>?) arrayListOf(/*lastPumpHistoryEntry*/ null, targetDate) as? ArrayList<Any>?)
if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: After task") if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: After task")
val historyResult = responseTask2.result as PumpHistoryResult? val historyResult = responseTask2?.result as PumpHistoryResult?
if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: History Result: " + historyResult.toString()) if (debugHistory) aapsLogger.debug(LTag.PUMP, "HST: History Result: " + historyResult.toString())
val latestEntry = historyResult!!.latestEntry val latestEntry = historyResult!!.latestEntry
if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "Last entry: " + latestEntry) if (debugHistory) aapsLogger.debug(LTag.PUMP, logPrefix + "Last entry: " + latestEntry)
@ -1018,8 +1016,8 @@ class MedtronicPumpPlugin @Inject constructor(
} }
private fun readTBR(): TempBasalPair? { private fun readTBR(): TempBasalPair? {
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.ReadTemporaryBasal) val responseTask = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.ReadTemporaryBasal)
return if (responseTask.hasData()) { return if (responseTask?.hasData() == true) {
val tbr = responseTask.result as TempBasalPair? val tbr = responseTask.result as TempBasalPair?
// we sometimes get rate returned even if TBR is no longer running // we sometimes get rate returned even if TBR is no longer running
@ -1060,8 +1058,8 @@ class MedtronicPumpPlugin @Inject constructor(
return PumpEnactResult(injector).success(false).enacted(false) return PumpEnactResult(injector).success(false).enacted(false)
.comment(R.string.medtronic_cmd_cant_read_tbr) .comment(R.string.medtronic_cmd_cant_read_tbr)
} }
val responseTask2 = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.CancelTBR) val responseTask2 = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.CancelTBR)
val response = responseTask2.result as Boolean? val response = responseTask2?.result as Boolean?
finishAction("TBR") finishAction("TBR")
return if (response == null || !response) { return if (response == null || !response) {
aapsLogger.info(LTag.PUMP, logPrefix + "cancelTempBasal - Cancel TBR failed.") aapsLogger.info(LTag.PUMP, logPrefix + "cancelTempBasal - Cancel TBR failed.")
@ -1145,9 +1143,9 @@ class MedtronicPumpPlugin @Inject constructor(
.enacted(false) // .enacted(false) //
.comment(rh.gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid)) .comment(rh.gs(R.string.medtronic_cmd_set_profile_pattern_overflow, profileInvalid))
} }
val responseTask = rileyLinkMedtronicService.medtronicUIComm.executeCommand(MedtronicCommandType.SetBasalProfileSTD, val responseTask = rileyLinkMedtronicService?.medtronicUIComm?.executeCommand(MedtronicCommandType.SetBasalProfileSTD,
arrayListOf(basalProfile)) arrayListOf(basalProfile))
val response = responseTask.result as Boolean? val response = responseTask?.result as Boolean?
aapsLogger.info(LTag.PUMP, logPrefix + "Basal Profile was set: " + response) aapsLogger.info(LTag.PUMP, logPrefix + "Basal Profile was set: " + response)
return if (response == null || !response) { return if (response == null || !response) {
PumpEnactResult(injector).success(false).enacted(false) // PumpEnactResult(injector).success(false).enacted(false) //
@ -1203,7 +1201,7 @@ class MedtronicPumpPlugin @Inject constructor(
override fun executeCustomAction(customActionType: CustomActionType) { override fun executeCustomAction(customActionType: CustomActionType) {
when (customActionType as? MedtronicCustomActionType) { when (customActionType as? MedtronicCustomActionType) {
MedtronicCustomActionType.WakeUpAndTune -> { MedtronicCustomActionType.WakeUpAndTune -> {
if (rileyLinkMedtronicService.verifyConfiguration()) { if (rileyLinkMedtronicService?.verifyConfiguration() == true) {
serviceTaskExecutor.startTask(WakeAndTuneTask(injector)) serviceTaskExecutor.startTask(WakeAndTuneTask(injector))
} else { } else {
runAlarm(context, rh.gs(R.string.medtronic_error_operation_not_possible_no_configuration), rh.gs(R.string.medtronic_warning), R.raw.boluserror) runAlarm(context, rh.gs(R.string.medtronic_error_operation_not_possible_no_configuration), rh.gs(R.string.medtronic_warning), R.raw.boluserror)

View file

@ -148,7 +148,7 @@ class MedtronicUIPostprocessor @Inject constructor(
medtronicUtil.settings = settings medtronicUtil.settings = settings
var checkValue: PumpSettingDTO var checkValue: PumpSettingDTO
medtronicPumpPlugin.rileyLinkService.verifyConfiguration() medtronicPumpPlugin.rileyLinkService?.verifyConfiguration()
// check profile // check profile
if (settings.containsKey("PCFG_BASAL_PROFILES_ENABLED") && settings.containsKey("PCFG_ACTIVE_BASAL_PROFILE")) { if (settings.containsKey("PCFG_BASAL_PROFILES_ENABLED") && settings.containsKey("PCFG_ACTIVE_BASAL_PROFILE")) {

View file

@ -58,7 +58,7 @@ class MedtronicPumpStatus @Inject constructor(private val rh: ResourceHelper,
if (medtronicDeviceTypeMap.isEmpty()) createMedtronicDeviceTypeMap() if (medtronicDeviceTypeMap.isEmpty()) createMedtronicDeviceTypeMap()
lastConnection = sp.getLong(MedtronicConst.Statistics.LastGoodPumpCommunicationTime, 0L) lastConnection = sp.getLong(MedtronicConst.Statistics.LastGoodPumpCommunicationTime, 0L)
lastDataTime = lastConnection lastDataTime = lastConnection
var serial = sp.getStringOrNull(MedtronicConst.Prefs.PumpSerial, null) val serial = sp.getStringOrNull(MedtronicConst.Prefs.PumpSerial, null)
if (serial != null) { if (serial != null) {
serialNumber = serial serialNumber = serial
} }
@ -105,7 +105,7 @@ class MedtronicPumpStatus @Inject constructor(private val rh: ResourceHelper,
private var batteryTypeByDescMap: MutableMap<String, BatteryType?> = HashMap() private var batteryTypeByDescMap: MutableMap<String, BatteryType?> = HashMap()
fun getBatteryTypeByDescription(batteryTypeStr: String?): BatteryType? { fun getBatteryTypeByDescription(batteryTypeStr: String?): BatteryType? {
if (batteryTypeByDescMap.size == 0) { if (batteryTypeByDescMap.isEmpty()) {
for (value in BatteryType.values()) { for (value in BatteryType.values()) {
batteryTypeByDescMap[rh.gs(value.description)] = value batteryTypeByDescMap[rh.gs(value.description)] = value
} }

View file

@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

View file

@ -30,8 +30,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
) : OmnipodDashBleManager { ) : OmnipodDashBleManager {
private val busy = AtomicBoolean(false) private val busy = AtomicBoolean(false)
private val bluetoothAdapter: BluetoothAdapter? private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private var connection: Connection? = null private var connection: Connection? = null
private val ids = Ids(podState) private val ids = Ids(podState)

View file

@ -53,8 +53,7 @@ class Connection(
private val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets, this) private val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets, this)
private var gattConnection: BluetoothGatt? = null private var gattConnection: BluetoothGatt? = null
private val bluetoothManager: BluetoothManager = private val bluetoothManager: BluetoothManager? = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
@Volatile @Volatile
var session: Session? = null var session: Session? = null
@ -67,8 +66,7 @@ class Connection(
podState.connectionAttempts++ podState.connectionAttempts++
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING
val autoConnect = false val autoConnect = false
val gatt = gattConnection val gatt = gattConnection ?: podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
?: podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
gattConnection = gatt gattConnection = gatt
if (!gatt.connect()) { if (!gatt.connect()) {
throw FailedToConnectException("connect() returned false") throw FailedToConnectException("connect() returned false")
@ -150,7 +148,7 @@ class Connection(
} }
fun connectionState(): ConnectionState { fun connectionState(): ConnectionState {
val connectionState = bluetoothManager.getConnectionState(podDevice, BluetoothProfile.GATT) val connectionState = bluetoothManager?.getConnectionState(podDevice, BluetoothProfile.GATT)
aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: $connectionState") aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: $connectionState")
if (connectionState != BluetoothProfile.STATE_CONNECTED) { if (connectionState != BluetoothProfile.STATE_CONNECTED) {
return NotConnected return NotConnected

View file

@ -1,5 +1,17 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activation package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activation
import android.os.Bundle
import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.PodActivationWizardActivity import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.PodActivationWizardActivity
import javax.inject.Inject
class DashPodActivationWizardActivity : PodActivationWizardActivity() class DashPodActivationWizardActivity : PodActivationWizardActivity() {
@Inject lateinit var blePreCheck: BlePreCheck
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
blePreCheck.prerequisitesCheck(this)
}
}

View file

@ -4,9 +4,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
import android.text.format.DateFormat import android.text.format.DateFormat
import com.google.gson.GsonBuilder
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
@ -16,20 +14,21 @@ import info.nightscout.androidaps.extensions.plannedRemainingMinutes
import info.nightscout.androidaps.extensions.toStringFull import info.nightscout.androidaps.extensions.toStringFull
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.PumpSync.TemporaryBasalType import info.nightscout.androidaps.interfaces.PumpSync.TemporaryBasalType
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress import info.nightscout.androidaps.plugins.general.overview.events.EventOverviewBolusProgress
import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus
import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryCarbs
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal
import info.nightscout.androidaps.utils.DecimalFormatter.to2Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to2Decimal
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import org.json.JSONException import org.json.JSONException
@ -74,8 +73,6 @@ abstract class PumpPluginAbstract protected constructor(
pumpDescription.fillFor(value) pumpDescription.fillFor(value)
} }
protected var gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()
abstract fun initPumpStatusData() abstract fun initPumpStatusData()
override fun onStart() { override fun onStart() {
@ -113,17 +110,9 @@ abstract class PumpPluginAbstract protected constructor(
abstract val serviceClass: Class<*>? abstract val serviceClass: Class<*>?
abstract val pumpStatusData: PumpStatus abstract val pumpStatusData: PumpStatus
override fun isInitialized(): Boolean { override fun isInitialized(): Boolean = pumpState.isInitialized()
return pumpState.isInitialized() override fun isSuspended(): Boolean = pumpState == PumpDriverState.Suspended
} override fun isBusy(): Boolean = pumpState == PumpDriverState.Busy
override fun isSuspended(): Boolean {
return pumpState === PumpDriverState.Suspended
}
override fun isBusy(): Boolean {
return pumpState === PumpDriverState.Busy
}
override fun isConnected(): Boolean { override fun isConnected(): Boolean {
if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "isConnected [PumpPluginAbstract].") if (displayConnectionMessages) aapsLogger.debug(LTag.PUMP, "isConnected [PumpPluginAbstract].")
@ -335,10 +324,9 @@ abstract class PumpPluginAbstract protected constructor(
// bolus needed, ask pump to deliver it // bolus needed, ask pump to deliver it
deliverBolus(detailedBolusInfo) deliverBolus(detailedBolusInfo)
} else { } else {
detailedBolusInfo.timestamp = System.currentTimeMillis()
// no bolus required, carb only treatment // no bolus required, carb only treatment
pumpSyncStorage.addCarbs(info.nightscout.androidaps.plugins.pump.common.sync.PumpDbEntryCarbs(detailedBolusInfo, this)) pumpSyncStorage.addCarbs(PumpDbEntryCarbs(detailedBolusInfo, this))
val bolusingEvent = EventOverviewBolusProgress val bolusingEvent = EventOverviewBolusProgress
bolusingEvent.t = EventOverviewBolusProgress.Treatment(0.0, detailedBolusInfo.carbs.toInt(), detailedBolusInfo.bolusType === DetailedBolusInfo.BolusType.SMB) bolusingEvent.t = EventOverviewBolusProgress.Treatment(0.0, detailedBolusInfo.carbs.toInt(), detailedBolusInfo.bolusType === DetailedBolusInfo.BolusType.SMB)
@ -357,25 +345,16 @@ abstract class PumpPluginAbstract protected constructor(
rxBus.send(EventCustomActionsChanged()) rxBus.send(EventCustomActionsChanged())
} }
override fun manufacturer(): ManufacturerType { override fun manufacturer(): ManufacturerType = pumpType.manufacturer!!
return pumpType.manufacturer!! override fun model(): PumpType = pumpType
} override fun canHandleDST(): Boolean = false
override fun model(): PumpType {
return pumpType
}
override fun canHandleDST(): Boolean {
return false
}
protected abstract fun deliverBolus(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult protected abstract fun deliverBolus(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult
protected abstract fun triggerUIChange() protected abstract fun triggerUIChange()
private fun getOperationNotSupportedWithCustomText(resourceId: Int): PumpEnactResult { private fun getOperationNotSupportedWithCustomText(resourceId: Int): PumpEnactResult =
return PumpEnactResult(injector).success(false).enacted(false).comment(resourceId) PumpEnactResult(injector).success(false).enacted(false).comment(resourceId)
}
init { init {
pumpDescription.fillFor(pumpType) pumpDescription.fillFor(pumpType)

View file

@ -3,12 +3,15 @@
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
<application> <application>
<activity android:name="info.nightscout.androidaps.plugins.pump.common.dialog.RileyLinkBLEConfigActivity"> <activity android:name="info.nightscout.androidaps.plugins.pump.common.dialog.RileyLinkBLEConfigActivity">
<intent-filter> <intent-filter>

View file

@ -42,7 +42,8 @@ class RileyLinkBLE @Inject constructor(private val context: Context) {
private val gattDebugEnabled = true private val gattDebugEnabled = true
private var manualDisconnect = false private var manualDisconnect = false
val bluetoothAdapter: BluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private val bluetoothGattCallback: BluetoothGattCallback private val bluetoothGattCallback: BluetoothGattCallback
var rileyLinkDevice: BluetoothDevice? = null var rileyLinkDevice: BluetoothDevice? = null
private var bluetoothConnectionGatt: BluetoothGatt? = null private var bluetoothConnectionGatt: BluetoothGatt? = null
@ -128,7 +129,7 @@ class RileyLinkBLE @Inject constructor(private val context: Context) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Start scan for OrangeLink device.") aapsLogger.debug(LTag.PUMPBTCOMM, "Start scan for OrangeLink device.")
orangeLink.startScan() orangeLink.startScan()
} else { } else {
rileyLinkDevice = bluetoothAdapter.getRemoteDevice(rileyLinkAddress) rileyLinkDevice = bluetoothAdapter?.getRemoteDevice(rileyLinkAddress)
// if this succeeds, we get a connection state change callback? // if this succeeds, we get a connection state change callback?
if (rileyLinkDevice != null) connectGattInternal() if (rileyLinkDevice != null) connectGattInternal()
else aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device not found with address: $rileyLinkAddress") else aapsLogger.error(LTag.PUMPBTCOMM, "RileyLink device not found with address: $rileyLinkAddress")
@ -155,7 +156,7 @@ class RileyLinkBLE @Inject constructor(private val context: Context) {
bluetoothConnectionGatt = rileyLinkDevice?.connectGatt(context, true, bluetoothGattCallback) bluetoothConnectionGatt = rileyLinkDevice?.connectGatt(context, true, bluetoothGattCallback)
// , BluetoothDevice.TRANSPORT_LE // , BluetoothDevice.TRANSPORT_LE
if (bluetoothConnectionGatt == null) if (bluetoothConnectionGatt == null)
aapsLogger.error(LTag.PUMPBTCOMM, "Failed to connect to Bluetooth Low Energy device at " + bluetoothAdapter.address) aapsLogger.error(LTag.PUMPBTCOMM, "Failed to connect to Bluetooth Low Energy device at " + bluetoothAdapter?.address)
else { else {
if (gattDebugEnabled) aapsLogger.debug(LTag.PUMPBTCOMM, "Gatt Connected.") if (gattDebugEnabled) aapsLogger.debug(LTag.PUMPBTCOMM, "Gatt Connected.")
val deviceName = bluetoothConnectionGatt?.device?.name val deviceName = bluetoothConnectionGatt?.device?.name
@ -361,7 +362,7 @@ class RileyLinkBLE @Inject constructor(private val context: Context) {
} }
if (newState == BluetoothProfile.STATE_CONNECTED) { if (newState == BluetoothProfile.STATE_CONNECTED) {
if (status == BluetoothGatt.GATT_SUCCESS) rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.BluetoothConnected, context) if (status == BluetoothGatt.GATT_SUCCESS) rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.Intents.BluetoothConnected, context)
else aapsLogger.debug(LTag.PUMPBTCOMM, "BT State connected, GATT status ${status} (${getGattStatusMessage(status)})") else aapsLogger.debug(LTag.PUMPBTCOMM, "BT State connected, GATT status $status (${getGattStatusMessage(status)})")
} else if (newState == BluetoothProfile.STATE_CONNECTING || newState == BluetoothProfile.STATE_DISCONNECTING) { } else if (newState == BluetoothProfile.STATE_CONNECTING || newState == BluetoothProfile.STATE_DISCONNECTING) {
aapsLogger.debug(LTag.PUMPBTCOMM, "We are in ${if (status == BluetoothProfile.STATE_CONNECTING) "Connecting" else "Disconnecting"} state.") aapsLogger.debug(LTag.PUMPBTCOMM, "We are in ${if (status == BluetoothProfile.STATE_CONNECTING) "Connecting" else "Disconnecting"} state.")
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) { } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {

View file

@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.device
import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGattCharacteristic import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanFilter import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanResult import android.bluetooth.le.ScanResult
@ -10,14 +9,14 @@ import android.bluetooth.le.ScanSettings
import android.os.Handler import android.os.Handler
import android.os.HandlerThread import android.os.HandlerThread
import android.os.Message import android.os.Message
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.RileyLinkBLE
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -37,10 +36,7 @@ class OrangeLinkImpl @Inject constructor(
if (characteristic.uuid.toString() == GattAttributes.CHARA_NOTIFICATION_ORANGE) { if (characteristic.uuid.toString() == GattAttributes.CHARA_NOTIFICATION_ORANGE) {
val data = characteristic.value val data = characteristic.value
val first = 0xff and data[0].toInt() val first = 0xff and data[0].toInt()
aapsLogger.info( aapsLogger.info(LTag.PUMPBTCOMM, "OrangeLinkImpl: onCharacteristicChanged ${ByteUtil.shortHexString(characteristic.value)}=====$first")
LTag.PUMPBTCOMM,
"OrangeLinkImpl: onCharacteristicChanged " + ByteUtil.shortHexString(characteristic.value) + "=====" + first
)
val fv = data[3].toString() + "." + data[4] val fv = data[3].toString() + "." + data[4]
val hv = data[5].toString() + "." + data[6] val hv = data[5].toString() + "." + data[6]
rileyLinkServiceData.versionOrangeFirmware = fv rileyLinkServiceData.versionOrangeFirmware = fv
@ -60,10 +56,9 @@ class OrangeLinkImpl @Inject constructor(
* We are checking if this is special Orange (with ORANGE_NOTIFICATION_SERVICE) * We are checking if this is special Orange (with ORANGE_NOTIFICATION_SERVICE)
*/ */
fun checkIsOrange(uuidService: UUID) { fun checkIsOrange(uuidService: UUID) {
if (GattAttributes.isOrange(uuidService)) { if (GattAttributes.isOrange(uuidService))
rileyLinkServiceData.isOrange = true rileyLinkServiceData.isOrange = true
} }
}
fun enableNotifications(): Boolean { fun enableNotifications(): Boolean {
aapsLogger.info(LTag.PUMPBTCOMM, "OrangeLinkImpl::enableNotifications") aapsLogger.info(LTag.PUMPBTCOMM, "OrangeLinkImpl::enableNotifications")
@ -98,15 +93,14 @@ class OrangeLinkImpl @Inject constructor(
fun startScan() { fun startScan() {
try { try {
stopScan() stopScan()
val bluetoothAdapter = rileyLinkBLE.bluetoothAdapter
aapsLogger.debug(LTag.PUMPBTCOMM, "startScan") aapsLogger.debug(LTag.PUMPBTCOMM, "startScan")
handler.sendEmptyMessageDelayed(TIME_OUT_WHAT, TIME_OUT.toLong()) handler.sendEmptyMessageDelayed(TIME_OUT_WHAT, TIME_OUT.toLong())
val bluetoothLeScanner: BluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner val bluetoothLeScanner = rileyLinkBLE.bluetoothAdapter?.bluetoothLeScanner
// if (bluetoothLeScanner == null) { // if (bluetoothLeScanner == null) {
// bluetoothAdapter.startLeScan(mLeScanCallback) // bluetoothAdapter.startLeScan(mLeScanCallback)
// return // return
// } // }
bluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), scanCallback) bluetoothLeScanner?.startScan(buildScanFilters(), buildScanSettings(), scanCallback)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
aapsLogger.error(LTag.PUMPBTCOMM, "Start scan: ${e.message}", e) aapsLogger.error(LTag.PUMPBTCOMM, "Start scan: ${e.message}", e)
@ -135,15 +129,6 @@ class OrangeLinkImpl @Inject constructor(
} }
} }
/*
private val mLeScanCallback = LeScanCallback { device, _, _ ->
if (rileyLinkServiceData.rileyLinkAddress.equals(device.address)) {
stopScan()
rileyLinkBLE.rileyLinkDevice = device
rileyLinkBLE.connectGattInternal()
}
}
*/
private val handler: Handler = object : Handler(HandlerThread(this::class.java.simpleName + "Handler").also { it.start() }.looper) { private val handler: Handler = object : Handler(HandlerThread(this::class.java.simpleName + "Handler").also { it.start() }.looper) {
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
super.handleMessage(msg) super.handleMessage(msg)
@ -156,35 +141,17 @@ class OrangeLinkImpl @Inject constructor(
fun stopScan() { fun stopScan() {
handler.removeMessages(TIME_OUT_WHAT) handler.removeMessages(TIME_OUT_WHAT)
val bluetoothAdapter = rileyLinkBLE.bluetoothAdapter
try { try {
val bluetoothLeScanner: BluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner if (isBluetoothAvailable())
rileyLinkBLE.bluetoothAdapter?.bluetoothLeScanner?.stopScan(scanCallback)
if (isBluetoothAvailable()) {
bluetoothLeScanner.stopScan(scanCallback)
}
return
// if (bluetoothLeScanner == null) {
// if (isBluetoothAvailable()) {
// bluetoothAdapter.stopLeScan(mLeScanCallback)
// }
// return
// }
// if (isBluetoothAvailable()) {
// bluetoothLeScanner.stopScan(scanCallback)
// }
} catch (e: Exception) { } catch (e: Exception) {
aapsLogger.error(LTag.PUMPBTCOMM, "Stop scan: ${e.message}", e) aapsLogger.error(LTag.PUMPBTCOMM, "Stop scan: ${e.message}", e)
} }
} }
private fun isBluetoothAvailable(): Boolean { private fun isBluetoothAvailable(): Boolean =
val bluetoothAdapter = rileyLinkBLE.bluetoothAdapter rileyLinkBLE.bluetoothAdapter?.isEnabled == true && rileyLinkBLE.bluetoothAdapter?.state == BluetoothAdapter.STATE_ON
return bluetoothAdapter.isEnabled && bluetoothAdapter.state == BluetoothAdapter.STATE_ON
}
companion object { companion object {

View file

@ -5,6 +5,7 @@ package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service;
*/ */
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
@ -134,7 +135,7 @@ public class RileyLinkBroadcastReceiver extends DaggerBroadcastReceiver {
RileyLinkService rileyLinkService = getServiceInstance(); RileyLinkService rileyLinkService = getServiceInstance();
if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) { if (action.equals(RileyLinkConst.Intents.RileyLinkDisconnected)) {
if (BluetoothAdapter.getDefaultAdapter().isEnabled()) { if (((BluetoothManager)context.getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter().isEnabled()) {
rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.RileyLinkUnreachable); rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.RileyLinkUnreachable);
} else { } else {
rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled); rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled);