package com.codegy.aerlink.connection; import android.bluetooth.*; import android.bluetooth.le.*; import android.content.Context; import android.os.Handler; import android.util.Log; import java.util.ArrayList; import java.util.List; /** * Created by Guiye on 28/8/15. */ public class DiscoveryManager { public interface Callback { void onDeviceDiscovery(BluetoothDevice device); } private static final String LOG_TAG = DiscoveryManager.class.getSimpleName(); private static final int RETRY_TIME = 3000; private Context mContext; private Callback mCallback; private boolean mScanning; private BluetoothAdapter mBluetoothAdapter; private List<String> mAllowedDevices; private ScanSettings mScanSettings; private BluetoothLeScanner mScanner; public DiscoveryManager(Context mContext, Callback mCallback, BluetoothManager bluetoothManager) { this.mContext = mContext; this.mCallback = mCallback; this.mAllowedDevices = new ArrayList<>(3); this.mAllowedDevices.add("Aerlink"); this.mAllowedDevices.add("BLE Utility"); this.mAllowedDevices.add("Blank"); mBluetoothAdapter = bluetoothManager.getAdapter(); } public void startDiscovery() { // If disabled -> enable bluetooth if (!mBluetoothAdapter.isEnabled()) { stopDiscovery(); mBluetoothAdapter.enable(); Log.wtf(LOG_TAG, "Bluetooth was disabled"); Handler handler = new Handler(mContext.getMainLooper()); handler.postDelayed(new Runnable() { @Override public void run() { startDiscovery(); } }, RETRY_TIME); return; } else if (isRunning()) { // Scanner is already running // Don't start anything return; } try { mScanning = startScanning(); } catch (Exception e) { e.printStackTrace(); mScanning = false; stopScanning(); } if (!mScanning) { // Scanning did not work, try again in a moment Handler handler = new Handler(mContext.getMainLooper()); handler.postDelayed(new Runnable() { @Override public void run() { startDiscovery(); } }, RETRY_TIME); } } public void stopDiscovery() { mScanning = false; stopScanning(); } public boolean isRunning() { return mScanning && mScanner != null; } private synchronized boolean startScanning() { boolean result = false; mScanner = mBluetoothAdapter.getBluetoothLeScanner(); // If bluetooth was disabled, the scanner may be null if (mScanner != null) { if (mScanSettings == null) { mScanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).build(); } try { mScanner.startScan(null, mScanSettings, mScanCallback); Log.d(LOG_TAG, "Scanning started"); result = true; } catch (Exception e) { e.printStackTrace(); } } return result; } private void stopScanning() { if (mScanner != null) { synchronized (this) { try { mScanner.stopScan(mScanCallback); } catch (Exception e) { e.printStackTrace(); } mScanner = null; Log.d(LOG_TAG, "Scanning stopped"); } } } private final ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { Log.d(LOG_TAG, "Scan Result: " + result.toString()); BluetoothDevice device = result.getDevice(); String deviceName = device != null ? device.getName() : null; if (mScanning && deviceName != null && mAllowedDevices.contains(deviceName)) { mCallback.onDeviceDiscovery(device); stopDiscovery(); } } @Override public void onBatchScanResults(List<ScanResult> results) { Log.i(LOG_TAG, "Batch Scan Results: " + results.toString()); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); Log.d(LOG_TAG, "Scan Failed: " + errorCode); stopScanning(); startDiscovery(); } }; }