aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/io/trygvis/android/bt/DefaultBtService.java')
-rw-r--r--app/src/main/java/io/trygvis/android/bt/DefaultBtService.java192
1 files changed, 192 insertions, 0 deletions
diff --git a/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java b/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
new file mode 100644
index 0000000..8638544
--- /dev/null
+++ b/app/src/main/java/io/trygvis/android/bt/DefaultBtService.java
@@ -0,0 +1,192 @@
+package io.trygvis.android.bt;
+
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import io.trygvis.soilmoisture.R;
+
+public class DefaultBtService<A> extends Service implements BtService<A> {
+ private final static String TAG = DefaultBtService.class.getSimpleName();
+
+ private final IBinder binder = new LocalBinder<>(this);
+
+ private Handler handler = new Handler();
+
+ // -----------------------------------------------------------------------
+ // State
+ // -----------------------------------------------------------------------
+
+ private BtServiceListener<A> serviceListener = new AbstractBtServiceListener<A>() {
+ @Override
+ public void onNewDevice(BtDevice<A> device) {
+ }
+ };
+
+ private Supplier<A> tagConstructor;
+
+ private BluetoothManager bluetoothManager;
+
+ private BluetoothAdapter bluetoothAdapter;
+
+ private final List<BtDevice<A>> devices = new ArrayList<>();
+
+ private boolean scanning = false;
+
+ // -----------------------------------------------------------------------
+ // BtService Implementation
+ // -----------------------------------------------------------------------
+
+ @Override
+ public boolean initialize(BtServiceListener<A> serviceListener, Supplier<A> dataSupplier) {
+ if (bluetoothManager != null) {
+ Log.e(TAG, "Already initialized");
+ return false;
+ }
+
+ this.tagConstructor = dataSupplier;
+
+ if (serviceListener != null) {
+ this.serviceListener = serviceListener;
+ }
+
+ // Use this check to determine whether BLE is supported on the device. Then you can
+ // selectively disable BLE-related features.
+ if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+ Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
+ // BluetoothAdapter through BluetoothManager.
+ bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+
+ if (bluetoothManager == null) {
+ Log.e(TAG, "Unable to initialize BluetoothManager.");
+ return false;
+ }
+
+ bluetoothAdapter = bluetoothManager.getAdapter();
+ if (bluetoothAdapter == null) {
+ Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
+ bluetoothManager = null;
+ return false;
+ }
+
+ Log.e(TAG, "Bluetooth initialized");
+ return true;
+ }
+
+ @Override
+ public void clearCache() {
+ }
+
+ @Override
+ public boolean isScanning() {
+ return scanning;
+ }
+
+ @Override
+ public boolean startScanning(long timeoutMs) {
+ if (timeoutMs > 0) {
+ handler.postDelayed(this::stopScanning, timeoutMs);
+ }
+
+ if (bluetoothAdapter.startLeScan(leScanCallback)) {
+ scanning = true;
+ serviceListener.onScanStarted();
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void stopScanning() {
+ // This doesn't mind being called twice.
+ bluetoothAdapter.stopLeScan(leScanCallback);
+
+ scanning = false;
+
+ serviceListener.onScanStopped();
+ }
+
+// @Override
+ public BtDevice<A> getDevice(String mac) {
+ BtDevice<A> device = findDevice(mac);
+
+ if (device != null) {
+ return device;
+ }
+
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(mac);
+ return register(bluetoothDevice, null, null);
+ }
+
+ @Override
+ public List<BtDevice<A>> getDevices() {
+ return Collections.unmodifiableList(devices);
+ }
+
+ // -----------------------------------------------------------------------
+ // Scanning
+ // -----------------------------------------------------------------------
+
+ private BluetoothAdapter.LeScanCallback leScanCallback = (device, rssi, scanRecord) -> {
+// Log.i(TAG, "onLeScan()");
+
+ BtScanResult scanResult = new BtScanResult(scanRecord);
+
+ register(device, rssi, scanResult);
+ };
+
+ // -----------------------------------------------------------------------
+ // Service Implementation
+ // -----------------------------------------------------------------------
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return binder;
+ }
+
+ // -----------------------------------------------------------------------
+ // Stuff
+ // -----------------------------------------------------------------------
+
+ private BtDevice<A> register(BluetoothDevice bluetoothDevice, Integer rssi, BtScanResult scanResult) {
+ BtDevice<A> btDevice = findDevice(bluetoothDevice.getAddress());
+
+ if (btDevice != null) {
+ return btDevice;
+ }
+
+ Log.i(TAG, "New device: " + bluetoothDevice.getAddress());
+ btDevice = new BtDevice<>(this, bluetoothDevice, tagConstructor.get(), rssi, scanResult);
+ devices.add(btDevice);
+
+ serviceListener.onNewDevice(btDevice);
+
+ return btDevice;
+ }
+
+ private BtDevice<A> findDevice(String mac) {
+ for (BtDevice<A> d : devices) {
+ if (d.getAddress().equals(mac)) {
+ return d;
+ }
+ }
+ return null;
+ }
+}