diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java index 8121d80dd2..97b50fca3b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Widget.java @@ -143,6 +143,8 @@ public class Widget extends AppWidgetProvider { if (sleep < 1) { views.setViewVisibility(R.id.todaywidget_sleep_layout, View.GONE); + } else { + views.setViewVisibility(R.id.todaywidget_sleep_layout, View.VISIBLE); } views.setTextViewText(R.id.todaywidget_steps, String.format("%1s", steps)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index d34ec77600..a1a1dc3eec 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -57,6 +57,7 @@ import android.widget.Toast; import androidx.core.app.NavUtils; import androidx.core.app.NotificationCompat; import androidx.core.app.RemoteInput; +import androidx.core.content.FileProvider; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.slf4j.Logger; @@ -681,10 +682,17 @@ public class DebugActivity extends AbstractGBActivity { return; } + final Uri providerUri = FileProvider.getUriForFile( + this, + getApplicationContext().getPackageName() + ".screenshot_provider", + logFile + ); + Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); + emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); emailIntent.setType("*/*"); emailIntent.putExtra(EXTRA_SUBJECT, "Gadgetbridge log file"); - emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(logFile)); + emailIntent.putExtra(Intent.EXTRA_STREAM, providerUri); startActivity(Intent.createChooser(emailIntent, "Share File")); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java index 2ba857dabe..056cdd6c40 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java @@ -198,6 +198,8 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView } } }; + int CallbackType = android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; + int MatchMode = android.bluetooth.le.ScanSettings.MATCH_MODE_STICKY; public void logMessageContent(byte[] value) { if (value != null) { @@ -654,17 +656,17 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView private ScanSettings getScanSettings() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { return new ScanSettings.Builder() - .setCallbackType(android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setCallbackType(CallbackType) .setScanMode(android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_LATENCY) - .setMatchMode(android.bluetooth.le.ScanSettings.MATCH_MODE_AGGRESSIVE) + .setMatchMode(MatchMode) .setPhy(android.bluetooth.le.ScanSettings.PHY_LE_ALL_SUPPORTED) .setNumOfMatches(android.bluetooth.le.ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT) .build(); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { return new ScanSettings.Builder() - .setCallbackType(android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES) + .setCallbackType(CallbackType) .setScanMode(android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_LATENCY) - .setMatchMode(android.bluetooth.le.ScanSettings.MATCH_MODE_AGGRESSIVE) + .setMatchMode(MatchMode) .setNumOfMatches(android.bluetooth.le.ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT) .build(); } else { @@ -910,6 +912,26 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView if (oldBleScanning) { LOG.info("New BLE scanning disabled via settings, using old method"); } + int level = prefs.getInt("scanning_intensity", 1); + switch (level) { + case 0: + CallbackType = android.bluetooth.le.ScanSettings.CALLBACK_TYPE_FIRST_MATCH; + MatchMode = android.bluetooth.le.ScanSettings.MATCH_MODE_STICKY; + break; + case 1: + CallbackType = android.bluetooth.le.ScanSettings.CALLBACK_TYPE_FIRST_MATCH; + MatchMode = android.bluetooth.le.ScanSettings.MATCH_MODE_AGGRESSIVE; + break; + case 2: + CallbackType = android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; + MatchMode = android.bluetooth.le.ScanSettings.MATCH_MODE_STICKY; + break; + case 3: + CallbackType = android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; + MatchMode = android.bluetooth.le.ScanSettings.MATCH_MODE_AGGRESSIVE; + break; + } + LOG.debug("Device discovery - scanning level: " + level + " " + CallbackType + " " + MatchMode); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryPairingPreferenceActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryPairingPreferenceActivity.java index af76e320c3..ca1b6e5fa0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryPairingPreferenceActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryPairingPreferenceActivity.java @@ -18,14 +18,33 @@ package nodomain.freeyourgadget.gadgetbridge.activities; import android.os.Bundle; +import android.preference.Preference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.util.Prefs; public class DiscoveryPairingPreferenceActivity extends AbstractSettingsActivity { + private static final Logger LOG = LoggerFactory.getLogger(AbstractSettingsActivity.class); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.discovery_pairing_preferences); + + final Prefs prefs = GBApplication.getPrefs(); + final Preference pref = findPreference("scanning_intensity"); + pref.setSummary(String.valueOf(prefs.getInt("scanning_intensity", 1))); + + pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newVal) { + preference.setSummary(newVal.toString()); + return true; + } + }); } @Override protected void onPostCreate(Bundle savedInstanceState) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java index f078a6f218..89bcef7d61 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/WidgetAlarmsActivity.java @@ -141,7 +141,7 @@ public class WidgetAlarmsActivity extends Activity implements View.OnClickListen this.getString(R.string.appwidget_setting_alarm, hours, minutes), Toast.LENGTH_SHORT, GB.INFO); - Alarm alarm = AlarmUtils.createSingleShot(0, true, false, calendar); + Alarm alarm = AlarmUtils.createSingleShot(0, true, true, calendar); ArrayList alarms = new ArrayList<>(1); alarms.add(alarm); GBApplication.deviceService().onSetAlarms(alarms); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java index 5eff096c1c..0fa311e5c3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huami/miband5/MiBand5Coordinator.java @@ -144,7 +144,7 @@ public class MiBand5Coordinator extends HuamiCoordinator { "id_ID", "it_IT", "nl_NL", - "pt_PT", + "pt_BR", "pl_PL", "ro_RO", "ru_RU", diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/fitpro/FitProDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/fitpro/FitProDeviceSupport.java index a35bfabca9..03bef7f056 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/fitpro/FitProDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/fitpro/FitProDeviceSupport.java @@ -956,33 +956,9 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport { // this device doesn't have concept of on-off alarm, so use the last slot for this and store // this alarm in the database so the user knows what is going on and can disable it - if (alarms.toArray().length == 1 && alarms.get(0).getRepetition() == 0) { + if (alarms.toArray().length == 1 && alarms.get(0).getRepetition() == 0) { //single shot? Alarm oneshot = alarms.get(0); - DBHandler db = null; - try { - db = GBApplication.acquireDB(); - DaoSession daoSession = db.getDaoSession(); - Device device = DBHelper.getDevice(gbDevice, daoSession); - User user = DBHelper.getUser(daoSession); - nodomain.freeyourgadget.gadgetbridge.entities.Alarm tmpAlarm = - new nodomain.freeyourgadget.gadgetbridge.entities.Alarm( - device.getId(), - user.getId(), - 7, - true, - false, - false, - 0, - oneshot.getHour(), - oneshot.getMinute(), - true, //kind of indicate the specialty of this alarm - "", - ""); - daoSession.insertOrReplace(tmpAlarm); - GBApplication.releaseDB(); - } catch (GBException e) { - LOG.error("error storing one shot quick alarm"); - } + alarms = (ArrayList) AlarmUtils.mergeOneshotToDeviceAlarms(gbDevice, (nodomain.freeyourgadget.gadgetbridge.entities.Alarm) oneshot, 7); } try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java index dcf0e256dc..c5fd9a084b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil/FossilWatchAdapter.java @@ -78,6 +78,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.mis import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.RequestHandControlRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SaveCalibrationRequest; +import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.UriHelper; @@ -516,6 +517,16 @@ public class FossilWatchAdapter extends WatchAdapter { @Override public void onSetAlarms(ArrayList alarms) { + + // handle one-shot alarm from the widget: + // this device doesn't have concept of on-off alarm, so use the last slot for this and store + // this alarm in the database so the user knows what is going on and can disable it + + if (alarms.toArray().length == 1 && alarms.get(0).getRepetition() == 0) { //single shot? + Alarm oneshot = alarms.get(0); + alarms = (ArrayList) AlarmUtils.mergeOneshotToDeviceAlarms(getDeviceSupport().getDevice(), (nodomain.freeyourgadget.gadgetbridge.entities.Alarm) oneshot, 5); + } + // throw new RuntimeException("noope"); ArrayList activeAlarms = new ArrayList<>(); for (Alarm alarm : alarms) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index 711aa3251b..f997d40f6a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -1380,7 +1380,9 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { outerLoop: for (ButtonConfiguration config : configs) { for (ApplicationInformation installedApp : installedApplications) { - if (installedApp.getAppName().equals(config.getAction())) { + if (installedApp.getAppName().equals(config.getAction()) || + config.getAction().equals("workoutApp") //workoutApp is part of internal firmware + ) { availableConfigs.add(config); continue outerLoop; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java index 02d9793a22..8a356623ff 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; @@ -50,7 +51,7 @@ public class AlarmUtils { * @return */ public static nodomain.freeyourgadget.gadgetbridge.model.Alarm createSingleShot(int index, boolean smartWakeup, boolean snooze, Calendar calendar) { - return new Alarm(-1, -1, index, true, smartWakeup, snooze, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false, null, null); + return new Alarm(-1, -1, index, true, smartWakeup, snooze, Alarm.ALARM_ONCE, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false, GBApplication.getContext().getString(R.string.quick_alarm), GBApplication.getContext().getString(R.string.quick_alarm_description)); } /** @@ -144,4 +145,23 @@ public class AlarmUtils { } }; } + + public static List mergeOneshotToDeviceAlarms(GBDevice gbDevice, Alarm oneshot, int position) { + List all_alarms = new ArrayList<>(); + try { + DBHandler db = GBApplication.acquireDB(); + DaoSession daoSession = db.getDaoSession(); + Device device = DBHelper.getDevice(gbDevice, daoSession); + User user = DBHelper.getUser(daoSession); + oneshot.setPosition(position); + oneshot.setDeviceId(device.getId()); + oneshot.setUserId(user.getId()); + daoSession.insertOrReplace(oneshot); + all_alarms = DBHelper.getAlarms(gbDevice); + GBApplication.releaseDB(); + } catch (Exception e) { + GB.log("error storing one shot quick alarm", GB.ERROR, e); + } + return all_alarms; + } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 325e74cbdb..944be85eaf 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -405,6 +405,7 @@ @string/menuitem_status @string/menuitem_pai @string/menuitem_hr + @string/menuitem_breathing @string/menuitem_stress @string/menuitem_eventreminder @string/menuitem_dnd @@ -427,6 +428,7 @@ @string/p_menuitem_status @string/p_menuitem_pai @string/p_menuitem_hr + @string/p_menuitem_breathing @string/p_menuitem_stress @string/p_menuitem_eventreminder @string/p_menuitem_dnd @@ -726,6 +728,7 @@ @string/menuitem_pai @string/menuitem_hr @string/menuitem_spo2 + @string/menuitem_breathing @string/menuitem_stress @string/menuitem_eventreminder @string/menuitem_dnd @@ -749,6 +752,7 @@ @string/p_menuitem_pai @string/p_menuitem_hr @string/p_menuitem_spo2 + @string/p_menuitem_breathing @string/p_menuitem_stress @string/p_menuitem_eventreminder @string/p_menuitem_dnd @@ -1431,7 +1435,8 @@ @string/german @string/italian @string/french - @string/portuguese + @string/portuguese_br + @string/portuguese_pt @string/dutch @string/polish @string/czesh @@ -1458,6 +1463,7 @@ it_IT fr_FR pt_BR + pt_PT nl_NL pl_PL cs_CZ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3ab499e126..469facb0ba 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -389,6 +389,8 @@ Minimum time between fetches Fetches every %d minutes + Scanning intensity + If you experience freezing or unresponsiveness, try to set Scanning intensity to lower level. If your device is not being discovered, try to set Scanning intensity to higher level. Disable new BLE scanning Check this option if your device cannot be found during discovery Not connected @@ -757,6 +759,8 @@ Thai Vietnamese Portuguese + Portuguese (Brazil) + Portuguese (Portugal) Romanian Hungarian Greek @@ -1133,6 +1137,8 @@ 10 minutes 20 minutes 1 hour + Quick alarm + Alarm from widget Icon Watch not connected vibration strength: diff --git a/app/src/main/res/xml/discovery_pairing_preferences.xml b/app/src/main/res/xml/discovery_pairing_preferences.xml index d7eba907a3..1889f3e20d 100644 --- a/app/src/main/res/xml/discovery_pairing_preferences.xml +++ b/app/src/main/res/xml/discovery_pairing_preferences.xml @@ -1,5 +1,6 @@ - + @@ -27,5 +28,17 @@ android:layout="@layout/preference_checkbox" android:summary="@string/discover_unsupported_devices_description" android:title="@string/discover_unsupported_devices" /> + + +