diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java
index dc47d2c2c..cb2a69d6e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FindPhoneActivity.java
@@ -25,7 +25,10 @@ import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+import android.os.VibrationEffect;
+import android.os.Vibrator;
import android.view.View;
import android.widget.Button;
@@ -58,6 +61,7 @@ public class FindPhoneActivity extends AbstractGBActivity {
}
};
+ Vibrator mVibrator;
AudioManager mAudioManager;
int userVolume;
MediaPlayer mp;
@@ -79,10 +83,26 @@ public class FindPhoneActivity extends AbstractGBActivity {
finish();
}
});
+
+ vibrate();
playRingtone();
}
- public void playRingtone(){
+ private void vibrate(){
+ mVibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
+
+ long[] vibrationPattern = new long[]{ 1000, 1000 };
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ VibrationEffect vibrationEffect = VibrationEffect.createWaveform(vibrationPattern, 0);
+
+ mVibrator.vibrate(vibrationEffect);
+ } else {
+ mVibrator.vibrate(vibrationPattern, 0);
+ }
+ }
+
+ private void playRingtone(){
mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
if (mAudioManager != null) {
userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
@@ -107,7 +127,11 @@ public class FindPhoneActivity extends AbstractGBActivity {
}
}
- public void stopSound() {
+ private void stopVibration() {
+ mVibrator.cancel();
+ }
+
+ private void stopSound() {
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, userVolume, AudioManager.FLAG_PLAY_SOUND);
mp.stop();
mp.reset();
@@ -116,7 +140,10 @@ public class FindPhoneActivity extends AbstractGBActivity {
@Override
protected void onDestroy() {
super.onDestroy();
+
+ stopVibration();
stopSound();
+
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
unregisterReceiver(mReceiver);
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java
index cb1fe6c63..90d75ef58 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/devicesettings/DeviceSpecificSettingsFragment.java
@@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory;
import java.util.Objects;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
+import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Constants;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
@@ -369,15 +370,25 @@ public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
});
}
- EditTextPreference pref = findPreference(MiBandConst.PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS);
- if (pref != null) {
- pref.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
+ EditTextPreference mibandTimeOffset = findPreference(MiBandConst.PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS);
+ if (mibandTimeOffset != null) {
+ mibandTimeOffset.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED);
}
});
}
+
+ EditTextPreference findPhoneDuration = findPreference(MakibesHR3Constants.PREF_FIND_PHONE_DURATION);
+ if (findPhoneDuration != null) {
+ findPhoneDuration.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
+ @Override
+ public void onBindEditText(@NonNull EditText editText) {
+ editText.setInputType(InputType.TYPE_CLASS_NUMBER);
+ }
+ });
+ }
}
static DeviceSpecificSettingsFragment newInstance(String settingsFileSuffix, @NonNull int[] supportedSettings) {
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java
index 4bf250bea..7a717c18b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Constants.java
@@ -28,6 +28,8 @@ public final class MakibesHR3Constants {
public static final String PREF_DO_NOT_DISTURB = "do_not_disturb_no_auto";
public static final String PREF_DO_NOT_DISTURB_START = "do_not_disturb_no_auto_start";
public static final String PREF_DO_NOT_DISTURB_END = "do_not_disturb_no_auto_end";
+ public static final String PREF_FIND_PHONE = "prefs_find_phone";
+ public static final String PREF_FIND_PHONE_DURATION = "prefs_find_phone_duration";
public static final UUID UUID_SERVICE = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
public static final UUID UUID_CHARACTERISTIC_CONTROL = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java
index 105d929f4..2b6276b75 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/makibeshr3/MakibesHR3Coordinator.java
@@ -39,7 +39,6 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
-import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySampleDao;
@@ -53,6 +52,9 @@ import static nodomain.freeyourgadget.gadgetbridge.GBApplication.getContext;
public class MakibesHR3Coordinator extends AbstractDeviceCoordinator {
+ public static final int FindPhone_ON = -1;
+ public static final int FindPhone_OFF = 0;
+
private static final Logger LOG = LoggerFactory.getLogger(MakibesHR3Coordinator.class);
@@ -108,6 +110,37 @@ public class MakibesHR3Coordinator extends AbstractDeviceCoordinator {
}
}
+ /**
+ * @return {@link #FindPhone_OFF}, {@link #FindPhone_ON}, or the duration
+ */
+ public static int getFindPhone(SharedPreferences sharedPrefs) {
+ String findPhone = sharedPrefs.getString(MakibesHR3Constants.PREF_FIND_PHONE, getContext().getString(R.string.p_off));
+
+ if (findPhone.equals(getContext().getString(R.string.p_off))) {
+ return FindPhone_OFF;
+ } else if (findPhone.equals(getContext().getString(R.string.p_on))) {
+ return FindPhone_ON;
+ } else { // Duration
+ String duration = sharedPrefs.getString(MakibesHR3Constants.PREF_FIND_PHONE_DURATION, "0");
+
+ try {
+ int iDuration;
+
+ try {
+ iDuration = Integer.valueOf(duration);
+ } catch (Exception ex) {
+ LOG.warn(ex.getMessage());
+ iDuration = 60;
+ }
+
+ return iDuration;
+ } catch (Exception e) {
+ LOG.error("Unexpected exception in MiBand2Coordinator.getTime: " + e.getMessage());
+ return FindPhone_ON;
+ }
+ }
+ }
+
@NonNull
@Override
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
@@ -225,7 +258,8 @@ public class MakibesHR3Coordinator extends AbstractDeviceCoordinator {
R.xml.devicesettings_timeformat,
R.xml.devicesettings_liftwrist_display,
R.xml.devicesettings_disconnectnotification,
- R.xml.devicesettings_donotdisturb_no_auto
+ R.xml.devicesettings_donotdisturb_no_auto,
+ R.xml.devicesettings_find_phone
};
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java
index e06cc605d..bc6830e25 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/makibeshr3/MakibesHR3DeviceSupport.java
@@ -17,15 +17,11 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.makibeshr3;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
-import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
-import android.os.Build;
import android.os.CountDownTimer;
import android.os.Handler;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
import android.widget.Toast;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -47,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSett
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
+import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventFindPhone;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Constants;
import nodomain.freeyourgadget.gadgetbridge.devices.makibeshr3.MakibesHR3Coordinator;
@@ -77,9 +74,6 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
private static final Logger LOG = LoggerFactory.getLogger(MakibesHR3DeviceSupport.class);
- private Handler mVibrationHandler = new Handler();
- private Vibrator mVibrator;
-
// The delay must be at least as long as it takes the watch to respond.
// Reordering the requests could maybe reduce the delay, but this works fine too.
private CountDownTimer mFetchCountDown = new CountDownTimer(2000, 2000) {
@@ -95,6 +89,8 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
}
};
+ private Handler mFindPhoneHandler = new Handler();
+
private BluetoothGattCharacteristic mControlCharacteristic = null;
private BluetoothGattCharacteristic mReportCharacteristic = null;
@@ -413,35 +409,35 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
}
private void onReverseFindDevice(boolean start) {
- if (this.mVibrator.hasVibrator()) {
- final long[] PATTERN = new long[]{
- 100, 100,
- 100, 100,
- 100, 100,
- 500
- };
+ if (start) {
+ SharedPreferences sharedPreferences = GBApplication.getDeviceSpecificSharedPrefs(
+ this.getDevice().getAddress());
- if (start) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- this.mVibrator.vibrate(VibrationEffect.createWaveform(PATTERN, 0));
- } else {
- this.mVibrator.vibrate(PATTERN, 0);
+ int findPhone = MakibesHR3Coordinator.getFindPhone(sharedPreferences);
+
+ if (findPhone != MakibesHR3Coordinator.FindPhone_OFF) {
+ GBDeviceEventFindPhone findPhoneEvent = new GBDeviceEventFindPhone();
+
+ findPhoneEvent.event = GBDeviceEventFindPhone.Event.START;
+
+ evaluateGBDeviceEvent(findPhoneEvent);
+
+ if (findPhone > 0) {
+ this.mFindPhoneHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ onReverseFindDevice(false);
+ }
+ }, findPhone * 1000);
}
-
- // In case the connection is closed while we're searching for the device.
-
- this.mVibrationHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mVibrator.cancel();
- }
- }, 1100 * 6);
-
- } else {
- this.mVibrator.cancel();
}
} else {
- // TODO: Alternative handling. Don't use sound, the connection isn't secure.
+ // Always send stop, ignore preferences.
+ GBDeviceEventFindPhone findPhoneEvent = new GBDeviceEventFindPhone();
+
+ findPhoneEvent.event = GBDeviceEventFindPhone.Event.STOP;
+
+ evaluateGBDeviceEvent(findPhoneEvent);
}
}
@@ -555,6 +551,9 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
key.equals(MakibesHR3Constants.PREF_DO_NOT_DISTURB_START) ||
key.equals(MakibesHR3Constants.PREF_DO_NOT_DISTURB_END)) {
this.setQuiteHours(transactionBuilder, sharedPreferences);
+ } else if (key.equals(MakibesHR3Constants.PREF_FIND_PHONE) ||
+ key.equals(MakibesHR3Constants.PREF_FIND_PHONE_DURATION)) {
+ // No action, we check the shared preferences when the device tries to ring the phone.
} else {
return;
}
@@ -594,8 +593,6 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
this.mControlCharacteristic = getCharacteristic(MakibesHR3Constants.UUID_CHARACTERISTIC_CONTROL);
this.mReportCharacteristic = getCharacteristic(MakibesHR3Constants.UUID_CHARACTERISTIC_REPORT);
- this.mVibrator = (Vibrator) this.getContext().getSystemService(Context.VIBRATOR_SERVICE);
-
builder.notify(this.mReportCharacteristic, true);
builder.setGattCallback(this);
diff --git a/app/src/main/res/drawable/ic_find_lost_phone.xml b/app/src/main/res/drawable/ic_find_lost_phone.xml
new file mode 100644
index 000000000..2740ef687
--- /dev/null
+++ b/app/src/main/res/drawable/ic_find_lost_phone.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index 13f301202..6a38a6e9b 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -141,6 +141,18 @@
- @string/p_pebble_privacy_mode_complete
+
+ - @string/off
+ - @string/on
+ - @string/maximum_duration
+
+
+
+ - @string/p_off
+ - @string/p_on
+ - @string/p_scheduled
+
+
- @string/dateformat_time
- @string/dateformat_date_time
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index af3b3a1c8..bde362b57 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -445,6 +445,10 @@
Alarms to reserve for upcoming events
Use heart rate sensor to improve sleep detection
Device time offset in hours (for detecting sleep of shift workers)
+ Find phone
+ Enable find phone
+ Use your band to play your phone\'s ringtone.
+ Ring duration in seconds
Date format
Time
@@ -600,6 +604,7 @@
At sunset
Automatic (sleep detection)
Scheduled (time interval)
+ Duration
Attempting to pair with %1$s
Bonding with %1$s failed immediately.
Trying to connect to: %1$s
diff --git a/app/src/main/res/xml/devicesettings_find_phone.xml b/app/src/main/res/xml/devicesettings_find_phone.xml
new file mode 100644
index 000000000..5baec8c70
--- /dev/null
+++ b/app/src/main/res/xml/devicesettings_find_phone.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file