kt, share some MDT code

This commit is contained in:
Milos Kozak 2020-03-24 18:17:28 +01:00
parent 7b0bc81c47
commit b872b82cd9
9 changed files with 326 additions and 399 deletions

View file

@ -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))
})
}
}

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps.plugins.pump.common.dialog;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
@ -10,7 +9,6 @@ import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
@ -26,13 +24,12 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -43,10 +40,10 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
import info.nightscout.androidaps.logging.AAPSLogger;
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.RileyLinkUtil;
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.events.EventMedtronicPumpConfigurationChanged;
import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil;
@ -60,9 +57,7 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
@Inject SP sp;
@Inject RxBusWrapper rxBus;
@Inject ResourceHelper resourceHelper;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 30241; // arbitrary.
private static final int REQUEST_ENABLE_BT = 30242; // arbitrary
@Inject BlePreCheck blePrecheck;
private static String TAG = "RileyLinkBLEScanActivity";
@ -156,36 +151,13 @@ public class RileyLinkBLEScanActivity extends NoSplashAppCompatActivity {
public void prepareForScanning() {
// https://developer.android.com/training/permissions/requesting.html
// 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);
}
boolean checkOK = blePrecheck.prerequisitesCheck(this);
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, R.string.rileylink_scanner_ble_not_enabled, Toast.LENGTH_SHORT).show();
} else {
// 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());
}
if (checkOK) {
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
filters = Collections.singletonList(new ScanFilter.Builder().setServiceUuid(
ParcelUuid.fromString(GattAttributes.SERVICE_RADIO)).build());
}
// 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() {
@Override

View file

@ -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;
// }
}

View file

@ -61,6 +61,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.Round;
import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.CompositeDisposable;
@ -77,16 +78,16 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
private final TreatmentsPlugin treatmentsPlugin;
private final SP sp;
private final RxBusWrapper rxBus;
private final CommandQueueProvider commandQueue;
private final DanaRPump danaRPump;
private final DetailedBolusInfoStorage detailedBolusInfoStorage;
private final FabricPrivacy fabricPrivacy;
private static DanaRSService danaRSService;
private DanaRSService danaRSService;
private static String mDeviceAddress = "";
public static String mDeviceName = "";
private String mDeviceAddress = "";
public String mDeviceName = "";
public static PumpDescription pumpDescription = new PumpDescription();
public PumpDescription pumpDescription = new PumpDescription();
// Bolus & history handling
public int bolusStartErrorCode; // from start message
@ -112,7 +113,8 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
SP sp,
CommandQueueProvider commandQueue,
DanaRPump danaRPump,
DetailedBolusInfoStorage detailedBolusInfoStorage
DetailedBolusInfoStorage detailedBolusInfoStorage,
FabricPrivacy fabricPrivacy
) {
super(new PluginDescription()
.mainType(PluginType.PUMP)
@ -130,9 +132,9 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
this.profileFunction = profileFunction;
this.treatmentsPlugin = treatmentsPlugin;
this.sp = sp;
this.commandQueue = commandQueue;
this.danaRPump = danaRPump;
this.detailedBolusInfoStorage = detailedBolusInfoStorage;
this.fabricPrivacy = fabricPrivacy;
pumpDescription.setPumpDescription(PumpType.DanaRS);
}
@ -153,12 +155,12 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
disposable.add(rxBus
.toObservable(EventAppExit.class)
.observeOn(Schedulers.io())
.subscribe(event -> context.unbindService(mConnection), exception -> FabricPrivacy.getInstance().logException(exception))
.subscribe(event -> context.unbindService(mConnection), fabricPrivacy::logException)
);
disposable.add(rxBus
.toObservable(EventDanaRSDeviceChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> loadAddress(), exception -> FabricPrivacy.getInstance().logException(exception))
.subscribe(event -> loadAddress(), fabricPrivacy::logException)
);
loadAddress(); // load device name
super.onStart();
@ -195,7 +197,9 @@ public class DanaRSPlugin extends PumpPluginBase implements PumpInterface, DanaR
public void connect(String from) {
getAapsLogger().debug(LTag.PUMP, "RS connect from: " + from);
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));
}
}

View file

@ -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();
}
}

View file

@ -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()
}
}

View file

