kt, share some MDT code
This commit is contained in:
parent
7b0bc81c47
commit
b872b82cd9
9 changed files with 326 additions and 399 deletions
|
@ -0,0 +1,88 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.common.ble
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.location.LocationManager
|
||||||
|
import android.provider.Settings
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.OKDialog.showConfirmation
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class BlePreCheck @Inject constructor(
|
||||||
|
val resourceHelper: ResourceHelper
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val PERMISSION_REQUEST_COARSE_LOCATION = 30241 // arbitrary.
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prerequisitesCheck(activity: AppCompatActivity): Boolean {
|
||||||
|
if (!activity.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||||
|
OKDialog.show(activity, resourceHelper.gs(R.string.app_name), resourceHelper.gs(R.string.rileylink_scanner_ble_not_supported))
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
// Use this check to determine whether BLE is supported on the device. Then
|
||||||
|
// you can selectively disable BLE-related features.
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// your code that requires permission
|
||||||
|
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSION_REQUEST_COARSE_LOCATION)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
|
||||||
|
// Ensures Bluetooth is available on the device and it is enabled. If not,
|
||||||
|
// displays a dialog requesting user permission to enable Bluetooth.
|
||||||
|
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled) {
|
||||||
|
OKDialog.show(activity, resourceHelper.gs(R.string.app_name), resourceHelper.gs(R.string.rileylink_scanner_ble_not_enabled))
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
// Will request that GPS be enabled for devices running Marshmallow or newer.
|
||||||
|
if (!isLocationEnabled(activity)) {
|
||||||
|
requestLocation(activity)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if GPS is currently enabled.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* On Android 6 (Marshmallow), location needs to be enabled for Bluetooth discovery to work.
|
||||||
|
*
|
||||||
|
* @param context The current app context.
|
||||||
|
* @return true if location is enabled, false otherwise.
|
||||||
|
*/
|
||||||
|
private fun isLocationEnabled(context: Context): Boolean {
|
||||||
|
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
|
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
|
||||||
|
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt the user to enable GPS location if it isn't already on.
|
||||||
|
*
|
||||||
|
* @param activity The currently visible activity.
|
||||||
|
*/
|
||||||
|
private fun requestLocation(activity: AppCompatActivity) {
|
||||||
|
if (isLocationEnabled(activity)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shamelessly borrowed from http://stackoverflow.com/a/10311877/868533
|
||||||
|
showConfirmation(activity, resourceHelper.gs(R.string.location_not_found_title), resourceHelper.gs(R.string.location_not_found_message), Runnable {
|
||||||
|
activity.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.common.dialog;
|
package info.nightscout.androidaps.plugins.pump.common.dialog;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.le.BluetoothLeScanner;
|
import android.bluetooth.le.BluetoothLeScanner;
|
||||||
|
@ -10,7 +9,6 @@ import android.bluetooth.le.ScanResult;
|
||||||
import android.bluetooth.le.ScanSettings;
|
import android.bluetooth.le.ScanSettings;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
|
@ -26,13 +24,12 @@ import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -43,10 +40,10 @@ import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst;
|
||||||
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.data.GattAttributes;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.LocationHelper;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
import info.nightscout.androidaps.plugins.pump.medtronic.driver.MedtronicPumpStatus;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpConfigurationChanged;
|
import info.nightscout.androidaps.plugins.pump.medtronic.events.EventMedtronicPumpConfigurationChanged;
|
||||||
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
|
||||||
|
@ -60,9 +57,7 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
|
||||||
@Inject SP sp;
|
@Inject SP sp;
|
||||||
@Inject RxBusWrapper rxBus;
|
@Inject RxBusWrapper rxBus;
|
||||||
@Inject ResourceHelper resourceHelper;
|
@Inject ResourceHelper resourceHelper;
|
||||||
|
@Inject BlePreCheck blePrecheck;
|
||||||
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 30241; // arbitrary.
|
|
||||||
private static final int REQUEST_ENABLE_BT = 30242; // arbitrary
|
|
||||||
|
|
||||||
private static String TAG = "RileyLinkBLEScanActivity";
|
private static String TAG = "RileyLinkBLEScanActivity";
|
||||||
|
|
||||||
|
@ -156,36 +151,13 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
public void prepareForScanning() {
|
public void prepareForScanning() {
|
||||||
// https://developer.android.com/training/permissions/requesting.html
|
boolean checkOK = blePrecheck.prerequisitesCheck(this);
|
||||||
// http://developer.radiusnetworks.com/2015/09/29/is-your-beacon-app-ready-for-android-6.html
|
|
||||||
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
|
||||||
Toast.makeText(this, R.string.rileylink_scanner_ble_not_supported, Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
|
||||||
// Use this check to determine whether BLE is supported on the device. Then
|
|
||||||
// you can selectively disable BLE-related features.
|
|
||||||
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// your code that requires permission
|
|
||||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
|
|
||||||
PERMISSION_REQUEST_COARSE_LOCATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensures Bluetooth is available on the device and it is enabled. If not,
|
if (checkOK) {
|
||||||
// displays a dialog requesting user permission to enable Bluetooth.
|
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
|
||||||
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
|
settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
|
||||||
Toast.makeText(this, R.string.rileylink_scanner_ble_not_enabled, Toast.LENGTH_SHORT).show();
|
filters = Collections.singletonList(new ScanFilter.Builder().setServiceUuid(
|
||||||
} else {
|
ParcelUuid.fromString(GattAttributes.SERVICE_RADIO)).build());
|
||||||
|
|
||||||
// Will request that GPS be enabled for devices running Marshmallow or newer.
|
|
||||||
if (!LocationHelper.isLocationEnabled(this)) {
|
|
||||||
LocationHelper.requestLocationForBluetooth(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
|
|
||||||
settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
|
|
||||||
filters = Arrays.asList(new ScanFilter.Builder().setServiceUuid(
|
|
||||||
ParcelUuid.fromString(GattAttributes.SERVICE_RADIO)).build());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable currently selected RL, so that we can discover it
|
// disable currently selected RL, so that we can discover it
|
||||||
|
@ -193,19 +165,6 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if (requestCode == REQUEST_ENABLE_BT) {
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
// User allowed Bluetooth to turn on
|
|
||||||
} else if (resultCode == RESULT_CANCELED) {
|
|
||||||
// Error, or user said "NO"
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScanCallback mScanCallback2 = new ScanCallback() {
|
private ScanCallback mScanCallback2 = new ScanCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.common.utils;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.location.LocationManager;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.utils.OKDialog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for checking if location services are enabled on the device.
|
|
||||||
*/
|
|
||||||
public class LocationHelper {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if GPS is currently enabled.
|
|
||||||
* <p>
|
|
||||||
* On Android 6 (Marshmallow), location needs to be enabled for Bluetooth discovery to work.
|
|
||||||
*
|
|
||||||
* @param context The current app context.
|
|
||||||
* @return true if location is enabled, false otherwise.
|
|
||||||
*/
|
|
||||||
public static boolean isLocationEnabled(Context context) {
|
|
||||||
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
|
||||||
|
|
||||||
return (locationManager != null && //
|
|
||||||
(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || //
|
|
||||||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)));
|
|
||||||
|
|
||||||
// return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt the user to enable GPS location if it isn't already on.
|
|
||||||
*
|
|
||||||
* @param parent The currently visible activity.
|
|
||||||
*/
|
|
||||||
public static void requestLocation(final Activity parent) {
|
|
||||||
if (LocationHelper.isLocationEnabled(parent)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shamelessly borrowed from http://stackoverflow.com/a/10311877/868533
|
|
||||||
OKDialog.showConfirmation(parent, MainApp.gs(R.string.location_not_found_title), MainApp.gs(R.string.location_not_found_message), () -> {
|
|
||||||
parent.startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prompt the user to enable GPS location on devices that need it for Bluetooth discovery.
|
|
||||||
* <p>
|
|
||||||
* Android 6 (Marshmallow) needs GPS enabled for Bluetooth discovery to work.
|
|
||||||
*
|
|
||||||
* @param activity The currently visible activity.
|
|
||||||
*/
|
|
||||||
public static void requestLocationForBluetooth(Activity activity) {
|
|
||||||
// Location needs to be enabled for Bluetooth discovery on Marshmallow.
|
|
||||||
LocationHelper.requestLocation(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// public static Boolean locationPermission(ActivityWithMenu act) {
|
|
||||||
// return ActivityCompat.checkSelfPermission(act, Manifest.permission.ACCESS_FINE_LOCATION) ==
|
|
||||||
// PackageManager.PERMISSION_GRANTED;
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
|
|
@ -61,6 +61,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
import info.nightscout.androidaps.utils.Round;
|
import info.nightscout.androidaps.utils.Round;
|
||||||
import info.nightscout.androidaps.utils.T;
|
import info.nightscout.androidaps.utils.T;
|
||||||
|
import info.nightscout.androidaps.utils.ToastUtils;
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
@ -77,16 +78,16 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
|
||||||
private final TreatmentsPlugin treatmentsPlugin;
|
private final TreatmentsPlugin treatmentsPlugin;
|
||||||
private final SP sp;
|
private final SP sp;
|
||||||
private final RxBusWrapper rxBus;
|
private final RxBusWrapper rxBus;
|
||||||
private final CommandQueueProvider commandQueue;
|
|
||||||
private final DanaRPump danaRPump;
|
private final DanaRPump danaRPump;
|
||||||
private final DetailedBolusInfoStorage detailedBolusInfoStorage;
|
private final DetailedBolusInfoStorage detailedBolusInfoStorage;
|
||||||
|
private final FabricPrivacy fabricPrivacy;
|
||||||
|
|
||||||
private static DanaRSService danaRSService;
|
private DanaRSService danaRSService;
|
||||||
|
|
||||||
private static String mDeviceAddress = "";
|
private String mDeviceAddress = "";
|
||||||
public static String mDeviceName = "";
|
public String mDeviceName = "";
|
||||||
|
|
||||||
public static PumpDescription pumpDescription = new PumpDescription();
|
public PumpDescription pumpDescription = new PumpDescription();
|
||||||
|
|
||||||
// Bolus & history handling
|
// Bolus & history handling
|
||||||
public int bolusStartErrorCode; // from start message
|
public int bolusStartErrorCode; // from start message
|
||||||
|
@ -112,7 +113,8 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
|
||||||
SP sp,
|
SP sp,
|
||||||
CommandQueueProvider commandQueue,
|
CommandQueueProvider commandQueue,
|
||||||
DanaRPump danaRPump,
|
DanaRPump danaRPump,
|
||||||
DetailedBolusInfoStorage detailedBolusInfoStorage
|
DetailedBolusInfoStorage detailedBolusInfoStorage,
|
||||||
|
FabricPrivacy fabricPrivacy
|
||||||
) {
|
) {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
.mainType(PluginType.PUMP)
|
.mainType(PluginType.PUMP)
|
||||||
|
@ -130,9 +132,9 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
|
||||||
this.profileFunction = profileFunction;
|
this.profileFunction = profileFunction;
|
||||||
this.treatmentsPlugin = treatmentsPlugin;
|
this.treatmentsPlugin = treatmentsPlugin;
|
||||||
this.sp = sp;
|
this.sp = sp;
|
||||||
this.commandQueue = commandQueue;
|
|
||||||
this.danaRPump = danaRPump;
|
this.danaRPump = danaRPump;
|
||||||
this.detailedBolusInfoStorage = detailedBolusInfoStorage;
|
this.detailedBolusInfoStorage = detailedBolusInfoStorage;
|
||||||
|
this.fabricPrivacy = fabricPrivacy;
|
||||||
|
|
||||||
pumpDescription.setPumpDescription(PumpType.DanaRS);
|
pumpDescription.setPumpDescription(PumpType.DanaRS);
|
||||||
}
|
}
|
||||||
|
@ -153,12 +155,12 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
|
||||||
disposable.add(rxBus
|
disposable.add(rxBus
|
||||||
.toObservable(EventAppExit.class)
|
.toObservable(EventAppExit.class)
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.subscribe(event -> context.unbindService(mConnection), exception -> FabricPrivacy.getInstance().logException(exception))
|
.subscribe(event -> context.unbindService(mConnection), fabricPrivacy::logException)
|
||||||
);
|
);
|
||||||
disposable.add(rxBus
|
disposable.add(rxBus
|
||||||
.toObservable(EventDanaRSDeviceChange.class)
|
.toObservable(EventDanaRSDeviceChange.class)
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.subscribe(event -> loadAddress(), exception -> FabricPrivacy.getInstance().logException(exception))
|
.subscribe(event -> loadAddress(), fabricPrivacy::logException)
|
||||||
);
|
);
|
||||||
loadAddress(); // load device name
|
loadAddress(); // load device name
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
@ -195,7 +197,9 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
|
||||||
public void connect(String from) {
|
public void connect(String from) {
|
||||||
getAapsLogger().debug(LTag.PUMP, "RS connect from: " + from);
|
getAapsLogger().debug(LTag.PUMP, "RS connect from: " + from);
|
||||||
if (danaRSService != null && !mDeviceAddress.equals("") && !mDeviceName.equals("")) {
|
if (danaRSService != null && !mDeviceAddress.equals("") && !mDeviceName.equals("")) {
|
||||||
danaRSService.connect(from, mDeviceAddress);
|
boolean success = danaRSService.connect(from, mDeviceAddress);
|
||||||
|
if (!success)
|
||||||
|
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.rileylink_scanner_ble_not_supported));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,217 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.danaRS.activities;
|
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.bluetooth.le.BluetoothLeScanner;
|
|
||||||
import android.bluetooth.le.ScanCallback;
|
|
||||||
import android.bluetooth.le.ScanResult;
|
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.danaRS.events.EventDanaRSDeviceChange;
|
|
||||||
import info.nightscout.androidaps.utils.SP;
|
|
||||||
|
|
||||||
public class BLEScanActivity extends NoSplashAppCompatActivity {
|
|
||||||
private ListAdapter mListAdapter = null;
|
|
||||||
private ArrayList<BluetoothDeviceItem> mDevices = new ArrayList<>();
|
|
||||||
|
|
||||||
private BluetoothLeScanner mBluetoothLeScanner = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.danars_blescanner_activity);
|
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
|
||||||
|
|
||||||
mListAdapter = new ListAdapter();
|
|
||||||
|
|
||||||
ListView listView = findViewById(R.id.danars_blescanner_listview);
|
|
||||||
listView.setEmptyView(findViewById(R.id.danars_blescanner_nodevice));
|
|
||||||
listView.setAdapter(mListAdapter);
|
|
||||||
|
|
||||||
mListAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
|
||||||
if (mBluetoothAdapter != null) {
|
|
||||||
if (!mBluetoothAdapter.isEnabled()) mBluetoothAdapter.enable();
|
|
||||||
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
|
|
||||||
|
|
||||||
if (mBluetoothLeScanner == null) {
|
|
||||||
mBluetoothAdapter.enable();
|
|
||||||
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
|
|
||||||
}
|
|
||||||
startScan();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
|
|
||||||
stopScan();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startScan() {
|
|
||||||
if (mBluetoothLeScanner != null)
|
|
||||||
mBluetoothLeScanner.startScan(mBleScanCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopScan() {
|
|
||||||
if (mBluetoothLeScanner != null)
|
|
||||||
mBluetoothLeScanner.stopScan(mBleScanCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBleDevice(BluetoothDevice device) {
|
|
||||||
if (device == null || device.getName() == null || device.getName().equals("")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BluetoothDeviceItem item = new BluetoothDeviceItem(device);
|
|
||||||
if (!isSNCheck(device.getName()) || mDevices.contains(item)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mDevices.add(item);
|
|
||||||
new Handler().post(() -> mListAdapter.notifyDataSetChanged());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScanCallback mBleScanCallback = new ScanCallback() {
|
|
||||||
@Override
|
|
||||||
public void onScanResult(int callbackType, ScanResult result) {
|
|
||||||
addBleDevice(result.getDevice());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ListAdapter extends BaseAdapter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return mDevices.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BluetoothDeviceItem getItem(int i) {
|
|
||||||
return mDevices.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int i) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int i, View convertView, ViewGroup parent) {
|
|
||||||
View v = convertView;
|
|
||||||
ViewHolder holder;
|
|
||||||
|
|
||||||
if (v == null) {
|
|
||||||
v = View.inflate(getApplicationContext(), R.layout.danars_blescanner_item, null);
|
|
||||||
holder = new ViewHolder(v);
|
|
||||||
v.setTag(holder);
|
|
||||||
} else {
|
|
||||||
holder = (ViewHolder) v.getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
BluetoothDeviceItem item = getItem(i);
|
|
||||||
holder.setData(item);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ViewHolder implements View.OnClickListener {
|
|
||||||
private BluetoothDeviceItem item = null;
|
|
||||||
|
|
||||||
private TextView mName;
|
|
||||||
private TextView mAddress;
|
|
||||||
|
|
||||||
ViewHolder(View v) {
|
|
||||||
mName = v.findViewById(R.id.ble_name);
|
|
||||||
mAddress = v.findViewById(R.id.ble_address);
|
|
||||||
|
|
||||||
v.setOnClickListener(ViewHolder.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
SP.putString(R.string.key_danars_address, item.device.getAddress());
|
|
||||||
SP.putString(R.string.key_danars_name, mName.getText().toString());
|
|
||||||
item.device.createBond();
|
|
||||||
RxBus.Companion.getINSTANCE().send(new EventDanaRSDeviceChange());
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(BluetoothDeviceItem data) {
|
|
||||||
if (data != null) {
|
|
||||||
try {
|
|
||||||
String tTitle = data.device.getName();
|
|
||||||
if (tTitle == null || tTitle.equals("")) {
|
|
||||||
tTitle = "(unknown)";
|
|
||||||
} else if (tTitle.length() > 10) {
|
|
||||||
tTitle = tTitle.substring(0, 10);
|
|
||||||
}
|
|
||||||
mName.setText(tTitle);
|
|
||||||
|
|
||||||
mAddress.setText(data.device.getAddress());
|
|
||||||
|
|
||||||
item = data;
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
private class BluetoothDeviceItem {
|
|
||||||
private BluetoothDevice device;
|
|
||||||
|
|
||||||
BluetoothDeviceItem(BluetoothDevice device) {
|
|
||||||
super();
|
|
||||||
this.device = device;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (device == null || !(o instanceof BluetoothDeviceItem)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
BluetoothDeviceItem checkItem = (BluetoothDeviceItem) o;
|
|
||||||
if (checkItem.device == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return stringEquals(device.getAddress(), checkItem.device.getAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean stringEquals(String arg1, String arg2) {
|
|
||||||
try {
|
|
||||||
return arg1.equals(arg2);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSNCheck(String sn) {
|
|
||||||
String regex = "^([a-zA-Z]{3})([0-9]{5})([a-zA-Z]{2})$";
|
|
||||||
Pattern p = Pattern.compile(regex);
|
|
||||||
Matcher m = p.matcher(sn);
|
|
||||||
|
|
||||||
return m.matches();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.danaRS.activities
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.bluetooth.BluetoothAdapter
|
||||||
|
import android.bluetooth.BluetoothDevice
|
||||||
|
import android.bluetooth.le.BluetoothLeScanner
|
||||||
|
import android.bluetooth.le.ScanCallback
|
||||||
|
import android.bluetooth.le.ScanResult
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.BaseAdapter
|
||||||
|
import android.widget.TextView
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
|
import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck
|
||||||
|
import info.nightscout.androidaps.plugins.pump.danaRS.events.EventDanaRSDeviceChange
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import kotlinx.android.synthetic.main.danars_blescanner_activity.*
|
||||||
|
import java.util.*
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class BLEScanActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
|
@Inject lateinit var sp: SP
|
||||||
|
@Inject lateinit var rxBus: RxBusWrapper
|
||||||
|
@Inject lateinit var blePreCheck: BlePreCheck
|
||||||
|
|
||||||
|
private var listAdapter: ListAdapter? = null
|
||||||
|
private val devices = ArrayList<BluetoothDeviceItem>()
|
||||||
|
private var bluetoothLeScanner: BluetoothLeScanner? = null
|
||||||
|
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(R.layout.danars_blescanner_activity)
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
|
||||||
|
blePreCheck.prerequisitesCheck(this)
|
||||||
|
|
||||||
|
listAdapter = ListAdapter()
|
||||||
|
danars_blescanner_listview.emptyView = findViewById(R.id.danars_blescanner_nodevice)
|
||||||
|
danars_blescanner_listview.adapter = listAdapter
|
||||||
|
listAdapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
|
||||||
|
BluetoothAdapter.getDefaultAdapter()?.let { bluetoothAdapter ->
|
||||||
|
if (!bluetoothAdapter.isEnabled) bluetoothAdapter.enable()
|
||||||
|
bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
|
||||||
|
startScan()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
stopScan()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startScan() {
|
||||||
|
if (bluetoothLeScanner != null) bluetoothLeScanner!!.startScan(mBleScanCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopScan() {
|
||||||
|
if (bluetoothLeScanner != null) bluetoothLeScanner!!.stopScan(mBleScanCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addBleDevice(device: BluetoothDevice?) {
|
||||||
|
if (device == null || device.name == null || device.name == "") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val item = BluetoothDeviceItem(device)
|
||||||
|
if (!isSNCheck(device.name) || devices.contains(item)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
devices.add(item)
|
||||||
|
Handler().post { listAdapter!!.notifyDataSetChanged() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val mBleScanCallback: ScanCallback = object : ScanCallback() {
|
||||||
|
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||||
|
addBleDevice(result.device)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inner class ListAdapter : BaseAdapter() {
|
||||||
|
override fun getCount(): Int = devices.size
|
||||||
|
override fun getItem(i: Int): BluetoothDeviceItem = devices[i]
|
||||||
|
override fun getItemId(i: Int): Long = 0
|
||||||
|
|
||||||
|
override fun getView(i: Int, convertView: View?, parent: ViewGroup?): View {
|
||||||
|
var v = convertView
|
||||||
|
val holder: ViewHolder
|
||||||
|
if (v == null) {
|
||||||
|
v = View.inflate(applicationContext, R.layout.danars_blescanner_item, null)
|
||||||
|
holder = ViewHolder(v)
|
||||||
|
v.tag = holder
|
||||||
|
} else {
|
||||||
|
// reuse view if already exists
|
||||||
|
holder = v.tag as ViewHolder
|
||||||
|
}
|
||||||
|
val item = getItem(i)
|
||||||
|
holder.setData(item)
|
||||||
|
return v!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class ViewHolder internal constructor(v: View) : View.OnClickListener {
|
||||||
|
private lateinit var item: BluetoothDeviceItem
|
||||||
|
private val name: TextView = v.findViewById(R.id.ble_name)
|
||||||
|
private val address: TextView = v.findViewById(R.id.ble_address)
|
||||||
|
|
||||||
|
init {
|
||||||
|
v.setOnClickListener(this@ViewHolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
sp.putString(R.string.key_danars_address, item.device.address)
|
||||||
|
sp.putString(R.string.key_danars_name, name.text.toString())
|
||||||
|
item.device.createBond()
|
||||||
|
rxBus.send(EventDanaRSDeviceChange())
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setData(data: BluetoothDeviceItem) {
|
||||||
|
var tTitle = data.device.name
|
||||||
|
if (tTitle == null || tTitle == "") {
|
||||||
|
tTitle = "(unknown)"
|
||||||
|
} else if (tTitle.length > 10) {
|
||||||
|
tTitle = tTitle.substring(0, 10)
|
||||||
|
}
|
||||||
|
name.text = tTitle
|
||||||
|
address.text = data.device.address
|
||||||
|
item = data
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
inner class BluetoothDeviceItem internal constructor(val device: BluetoothDevice) {
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (other !is BluetoothDeviceItem) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return stringEquals(device.address, other.device.address)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stringEquals(arg1: String, arg2: String): Boolean {
|
||||||
|
return try {
|
||||||
|
arg1 == arg2
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = device.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isSNCheck(sn: String?): Boolean {
|
||||||
|
val regex = "^([a-zA-Z]{3})([0-9]{5})([a-zA-Z]{2})$"
|
||||||
|
val p = Pattern.compile(regex)
|
||||||
|
val m = p.matcher(sn)
|
||||||
|
return m.matches()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.danaRS.activities
|
package info.nightscout.androidaps.plugins.pump.danaRS.activities
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||||
import info.nightscout.androidaps.plugins.pump.danaRS.dialogs.PairingProgressDialog
|
import info.nightscout.androidaps.plugins.pump.danaRS.dialogs.PairingProgressDialog
|
||||||
|
|
||||||
class PairingHelperActivity : NoSplashAppCompatActivity() {
|
class PairingHelperActivity : NoSplashAppCompatActivity() {
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
PairingProgressDialog()
|
PairingProgressDialog()
|
||||||
|
|
|
@ -37,6 +37,7 @@ class BLEComm @Inject internal constructor(
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val danaRSMessageHashTable: DanaRSMessageHashTable,
|
private val danaRSMessageHashTable: DanaRSMessageHashTable,
|
||||||
private val danaRPump: DanaRPump,
|
private val danaRPump: DanaRPump,
|
||||||
|
private val danaRSPlugin: DanaRSPlugin,
|
||||||
private val bleEncryption: BleEncryption
|
private val bleEncryption: BleEncryption
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -52,66 +53,51 @@ class BLEComm @Inject internal constructor(
|
||||||
private var scheduledDisconnection: ScheduledFuture<*>? = null
|
private var scheduledDisconnection: ScheduledFuture<*>? = null
|
||||||
private var processedMessage: DanaRS_Packet? = null
|
private var processedMessage: DanaRS_Packet? = null
|
||||||
private val mSendQueue = ArrayList<ByteArray>()
|
private val mSendQueue = ArrayList<ByteArray>()
|
||||||
private var mBluetoothManager: BluetoothManager? = null
|
private var bluetoothManager: BluetoothManager? = null
|
||||||
private var mBluetoothAdapter: BluetoothAdapter? = null
|
private var bluetoothAdapter: BluetoothAdapter? = null
|
||||||
private var connectDeviceName: String? = null
|
private var connectDeviceName: String? = null
|
||||||
private var mBluetoothGatt: BluetoothGatt? = null
|
private var bluetoothGatt: BluetoothGatt? = null
|
||||||
|
|
||||||
var isConnected = false
|
var isConnected = false
|
||||||
var isConnecting = false
|
var isConnecting = false
|
||||||
private var uartRead: BluetoothGattCharacteristic? = null
|
private var uartRead: BluetoothGattCharacteristic? = null
|
||||||
private var uartWrite: BluetoothGattCharacteristic? = null
|
private var uartWrite: BluetoothGattCharacteristic? = null
|
||||||
|
|
||||||
init {
|
@Synchronized
|
||||||
initialize()
|
fun connect(from: String, address: String?): Boolean {
|
||||||
}
|
|
||||||
|
|
||||||
private fun initialize(): Boolean {
|
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing BLEComm.")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing BLEComm.")
|
||||||
if (mBluetoothManager == null) {
|
if (bluetoothManager == null) {
|
||||||
mBluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
if (mBluetoothManager == null) {
|
if (bluetoothManager == null) {
|
||||||
aapsLogger.error("Unable to initialize BluetoothManager.")
|
aapsLogger.error("Unable to initialize BluetoothManager.")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mBluetoothAdapter = mBluetoothManager?.adapter
|
bluetoothAdapter = bluetoothManager?.adapter
|
||||||
if (mBluetoothAdapter == null) {
|
if (bluetoothAdapter == null) {
|
||||||
aapsLogger.error("Unable to obtain a BluetoothAdapter.")
|
aapsLogger.error("Unable to obtain a BluetoothAdapter.")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun connect(from: String, address: String?): Boolean {
|
|
||||||
// test existing BT device
|
|
||||||
val tBluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?
|
|
||||||
?: return false
|
|
||||||
tBluetoothManager.adapter ?: return false
|
|
||||||
|
|
||||||
if (address == null) {
|
if (address == null) {
|
||||||
aapsLogger.error("unspecified address.")
|
aapsLogger.error("unspecified address.")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mBluetoothAdapter == null) {
|
|
||||||
if (!initialize()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isConnecting = true
|
isConnecting = true
|
||||||
val device = mBluetoothAdapter?.getRemoteDevice(address)
|
val device = bluetoothAdapter?.getRemoteDevice(address)
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
aapsLogger.error("Device not found. Unable to connect from: $from")
|
aapsLogger.error("Device not found. Unable to connect from: $from")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Trying to create a new connection from: $from")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Trying to create a new connection from: $from")
|
||||||
connectDeviceName = device.name
|
connectDeviceName = device.name
|
||||||
mBluetoothGatt = device.connectGatt(context, false, mGattCallback)
|
bluetoothGatt = device.connectGatt(context, false, mGattCallback)
|
||||||
setCharacteristicNotification(uartReadBTGattChar, true)
|
setCharacteristicNotification(uartReadBTGattChar, true)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
fun stopConnecting() {
|
fun stopConnecting() {
|
||||||
isConnecting = false
|
isConnecting = false
|
||||||
}
|
}
|
||||||
|
@ -124,21 +110,21 @@ class BLEComm @Inject internal constructor(
|
||||||
scheduledDisconnection?.cancel(false)
|
scheduledDisconnection?.cancel(false)
|
||||||
scheduledDisconnection = null
|
scheduledDisconnection = null
|
||||||
|
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (bluetoothAdapter == null || bluetoothGatt == null) {
|
||||||
aapsLogger.error("disconnect not possible: (mBluetoothAdapter == null) " + (mBluetoothAdapter == null))
|
aapsLogger.error("disconnect not possible: (mBluetoothAdapter == null) " + (bluetoothAdapter == null))
|
||||||
aapsLogger.error("disconnect not possible: (mBluetoothGatt == null) " + (mBluetoothGatt == null))
|
aapsLogger.error("disconnect not possible: (mBluetoothGatt == null) " + (bluetoothGatt == null))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setCharacteristicNotification(uartReadBTGattChar, false)
|
setCharacteristicNotification(uartReadBTGattChar, false)
|
||||||
mBluetoothGatt?.disconnect()
|
bluetoothGatt?.disconnect()
|
||||||
isConnected = false
|
isConnected = false
|
||||||
SystemClock.sleep(2000)
|
SystemClock.sleep(2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized fun close() {
|
@Synchronized fun close() {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "BluetoothAdapter close")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "BluetoothAdapter close")
|
||||||
mBluetoothGatt?.close()
|
bluetoothGatt?.close()
|
||||||
mBluetoothGatt = null
|
bluetoothGatt = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
|
private val mGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
|
||||||
|
@ -185,20 +171,20 @@ class BLEComm @Inject internal constructor(
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
|
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "setCharacteristicNotification")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "setCharacteristicNotification")
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (bluetoothAdapter == null || bluetoothGatt == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||||
isConnecting = false
|
isConnecting = false
|
||||||
isConnected = false
|
isConnected = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mBluetoothGatt!!.setCharacteristicNotification(characteristic, enabled)
|
bluetoothGatt!!.setCharacteristicNotification(characteristic, enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun writeCharacteristicNoResponse(characteristic: BluetoothGattCharacteristic, data: ByteArray) {
|
private fun writeCharacteristicNoResponse(characteristic: BluetoothGattCharacteristic, data: ByteArray) {
|
||||||
Thread(Runnable {
|
Thread(Runnable {
|
||||||
SystemClock.sleep(WRITE_DELAY_MILLIS)
|
SystemClock.sleep(WRITE_DELAY_MILLIS)
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (bluetoothAdapter == null || bluetoothGatt == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||||
isConnecting = false
|
isConnecting = false
|
||||||
isConnected = false
|
isConnected = false
|
||||||
|
@ -207,7 +193,7 @@ class BLEComm @Inject internal constructor(
|
||||||
characteristic.value = data
|
characteristic.value = data
|
||||||
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
|
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
|
||||||
aapsLogger.debug("writeCharacteristic:" + DanaRS_Packet.toHexString(data))
|
aapsLogger.debug("writeCharacteristic:" + DanaRS_Packet.toHexString(data))
|
||||||
mBluetoothGatt!!.writeCharacteristic(characteristic)
|
bluetoothGatt!!.writeCharacteristic(characteristic)
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,15 +206,15 @@ class BLEComm @Inject internal constructor(
|
||||||
?: BluetoothGattCharacteristic(UUID.fromString(UART_WRITE_UUID), BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, 0).also { uartWrite = it }
|
?: BluetoothGattCharacteristic(UUID.fromString(UART_WRITE_UUID), BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, 0).also { uartWrite = it }
|
||||||
|
|
||||||
private fun getSupportedGattServices(): List<BluetoothGattService>? {
|
private fun getSupportedGattServices(): List<BluetoothGattService>? {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "getSupportedGattServices")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "getSupportedGattServices")
|
||||||
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
|
if (bluetoothAdapter == null || bluetoothGatt == null) {
|
||||||
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
|
||||||
isConnecting = false
|
isConnecting = false
|
||||||
isConnected = false
|
isConnected = false
|
||||||
return null
|
return null
|
||||||
}
|
|
||||||
return mBluetoothGatt?.services
|
|
||||||
}
|
}
|
||||||
|
return bluetoothGatt?.services
|
||||||
|
}
|
||||||
|
|
||||||
private fun findCharacteristic() {
|
private fun findCharacteristic() {
|
||||||
val gattServices = getSupportedGattServices() ?: return
|
val gattServices = getSupportedGattServices() ?: return
|
||||||
|
@ -339,7 +325,7 @@ class BLEComm @Inject internal constructor(
|
||||||
BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK.toByte() -> if (decryptedBuffer.size == 4 && decryptedBuffer[2] == 'O'.toByte() && decryptedBuffer[3] == 'K'.toByte()) {
|
BleEncryption.DANAR_PACKET__OPCODE_ENCRYPTION__PUMP_CHECK.toByte() -> if (decryptedBuffer.size == 4 && decryptedBuffer[2] == 'O'.toByte() && decryptedBuffer[3] == 'K'.toByte()) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK (OK)" + " " + DanaRS_Packet.toHexString(decryptedBuffer))
|
aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK (OK)" + " " + DanaRS_Packet.toHexString(decryptedBuffer))
|
||||||
// Grab pairing key from preferences if exists
|
// Grab pairing key from preferences if exists
|
||||||
val pairingKey = sp.getString(resourceHelper.gs(R.string.key_danars_pairingkey) + DanaRSPlugin.mDeviceName, "")
|
val pairingKey = sp.getString(resourceHelper.gs(R.string.key_danars_pairingkey) + danaRSPlugin.mDeviceName, "")
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Using stored pairing key: $pairingKey")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Using stored pairing key: $pairingKey")
|
||||||
if (pairingKey.isNotEmpty()) {
|
if (pairingKey.isNotEmpty()) {
|
||||||
val encodedPairingKey = DanaRS_Packet.hexToBytes(pairingKey)
|
val encodedPairingKey = DanaRS_Packet.hexToBytes(pairingKey)
|
||||||
|
@ -366,7 +352,7 @@ class BLEComm @Inject internal constructor(
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK (ERROR)" + " " + DanaRS_Packet.toHexString(decryptedBuffer))
|
aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK (ERROR)" + " " + DanaRS_Packet.toHexString(decryptedBuffer))
|
||||||
mSendQueue.clear()
|
mSendQueue.clear()
|
||||||
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED, resourceHelper.gs(R.string.connectionerror)))
|
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED, resourceHelper.gs(R.string.connectionerror)))
|
||||||
sp.remove(resourceHelper.gs(R.string.key_danars_pairingkey) + DanaRSPlugin.mDeviceName)
|
sp.remove(resourceHelper.gs(R.string.key_danars_pairingkey) + danaRSPlugin.mDeviceName)
|
||||||
val n = Notification(Notification.WRONGSERIALNUMBER, resourceHelper.gs(R.string.wrongpassword), Notification.URGENT)
|
val n = Notification(Notification.WRONGSERIALNUMBER, resourceHelper.gs(R.string.wrongpassword), Notification.URGENT)
|
||||||
rxBus.send(EventNewNotification(n))
|
rxBus.send(EventNewNotification(n))
|
||||||
}
|
}
|
||||||
|
@ -396,7 +382,7 @@ class BLEComm @Inject internal constructor(
|
||||||
sendTimeInfo()
|
sendTimeInfo()
|
||||||
val pairingKey = byteArrayOf(decryptedBuffer[2], decryptedBuffer[3])
|
val pairingKey = byteArrayOf(decryptedBuffer[2], decryptedBuffer[3])
|
||||||
// store pairing key to preferences
|
// store pairing key to preferences
|
||||||
sp.putString(resourceHelper.gs(R.string.key_danars_pairingkey) + DanaRSPlugin.mDeviceName, DanaRS_Packet.bytesToHex(pairingKey))
|
sp.putString(resourceHelper.gs(R.string.key_danars_pairingkey) + danaRSPlugin.mDeviceName, DanaRS_Packet.bytesToHex(pairingKey))
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Got pairing key: " + DanaRS_Packet.bytesToHex(pairingKey))
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Got pairing key: " + DanaRS_Packet.bytesToHex(pairingKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,6 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
public RileyLinkMedtronicService() {
|
public RileyLinkMedtronicService() {
|
||||||
super();
|
super();
|
||||||
instance = this;
|
instance = this;
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly constructed");
|
|
||||||
MedtronicUtil.setMedtronicService(this);
|
|
||||||
pumpStatus = (MedtronicPumpStatus) medtronicPumpPlugin.getPumpStatusData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,6 +65,12 @@ public class RileyLinkMedtronicService extends RileyLinkService {
|
||||||
return instance.medtronicCommunicationManager;
|
return instance.medtronicCommunicationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly created");
|
||||||
|
MedtronicUtil.setMedtronicService(this);
|
||||||
|
pumpStatus = (MedtronicPumpStatus) medtronicPumpPlugin.getPumpStatusData();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(Configuration newConfig) {
|
public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
|
Loading…
Reference in a new issue