mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-24 19:06:53 +01:00
Added scannable-only devices (#3621)
Co-authored-by: Daniel Dakhno <dakhnod@gmail.com> Co-committed-by: Daniel Dakhno <dakhnod@gmail.com>
This commit is contained in:
parent
bf762a25a5
commit
8cf87a418b
@ -1005,10 +1005,15 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
return;
|
||||
}
|
||||
DeviceType deviceType = DeviceType.values()[(int) deviceKey];
|
||||
String deviceName = deviceType.name();
|
||||
int deviceNameResource = deviceType.getDeviceCoordinator().getDeviceNameResource();
|
||||
if(deviceNameResource != 0){
|
||||
deviceName = context.getString(deviceNameResource);
|
||||
}
|
||||
try (
|
||||
DBHandler db = GBApplication.acquireDB()) {
|
||||
DaoSession daoSession = db.getDaoSession();
|
||||
GBDevice gbDevice = new GBDevice(deviceMac, deviceType.name(), "", null, deviceType);
|
||||
GBDevice gbDevice = new GBDevice(deviceMac, deviceName, "", null, deviceType);
|
||||
gbDevice.setFirmwareVersion("N/A");
|
||||
gbDevice.setFirmwareVersion2("N/A");
|
||||
|
||||
@ -1018,7 +1023,7 @@ public class DebugActivity extends AbstractGBActivity {
|
||||
Device device = DBHelper.getDevice(gbDevice, daoSession); //the addition happens here
|
||||
Intent refreshIntent = new Intent(DeviceManager.ACTION_REFRESH_DEVICELIST);
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(refreshIntent);
|
||||
GB.toast(context, "Added test device: " + deviceType.name(), Toast.LENGTH_SHORT, GB.INFO);
|
||||
GB.toast(context, "Added test device: " + deviceName, Toast.LENGTH_SHORT, GB.INFO);
|
||||
|
||||
} catch (
|
||||
Exception e) {
|
||||
|
@ -258,6 +258,16 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
|
||||
holder.root.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
|
||||
}
|
||||
|
||||
void handleDeviceConnect(GBDevice device){
|
||||
if(!device.getDeviceCoordinator().isConnectable()){
|
||||
device.setState(GBDevice.State.WAITING_FOR_SCAN);
|
||||
device.sendDeviceUpdateIntent(GBApplication.getContext(), GBDevice.DeviceUpdateSubject.CONNECTION_STATE);
|
||||
return;
|
||||
}
|
||||
|
||||
GBApplication.deviceService(device).connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
|
||||
final GBDevice device = devicesListWithFolders.get(position);
|
||||
@ -298,7 +308,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
createDynamicShortcut(device);
|
||||
}
|
||||
GBApplication.deviceService(device).connect();
|
||||
handleDeviceConnect(device);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -853,7 +863,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
|
||||
case R.id.controlcenter_device_submenu_connect:
|
||||
if (device.getState() != GBDevice.State.CONNECTED) {
|
||||
showTransientSnackbar(R.string.controlcenter_snackbar_connecting);
|
||||
GBApplication.deviceService(device).connect();
|
||||
handleDeviceConnect(device);
|
||||
}
|
||||
return true;
|
||||
case R.id.controlcenter_device_submenu_disconnect:
|
||||
|
@ -115,6 +115,11 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
||||
return ConnectionType.BOTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectable(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Collection<? extends ScanFilter> createBLEScanFilters() {
|
||||
|
@ -123,6 +123,14 @@ public interface DeviceCoordinator {
|
||||
*/
|
||||
ConnectionType getConnectionType();
|
||||
|
||||
/**
|
||||
* Returns false is the Device is not connectable,
|
||||
* only scannable, like beacons
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
boolean isConnectable();
|
||||
|
||||
/**
|
||||
* Checks whether this coordinator handles the given candidate.
|
||||
*
|
||||
|
@ -0,0 +1,61 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.scannable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
|
||||
public class ScannableDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
@Override
|
||||
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getSupportedDeviceSpecificApplicationSettings() {
|
||||
return new int[]{
|
||||
R.xml.devicesettings_scannable
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnectable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManufacturer() {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Class<? extends DeviceSupport> getDeviceSupportClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeviceNameResource() {
|
||||
return R.string.devicetype_scannable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBatteryCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultIconResource() {
|
||||
return R.drawable.ic_device_scannable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisabledIconResource() {
|
||||
return R.drawable.ic_device_scannable_disabled;
|
||||
}
|
||||
}
|
@ -310,7 +310,7 @@ public class GBDevice implements Parcelable {
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return mState.equalsOrHigherThan(State.CONNECTED);
|
||||
return mState == State.SCANNED || mState.equalsOrHigherThan(State.CONNECTED);
|
||||
}
|
||||
|
||||
public boolean isInitializing() {
|
||||
@ -318,7 +318,7 @@ public class GBDevice implements Parcelable {
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return mState.equalsOrHigherThan(State.INITIALIZED);
|
||||
return mState == State.SCANNED || mState.equalsOrHigherThan(State.INITIALIZED);
|
||||
}
|
||||
|
||||
public boolean isConnecting() {
|
||||
@ -728,6 +728,7 @@ public class GBDevice implements Parcelable {
|
||||
NOT_CONNECTED(R.string.not_connected),
|
||||
WAITING_FOR_RECONNECT(R.string.waiting_for_reconnect),
|
||||
WAITING_FOR_SCAN(R.string.device_state_waiting_scan),
|
||||
SCANNED(R.string.state_scanned),
|
||||
CONNECTING(R.string.connecting),
|
||||
CONNECTED(R.string.connected, R.string.connecting),
|
||||
INITIALIZING(R.string.initializing, R.string.connecting),
|
||||
|
@ -151,6 +151,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.qc35.QC35Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi1Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi3Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.scannable.ScannableDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.smaq2oss.SMAQ2OSSCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.soflow.SoFlowCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sony.headphones.coordinators.SonyLinkBudsCoordinator;
|
||||
@ -374,6 +375,7 @@ public enum DeviceType {
|
||||
SONY_WENA_3(SonyWena3Coordinator.class),
|
||||
FEMOMETER_VINCA2(FemometerVinca2DeviceCoordinator.class),
|
||||
PIXOO(PixooCoordinator.class),
|
||||
SCANNABLE(ScannableDeviceCoordinator.class),
|
||||
TEST(TestDeviceCoordinator.class);
|
||||
|
||||
private DeviceCoordinator coordinator;
|
||||
|
@ -255,6 +255,8 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
||||
|
||||
private OsmandEventReceiver mOsmandAidlHelper = null;
|
||||
|
||||
private HashMap<String, Long> deviceLastScannedTimestamps = new HashMap<>();
|
||||
|
||||
private final String[] mMusicActions = {
|
||||
"com.android.music.metachanged",
|
||||
"com.android.music.playstatechanged",
|
||||
@ -270,21 +272,26 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
||||
|
||||
private final String COMMAND_BLUETOOTH_CONNECT = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECT";
|
||||
private final String ACTION_DEVICE_CONNECTED = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_CONNECTED";
|
||||
private final String ACTION_DEVICE_SCANNED = "nodomain.freeyourgadget.gadgetbridge.BLUETOOTH_SCANNED";
|
||||
private final int NOTIFICATIONS_CACHE_MAX = 10; // maximum amount of notifications to cache per device while disconnected
|
||||
private boolean allowBluetoothIntentApi = false;
|
||||
private boolean reconnectViaScan = GBPrefs.RECONNECT_SCAN_DEFAULT;
|
||||
|
||||
private void sendDeviceConnectedBroadcast(String address){
|
||||
private void sendDeviceAPIBroadcast(String address, String action){
|
||||
if(!allowBluetoothIntentApi){
|
||||
GB.log("not sending API event due to settings", GB.INFO, null);
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(ACTION_DEVICE_CONNECTED);
|
||||
Intent intent = new Intent(action);
|
||||
intent.putExtra("EXTRA_DEVICE_ADDRESS", address);
|
||||
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
|
||||
private void sendDeviceConnectedBroadcast(String address){
|
||||
sendDeviceAPIBroadcast(address, ACTION_DEVICE_CONNECTED);
|
||||
}
|
||||
|
||||
BroadcastReceiver bluetoothCommandReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@ -368,6 +375,8 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
||||
LOG.debug("device state update reason");
|
||||
sendDeviceConnectedBroadcast(device.getAddress());
|
||||
sendCachedNotifications(device);
|
||||
}else if(subject == GBDevice.DeviceUpdateSubject.CONNECTION_STATE && (device.getState() == GBDevice.State.SCANNED)){
|
||||
sendDeviceAPIBroadcast(device.getAddress(), ACTION_DEVICE_SCANNED);
|
||||
}
|
||||
}else if(BLEScanService.EVENT_DEVICE_FOUND.equals(action)){
|
||||
String deviceAddress = intent.getStringExtra(BLEScanService.EXTRA_DEVICE_ADDRESS);
|
||||
@ -382,6 +391,44 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
||||
return;
|
||||
}
|
||||
|
||||
if(!target.getDeviceCoordinator().isConnectable()){
|
||||
int actualRSSI = intent.getIntExtra(BLEScanService.EXTRA_RSSI, 0);
|
||||
Prefs prefs = new Prefs(
|
||||
GBApplication.getDeviceSpecificSharedPrefs(target.getAddress())
|
||||
);
|
||||
long timeoutSeconds = prefs.getLong("devicesetting_scannable_debounce", 60);
|
||||
long minimumUnseenSeconds = prefs.getLong("devicesetting_scannable_unseen", 0);
|
||||
int thresholdRSSI = prefs.getInt("devicesetting_scannable_rssi", -100);
|
||||
|
||||
if(actualRSSI < thresholdRSSI){
|
||||
LOG.debug("ignoring {} since RSSI is too low ({} < {})", deviceAddress, actualRSSI, thresholdRSSI);
|
||||
return;
|
||||
}
|
||||
|
||||
Long lastSeenTimestamp = deviceLastScannedTimestamps.get(deviceAddress);
|
||||
deviceLastScannedTimestamps.put(deviceAddress, System.currentTimeMillis());
|
||||
|
||||
if(lastSeenTimestamp != null){
|
||||
long secondsSince = (System.currentTimeMillis() - lastSeenTimestamp) / 1000;
|
||||
if(secondsSince < minimumUnseenSeconds){
|
||||
LOG.debug("ignoring {}, since only {} seconds passed (< {})", deviceAddress, secondsSince, minimumUnseenSeconds);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
target.setState(GBDevice.State.SCANNED);
|
||||
target.sendDeviceUpdateIntent(DeviceCommunicationService.this, GBDevice.DeviceUpdateSubject.CONNECTION_STATE);
|
||||
new Handler().postDelayed(() -> {
|
||||
if(target.getState() != GBDevice.State.SCANNED){
|
||||
return;
|
||||
}
|
||||
deviceLastScannedTimestamps.put(target.getAddress(), System.currentTimeMillis());
|
||||
target.setState(GBDevice.State.WAITING_FOR_SCAN);
|
||||
target.sendDeviceUpdateIntent(DeviceCommunicationService.this, GBDevice.DeviceUpdateSubject.CONNECTION_STATE);
|
||||
}, timeoutSeconds * 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
connectToDevice(target);
|
||||
}
|
||||
}
|
||||
@ -501,6 +548,11 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
||||
}
|
||||
|
||||
private void connectToDevice(GBDevice device, boolean firstTime){
|
||||
if(!device.getDeviceCoordinator().isConnectable()){
|
||||
GB.toast("Cannot connect to Scannable Device", Toast.LENGTH_SHORT, GB.INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
List<GBDevice> gbDevs = null;
|
||||
boolean fromExtra = false;
|
||||
|
||||
|
@ -62,6 +62,7 @@ public class BLEScanService extends Service {
|
||||
|
||||
public static final String EXTRA_DEVICE = "EXTRA_DEVICE";
|
||||
public static final String EXTRA_DEVICE_ADDRESS = "EXTRA_DEVICE_ADDRESS";
|
||||
public static final String EXTRA_RSSI = "EXTRA_RSSI";
|
||||
|
||||
// 5 minutes scan restart interval
|
||||
private final int DELAY_SCAN_RESTART = 5 * 60 * 1000;
|
||||
@ -100,6 +101,7 @@ public class BLEScanService extends Service {
|
||||
|
||||
Intent intent = new Intent(EVENT_DEVICE_FOUND);
|
||||
intent.putExtra(EXTRA_DEVICE_ADDRESS, device.getAddress());
|
||||
intent.putExtra(EXTRA_RSSI, result.getRssi());
|
||||
localBroadcastManager.sendBroadcast(intent);
|
||||
|
||||
// device found, attempt connection
|
||||
|
28
app/src/main/res/drawable/ic_device_scannable.xml
Normal file
28
app/src/main/res/drawable/ic_device_scannable.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:name="vector"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="30"
|
||||
android:viewportHeight="30">
|
||||
<path
|
||||
android:name="path"
|
||||
android:pathData="M 3.871 3.877 L 24.796 3.877 C 24.962 3.877 25.126 3.92 25.27 4.004 C 25.414 4.087 25.534 4.206 25.617 4.35 C 25.7 4.494 25.744 4.658 25.744 4.824 L 25.744 24.834 C 25.744 25 25.7 25.164 25.617 25.308 C 25.534 25.452 25.414 25.572 25.27 25.655 C 25.126 25.738 24.962 25.782 24.796 25.782 L 3.871 25.782 C 3.705 25.782 3.541 25.738 3.397 25.655 C 3.253 25.572 3.134 25.452 3.051 25.308 C 2.967 25.164 2.924 25 2.924 24.834 L 2.924 4.824 C 2.924 4.573 3.024 4.332 3.201 4.154 C 3.379 3.977 3.62 3.877 3.871 3.877 Z"
|
||||
android:fillColor="#1f7fdb"
|
||||
android:strokeWidth="1"/>
|
||||
<path
|
||||
android:name="path_1"
|
||||
android:pathData="M 3.879 3.035 L 24.804 3.035 C 25.055 3.035 25.296 3.135 25.474 3.312 C 25.651 3.49 25.751 3.731 25.751 3.982 L 25.751 23.992 C 25.751 24.158 25.708 24.322 25.624 24.466 C 25.541 24.61 25.422 24.73 25.278 24.813 C 25.134 24.896 24.97 24.94 24.804 24.94 L 3.88 24.94 C 3.714 24.94 3.55 24.896 3.406 24.813 C 3.262 24.73 3.143 24.61 3.06 24.466 C 2.976 24.322 2.933 24.158 2.933 23.992 L 2.933 3.982 C 2.933 3.731 3.033 3.49 3.21 3.312 C 3.388 3.135 3.629 3.035 3.88 3.035 Z"
|
||||
android:fillColor="#4dabf5"
|
||||
android:strokeWidth="1"/>
|
||||
<path
|
||||
android:name="path_2"
|
||||
android:pathData="M 3.871 3.413 L 24.796 3.413 C 24.962 3.413 25.126 3.456 25.27 3.54 C 25.414 3.623 25.534 3.742 25.617 3.886 C 25.7 4.03 25.744 4.194 25.744 4.36 L 25.744 24.37 C 25.744 24.536 25.7 24.7 25.617 24.844 C 25.534 24.988 25.414 25.108 25.27 25.191 C 25.126 25.274 24.962 25.318 24.796 25.318 L 3.871 25.318 C 3.705 25.318 3.541 25.274 3.397 25.191 C 3.253 25.108 3.134 24.988 3.051 24.844 C 2.967 24.7 2.924 24.536 2.924 24.37 L 2.924 4.36 C 2.924 4.109 3.024 3.868 3.201 3.691 C 3.378 3.513 3.619 3.413 3.87 3.413 Z"
|
||||
android:fillColor="#2196f3"
|
||||
android:strokeWidth="1"/>
|
||||
<path
|
||||
android:name="path_3"
|
||||
android:pathData="M 16.122 14.46 L 17.825 16.245 C 18.03 15.691 18.148 15.083 18.148 14.452 C 18.148 13.821 18.03 13.229 17.832 12.675 Z M 20.005 10.382 L 19.08 11.351 C 19.543 12.282 19.8 13.329 19.8 14.444 C 19.8 15.56 19.535 16.614 19.08 17.538 L 19.961 18.461 C 20.673 17.276 21.092 15.875 21.092 14.375 C 21.084 12.921 20.688 11.551 20.005 10.382 Z M 17.201 11.151 L 13.009 6.758 L 12.275 6.758 L 12.275 12.598 L 8.906 9.066 L 7.871 10.151 L 11.974 14.452 L 7.871 18.753 L 8.906 19.838 L 12.275 16.306 L 12.275 22.147 L 13.009 22.147 L 17.201 17.753 L 14.044 14.452 Z M 13.743 9.705 L 15.123 11.151 L 13.743 12.598 Z M 15.123 17.753 L 13.743 19.2 L 13.743 16.306 Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeWidth="1"/>
|
||||
</vector>
|
26
app/src/main/res/drawable/ic_device_scannable_disabled.xml
Normal file
26
app/src/main/res/drawable/ic_device_scannable_disabled.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:name="vector"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="30"
|
||||
android:viewportHeight="30">
|
||||
<path
|
||||
android:fillColor="#7a7a7a"
|
||||
android:pathData="M3.871 3.877h20.925a0.947 0.947 0 0 1 0.948 0.947v20.01a0.947 0.947 0 0 1-0.948 0.948H3.871a0.947 0.947 0 0 1-0.947-0.948V4.824a0.947 0.947 0 0 1 0.947-0.947z"
|
||||
android:strokeWidth="3.57115173" />
|
||||
<path
|
||||
android:fillAlpha="0.9411765"
|
||||
android:fillColor="#9f9f9f"
|
||||
android:pathData="M3.879 3.035h20.925a0.947 0.947 0 0 1 0.947 0.947v20.01a0.947 0.947 0 0 1-0.947 0.948H3.88a0.947 0.947 0 0 1-0.947-0.948V3.982A0.947 0.947 0 0 1 3.88 3.035z"
|
||||
android:strokeWidth="3.57115173" />
|
||||
<path
|
||||
android:fillColor="#8a8a8a"
|
||||
android:pathData="M3.871 3.413h20.925a0.947 0.947 0 0 1 0.948 0.947v20.01a0.947 0.947 0 0 1-0.948 0.948H3.871a0.947 0.947 0 0 1-0.947-0.948V4.36A0.947 0.947 0 0 1 3.87 3.413z"
|
||||
android:strokeWidth="3.57115173" />
|
||||
<path
|
||||
android:name="path_3"
|
||||
android:pathData="M 16.122 14.46 L 17.825 16.245 C 18.03 15.691 18.148 15.083 18.148 14.452 C 18.148 13.821 18.03 13.229 17.832 12.675 Z M 20.005 10.382 L 19.08 11.351 C 19.543 12.282 19.8 13.329 19.8 14.444 C 19.8 15.56 19.535 16.614 19.08 17.538 L 19.961 18.461 C 20.673 17.276 21.092 15.875 21.092 14.375 C 21.084 12.921 20.688 11.551 20.005 10.382 Z M 17.201 11.151 L 13.009 6.758 L 12.275 6.758 L 12.275 12.598 L 8.906 9.066 L 7.871 10.151 L 11.974 14.452 L 7.871 18.753 L 8.906 19.838 L 12.275 16.306 L 12.275 22.147 L 13.009 22.147 L 17.201 17.753 L 14.044 14.452 Z M 13.743 9.705 L 15.123 11.151 L 13.743 12.598 Z M 15.123 17.753 L 13.743 19.2 L 13.743 16.306 Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeWidth="1"/>
|
||||
</vector>
|
@ -2711,4 +2711,12 @@
|
||||
<string name="unbind_before_pair_message">This device is already bound in Android settings, which can make pairing fail for some devices.\n\nIf adding the device fails, please remove it in Android settings and try again.</string>
|
||||
<string name="companion_pairing_request_title">Companion device</string>
|
||||
<string name="companion_pairing_request_description">Pair this device as companion?.\n\nThis is recommended for some functions such as find device, and provides a better connection.</string>
|
||||
<string name="devicetype_scannable">Scannable device</string>
|
||||
<string name="state_scanned">Scanned</string>
|
||||
<string name="devicesetting_scannable_debounce">Scannable debounce timeout (seconds)</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen">Minimum unseen time (seconds)</string>
|
||||
<string name="devicesetting_scannable_rssi">Minimal RSSI threshold</string>
|
||||
<string name="devicesetting_scannable_debounce_summary">After being scanned, the device will stick as scanned and ignored for the specified amount of time</string>
|
||||
<string name="devicesetting_scannable_minimum_unseen_summary">After being scanned, the device has to be unseen for this amount of time before being registered again</string>
|
||||
<string name="devicesetting_scannable_rssi_summary">The minimum RSSI threshold for detection</string>
|
||||
</resources>
|
||||
|
29
app/src/main/res/xml/devicesettings_scannable.xml
Normal file
29
app/src/main/res/xml/devicesettings_scannable.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<EditTextPreference
|
||||
android:title="@string/devicesetting_scannable_debounce"
|
||||
android:summary="@string/devicesetting_scannable_debounce_summary"
|
||||
android:key="devicesetting_scannable_debounce"
|
||||
android:defaultValue="60"
|
||||
android:inputType="number" />
|
||||
|
||||
<EditTextPreference
|
||||
android:title="@string/devicesetting_scannable_minimum_unseen"
|
||||
android:summary="@string/devicesetting_scannable_minimum_unseen_summary"
|
||||
android:key="devicesetting_scannable_unseen"
|
||||
android:defaultValue="0"
|
||||
android:inputType="number" />
|
||||
|
||||
<EditTextPreference
|
||||
android:title="@string/devicesetting_scannable_rssi"
|
||||
android:summary="@string/devicesetting_scannable_rssi_summary"
|
||||
android:key="devicesetting_scannable_rssi"
|
||||
android:defaultValue="-100"
|
||||
android:min="-100"
|
||||
android:max="0"
|
||||
android:inputType="number" />
|
||||
|
||||
</PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user