@ -1,11 +1,13 @@
package info.nightscout.androidaps.plugins.pump.danaRS.activities
import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Bundle
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
import info.nightscout.androidaps.plugins.pump.danaRS.dialogs.PairingProgressDialog
class PairingHelperActivity : NoSplashAppCompatActivity() {
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
PairingProgressDialog()

View file

@ -37,6 +37,7 @@ class BLEComm @Inject internal constructor(
private val sp: SP,
private val danaRSMessageHashTable: DanaRSMessageHashTable,
private val danaRPump: DanaRPump,
private val danaRSPlugin: DanaRSPlugin,
private val bleEncryption: BleEncryption
) {
@ -52,66 +53,51 @@ class BLEComm @Inject internal constructor(
private var scheduledDisconnection: ScheduledFuture<*>? = null
private var processedMessage: DanaRS_Packet? = null
private val mSendQueue = ArrayList<ByteArray>()
private var mBluetoothManager: BluetoothManager? = null
private var mBluetoothAdapter: BluetoothAdapter? = null
private var bluetoothManager: BluetoothManager? = null
private var bluetoothAdapter: BluetoothAdapter? = null
private var connectDeviceName: String? = null
private var mBluetoothGatt: BluetoothGatt? = null
private var bluetoothGatt: BluetoothGatt? = null
var isConnected = false
var isConnecting = false
private var uartRead: BluetoothGattCharacteristic? = null
private var uartWrite: BluetoothGattCharacteristic? = null
init {
initialize()
}
private fun initialize(): Boolean {
@Synchronized
fun connect(from: String, address: String?): Boolean {
aapsLogger.debug(LTag.PUMPBTCOMM, "Initializing BLEComm.")
if (mBluetoothManager == null) {
mBluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
if (mBluetoothManager == null) {
if (bluetoothManager == null) {
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
if (bluetoothManager == null) {
aapsLogger.error("Unable to initialize BluetoothManager.")
return false
}
}
mBluetoothAdapter = mBluetoothManager?.adapter
if (mBluetoothAdapter == null) {
bluetoothAdapter = bluetoothManager?.adapter
if (bluetoothAdapter == null) {
aapsLogger.error("Unable to obtain a BluetoothAdapter.")
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) {
aapsLogger.error("unspecified address.")
return false
}
if (mBluetoothAdapter == null) {
if (!initialize()) {
return false
}
}
isConnecting = true
val device = mBluetoothAdapter?.getRemoteDevice(address)
val device = bluetoothAdapter?.getRemoteDevice(address)
if (device == null) {
aapsLogger.error("Device not found. Unable to connect from: $from")
return false
}
aapsLogger.debug(LTag.PUMPBTCOMM, "Trying to create a new connection from: $from")
connectDeviceName = device.name
mBluetoothGatt = device.connectGatt(context, false, mGattCallback)
bluetoothGatt = device.connectGatt(context, false, mGattCallback)
setCharacteristicNotification(uartReadBTGattChar, true)
return true
}
@Synchronized
fun stopConnecting() {
isConnecting = false
}
@ -124,21 +110,21 @@ class BLEComm @Inject internal constructor(
scheduledDisconnection?.cancel(false)
scheduledDisconnection = null
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
aapsLogger.error("disconnect not possible: (mBluetoothAdapter == null) " + (mBluetoothAdapter == null))
aapsLogger.error("disconnect not possible: (mBluetoothGatt == null) " + (mBluetoothGatt == null))
if (bluetoothAdapter == null || bluetoothGatt == null) {
aapsLogger.error("disconnect not possible: (mBluetoothAdapter == null) " + (bluetoothAdapter == null))
aapsLogger.error("disconnect not possible: (mBluetoothGatt == null) " + (bluetoothGatt == null))
return
}
setCharacteristicNotification(uartReadBTGattChar, false)
mBluetoothGatt?.disconnect()
bluetoothGatt?.disconnect()
isConnected = false
SystemClock.sleep(2000)
}
@Synchronized fun close() {
aapsLogger.debug(LTag.PUMPBTCOMM, "BluetoothAdapter close")
mBluetoothGatt?.close()
mBluetoothGatt = null
bluetoothGatt?.close()
bluetoothGatt = null
}
private val mGattCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
@ -185,20 +171,20 @@ class BLEComm @Inject internal constructor(
@Synchronized
private fun setCharacteristicNotification(characteristic: BluetoothGattCharacteristic?, enabled: Boolean) {
aapsLogger.debug(LTag.PUMPBTCOMM, "setCharacteristicNotification")
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
if (bluetoothAdapter == null || bluetoothGatt == null) {
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
isConnecting = false
isConnected = false
return
}
mBluetoothGatt!!.setCharacteristicNotification(characteristic, enabled)
bluetoothGatt!!.setCharacteristicNotification(characteristic, enabled)
}
@Synchronized
private fun writeCharacteristicNoResponse(characteristic: BluetoothGattCharacteristic, data: ByteArray) {
Thread(Runnable {
SystemClock.sleep(WRITE_DELAY_MILLIS)
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
if (bluetoothAdapter == null || bluetoothGatt == null) {
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
isConnecting = false
isConnected = false
@ -207,7 +193,7 @@ class BLEComm @Inject internal constructor(
characteristic.value = data
characteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
aapsLogger.debug("writeCharacteristic:" + DanaRS_Packet.toHexString(data))
mBluetoothGatt!!.writeCharacteristic(characteristic)
bluetoothGatt!!.writeCharacteristic(characteristic)
}).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 }
private fun getSupportedGattServices(): List<BluetoothGattService>? {
aapsLogger.debug(LTag.PUMPBTCOMM, "getSupportedGattServices")
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
isConnecting = false
isConnected = false
return null
}
return mBluetoothGatt?.services
aapsLogger.debug(LTag.PUMPBTCOMM, "getSupportedGattServices")
if (bluetoothAdapter == null || bluetoothGatt == null) {
aapsLogger.error("BluetoothAdapter not initialized_ERROR")
isConnecting = false
isConnected = false
return null
}
return bluetoothGatt?.services
}
private fun findCharacteristic() {
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()) {
aapsLogger.debug(LTag.PUMPBTCOMM, "<<<<< " + "ENCRYPTION__PUMP_CHECK (OK)" + " " + DanaRS_Packet.toHexString(decryptedBuffer))
// 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")
if (pairingKey.isNotEmpty()) {
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))
mSendQueue.clear()
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)
rxBus.send(EventNewNotification(n))
}
@ -396,7 +382,7 @@ class BLEComm @Inject internal constructor(
sendTimeInfo()
val pairingKey = byteArrayOf(decryptedBuffer[2], decryptedBuffer[3])
// 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))
}

View file

@ -53,9 +53,6 @@ public class RileyLinkMedtronicService extends RileyLinkService {
public RileyLinkMedtronicService() {
super();
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;
}
@Override public void onCreate() {
super.onCreate();
aapsLogger.debug(LTag.PUMPCOMM, "RileyLinkMedtronicService newly created");
MedtronicUtil.setMedtronicService(this);
pumpStatus = (MedtronicPumpStatus) medtronicPumpPlugin.getPumpStatusData();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {