mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-20 07:21:40 +02:00
Do BLE scan in addition to bluetooth discovery
After running the old school bluetooth discovery, start a 10 second BLE scan. This is a better way to find BLE devices and at least for me always find my scale (something that the discovery doesn't always do). Also add a simple progress bar that is shown while the discovery is in progress. Finally add a link to the wiki for users with unsupported scales.
This commit is contained in:
@@ -19,11 +19,14 @@ import android.bluetooth.BluetoothAdapter;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
@@ -44,61 +47,145 @@ import java.util.Map;
|
|||||||
public class BluetoothPreferences extends PreferenceFragment {
|
public class BluetoothPreferences extends PreferenceFragment {
|
||||||
private static final String PREFERENCE_KEY_BLUETOOTH_SCANNER = "btScanner";
|
private static final String PREFERENCE_KEY_BLUETOOTH_SCANNER = "btScanner";
|
||||||
|
|
||||||
|
public static final String PREFERENCE_KEY_BLUETOOTH_DEVICE_NAME = "btDeviceName";
|
||||||
|
public static final String PREFERENCE_KEY_BLUETOOTH_HW_ADDRESS = "btHwAddress";
|
||||||
|
|
||||||
private PreferenceScreen btScanner;
|
private PreferenceScreen btScanner;
|
||||||
private BluetoothAdapter btAdapter = null;
|
private BluetoothAdapter btAdapter = null;
|
||||||
|
private Handler handler = null;
|
||||||
private Map<String, String> foundDevices = new HashMap<>();
|
private Map<String, String> foundDevices = new HashMap<>();
|
||||||
|
|
||||||
public void startSearching() {
|
private void startBluetoothDiscovery() {
|
||||||
foundDevices.clear();
|
foundDevices.clear();
|
||||||
btScanner.removeAll();
|
btScanner.removeAll();
|
||||||
|
handler = new Handler();
|
||||||
|
|
||||||
Preference scanning = new Preference(getActivity());
|
final Preference scanning = new Preference(getActivity());
|
||||||
scanning.setEnabled(false);
|
scanning.setEnabled(false);
|
||||||
btScanner.addPreference(scanning);
|
btScanner.addPreference(scanning);
|
||||||
|
|
||||||
|
final int progressUpdatePeriod = 150;
|
||||||
|
final String[] blocks = {"▏","▎","▍","▌","▋","▊","▉","█"};
|
||||||
|
scanning.setSummary(blocks[0]);
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
|
int index = 1;
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String summary = scanning.getSummary()
|
||||||
|
.subSequence(0, scanning.getSummary().length() - 1).toString();
|
||||||
|
if (index == blocks.length) {
|
||||||
|
summary += blocks[blocks.length - 1];
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
summary += blocks[index++];
|
||||||
|
scanning.setSummary(summary);
|
||||||
|
handler.postDelayed(this, progressUpdatePeriod);
|
||||||
|
}
|
||||||
|
}, progressUpdatePeriod);
|
||||||
|
|
||||||
OpenScale.getInstance(getActivity()).stopSearchingForBluetooth();
|
OpenScale.getInstance(getActivity()).stopSearchingForBluetooth();
|
||||||
|
|
||||||
|
btScanner.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
btAdapter.cancelDiscovery();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Do old school bluetooth discovery first and BLE scan afterwards
|
||||||
btAdapter.startDiscovery();
|
btAdapter.startDiscovery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startBleScan() {
|
||||||
|
final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||||
|
@Override
|
||||||
|
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||||
|
onDeviceFound(device);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't let the BLE scan run forever
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
btAdapter.stopLeScan(leScanCallback);
|
||||||
|
|
||||||
|
Preference scanning = btScanner.getPreference(0);
|
||||||
|
scanning.setTitle(R.string.label_bluetooth_searching_finished);
|
||||||
|
scanning.setSummary("");
|
||||||
|
|
||||||
|
Intent notSupportedIntent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
notSupportedIntent.setData(
|
||||||
|
Uri.parse("https://github.com/oliexdev/openScale/wiki/Supported-scales-in-openScale"));
|
||||||
|
|
||||||
|
Preference notSupported = new Preference(getActivity());
|
||||||
|
notSupported.setTitle(R.string.label_scale_not_supported);
|
||||||
|
notSupported.setSummary(R.string.label_click_to_help_add_support);
|
||||||
|
notSupported.setIntent(notSupportedIntent);
|
||||||
|
btScanner.addPreference(notSupported);
|
||||||
|
}
|
||||||
|
}, 10 * 1000);
|
||||||
|
|
||||||
|
// Also cancel scan if dialog is dismissed
|
||||||
|
btScanner.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
btAdapter.stopLeScan(leScanCallback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btAdapter.startLeScan(leScanCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDeviceFound(BluetoothDevice device) {
|
||||||
|
if (device.getName() == null || foundDevices.containsKey(device.getAddress())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Preference prefBtDevice = new Preference(getActivity());
|
||||||
|
prefBtDevice.setTitle(device.getName() + " [" + device.getAddress() + "]");
|
||||||
|
|
||||||
|
BluetoothCommunication btDevice = BluetoothFactory.createDeviceDriver(getActivity(), device.getName());
|
||||||
|
if (btDevice != null) {
|
||||||
|
prefBtDevice.setOnPreferenceClickListener(new onClickListenerDeviceSelect());
|
||||||
|
prefBtDevice.setKey(device.getAddress());
|
||||||
|
prefBtDevice.setIcon(R.drawable.ic_bluetooth_connection_lost);
|
||||||
|
prefBtDevice.setSummary(btDevice.deviceName());
|
||||||
|
|
||||||
|
int tintColor = new EditText(getActivity()).getCurrentTextColor();
|
||||||
|
prefBtDevice.getIcon().setColorFilter(tintColor, PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prefBtDevice.setIcon(R.drawable.ic_bluetooth_disabled);
|
||||||
|
prefBtDevice.setSummary(R.string.label_bt_device_no_support);
|
||||||
|
prefBtDevice.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
foundDevices.put(device.getAddress(), device.getName());
|
||||||
|
btScanner.addPreference(prefBtDevice);
|
||||||
|
}
|
||||||
|
|
||||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(final Context context, Intent intent) {
|
||||||
|
// May be called before the dialog is shown or while it is being dismissed
|
||||||
|
if (btScanner.getDialog() == null || !btScanner.getDialog().isShowing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
|
|
||||||
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
|
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
|
||||||
btScanner.getPreference(0).setTitle(R.string.label_bluetooth_searching);
|
btScanner.getPreference(0).setTitle(R.string.label_bluetooth_searching);
|
||||||
}
|
}
|
||||||
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
|
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
|
||||||
btScanner.getPreference(0).setTitle(R.string.label_bluetooth_searching_finished);
|
startBleScan();
|
||||||
}
|
}
|
||||||
else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
|
else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
|
||||||
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||||
|
onDeviceFound(device);
|
||||||
if (device.getName() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Preference prefBtDevice = new Preference(getActivity());
|
|
||||||
prefBtDevice.setTitle(device.getName() + " [" + device.getAddress() + "]");
|
|
||||||
|
|
||||||
BluetoothCommunication btDevice = BluetoothFactory.createDeviceDriver(getActivity(), device.getName());
|
|
||||||
if (btDevice != null) {
|
|
||||||
prefBtDevice.setOnPreferenceClickListener(new onClickListenerDeviceSelect());
|
|
||||||
prefBtDevice.setKey(device.getAddress());
|
|
||||||
prefBtDevice.setIcon(R.drawable.ic_bluetooth_connection_lost);
|
|
||||||
prefBtDevice.setSummary(btDevice.deviceName());
|
|
||||||
|
|
||||||
int tintColor = new EditText(getActivity()).getCurrentTextColor();
|
|
||||||
prefBtDevice.getIcon().setColorFilter(tintColor, PorterDuff.Mode.SRC_IN);
|
|
||||||
|
|
||||||
foundDevices.put(device.getAddress(), device.getName());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
prefBtDevice.setIcon(R.drawable.ic_bluetooth_disabled);
|
|
||||||
prefBtDevice.setSummary(R.string.label_bt_device_no_support);
|
|
||||||
prefBtDevice.setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
btScanner.addPreference(prefBtDevice);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -107,13 +194,6 @@ public class BluetoothPreferences extends PreferenceFragment {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
// Intent filter for the scanning process
|
|
||||||
IntentFilter filter = new IntentFilter();
|
|
||||||
filter.addAction(BluetoothDevice.ACTION_FOUND);
|
|
||||||
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
|
|
||||||
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
|
|
||||||
getActivity().registerReceiver(mReceiver, filter);
|
|
||||||
|
|
||||||
btAdapter = BluetoothAdapter.getDefaultAdapter();
|
btAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.bluetooth_preferences);
|
addPreferencesFromResource(R.xml.bluetooth_preferences);
|
||||||
@@ -124,17 +204,37 @@ public class BluetoothPreferences extends PreferenceFragment {
|
|||||||
btScanner.setSummary("Bluetooth " + getResources().getString(R.string.info_is_not_available));
|
btScanner.setSummary("Bluetooth " + getResources().getString(R.string.info_is_not_available));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
btScanner.setOnPreferenceClickListener(new onClickListenerScannerSelect());
|
// Might have been started by another app
|
||||||
String deviceName = btScanner.getSharedPreferences().getString("btDeviceName", "-");
|
btAdapter.cancelDiscovery();
|
||||||
|
|
||||||
|
btScanner.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
if (PermissionHelper.requestBluetoothPermission(getActivity(), true)) {
|
||||||
|
startBluetoothDiscovery();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
String deviceName = btScanner.getSharedPreferences().getString(
|
||||||
|
PREFERENCE_KEY_BLUETOOTH_DEVICE_NAME, "-");
|
||||||
if (!deviceName.equals("-")) {
|
if (!deviceName.equals("-")) {
|
||||||
deviceName += " [" +
|
deviceName += " [" + btScanner.getSharedPreferences().getString(
|
||||||
btScanner.getSharedPreferences().getString("btHwAddress", "") +
|
PREFERENCE_KEY_BLUETOOTH_HW_ADDRESS, "") + "]";
|
||||||
"]";
|
|
||||||
}
|
}
|
||||||
btScanner.setSummary(deviceName);
|
btScanner.setSummary(deviceName);
|
||||||
|
|
||||||
// Dummy preference to make screen open
|
// Dummy preference to make screen open
|
||||||
btScanner.addPreference(new Preference(getActivity()));
|
btScanner.addPreference(new Preference(getActivity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Intent filter for the scanning process
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(BluetoothDevice.ACTION_FOUND);
|
||||||
|
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
|
||||||
|
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
|
||||||
|
getActivity().registerReceiver(mReceiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -144,26 +244,14 @@ public class BluetoothPreferences extends PreferenceFragment {
|
|||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class onClickListenerScannerSelect implements Preference.OnPreferenceClickListener {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
|
||||||
if (PermissionHelper.requestBluetoothPermission(getActivity(), true)) {
|
|
||||||
startSearching();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class onClickListenerDeviceSelect implements Preference.OnPreferenceClickListener {
|
private class onClickListenerDeviceSelect implements Preference.OnPreferenceClickListener {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceClick(final Preference preference) {
|
public boolean onPreferenceClick(final Preference preference) {
|
||||||
preference.getSharedPreferences().edit()
|
preference.getSharedPreferences().edit()
|
||||||
.putString("btHwAddress", preference.getKey())
|
.putString(PREFERENCE_KEY_BLUETOOTH_HW_ADDRESS, preference.getKey())
|
||||||
.putString("btDeviceName", foundDevices.get(preference.getKey()))
|
.putString(PREFERENCE_KEY_BLUETOOTH_DEVICE_NAME, foundDevices.get(preference.getKey()))
|
||||||
.apply();
|
.apply();
|
||||||
|
|
||||||
btAdapter.cancelDiscovery();
|
|
||||||
|
|
||||||
// Set summary text and trigger data set changed to make UI update
|
// Set summary text and trigger data set changed to make UI update
|
||||||
btScanner.setSummary(preference.getTitle());
|
btScanner.setSummary(preference.getTitle());
|
||||||
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
|
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
|
||||||
@@ -177,9 +265,9 @@ public class BluetoothPreferences extends PreferenceFragment {
|
|||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION: {
|
case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION: {
|
||||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
startSearching();
|
startBluetoothDiscovery();
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(getActivity().getApplicationContext(), getResources().getString(R.string.permission_not_granted), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity().getApplicationContext(), R.string.permission_not_granted, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -223,4 +223,6 @@
|
|||||||
<string name="label_percent">Percent</string>
|
<string name="label_percent">Percent</string>
|
||||||
<string name="label_estimated">Estimated</string>
|
<string name="label_estimated">Estimated</string>
|
||||||
<string name="label_estimate_measurement_summary">Based on weight, height, age, gender, etc.</string>
|
<string name="label_estimate_measurement_summary">Based on weight, height, age, gender, etc.</string>
|
||||||
|
<string name="label_scale_not_supported">Is your scale not supported?</string>
|
||||||
|
<string name="label_click_to_help_add_support">Click here if you want to help add support for it</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Reference in New Issue
Block a user