forked from upstream-mirrors/OpenTracks
Settings: scan for Bluetooth sensors rather than using bonded devices.
Bonded devices do no provide information what services (e.g., heart rate) they support.
This commit is contained in:
+3
-2
@@ -45,7 +45,7 @@ public class BluetoothConnectionManager {
|
|||||||
static final int MESSAGE_READ = 3;
|
static final int MESSAGE_READ = 3;
|
||||||
static final int MESSAGE_DISCONNECTED = 4;
|
static final int MESSAGE_DISCONNECTED = 4;
|
||||||
|
|
||||||
private static final UUID HEART_RATE_SERVICE_UUID = new UUID(0x180D00001000L, 0x800000805f9b34fbL);
|
public static final UUID HEART_RATE_SERVICE_UUID = new UUID(0x180D00001000L, 0x800000805f9b34fbL);
|
||||||
private static final UUID HEART_RATE_MEASUREMENT_CHAR_UUID = new UUID(0x2A3700001000L, 0x800000805f9b34fbL);
|
private static final UUID HEART_RATE_MEASUREMENT_CHAR_UUID = new UUID(0x2A3700001000L, 0x800000805f9b34fbL);
|
||||||
private static final UUID CLIENT_CHARACTERISTIC_CONFIG_UUID = new UUID(0x290200001000L, 0x800000805f9b34fbL);
|
private static final UUID CLIENT_CHARACTERISTIC_CONFIG_UUID = new UUID(0x290200001000L, 0x800000805f9b34fbL);
|
||||||
|
|
||||||
@@ -131,8 +131,9 @@ public class BluetoothConnectionManager {
|
|||||||
|
|
||||||
Log.d(TAG, "Connecting to: " + bluetoothDevice);
|
Log.d(TAG, "Connecting to: " + bluetoothDevice);
|
||||||
|
|
||||||
setState(SensorState.CONNECTING);
|
|
||||||
bluetoothGatt = bluetoothDevice.connectGatt(this.context, true, this.connectCallback);
|
bluetoothGatt = bluetoothDevice.connectGatt(this.context, true, this.connectCallback);
|
||||||
|
|
||||||
|
setState(SensorState.CONNECTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void disconnect() {
|
public synchronized void disconnect() {
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package de.dennisguse.opentracks.settings;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothDevice;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class BluetoothLeAdapter extends BaseAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains a unique list (by address) of devices.
|
||||||
|
*/
|
||||||
|
private final List<Device> devices = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return devices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return devices.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return devices.get(position).hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
View currentView = convertView;
|
||||||
|
if (convertView == null) {
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||||
|
//TODO Check if there is a better way to achieve identical look and feel to ListPreference.
|
||||||
|
//Use material design single choice; for old style use: android.R.layout.select_dialog_singlechoice
|
||||||
|
currentView = inflater.inflate(androidx.appcompat.R.layout.select_dialog_singlechoice_material, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Device device = devices.get(position);
|
||||||
|
TextView textView = currentView.findViewById(android.R.id.text1);
|
||||||
|
textView.setText(device.getName());
|
||||||
|
|
||||||
|
return currentView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(String name, String address) {
|
||||||
|
Device device = new Device(name, address);
|
||||||
|
if (!devices.contains(device)) {
|
||||||
|
devices.add(new Device(name, address));
|
||||||
|
} else {
|
||||||
|
for (Device currentDevice : devices) {
|
||||||
|
if (currentDevice.getAddress().equals(address)) {
|
||||||
|
currentDevice.setName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(BluetoothDevice bluetoothDevice) {
|
||||||
|
add(bluetoothDevice.getName(), bluetoothDevice.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Device get(int index) {
|
||||||
|
return devices.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Device {
|
||||||
|
private String name;
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
public Device(String name, String address) {
|
||||||
|
this.name = name;
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the address is identical.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof Device)) return false;
|
||||||
|
Device device = (Device) o;
|
||||||
|
return address.equals(device.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
package de.dennisguse.opentracks.settings;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.bluetooth.le.BluetoothLeScanner;
|
||||||
|
import android.bluetooth.le.ScanCallback;
|
||||||
|
import android.bluetooth.le.ScanFilter;
|
||||||
|
import android.bluetooth.le.ScanResult;
|
||||||
|
import android.bluetooth.le.ScanSettings;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.ParcelUuid;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.preference.DialogPreference;
|
||||||
|
import androidx.preference.PreferenceDialogFragmentCompat;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.R;
|
||||||
|
import de.dennisguse.opentracks.services.sensors.BluetoothConnectionManager;
|
||||||
|
import de.dennisguse.opentracks.util.BluetoothUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preference to select a discoverable Bluetooth LE device.
|
||||||
|
* Based upon ListPreference.
|
||||||
|
*/
|
||||||
|
public class BluetoothLeListPreference extends DialogPreference {
|
||||||
|
|
||||||
|
private final static String TAG = BluetoothLeListPreference.class.getSimpleName();
|
||||||
|
|
||||||
|
public BluetoothLeListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BluetoothLeListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BluetoothLeListPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BluetoothLeListPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
private boolean valueSet = false;
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
final boolean changed = !TextUtils.equals(this.value, value);
|
||||||
|
if (changed || !valueSet) {
|
||||||
|
this.value = value;
|
||||||
|
valueSet = true;
|
||||||
|
persistString(value);
|
||||||
|
if (changed) {
|
||||||
|
notifyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSetInitialValue(Object defaultValue) {
|
||||||
|
setValue(getPersistedString((String) defaultValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getSummary() {
|
||||||
|
return getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BluetoothLeListPreferenceDialog extends PreferenceDialogFragmentCompat {
|
||||||
|
|
||||||
|
private int selectedEntryIndex;
|
||||||
|
private BluetoothLeAdapter listAdapter = new BluetoothLeAdapter();
|
||||||
|
|
||||||
|
private BluetoothLeScanner scanner = null;
|
||||||
|
private ScanCallback scanCallback = new ScanCallback() {
|
||||||
|
@Override
|
||||||
|
public void onScanResult(int callbackType, ScanResult result) {
|
||||||
|
super.onScanResult(callbackType, result);
|
||||||
|
Log.d(TAG, "Found device " + result.getDevice().getName() + " " + result);
|
||||||
|
|
||||||
|
listAdapter.add(result.getDevice());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBatchScanResults(List<ScanResult> results) {
|
||||||
|
for (ScanResult scanResult : results) {
|
||||||
|
listAdapter.add(scanResult.getDevice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScanFailed(int errorCode) {
|
||||||
|
super.onScanFailed(errorCode);
|
||||||
|
Log.e(TAG, "Bluetooth scan failed with errorCode " + errorCode);
|
||||||
|
Toast.makeText(getContext(), R.string.sensor_could_not_scan, Toast.LENGTH_LONG).show();
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static BluetoothLeListPreferenceDialog newInstance(String key) {
|
||||||
|
final BluetoothLeListPreferenceDialog fragment = new BluetoothLeListPreferenceDialog();
|
||||||
|
final Bundle b = new Bundle(1);
|
||||||
|
b.putString(ARG_KEY, key);
|
||||||
|
fragment.setArguments(b);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
BluetoothAdapter bluetoothAdapter = BluetoothUtils.getDefaultBluetoothAdapter(TAG);
|
||||||
|
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
|
||||||
|
Log.w(TAG, "Bluetooth adapter is present or not enabled.");
|
||||||
|
Toast.makeText(getContext(), R.string.bluetooth_disabled, Toast.LENGTH_SHORT).show();
|
||||||
|
dismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bluetoothAdapter.isDiscovering()) {
|
||||||
|
Log.i(TAG, "Cancelling ongoing bluetooth discovery.");
|
||||||
|
bluetoothAdapter.cancelDiscovery();
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner = bluetoothAdapter.getBluetoothLeScanner();
|
||||||
|
if (scanner == null) {
|
||||||
|
Log.e(TAG, "BluetoothLeScanner is null.");
|
||||||
|
dismiss();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String deviceNone = getContext().getString(R.string.sensor_type_value_none);
|
||||||
|
listAdapter.add(getContext().getString(R.string.value_none), deviceNone);
|
||||||
|
selectedEntryIndex = 0;
|
||||||
|
|
||||||
|
BluetoothLeListPreference preference = (BluetoothLeListPreference) getPreference();
|
||||||
|
String deviceSelected = preference.getValue();
|
||||||
|
if (!deviceNone.equals(deviceSelected)) {
|
||||||
|
listAdapter.add(preference.getValue(), preference.getValue());
|
||||||
|
selectedEntryIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanFilter.Builder scanFilterBuilder = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(BluetoothConnectionManager.HEART_RATE_SERVICE_UUID));
|
||||||
|
List<ScanFilter> scanFilter = new ArrayList<>();
|
||||||
|
scanFilter.add(scanFilterBuilder.build());
|
||||||
|
|
||||||
|
ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
|
||||||
|
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
|
||||||
|
|
||||||
|
scanner.startScan(scanFilter, scanSettingsBuilder.build(), scanCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Behave like ListPreferenceDialogFragmentCompat, but uses a custom listAdapter.
|
||||||
|
@Override
|
||||||
|
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||||
|
super.onPrepareDialogBuilder(builder);
|
||||||
|
|
||||||
|
builder.setSingleChoiceItems(listAdapter, selectedEntryIndex,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
selectedEntryIndex = which;
|
||||||
|
|
||||||
|
BluetoothLeListPreferenceDialog.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setIcon(android.R.drawable.stat_sys_data_bluetooth);
|
||||||
|
builder.setPositiveButton(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDialogClosed(boolean positiveResult) {
|
||||||
|
if (scanner != null) {
|
||||||
|
scanner.stopScan(scanCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (positiveResult && selectedEntryIndex >= 0) {
|
||||||
|
String value = listAdapter.get(selectedEntryIndex).getAddress();
|
||||||
|
BluetoothLeListPreference preference = (BluetoothLeListPreference) getPreference();
|
||||||
|
if (preference.callChangeListener(value)) {
|
||||||
|
preference.setValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
package de.dennisguse.opentracks.settings;
|
package de.dennisguse.opentracks.settings;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.preference.ListPreference;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.util.BluetoothUtils;
|
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.UnitConversions;
|
import de.dennisguse.opentracks.util.UnitConversions;
|
||||||
|
|
||||||
@@ -167,34 +160,4 @@ final class PreferenceHelper {
|
|||||||
|
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Configures the bluetooth sensor.
|
|
||||||
*/
|
|
||||||
static void configureBluetoothSensorList(ListPreference preference) {
|
|
||||||
Context context = preference.getContext();
|
|
||||||
|
|
||||||
String value = PreferencesUtils.getString(context, R.string.settings_sensor_bluetooth_sensor_key, PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT);
|
|
||||||
List<String> devicesNameList = new ArrayList<>();
|
|
||||||
List<String> devicesAddressList = new ArrayList<>();
|
|
||||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
|
||||||
if (bluetoothAdapter != null) {
|
|
||||||
BluetoothUtils.populateDeviceLists(bluetoothAdapter, devicesNameList, devicesAddressList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Was the previously configured device unpaired? Then forget it.
|
|
||||||
if (!devicesAddressList.contains(value)) {
|
|
||||||
value = PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT;
|
|
||||||
PreferencesUtils.setString(context, R.string.settings_sensor_bluetooth_sensor_key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
devicesNameList.add(0, context.getString(R.string.value_none));
|
|
||||||
devicesAddressList.add(0, PreferencesUtils.BLUETOOTH_SENSOR_DEFAULT);
|
|
||||||
|
|
||||||
String[] values = devicesAddressList.toArray(new String[0]);
|
|
||||||
preference.setEntryValues(values);
|
|
||||||
|
|
||||||
String[] options = devicesNameList.toArray(new String[0]);
|
|
||||||
preference.setEntries(options);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ import androidx.preference.PreferenceFragmentCompat;
|
|||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
import de.dennisguse.opentracks.fragments.ChooseActivityTypeDialogFragment;
|
||||||
|
import de.dennisguse.opentracks.util.BluetoothUtils;
|
||||||
import de.dennisguse.opentracks.util.HackUtils;
|
import de.dennisguse.opentracks.util.HackUtils;
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
import de.dennisguse.opentracks.util.StringUtils;
|
import de.dennisguse.opentracks.util.StringUtils;
|
||||||
|
|
||||||
public class SettingsActivity extends AppCompatActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, ResetDialogPreference.ResetCallback {
|
public class SettingsActivity extends AppCompatActivity implements ChooseActivityTypeDialogFragment.ChooseActivityTypeCaller, ResetDialogPreference.ResetCallback {
|
||||||
|
|
||||||
|
private static final String TAG = SettingsActivity.class.getSimpleName();
|
||||||
|
|
||||||
private PrefsFragment prefsFragment;
|
private PrefsFragment prefsFragment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -54,13 +57,14 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
|||||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
if (PreferencesUtils.isKey(getActivity(), R.string.recording_track_id_key, key)) {
|
||||||
@Override
|
getActivity().runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
@Override
|
||||||
updateUI();
|
public void run() {
|
||||||
}
|
updateReset();
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
if (PreferencesUtils.isKey(getActivity(), R.string.stats_units_key, key)) {
|
if (PreferencesUtils.isKey(getActivity(), R.string.stats_units_key, key)) {
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
getActivity().runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -69,6 +73,14 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (PreferencesUtils.isKey(getActivity(), R.string.chart_show_speed_key, key)) {
|
||||||
|
getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateSpeed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,7 +105,8 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
|||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
PreferencesUtils.getSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
PreferencesUtils.getSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||||
updateUI();
|
updateReset();
|
||||||
|
updateBluetooth();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,6 +123,8 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
|||||||
} else if (preference instanceof ActivityTypePreference) {
|
} else if (preference instanceof ActivityTypePreference) {
|
||||||
activityPreferenceDialog = ActivityTypePreference.ActivityPreferenceDialog.newInstance(preference.getKey());
|
activityPreferenceDialog = ActivityTypePreference.ActivityPreferenceDialog.newInstance(preference.getKey());
|
||||||
dialogFragment = activityPreferenceDialog;
|
dialogFragment = activityPreferenceDialog;
|
||||||
|
} else if (preference instanceof BluetoothLeListPreference) {
|
||||||
|
dialogFragment = BluetoothLeListPreference.BluetoothLeListPreferenceDialog.newInstance(preference.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogFragment != null) {
|
if (dialogFragment != null) {
|
||||||
@@ -127,17 +142,22 @@ public class SettingsActivity extends AppCompatActivity implements ChooseActivit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUI() {
|
private void updateReset() {
|
||||||
final boolean isRecording = PreferencesUtils.isRecording(getActivity());
|
final boolean isRecording = PreferencesUtils.isRecording(getActivity());
|
||||||
Preference resetPreference = findPreference(getString(R.string.settings_reset_key));
|
Preference resetPreference = findPreference(getString(R.string.settings_reset_key));
|
||||||
resetPreference.setSummary(isRecording ? getString(R.string.settings_not_while_recording) : "");
|
resetPreference.setSummary(isRecording ? getString(R.string.settings_not_while_recording) : "");
|
||||||
resetPreference.setEnabled(!isRecording);
|
resetPreference.setEnabled(!isRecording);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSpeed() {
|
||||||
Preference speedCheckBoxPreference = findPreference(getString(R.string.chart_show_speed_key));
|
Preference speedCheckBoxPreference = findPreference(getString(R.string.chart_show_speed_key));
|
||||||
speedCheckBoxPreference.setTitle(PreferencesUtils.isReportSpeed(getActivity()) ? R.string.stats_speed : R.string.stats_pace);
|
speedCheckBoxPreference.setTitle(PreferencesUtils.isReportSpeed(getActivity()) ? R.string.stats_speed : R.string.stats_pace);
|
||||||
|
}
|
||||||
|
|
||||||
ListPreference bluetoothPreference = findPreference(getString(R.string.settings_sensor_bluetooth_sensor_key));
|
private void updateBluetooth() {
|
||||||
PreferenceHelper.configureBluetoothSensorList(bluetoothPreference);
|
// Disable Bluetooth preference if device does not have Bluetooth
|
||||||
|
BluetoothLeListPreference bluetoothPreference = findPreference(getString(R.string.settings_sensor_bluetooth_sensor_key));
|
||||||
|
bluetoothPreference.setVisible(BluetoothUtils.hasBluetooth(TAG));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUnits() {
|
private void updateUnits() {
|
||||||
|
|||||||
@@ -16,16 +16,12 @@
|
|||||||
package de.dennisguse.opentracks.util;
|
package de.dennisguse.opentracks.util;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothClass;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for dealing with bluetooth devices.
|
* Utilities for dealing with bluetooth devices.
|
||||||
@@ -74,26 +70,8 @@ public class BluetoothUtils {
|
|||||||
return adapters.get(0);
|
return adapters.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static boolean hasBluetooth(final String TAG) {
|
||||||
* Populates the device names and the device addresses with all the suitable
|
return BluetoothUtils.getDefaultBluetoothAdapter(TAG) != null;
|
||||||
* bluetooth devices.
|
|
||||||
*
|
|
||||||
* @param bluetoothAdapter the bluetooth adapter
|
|
||||||
* @param deviceNames list of device names
|
|
||||||
* @param deviceAddresses list of device addresses
|
|
||||||
*/
|
|
||||||
public static void populateDeviceLists(BluetoothAdapter bluetoothAdapter, List<String> deviceNames, List<String> deviceAddresses) {
|
|
||||||
// Ensure the bluetooth adapter is not in discovery mode.
|
|
||||||
bluetoothAdapter.cancelDiscovery();
|
|
||||||
|
|
||||||
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
|
|
||||||
for (BluetoothDevice device : pairedDevices) {
|
|
||||||
BluetoothClass bluetoothClass = device.getBluetoothClass();
|
|
||||||
if (bluetoothClass != null && (bluetoothClass.getDeviceClass() & BluetoothClass.Device.HEALTH_PULSE_RATE) != 0) {
|
|
||||||
deviceAddresses.add(device.getAddress());
|
|
||||||
deviceNames.add(device.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int parseHeartRate(BluetoothGattCharacteristic characteristic) {
|
public static int parseHeartRate(BluetoothGattCharacteristic characteristic) {
|
||||||
|
|||||||
@@ -1055,7 +1055,13 @@ limitations under the License.
|
|||||||
Sending
|
Sending
|
||||||
</string>
|
</string>
|
||||||
<string name="sensor_not_known" translation_description="Error message if sensor is not available in Android (e.g., pairing was removed in Bluetooth Settings).">
|
<string name="sensor_not_known" translation_description="Error message if sensor is not available in Android (e.g., pairing was removed in Bluetooth Settings).">
|
||||||
Sensor %1$s is not known. Please check the settings.
|
Sensor %1$s is unknown. Please check the settings.
|
||||||
|
</string>
|
||||||
|
<string name="sensor_could_not_scan">
|
||||||
|
Could not scan for Bluetooth devices (error %1$i).
|
||||||
|
</string>
|
||||||
|
<string name="bluetooth_disabled">
|
||||||
|
Please enable Bluetooth.
|
||||||
</string>
|
</string>
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="settings_not_while_recording" translation_description="In settings, the summary for an option that is not available during a
|
<string name="settings_not_while_recording" translation_description="In settings, the summary for an option that is not available during a
|
||||||
@@ -1220,7 +1226,7 @@ limitations under the License.
|
|||||||
</string>
|
</string>
|
||||||
|
|
||||||
<string name="settings_error_initial_values_restored" translation_description="If the ">
|
<string name="settings_error_initial_values_restored" translation_description="If the ">
|
||||||
Sorry, but an error occurred: and the all settings were reset to there default values.
|
Sorry, but an error occurred. All settings have been reverted to the default values.
|
||||||
</string>
|
</string>
|
||||||
|
|
||||||
<!-- Settings Sensor -->
|
<!-- Settings Sensor -->
|
||||||
|
|||||||
@@ -130,11 +130,10 @@ limitations under the License.
|
|||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/settings_sensor">
|
<PreferenceCategory android:title="@string/settings_sensor">
|
||||||
<ListPreference
|
<de.dennisguse.opentracks.settings.BluetoothLeListPreference
|
||||||
android:defaultValue="@string/sensor_type_value_none"
|
android:defaultValue="@string/sensor_type_value_none"
|
||||||
android:key="@string/settings_sensor_bluetooth_sensor_key"
|
android:key="@string/settings_sensor_bluetooth_sensor_key"
|
||||||
android:title="@string/settings_sensor_bluetooth_sensor"
|
android:title="@string/settings_sensor_bluetooth_sensor" />
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="@string/settings_sensor_bluetooth_pairing_key"
|
android:key="@string/settings_sensor_bluetooth_pairing_key"
|
||||||
android:persistent="false"
|
android:persistent="false"
|
||||||
|
|||||||
Reference in New Issue
Block a user