1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-07 05:38:13 +02:00

Do both BT and BTLE discovery (one after another) #33

This commit is contained in:
cpfeiffer 2015-05-09 23:54:47 +02:00
parent 60210e069c
commit 1a7c3c42e4
4 changed files with 95 additions and 51 deletions

View File

@ -16,9 +16,8 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.fsck.k9.permission.READ_MESSAGES" />
<android:uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
<application
android:name=".GBApplication"

View File

@ -81,6 +81,10 @@ public class GB {
return adapter != null && adapter.isEnabled();
}
public static boolean supportsBluetoothLE() {
return GBApplication.getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
public static String hexdump(byte[] buffer, int offset, int length) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[length * 2];

View File

@ -12,8 +12,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
@ -22,11 +20,11 @@ import android.widget.ProgressBar;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.GB;
import nodomain.freeyourgadget.gadgetbridge.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.adapter.DeviceCandidateAdapter;
@ -41,10 +39,15 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
discoveryStarted();
discoveryStarted(Scanning.SCANNING_BT);
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
discoveryFinished();
// continue with LE scan, if available
if (GB.supportsBluetoothLE()) {
startBTLEDiscovery();
} else {
discoveryFinished();
}
break;
case BluetoothAdapter.ACTION_STATE_CHANGED:
int oldState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, BluetoothAdapter.STATE_OFF);
@ -52,10 +55,21 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
bluetoothStateChanged(oldState, newState);
break;
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, GBDevice.RSSI_UNKNOWN);
handleDeviceFound(device, rssi);
break;
}
}
};
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
handleDeviceFound(device, (short) rssi);
}
};
private Runnable stopRunnable = new Runnable() {
@Override
public void run() {
@ -63,45 +77,19 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
}
};
private void bluetoothStateChanged(int oldState, int newState) {
discoveryFinished();
startButton.setEnabled(newState == BluetoothAdapter.STATE_ON);
}
private void discoveryFinished() {
isScanning = false;
progressView.setVisibility(View.GONE);
startButton.setText(getString(R.string.discovery_start_scanning));
}
private void discoveryStarted() {
isScanning = true;
progressView.setVisibility(View.VISIBLE);
startButton.setText(getString(R.string.discovery_stop_scanning));
}
private ProgressBar progressView;
private BluetoothAdapter adapter;
private ArrayList<DeviceCandidate> deviceCandidates = new ArrayList<>();
private ListView deviceCandidatesView;
private DeviceCandidateAdapter cadidateListAdapter;
private Button startButton;
private boolean isScanning;
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
DeviceCandidate candidate = new DeviceCandidate(device, (short) rssi);
if (DeviceHelper.getInstance().isSupported(candidate)) {
int index = deviceCandidates.indexOf(candidate);
if (index >= 0) {
deviceCandidates.set(index, candidate); // replace
} else {
deviceCandidates.add(candidate);
}
cadidateListAdapter.notifyDataSetChanged();
}
}
};
private Scanning isScanning = Scanning.SCANNING_OFF;
private enum Scanning {
SCANNING_BT,
SCANNING_BTLE,
SCANNING_OFF
}
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -157,7 +145,7 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
public void onStartButtonClick(View button) {
Log.d(TAG, "Start Button clicked");
if (isScanning) {
if (isScanning()) {
stopDiscovery();
} else {
startDiscovery();
@ -170,29 +158,51 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
super.onDestroy();
}
private void handleDeviceFound(BluetoothDevice device, short rssi) {
DeviceCandidate candidate = new DeviceCandidate(device, (short) rssi);
if (DeviceHelper.getInstance().isSupported(candidate)) {
int index = deviceCandidates.indexOf(candidate);
if (index >= 0) {
deviceCandidates.set(index, candidate); // replace
} else {
deviceCandidates.add(candidate);
}
cadidateListAdapter.notifyDataSetChanged();
}
}
/**
* Pre: bluetooth is available, enabled and scanning is off
* Pre: bluetooth is available, enabled and scanning is off.
* Post: BT is discovering
*/
private void startDiscovery() {
if (isScanning) {
if (isScanning()) {
Log.w(TAG, "Not starting BLE discovery, because already scanning.");
return;
}
Log.i(TAG, "Starting discovery...");
discoveryStarted(); // just to make sure
discoveryStarted(Scanning.SCANNING_BT); // just to make sure
if (ensureBluetoothReady()) {
startBLEDiscovery();
startBTDiscovery();
} else {
discoveryFinished();
Toast.makeText(this, "Enable Bluetooth to discover devices.", Toast.LENGTH_LONG).show();
}
}
private boolean isScanning() {
return isScanning != Scanning.SCANNING_OFF;
}
private void stopDiscovery() {
Log.i(TAG, "Stopping discovery");
if (isScanning) {
adapter.stopLeScan(leScanCallback);
if (isScanning()) {
if (isScanning == Scanning.SCANNING_BT) {
stopBTDiscovery();
} else if (isScanning == Scanning.SCANNING_BTLE) {
stopBTLEDiscovery();
}
handler.removeMessages(0, stopRunnable);
// unfortunately, we never get a call back when stopping the scan, so
// we do it manually:
@ -200,6 +210,31 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
}
}
private void stopBTLEDiscovery() {
adapter.stopLeScan(leScanCallback);
}
private void stopBTDiscovery() {
adapter.cancelDiscovery();
}
private void bluetoothStateChanged(int oldState, int newState) {
discoveryFinished();
startButton.setEnabled(newState == BluetoothAdapter.STATE_ON);
}
private void discoveryFinished() {
isScanning = Scanning.SCANNING_OFF;
progressView.setVisibility(View.GONE);
startButton.setText(getString(R.string.discovery_start_scanning));
}
private void discoveryStarted(Scanning what) {
isScanning = what;
progressView.setVisibility(View.VISIBLE);
startButton.setText(getString(R.string.discovery_stop_scanning));
}
private boolean ensureBluetoothReady() {
boolean available = checkBluetoothAvailable();
startButton.setEnabled(available);
@ -229,12 +264,18 @@ public class DiscoveryActivity extends Activity implements AdapterView.OnItemCli
return true;
}
private void startBLEDiscovery() {
private void startBTLEDiscovery() {
handler.removeMessages(0, stopRunnable);
handler.postDelayed(stopRunnable, SCAN_DURATION);
adapter.startLeScan(leScanCallback);
}
private void startBTDiscovery() {
handler.removeMessages(0, stopRunnable);
handler.postDelayed(stopRunnable, SCAN_DURATION);
adapter.startDiscovery();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DeviceCandidate deviceCandidate = deviceCandidates.get(position);

View File

@ -89,7 +89,7 @@
<string name="miband_pairing_using_dummy_userdata">No valid user data given, using dummy user data for now.</string>
<string name="miband_pairing_tap_hint">When your Mi Band vibrates and blinks, tap it a few times in a row.</string>
<string name="appinstaller_install">Install</string>
<string name="discovery_connected_devices_hint">Currently connected devices will likely not be discovered.</string>
<string name="discovery_connected_devices_hint">Make your device discoverable. Currently connected devices will likely not be discovered.</string>
<string name="discovery_note">Note:</string>
<string name="candidate_item_device_image">Device Image</string>
<string name="miband_prefs_about_you">About You</string>