diff --git a/.travis.yml b/.travis.yml index 522f9194d..5cb8117f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,10 @@ android: - tools # The BuildTools version used by your project - - build-tools-23.0.3 + - build-tools-25.0.2 # The SDK version used to compile your project - - android-23 + - android-25 # Additional components - extra-android-m2repository @@ -30,4 +30,4 @@ android: #- sys-img-armeabi-v7a-android-19 #- sys-img-x86-android-17 -script: ./gradlew build connectedCheck --info --stacktrace +script: ./gradlew build connectedCheck --stacktrace diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aa956f79..bcdeac3ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ ###Changelog +###Version 0.18.0 (next) +* Added Portuguese pt_PT and pt_BR translations +* Added Hebrew translation +* Consistently display device specific icons already during discovery +* Add sleep chart diplaying the last week of sleep + ####Version 0.17.5 * Automatically start the service on boot (can be turned off) * Pebble: PebbleKit compatibility improvements (Datalogging) diff --git a/app/build.gradle b/app/build.gradle index efd0ed855..1e73629c0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,17 +17,17 @@ android { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion '25.0.2' defaultConfig { applicationId "nodomain.freeyourgadget.gadgetbridge" minSdkVersion 19 - targetSdkVersion 23 + targetSdkVersion 25 // note: always bump BOTH versionCode and versionName! - versionName "0.17.5" - versionCode 86 + versionName "0.18.0" + versionCode 87 } buildTypes { release { @@ -63,9 +63,9 @@ dependencies { testCompile "org.robolectric:robolectric:3.1.2" compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.3.0' - compile 'com.android.support:support-v4:23.3.0' - compile 'com.android.support:design:23.3.0' + compile 'com.android.support:appcompat-v7:25.1.1' + compile 'com.android.support:support-v4:25.1.1' + compile 'com.android.support:design:25.1.1' compile 'com.github.tony19:logback-android-classic:1.1.1-4' compile 'org.slf4j:slf4j-api:1.7.7' compile 'com.github.PhilJay:MPAndroidChart:v3.0.1' 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 e42f1bd85..5358c479d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java @@ -109,8 +109,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC if (device != null && device.getAddress().equals(bondingAddress)) { int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); if (bondState == BluetoothDevice.BOND_BONDED) { - GB.toast(DiscoveryActivity.this, "Successfully bonded with: " + bondingAddress, Toast.LENGTH_SHORT, GB.INFO); - finish(); + handleDeviceBonded(); } } } @@ -118,6 +117,11 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC } }; + private void handleDeviceBonded() { + GB.toast(DiscoveryActivity.this, "Successfully bonded with: " + bondingAddress, Toast.LENGTH_SHORT, GB.INFO); + finish(); + } + private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { @@ -516,9 +520,21 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC } else { try { BluetoothDevice btDevice = adapter.getRemoteDevice(deviceCandidate.getMacAddress()); - if (btDevice.createBond()) { - // async, wait for bonding event to finish this activity - bondingAddress = btDevice.getAddress(); + switch (btDevice.getBondState()) { + case BluetoothDevice.BOND_NONE: { + if (btDevice.createBond()) { + // async, wait for bonding event to finish this activity + bondingAddress = btDevice.getAddress(); + } + break; + } + case BluetoothDevice.BOND_BONDING: + // async, wait for bonding event to finish this activity + bondingAddress = btDevice.getAddress(); + break; + case BluetoothDevice.BOND_BONDED: + handleDeviceBonded(); + break; } } catch (Exception e) { LOG.error("Error pairing device: " + deviceCandidate.getMacAddress()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java index b33d14cdb..ee16f2ddc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/AbstractWeekChartFragment.java @@ -19,6 +19,7 @@ import com.github.mikephil.charting.data.BarEntry; import com.github.mikephil.charting.data.PieData; import com.github.mikephil.charting.data.PieDataSet; import com.github.mikephil.charting.data.PieEntry; +import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter; import org.slf4j.Logger; @@ -46,6 +47,8 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { private PieChart mTodayPieChart; private BarChart mWeekChart; + private int mOffsetHours = getOffsetHours(); + @Override protected ChartsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) { Calendar day = Calendar.getInstance(); @@ -93,7 +96,7 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { BarDataSet set = new BarDataSet(entries, ""); set.setColors(getColors()); - set.setValueFormatter(getFormatter()); + set.setValueFormatter(getBarValueFormatter()); BarData barData = new BarData(set); barData.setValueTextColor(Color.GRAY); //prevent tearing other graph elements with the black text. Another approach would be to hide the values cmpletely with data.setDrawValues(false); @@ -119,7 +122,7 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { entries.add(new PieEntry(value)); } - set.setValueFormatter(getFormatter()); + set.setValueFormatter(getPieValueFormatter()); set.setColors(getColors()); if (totalValue < mTargetValue) { @@ -134,8 +137,6 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { return new DayData(data, formatPieValue((int) totalValue)); } - protected abstract String formatPieValue(int value); - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -163,7 +164,7 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { private void setupTodayPieChart() { mTodayPieChart.setBackgroundColor(BACKGROUND_COLOR); mTodayPieChart.getDescription().setTextColor(DESCRIPTION_COLOR); - mTodayPieChart.getDescription().setText(getContext().getString(R.string.weeksteps_today_steps_description, String.valueOf(mTargetValue))); + mTodayPieChart.getDescription().setText(getPieDescription(mTargetValue)); // mTodayPieChart.setNoDataTextDescription(""); mTodayPieChart.setNoDataText(""); mTodayPieChart.getLegend().setEnabled(false); @@ -193,7 +194,7 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { y.setDrawZeroLine(true); y.setSpaceBottom(0); y.setAxisMinimum(0); - + y.setValueFormatter(getYAxisFormatter()); y.setEnabled(true); YAxis yAxisRight = mWeekChart.getAxisRight(); @@ -214,7 +215,7 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { // chart.getLegend().setTextColor(LEGEND_TEXT_COLOR); } - private List getSamplesOfDay(DBHandler db, Calendar day, GBDevice device) { + private List getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) { int startTs; int endTs; @@ -222,12 +223,10 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { day.set(Calendar.HOUR_OF_DAY, 0); day.set(Calendar.MINUTE, 0); day.set(Calendar.SECOND, 0); - startTs = (int) (day.getTimeInMillis() / 1000); + day.add(Calendar.HOUR, offsetHours); - day.set(Calendar.HOUR_OF_DAY, 23); - day.set(Calendar.MINUTE, 59); - day.set(Calendar.SECOND, 59); - endTs = (int) (day.getTimeInMillis() / 1000); + startTs = (int) (day.getTimeInMillis() / 1000); + endTs = startTs + 24 * 60 * 60 - 1; return getSamples(db, device, startTs, endTs); } @@ -273,14 +272,14 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { Activity activity = getActivity(); if (activity != null) { activityAmountCache = ((ChartsActivity) activity).mActivityAmountCache; - amounts = (ActivityAmounts) (activityAmountCache.lookup(day.hashCode())); + amounts = (ActivityAmounts) (activityAmountCache.lookup(day.hashCode() ^ mOffsetHours)); } if (amounts == null) { ActivityAnalysis analysis = new ActivityAnalysis(); - amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, device)); + amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, mOffsetHours, device)); if (activityAmountCache != null) { - activityAmountCache.add(day.hashCode(), amounts); + activityAmountCache.add(day.hashCode() ^ mOffsetHours, amounts); } } @@ -289,9 +288,19 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment { abstract int getGoal(); + abstract int getOffsetHours(); + abstract float[] getTotalsForActivityAmounts(ActivityAmounts activityAmounts); - abstract IValueFormatter getFormatter(); + abstract String formatPieValue(int value); + + abstract IValueFormatter getPieValueFormatter(); + + abstract IValueFormatter getBarValueFormatter(); + + abstract IAxisValueFormatter getYAxisFormatter(); abstract int[] getColors(); + + abstract String getPieDescription(int targetValue); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java index 02adaeb26..19a42c663 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java @@ -53,7 +53,7 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts private PagerTabStrip mPagerTabStrip; private ViewPager viewPager; - LimitedQueue mActivityAmountCache = new LimitedQueue(32); + LimitedQueue mActivityAmountCache = new LimitedQueue(60); private static class ShowDurationDialog extends Dialog { private final String mDuration; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java index 30e1c4b55..1f2fd0085 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekSleepChartFragment.java @@ -1,6 +1,8 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts; +import com.github.mikephil.charting.components.AxisBase; import com.github.mikephil.charting.data.Entry; +import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.utils.ViewPortHandler; @@ -18,11 +20,21 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment { return getString(R.string.weeksleepchart_sleep_a_week); } + @Override + String getPieDescription(int targetValue) { + return getString(R.string.weeksleepchart_today_sleep_description, DateTimeUtils.minutesToHHMM(targetValue)); + } + @Override int getGoal() { return 8 * 60; // FIXME } + @Override + int getOffsetHours() { + return -12; + } + @Override float[] getTotalsForActivityAmounts(ActivityAmounts activityAmounts) { long totalSecondsDeepSleep = 0; @@ -43,7 +55,7 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment { } @Override - IValueFormatter getFormatter() { + IValueFormatter getPieValueFormatter() { return new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { @@ -52,6 +64,26 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment { }; } + @Override + IValueFormatter getBarValueFormatter() { + return new IValueFormatter() { + @Override + public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { + return DateTimeUtils.minutesToHHMM((int) value); + } + }; + } + + @Override + IAxisValueFormatter getYAxisFormatter() { + return new IAxisValueFormatter() { + @Override + public String getFormattedValue(float value, AxisBase axis) { + return DateTimeUtils.minutesToHHMM((int) value); + } + }; + } + @Override int[] getColors() { return new int[]{akDeepSleep.color, akLightSleep.color}; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java index ee843f7bb..23756010e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/WeekStepsChartFragment.java @@ -1,5 +1,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts; +import com.github.mikephil.charting.formatter.IAxisValueFormatter; import com.github.mikephil.charting.formatter.IValueFormatter; import nodomain.freeyourgadget.gadgetbridge.R; @@ -14,6 +15,11 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment { return getString(R.string.weekstepschart_steps_a_week); } + @Override + String getPieDescription(int targetValue) { + return getString(R.string.weeksteps_today_steps_description, String.valueOf(targetValue)); + } + @Override int getGoal() { GBDevice device = getChartsHost().getDevice(); @@ -23,6 +29,11 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment { return -1; } + @Override + int getOffsetHours() { + return 0; + } + @Override float[] getTotalsForActivityAmounts(ActivityAmounts activityAmounts) { int totalSteps = 0; @@ -39,7 +50,17 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment { } @Override - IValueFormatter getFormatter() { + IValueFormatter getPieValueFormatter() { + return null; + } + + @Override + IValueFormatter getBarValueFormatter() { + return null; + } + + @Override + IAxisValueFormatter getYAxisFormatter() { return null; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java index fb3e9a107..a4dac5f1c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBand2Service.java @@ -98,6 +98,8 @@ public class MiBand2Service { public static final byte[] DATEFORMAT_DATE_TIME = new byte[] { COMMAND_DATEFORMAT, 0x0a, 0x0, 0x03 }; public static final byte[] DATEFORMAT_TIME = new byte[] { COMMAND_DATEFORMAT, 0x0a, 0x0, 0x0 }; + public static final byte[] DATEFORMAT_TIME_12_HOURS = new byte[] { COMMAND_DATEFORMAT, 0x02, 0x0, 0x0 }; + public static final byte[] DATEFORMAT_TIME_24_HOURS = new byte[] { COMMAND_DATEFORMAT, 0x02, 0x0, 0x1 }; public static final byte RESPONSE = 0x10; @@ -128,6 +130,8 @@ public class MiBand2Service { public static final byte[] COMMAND_ENABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{0x06, 0x05, 0x00, 0x01}; public static final byte[] COMMAND_DISABLE_DISPLAY_ON_LIFT_WRIST = new byte[]{0x06, 0x05, 0x00, 0x00}; + public static final byte[] COMMAND_TEXT_NOTIFICATION = new byte[] {0x05, 0x01}; + public static final byte[] COMMAND_TEXT_NOTIFICATION_CONTINUATION = new byte[] {(byte) 0xfa, 0x01, 0x00}; static { MIBAND_DEBUG = new HashMap<>(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java index 129f4afe4..be4052821 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPreferencesActivity.java @@ -26,7 +26,6 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PR import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_FITNESS_GOAL; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_USE_HR_FOR_SLEEP_DETECTION; -import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_SETUP_BT_PAIRING; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_ALIAS; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.getNotificationPrefKey; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java index 2f0128259..4af9af6c0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/NotificationType.java @@ -5,6 +5,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID; public enum NotificationType { + // TODO: this this pebbleism needs to be moved somewhere else UNKNOWN(PebbleIconID.NOTIFICATION_GENERIC, PebbleColor.Red), CONVERSATIONS(PebbleIconID.NOTIFICATION_HIPCHAT, PebbleColor.Inchworm), @@ -19,6 +20,7 @@ public enum NotificationType { TELEGRAM(PebbleIconID.NOTIFICATION_TELEGRAM, PebbleColor.PictonBlue), WHATSAPP(PebbleIconID.NOTIFICATION_WHATSAPP, PebbleColor.MayGreen), GENERIC_ALARM_CLOCK(PebbleIconID.ALARM_CLOCK, PebbleColor.Red); + // Note: if you add any more constants, update all clients as well public int icon; public byte color; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java index 90ccc4dbe..56e59bc0b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLETypeConversions.java @@ -1,10 +1,13 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle; +import java.nio.charset.StandardCharsets; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.TimeZone; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; /** * Provides methods to convert standard BLE units to byte sequences and vice versa. @@ -233,4 +236,33 @@ public class BLETypeConversions { } return 0; } + + public static byte[] toUtf8s(String message) { + return message.getBytes(StandardCharsets.UTF_8); + } + + public static AlertCategory toAlertCategory(NotificationType type) { + switch (type) { + case GENERIC_ALARM_CLOCK: + return AlertCategory.HighPriorityAlert; + case GENERIC_SMS: + return AlertCategory.SMS; + case GENERIC_EMAIL: + return AlertCategory.Email; + case GENERIC_NAVIGATION: + return AlertCategory.Simple; + case RIOT: + case SIGNAL: + case TELEGRAM: + case WHATSAPP: + case CONVERSATIONS: + case FACEBOOK: + case FACEBOOK_MESSENGER: + case TWITTER: + return AlertCategory.InstantMessage; + case UNKNOWN: + return AlertCategory.Simple; + } + return AlertCategory.Simple; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java index 1767c15ee..be13a084c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/GattCharacteristic.java @@ -21,6 +21,7 @@ public class GattCharacteristic { public static final UUID UUID_CHARACTERISTIC_ALERT_CATEGORY_ID = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A43"))); public static final UUID UUID_CHARACTERISTIC_ALERT_CATEGORY_ID_BIT_MASK = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A42"))); public static final UUID UUID_CHARACTERISTIC_ALERT_LEVEL = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2A06"))); + public static final UUID UUID_CHARACTERISTIC_CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString((String.format(AbstractBTLEDeviceSupport.BASE_UUID, "2902"))); public static final byte NO_ALERT = 0x0; public static final byte MILD_ALERT = 0x1; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java index 1f37e42ae..3ce3cc7cc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/AlertNotificationProfile.java @@ -1,12 +1,66 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; +import android.bluetooth.BluetoothGattCharacteristic; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; +import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile; +import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class AlertNotificationProfile extends AbstractBleProfile { + private static final Logger LOG = LoggerFactory.getLogger(AlertNotificationProfile.class); + private static final int MAX_MSG_LENGTH = 18; + public AlertNotificationProfile(T support) { super(support); } + public void newAlert(TransactionBuilder builder, NewAlert alert, OverflowStrategy strategy) { + BluetoothGattCharacteristic characteristic = getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_NEW_ALERT); + if (characteristic != null) { + String message = alert.getMessage(); + if (message.length() > MAX_MSG_LENGTH && strategy == OverflowStrategy.TRUNCATE) { + message = StringUtils.truncate(message, MAX_MSG_LENGTH); + } + int numChunks = message.length() / MAX_MSG_LENGTH; + if (message.length() % MAX_MSG_LENGTH > 0) { + numChunks++; + } + + for (int i = 0; i < numChunks; i++) { + int offset = i * MAX_MSG_LENGTH; + int restLength = message.length() - offset; + message = message.substring(offset, offset + Math.min(MAX_MSG_LENGTH, restLength)); + if (message.length() == 0) { + break; + } + writeAlertMessage(builder, characteristic, alert, message, i); + } + } else { + LOG.warn("NEW_ALERT characteristic not available"); + } + } + + protected void writeAlertMessage(TransactionBuilder builder, BluetoothGattCharacteristic characteristic, NewAlert alert, String message, int chunk) { + try { + ByteArrayOutputStream stream = new ByteArrayOutputStream(100); + stream.write(alert.getCategory().getId()); + stream.write(alert.getNumAlerts()); + stream.write(BLETypeConversions.toUtf8s(message)); + + builder.write(characteristic, stream.toByteArray()); + } catch (IOException ex) { + // aint gonna happen + LOG.error("Error writing alert message to ByteArrayOutputStream"); + } + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java new file mode 100644 index 000000000..c62327335 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/NewAlert.java @@ -0,0 +1,52 @@ +package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; + +/** + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.new_alert.xml&u=org.bluetooth.characteristic.new_alert.xml + * + Recommended Usage for Text String Information Field in New Incoming Alert: + + The usage of this text is up to the implementation, but the recommended text for the category is defined as following for best user experience: + + Category: Simple Alert - The title of the alert + + Category: Email - Sender name + + Category: News - Title of the news feed + + Category: Call - Caller name or caller ID + + Category: Missed call - Caller name or caller ID + + Category: SMS - Sender name or caller ID + + Category: Voice mail - Sender name or caller ID + + Category: Schedule - Title of the schedule + + Category Hig:h Prioritized Aler - Title of the alert + + Category: Instant Messaging - Sender name + */ +public class NewAlert { + private final AlertCategory category; + private final int numAlerts; + private final String message; + + public NewAlert(AlertCategory category, int /*uint8*/ numAlerts, String /*utf8s*/ message) { + this.category = category; + this.numAlerts = numAlerts; + this.message = message; + } + + public AlertCategory getCategory() { + return category; + } + + public int getNumAlerts() { + return numAlerts; + } + + public String getMessage() { + return message; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java new file mode 100644 index 000000000..5fbbcac5a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/profiles/alertnotification/OverflowStrategy.java @@ -0,0 +1,6 @@ +package nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification; + +public enum OverflowStrategy { + TRUNCATE, + MAKE_MULTIPLE +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java new file mode 100644 index 000000000..1aed3bb6a --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/common/SimpleNotification.java @@ -0,0 +1,21 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.common; + +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; + +public class SimpleNotification { + private final String message; + private final AlertCategory alertCategory; + + public SimpleNotification(String message, AlertCategory alertCategory) { + this.message = message; + this.alertCategory = alertCategory; + } + + public AlertCategory getAlertCategory() { + return alertCategory; + } + + public String getMessage() { + return message; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index e5ef862a8..e58dec765 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -53,6 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; @@ -61,10 +62,13 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactio import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWriteAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.FetchActivityOperation; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.UpdateFirmwareOperation; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_FLASH_COLOUR; @@ -205,19 +209,19 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return mDeviceInfo; } - private MiBandSupport sendDefaultNotification(TransactionBuilder builder, short repeat, BtLEAction extraAction) { + private MiBandSupport sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) { LOG.info("Sending notification to MiBand: (" + repeat + " times)"); NotificationStrategy strategy = getNotificationStrategy(); for (short i = 0; i < repeat; i++) { - strategy.sendDefaultNotification(builder, extraAction); + strategy.sendDefaultNotification(builder, simpleNotification, extraAction); } return this; } /** * Adds a custom notification to the given transaction builder - * - * @param vibrationProfile specifies how and how often the Band shall vibrate. + * @param vibrationProfile specifies how and how often the Band shall vibrate. + * @param simpleNotification * @param flashTimes * @param flashColour * @param originalColour @@ -225,8 +229,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { * @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example. * @param builder */ - private MiBandSupport sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { - getNotificationStrategy().sendCustomNotification(vibrationProfile, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); + private MiBandSupport sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + getNotificationStrategy().sendCustomNotification(vibrationProfile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); LOG.info("Sending notification to MiBand"); return this; } @@ -454,17 +458,17 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return this; } - private void performDefaultNotification(String task, short repeat, BtLEAction extraAction) { + private void performDefaultNotification(String task, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) { try { TransactionBuilder builder = performInitialized(task); - sendDefaultNotification(builder, repeat, extraAction); + sendDefaultNotification(builder, simpleNotification, repeat, extraAction); builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Unable to send notification to MI device", ex); } } - private void performPreferredNotification(String task, String notificationOrigin, BtLEAction extraAction) { + private void performPreferredNotification(String task, SimpleNotification simpleNotification, String notificationOrigin, BtLEAction extraAction) { try { TransactionBuilder builder = performInitialized(task); Prefs prefs = GBApplication.getPrefs(); @@ -479,7 +483,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { int flashDuration = getPreferredFlashDuration(notificationOrigin, prefs); // setLowLatency(builder); - sendCustomNotification(profile, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); + sendCustomNotification(profile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); // setHighLatency(builder); // sendCustomNotification(vibrateDuration, vibrateTimes, vibratePause, flashTimes, flashColour, originalColour, flashDuration, builder); builder.queue(getQueue()); @@ -549,8 +553,11 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return; } + String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim(); + SimpleNotification simpleNotification = new SimpleNotification(message, BLETypeConversions.toAlertCategory(notificationSpec.type)); + String origin = notificationSpec.type.getGenericType(); - performPreferredNotification(origin + " received", origin, null); + performPreferredNotification(origin + " received", simpleNotification, origin, null); } private void onAlarmClock(NotificationSpec notificationSpec) { @@ -561,7 +568,9 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return !isAlarmClockRinging(); } }; - performPreferredNotification("alarm clock ringing", MiBandConst.ORIGIN_ALARM_CLOCK, abortAction); + String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()); + SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.HighPriorityAlert); + performPreferredNotification("alarm clock ringing", simpleNotification, MiBandConst.ORIGIN_ALARM_CLOCK, abortAction); } @Override @@ -625,7 +634,9 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return !isTelephoneRinging(); } }; - performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, abortAction); + String message = NotificationUtils.getPreferredTextFor(callSpec); + SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.IncomingCall); + performPreferredNotification("incoming call", simpleNotification, MiBandConst.ORIGIN_INCOMING_CALL, abortAction); } else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) { telephoneRinging = false; } @@ -716,7 +727,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return !isLocatingDevice; } }; - performDefaultNotification("locating device", (short) 255, abortAction); + SimpleNotification simpleNotification = new SimpleNotification(getContext().getString(R.string.find_device_you_found_it), AlertCategory.HighPriorityAlert); + performDefaultNotification("locating device", simpleNotification, (short) 255, abortAction); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java index 45a8e45b6..e72add17c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NoNotificationStrategy.java @@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; /** * Does not do anything. @@ -14,12 +15,12 @@ public class NoNotificationStrategy implements NotificationStrategy { private static final Logger LOG = LoggerFactory.getLogger(NoNotificationStrategy.class); @Override - public void sendDefaultNotification(TransactionBuilder builder, BtLEAction extraAction) { + public void sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, BtLEAction extraAction) { LOG.info("dummy notification stragegy: default notification"); } @Override - public void sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { - LOG.info("dummy notification stragegy: custom notification"); + public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + LOG.info("dummy notification stragegy: custom notification: " + simpleNotification); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java index 1007f7ce3..d8cbca954 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/NotificationStrategy.java @@ -3,14 +3,15 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.miband; import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; public interface NotificationStrategy { - void sendDefaultNotification(TransactionBuilder builder, BtLEAction extraAction); + void sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, BtLEAction extraAction); /** * Adds a custom notification to the given transaction builder - * * @param vibrationProfile specifies how and how often the Band shall vibrate. + * @param simpleNotification * @param flashTimes * @param flashColour * @param originalColour @@ -18,5 +19,5 @@ public interface NotificationStrategy { * @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example. * @param builder */ - void sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder); + void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java index ab28be7b7..b7d74d154 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V1NotificationStrategy.java @@ -10,6 +10,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; public class V1NotificationStrategy implements NotificationStrategy { private static final Logger LOG = LoggerFactory.getLogger(V1NotificationStrategy.class); @@ -24,7 +25,7 @@ public class V1NotificationStrategy implements NotificationStrategy { } @Override - public void sendDefaultNotification(TransactionBuilder builder, BtLEAction extraAction) { + public void sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, BtLEAction extraAction) { BluetoothGattCharacteristic characteristic = support.getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT); builder.write(characteristic, getDefaultNotification()); builder.add(extraAction); @@ -53,8 +54,8 @@ public class V1NotificationStrategy implements NotificationStrategy { /** * Adds a custom notification to the given transaction builder - * * @param vibrationProfile specifies how and how often the Band shall vibrate. + * @param simpleNotification * @param flashTimes * @param flashColour * @param originalColour @@ -63,7 +64,7 @@ public class V1NotificationStrategy implements NotificationStrategy { * @param builder */ @Override - public void sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { BluetoothGattCharacteristic controlPoint = support.getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT); for (short i = 0; i < vibrationProfile.getRepeat(); i++) { int[] onOffSequence = vibrationProfile.getOnOffSequence(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java index 8d2135433..65957f09d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/V2NotificationStrategy.java @@ -7,6 +7,10 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSuppo import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; public class V2NotificationStrategy implements NotificationStrategy { private final AbstractBTLEDeviceSupport support; @@ -20,12 +24,12 @@ public class V2NotificationStrategy implements NotificationStrategy { } @Override - public void sendDefaultNotification(TransactionBuilder builder, BtLEAction extraAction) { + public void sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, BtLEAction extraAction) { VibrationProfile profile = VibrationProfile.getProfile(VibrationProfile.ID_MEDIUM, (short) 3); - sendCustomNotification(profile, extraAction, builder); + sendCustomNotification(profile, simpleNotification, extraAction, builder); } - protected void sendCustomNotification(VibrationProfile vibrationProfile, BtLEAction extraAction, TransactionBuilder builder) { + protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) { //use the new alert characteristic BluetoothGattCharacteristic alert = support.getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL); for (short i = 0; i < vibrationProfile.getRepeat(); i++) { @@ -49,11 +53,18 @@ public class V2NotificationStrategy implements NotificationStrategy { } } } + sendAlert(simpleNotification, builder); + } + + protected void sendAlert(SimpleNotification simpleNotification, TransactionBuilder builder) { + AlertNotificationProfile profile = new AlertNotificationProfile<>(getSupport()); + NewAlert alert = new NewAlert(simpleNotification.getAlertCategory(), 1, simpleNotification.getMessage()); + profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE); } @Override - public void sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { // all other parameters are unfortunately not supported anymore ;-( - sendCustomNotification(vibrationProfile, extraAction, builder); + sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java index 3cfed0a92..d5a483309 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/Mi2NotificationStrategy.java @@ -7,6 +7,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSuppo import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.V2NotificationStrategy; public class Mi2NotificationStrategy extends V2NotificationStrategy { @@ -16,7 +18,7 @@ public class Mi2NotificationStrategy extends V2NotificationStrategy { } @Override - protected void sendCustomNotification(VibrationProfile vibrationProfile, BtLEAction extraAction, TransactionBuilder builder) { + protected void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, BtLEAction extraAction, TransactionBuilder builder) { //use the new alert characteristic BluetoothGattCharacteristic alert = getSupport().getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_ALERT_LEVEL); for (short i = 0; i < vibrationProfile.getRepeat(); i++) { @@ -38,11 +40,13 @@ public class Mi2NotificationStrategy extends V2NotificationStrategy { } } } + + } @Override - public void sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + public void sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { // all other parameters are unfortunately not supported anymore ;-( - sendCustomNotification(vibrationProfile, extraAction, builder); + sendCustomNotification(vibrationProfile, simpleNotification, extraAction, builder); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java index 6d9a83fcf..f44bd5050 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/MiBand2Support.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.support.v4.content.LocalBroadcastManager; +import android.text.format.DateFormat; import android.widget.Toast; import org.apache.commons.lang3.ArrayUtils; @@ -67,8 +68,10 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile; +import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.CheckAuthenticationNeededAction; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.DeviceInfo; import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy; @@ -79,6 +82,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.I import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.UpdateFirmwareOperation; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_FLASH_COLOUR; @@ -301,19 +305,19 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return mDeviceInfo; } - private MiBand2Support sendDefaultNotification(TransactionBuilder builder, short repeat, BtLEAction extraAction) { + private MiBand2Support sendDefaultNotification(TransactionBuilder builder, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) { LOG.info("Sending notification to MiBand: (" + repeat + " times)"); NotificationStrategy strategy = getNotificationStrategy(); for (short i = 0; i < repeat; i++) { - strategy.sendDefaultNotification(builder, extraAction); + strategy.sendDefaultNotification(builder, simpleNotification, extraAction); } return this; } /** * Adds a custom notification to the given transaction builder - * * @param vibrationProfile specifies how and how often the Band shall vibrate. + * @param simpleNotification * @param flashTimes * @param flashColour * @param originalColour @@ -321,8 +325,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { * @param extraAction an extra action to be executed after every vibration and flash sequence. Allows to abort the repetition, for example. * @param builder */ - private MiBand2Support sendCustomNotification(VibrationProfile vibrationProfile, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { - getNotificationStrategy().sendCustomNotification(vibrationProfile, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); + private MiBand2Support sendCustomNotification(VibrationProfile vibrationProfile, SimpleNotification simpleNotification, int flashTimes, int flashColour, int originalColour, long flashDuration, BtLEAction extraAction, TransactionBuilder builder) { + getNotificationStrategy().sendCustomNotification(vibrationProfile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); LOG.info("Sending notification to MiBand"); return this; } @@ -500,17 +504,17 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } - private void performDefaultNotification(String task, short repeat, BtLEAction extraAction) { + private void performDefaultNotification(String task, SimpleNotification simpleNotification, short repeat, BtLEAction extraAction) { try { TransactionBuilder builder = performInitialized(task); - sendDefaultNotification(builder, repeat, extraAction); + sendDefaultNotification(builder, simpleNotification, repeat, extraAction); builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Unable to send notification to MI device", ex); } } - private void performPreferredNotification(String task, String notificationOrigin, int alertLevel, BtLEAction extraAction) { + private void performPreferredNotification(String task, String notificationOrigin, SimpleNotification simpleNotification, int alertLevel, BtLEAction extraAction) { try { TransactionBuilder builder = performInitialized(task); Prefs prefs = GBApplication.getPrefs(); @@ -525,7 +529,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { int originalColour = getPreferredOriginalColour(notificationOrigin, prefs); int flashDuration = getPreferredFlashDuration(notificationOrigin, prefs); - sendCustomNotification(profile, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); + sendCustomNotification(profile, simpleNotification, flashTimes, flashColour, originalColour, flashDuration, extraAction, builder); // sendCustomNotification(vibrateDuration, vibrateTimes, vibratePause, flashTimes, flashColour, originalColour, flashDuration, builder); builder.queue(getQueue()); } catch (IOException ex) { @@ -597,8 +601,10 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { if (notificationSpec.type == NotificationType.UNKNOWN) { alertLevel = MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY; } + String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()).trim(); String origin = notificationSpec.type.getGenericType(); - performPreferredNotification(origin + " received", origin, alertLevel, null); + SimpleNotification simpleNotification = new SimpleNotification(message, BLETypeConversions.toAlertCategory(notificationSpec.type)); + performPreferredNotification(origin + " received", origin, simpleNotification, alertLevel, null); } private void onAlarmClock(NotificationSpec notificationSpec) { @@ -609,7 +615,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return !isAlarmClockRinging(); } }; - performPreferredNotification("alarm clock ringing", MiBandConst.ORIGIN_ALARM_CLOCK, MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY, abortAction); + String message = NotificationUtils.getPreferredTextFor(notificationSpec, 40, 40, getContext()); + SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.HighPriorityAlert); + performPreferredNotification("alarm clock ringing", MiBandConst.ORIGIN_ALARM_CLOCK, simpleNotification, MiBand2Service.ALERT_LEVEL_VIBRATE_ONLY, abortAction); } @Override @@ -640,7 +648,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return !isTelephoneRinging(); } }; - performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, MiBand2Service.ALERT_LEVEL_PHONE_CALL, abortAction); + String message = NotificationUtils.getPreferredTextFor(callSpec); + SimpleNotification simpleNotification = new SimpleNotification(message, AlertCategory.IncomingCall); + performPreferredNotification("incoming call", MiBandConst.ORIGIN_INCOMING_CALL, simpleNotification, MiBand2Service.ALERT_LEVEL_PHONE_CALL, abortAction); } else if ((callSpec.command == CallSpec.CALL_START) || (callSpec.command == CallSpec.CALL_END)) { telephoneRinging = false; } @@ -722,7 +732,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return !isLocatingDevice; } }; - performDefaultNotification("locating device", (short) 255, abortAction); + SimpleNotification simpleNotification = new SimpleNotification(getContext().getString(R.string.find_device_you_found_it), AlertCategory.HighPriorityAlert.HighPriorityAlert); + performDefaultNotification("locating device", simpleNotification, (short) 255, abortAction); } } @@ -1250,7 +1261,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { @Override public void onSendConfiguration(String config) { - TransactionBuilder builder = null; + TransactionBuilder builder; try { builder = performInitialized("Sending configuration for option: " + config); switch (config) { @@ -1300,6 +1311,17 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return this; } + private MiBand2Support setTimeFormat(TransactionBuilder builder) { + boolean is24Format = DateFormat.is24HourFormat(getContext()); + LOG.info("Setting 24h time format to " + is24Format); + if (is24Format) { + builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.DATEFORMAT_TIME_24_HOURS); + } else { + builder.write(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand2Service.DATEFORMAT_TIME_12_HOURS); + } + return this; + } + private MiBand2Support setActivateDisplayOnLiftWrist(TransactionBuilder builder) { boolean enable = MiBand2Coordinator.getActivateDisplayOnLiftWrist(); LOG.info("Setting activate display on lift wrist to " + enable); @@ -1316,6 +1338,7 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { enableFurtherNotifications(builder, true); requestBatteryInfo(builder); setDateDisplay(builder); + setTimeFormat(builder); setWearLocation(builder); setFitnessGoal(builder); setActivateDisplayOnLiftWrist(builder); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java index 6781bcb07..6dbdf994c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DateTimeUtils.java @@ -78,4 +78,8 @@ public class DateTimeUtils { public static Calendar getCalendarUTC() { return GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC")); } + + public static String minutesToHHMM(int minutes) { + return String.format(Locale.US, "%d:%02d", minutes / 60, minutes % 60); // no I do not want to use durationformatter :P + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java new file mode 100644 index 000000000..124b4bcd3 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/NotificationUtils.java @@ -0,0 +1,46 @@ +package nodomain.freeyourgadget.gadgetbridge.util; + +import android.content.Context; +import android.support.annotation.NonNull; + +import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; +import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; + +public class NotificationUtils { + @NonNull + public static String getPreferredTextFor(NotificationSpec notificationSpec, int lengthBody, int lengthSubject, Context context) { + switch (notificationSpec.type) { + case GENERIC_ALARM_CLOCK: + return StringUtils.getFirstOf(notificationSpec.title, notificationSpec.subject); + case GENERIC_SMS: + case GENERIC_EMAIL: + return formatText(notificationSpec.sender, notificationSpec.subject, notificationSpec.body, lengthBody, lengthSubject, context); + case GENERIC_NAVIGATION: + return StringUtils.getFirstOf(notificationSpec.title, notificationSpec.body); + case RIOT: + case SIGNAL: + case TELEGRAM: + case TWITTER: + case WHATSAPP: + case CONVERSATIONS: + case FACEBOOK: + case FACEBOOK_MESSENGER: + return notificationSpec.body; + } + return ""; + } + + @NonNull + public static String formatText(String sender, String subject, String body, int lengthBody, int lengthSubject, Context context) { + StringBuilder builder = new StringBuilder(); + builder.append(StringUtils.truncate(body, lengthBody)); + builder.append(StringUtils.truncate(subject, lengthSubject)); + builder.append(StringUtils.formatSender(sender, context)); + + return builder.toString(); + } + + public static String getPreferredTextFor(CallSpec callSpec) { + return StringUtils.getFirstOf(callSpec.name, callSpec.number); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java index 8dd6d8ccb..0ac480cf8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/StringUtils.java @@ -1,12 +1,21 @@ package nodomain.freeyourgadget.gadgetbridge.util; +import android.content.Context; +import android.support.annotation.NonNull; + +import nodomain.freeyourgadget.gadgetbridge.R; + public class StringUtils { public static String truncate(String s, int maxLength){ - int length = Math.min(s.length(), maxLength); - - if(length < 0) + if (s == null) { return ""; + } + + int length = Math.min(s.length(), maxLength); + if(length < 0) { + return ""; + } return s.substring(0, length); } @@ -16,10 +25,28 @@ public class StringUtils { } public static String pad(String s, int length, char padChar){ - - while(s.length() < length) + while(s.length() < length) { s += padChar; - + } return s; } + + @NonNull + public static String formatSender(String sender, Context context) { + if (sender == null || sender.length() == 0) { + return ""; + } + return context.getString(R.string.StringUtils_sender, sender); + } + + @NonNull + public static String getFirstOf(String first, String second) { + if (first != null && first.length() > 0) { + return first; + } + if (second != null) { + return second; + } + return ""; + } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e458991e4..7af08db3d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -6,13 +6,13 @@ Debug Beenden Synchronisieren - Schlafmonitor (ALPHA) + Schlafaufzeichnung (ALPHA) Suche verlegtes Gerät… - Bildschirmfoto + Bildschirmfoto machen Trennen - Gerät Löschen - %1$s Löschen - Das wird das Gerät und die dazugehörigen Daten löschen! + Gerät löschen + %1$s löschen + Das wird das Gerät und alle zugehörigen Daten löschen! Debug App Manager @@ -27,6 +27,9 @@ deaktivieren HRM aktivieren HRM deaktivieren + System Wetter-App aktivieren + System Wetter-App deaktivieren + Installiere die Wetter-Benachrichtigungs-App Konfigurieren Nach oben @@ -43,27 +46,31 @@ Allgemeine Einstellungen Verbinde, wenn Bluetooth eingeschaltet wird Automatisch starten - Verbindungen automatisch wiederherstellen + Verbindung automatisch wiederherstellen Bevorzugter Audioplayer Standard Datum und Zeit Uhrzeit synchronisieren - Synchronisiere die Urzeit mit dem Gerät (bei Verbindingsaufbau und wenn die Zeit oder Zeitzone auf dem Android Gerät eingestellt wird) - Thema + Synchronisiere die Uhrzeit mit dem Gerät bei Verbindungsaufbau und wenn die Zeit oder Zeitzone auf dem Android Gerät geändert wird + Theme Hell Dunkel Sprache + Gadgetbridge-Benachrichtigung ausblenden + Das Symbol in der Statusleiste und die Benachrichtigung auf dem Sperrbildschirm werden angezeigt + Das Symbol in der Statusleiste und die Benachrichtigung auf dem Sperrbildschirm werden nicht angezeigt Benachrichtigungen Wiederholungen Anrufe SMS Pebble Nachrichten - Unterstützung für Anwendungen die Benachrichtigungen an die Pebble via PebbleKit senden. + Unterstützung für Anwendungen, die Benachrichtigungen an die Pebble via PebbleKit senden. Andere Benachrichtigungen … auch wenn der Bildschirm an ist Bitte nicht stören - Stoppe unerwünschte Nachrichten, wenn im \"Nicht Stören\"-Modus - Transliteration + Benachrichtigungen nicht senden, wenn im \"Nicht Stören\"-Modus + Transkription + Aktiviere dies, falls dein Gerät keine Unterstützung für den Zeichensatz deiner Sprache hat (momentan nur Kyrillisch) immer wenn der Bildschirm aus ist niemals @@ -72,7 +79,7 @@ Zeige Name und Telefonnumer Verstecke den Namen aber zeige die Telefonnummer an Verstecke Name und Telefonnummer - Sperre für Apps + App-Benachrichtigungen blockieren Vorgefertigte Nachrichten Antworten Gemeinsame Endung @@ -87,35 +94,43 @@ Misfit synchronisieren Morpheuz synchronisieren Unterstützung für ausgehende Anrufe + Falls dies deaktiviert wird, vibriert die Pebble 2/LE nicht bei ausgehenden Anrufen Erlaube Zugriff von anderen Android Apps Experimentelle Unterstützung für Android Apps, die PebbleKit benutzen Sonnenauf- und -untergang Sende Sonnenauf- und -untergangszeiten abhänging vom Standort auf die Pebble Timeline + Verworfene Benachrichtigungen automatisch entfernen + Benachrichtigungen werden automatisch von der Pebble entfernt, wenn sie auf dem Android-Gerät verworfen werden Privatsphäre-Modus Normale Benachrichtigungen - Verschiebe den Benachrichttigungstext außerhalb des Bildschirms + Verschiebe den Benachrichtigungstext außerhalb des Bildschirms Zeige nur das Benachrichtigungs-Symbol Standort - Standort Bestimmen + Standort bestimmen Breitengrad Längengrad Automatisch Standort aktualisieren - Versuche den aktuellen Standort zur Laufzeit abzufragen und nutze die gespeicherten Standort falls das fehlschlägt - Bitte ungefähre Standortbestimmung einschalten + Versuche, den aktuellen Standort abzufragen und nutze den gespeicherten Standort, falls das fehlschlägt + Bitte netzwerkbasierte Standortbestimmung einschalten Standort wurde bestimmt Benachrichtigungsprotokoll erzwingen - Diese Option erzwingt das neuste Benachrichtigungsprotokoll abhängig von der Firmwareversion. NUR EINSCHALTEN, WENN DU WEISST WAS DU TUST! + Diese Option erzwingt das neuste Benachrichtigungsprotokoll abhängig von der Firmwareversion. NUR EINSCHALTEN, WENN DU WEISST, WAS DU TUST! Ungetestete Features freischalten - Schaltet ungetetestete Features frei. TU DIES NUR, WENN DU WEIßT, WAS DU TUST! + Schaltet ungetetestete Features frei. NUR EINSCHALTEN WENN DU WEISST WAS DU TUST! BLE immer bevorzugen - Nutze den experimentellen LE support für alle Pebbles anstelle von BT classic. Setzt voraus, dass die \"Pebble LE\" gepaart wird, nachdem die nicht-LE Pebble einmal verbunden war. + Nutze den experimentellen LE support für alle Pebbles anstelle von klassischem BT. Setzt voraus, dass die \"Pebble LE\" gekoppelt wird nachdem die nicht-LE Pebble einmal verbunden war. Pebble 2/LE GATT MTU Limit - Wenn deine Pebble 2/Pebble LE nicht so wie erwartet funktioniert, versuche die MTU zu begrenzen (erlaubte Werte zwischen 20–512) + Wenn deine Pebble 2/Pebble LE nicht so wie erwartet funktioniert, versuche die MTU zu begrenzen (erlaubte Werte 20 bis 512) Watch App Logging einschalten - Schreibt logs von Watch Apps in Gadgetbridge logs (Pebble muss nach Ändern der Option erneut verbunden werden) - Neuverbindungsversuche + Schreibt Logs von Watch Apps in Gadgetbridge-Logs (Pebble muss nach Ändern der Option erneut verbunden werden) + nicht ausgereiftes PebbleKit ACKen + Nachrichten, die an externe Drittanbieter-Apps geschickt werden, werden immer und sofort bestätigt + Wiederverbindungsversuche Einheiten Zeitformat + Bildschirm-An-Dauer + Den ganzen Tag Herzfrequenz messen + HPlus/Makibes Einstellungen nicht verbunden verbinde verbunden @@ -128,10 +143,10 @@ Dies ist eine Test Benachrichtigung von Gadgetbridge Bluetooth wird nicht unterstützt. Bluetooth ist abgeschaltet. - berühre das verbundene Gerät, um den App Manager zu starten - Tippe auf das verbundene Gerät um die Aktivitätsdaten anzuzeigen - Tippe auf das verbundene Gerät um zu vibrieren - berühre ein Gerät zum Verbinden + Tippe auf das verbundene Gerät, um den App Manager zu starten + Tippe auf das verbundene Gerät, um die Aktivitätsdaten anzuzeigen + Tippe auf das verbundene Gerät, um zu vibrieren + Tippe zum Verbinden auf das gewünschte Gerät Verbindung kann nicht aufgebaut werden. BT Adresse ungültig? Gadgetbridge läuft installiere Datei %1$d/%2$d @@ -147,11 +162,15 @@ Suche starten Neues Gerät verbinden %1$s (%2$s) - Gerät paaren - Verwende den Android Bluetooth Paaren-Dialog um Dein Gerät zu paaren. - Paare Dein Mi Band - Pairing mit %s… - Kein MAC Adresse bekommen, kann nicht paaren. + Gerät koppeln + Verwende den Android Bluetooth Kopplungsdialog um Dein Gerät zu koppeln. + Kopple Dein Mi Band + Koppeln mit %s… + Bindung mit %1$s (%2$s) herstellen + Kann nicht mit %1$s (%2$s) koppeln + Bindung findet statt: %1$s (%2$s) + Bereits mit %1$s (%2$s) gebunden, stelle Verbindung her...... + Keine MAC Adresse erhalten, kann nicht koppeln. Gerätespezifische Einstellungen Mi Band Einstellungen männlich @@ -169,18 +188,18 @@ Name/Alias Anzahl der Vibrationen Schlafmonitor - Log-Dateien schreiben + Logdateien schreiben initialisiere - Hole Aktivitätsdaten + Rufe Aktivitätsdaten ab Von %1$s bis %2$s - Links- oder Rechtsträger? + Linker oder rechter Arm? Vibrationsprofile Stakkato Kurz Mittel Lang Wassertropfen - Ring + Klingel Wecker Vibration Test @@ -193,7 +212,7 @@ Navigation Soziales Netzwerk Verlegtes Gerät suchen - Abbrechen um die Vibration zu stoppen. + Abbrechen, um die Vibration zu stoppen. Deine Aktivität Wecker stellen Wecker stellen @@ -207,7 +226,7 @@ Sa Intelligenter Wecker Beim Stellen der Wecker ist ein Fehler aufgetreten. Bitte erneut versuchen! - Wecker wurden auf dem Gerät gestellt! + Wecker wurden an das Gerät gesendet! Keine Daten. Gerät synchronisieren? %1$s an Daten werden übertragen, beginnend mit %2$s Ziel Anzahl Schritte pro Tag @@ -216,14 +235,15 @@ Kann keine Verbindung herstellen: %1$s Kann keinen Handler für die Installation dieser Datei finden. Konnte folgende Datei nicht installieren: %1$s - Kann die gegebene Firmware nicht installieren. Sie passt nicht zur Hardware Revision der Pebble. - Bitte warten während der Installationsoption festgestellt wird… + Kann die gegebene Firmware nicht installieren. Sie passt nicht zur Hardware-Revision der Pebble. + Bitte warten, Installationsstatus wird festgestellt... Gadget Akkustand niedrig! %1$s Akku übrig: %2$s%% Zuletzt aufgeladen: %s\n Anzahl Ladungen: %s Dein Schlaf - Schritte der Woche + Schlaf pro Woche + Schritte pro Woche Deine Aktivität und Schlaf Firmware wird aktualisiert… Datei kann nicht installiert werden, Gerät nicht bereit. @@ -232,20 +252,20 @@ Ungetestete Version! Verbindung zum Gerät: %1$s Pebble Firmware %1$s - Korrekte Hardware Revision - Falsche Hardware Revision! + Korrekte Hardware-Revision + Falsche Hardware-Revision! %1$s (%2$s) - Problem mit der Firmwareübertragung: NICHT das Mi Band neu starten! + Problem mit der Firmwareübertragung. NICHT das Mi Band neu starten! Problem bei der Firmware Metadatenübertragung - Firmware Installation erfolgreich beendet - Firmware Installation erfolgreich beendet, Gerät wird neu gestartet… + Firmware-Installation erfolgreich beendet + Firmware-Installation erfolgreich beendet, Gerät wird neu gestartet… Schreiben der Firmware fehlgeschlagen Schritte Live Aktivität Schritte heute, Ziel: %1$s Transfer von Aktivitätsdaten nicht bestätigen - Wenn der Transfer der Aktivitätsdaten nicht bestätigt wird, werden die Daten nicht auf dem Mi Band gelöscht. Das ist Sinnvoll, wenn neben Gadgetbridge noch andere Apps auf das Mi Band zugreifen. - Aktivitätsdaten verbleiben auf dem Mi Band, auch nach der Synchronisierung. Hilfreich wenn das Mi Band mit weiteren Apps verwendet wird. + Wenn der Transfer der Aktivitätsdaten nicht bestätigt wird, werden die Daten nicht auf dem Mi Band gelöscht. Das ist sinnvoll, wenn neben Gadgetbridge noch andere Apps auf das Mi Band zugreifen. + Aktivitätsdaten verbleiben auf dem Mi Band, auch nach der Synchronisierung. Hilfreich, wenn das Mi Band mit weiteren Apps verwendet wird. Benutze Modus mit niedriger Latenz für FW-Updates Dies kann bei Geräten helfen, bei denen Firmwareupdates fehlschlagen Verlauf Schritte @@ -257,14 +277,19 @@ Leichter Schlaf Tiefschlaf Nicht getragen - Nicht verbunden + Nicht verbunden. Alle Alarme deaktiviert Aktivitätsdaten auf dem Gerät lassen Inkompatible Firmware Diese Firmware ist nicht mit dem Gerät kompatibel Wecker für zukünftige Ereignisse vormerken - Verwende den Herzfrequenzsensor um die Schlaferkennung zu verbessern + Verwende den Herzfrequenzsensor, um die Schlaferkennung zu verbessern Zeitausgleich in Stunden (um den Schlaf von Schichtarbeitern zu erkennen) + Mi2: Datumsformat + Zeit + + Display beim Anheben aktivieren + Werde Daten ab %1$s übertragen. warte auf Verbindung Über Dich Geburtsjahr @@ -285,31 +310,21 @@ Firmware wurde nicht gesendet Herzfrequenz Herzfrequenz - - Datenbankimport - Alte Aktivitätsdaten importieren - Seit Gadgetbridge 0.12.0 benutzen wir ein neues Datenbankformat. -Du kannst alte Aktivitätsdaten dem zu verbindenden Gerär (%1$s.) zuordnen\n -\n -Wenn Du jetzt keine alten Aktivitätsdaten importierst, kannst Du das immer noch später in dem Datenbankverwaltung Bildschirm machen, indem Du dort den \"MERGE OLD ACTIVITY DATA\" Knopf drückst.\n -\n -Bitte beachte, dass Du Daten vom Mi Band, Pebble Health und Morpheuz importieren kannst - aber nicht von Pebble Misfit. - Rohdaten in der Datenbank speichern - Wenn eingeschaltet, werden Daten so wie sie eingehen gespeichrt, um später noch interpretiert werden zu können. Achtung: Die Datenbank wird dadurch größer! - Datenbankmanagement - Datenbankmanagement - Die Aktivitätsdaten, die mit Gadgetbridge Versionen vor 0.12.0 aufgezeichnet wurden, müssen in ein neues Format umgewandelt werden.\n -Du kannst das tun, indem du den Knopf unten drückst. Bitte beachte, dass Du mit dem Gerät verbunden sein musst, für das Du alten Aktivitätsdaten importieren willst.\n -Wenn Du schon deine Daten importiert hast und mit dem Ergebnis zufrieden bist, kannst du die alte Datenbank löschen. + Wenn eingeschaltet, werden Daten so wie sie eingehen für eine spätere analyse gespeichert. Achtung: Die Datenbank wird dadurch größer! + Datenbankverwaltung + Datenbankverwaltung + Die Datenbankoperationen verwenden den folgenden Pfad auf dem Gerät. \nDieser Pfad ist von anderen Android-Apps und ihrem Computer aus zugreifbar. \nSie finden die exportierte Datenbank hier (bzw. legen die zu importierende dort ab): + Legacy-Datenbank löschen + Kann nicht auf den Exportpfad zugreifen. Bitte die Entwickler kontaktieren. Exportiert nach: %1$s Fehler beim Exportieren der DB: %1$s Daten importieren? + Wirklich die aktuelle Datenbank überschreiben? Alle aktuellen Aktivitätsdaten (sofern vorhanden) gehen verloren! Import erfolgreich. Fehler beim Importieren der DB: %1$s - Führe Aktivitätsdaten zusammen - Beim Importieren der alten Aktivitätsdaten ist ein Fehler aufgetreten! - Alte Daten löschen? + Aktivitätsdaten löschen? + Wirklich die komplette Datenbank löschen? Alle Aktivitätsdaten und Informationen über Deine Geräte gehen verloren! Daten erfolgreich gelöscht. Löschen der Datenbank fehlgeschlagen. Alte Aktivitätsdatenbank löschen? @@ -322,5 +337,13 @@ Wenn Du schon deine Daten importiert hast und mit dem Ergebnis zufrieden bist, k Vibration + Pebble-Kopplung + Ein Kopplungsdialog sollte auf dem Android-Gerät aufpoppen. Falls das nicht passiert, schau in die Benachrichtigungen und akzeptiere die Kopplungsanfrage. Akzeptiere danach die Kopplungsanfrage auf Deiner Pebble. + Bluetooth-Kopplung aktivieren + Deaktiviere dies falls Du Probleme beim verbinden hast + Metrisch + Imperial (US/UK) + 24h + AM/PM Wecker diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index aa21fdae5..60730fe18 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -163,7 +163,7 @@ Conectar un nuevo dispositivo %1$s (%2$s) Emparejar dispositivo - Usar el menú de emparejar Bluetooth de Android para emparejar el dispositivo. + Usar el menú de emparejamiento Bluetooth de Android para vincular el dispositivo. Emparejar tu MiBand Emparejando con %s... Creando emparejamiento con %1$s (%2$s) @@ -241,6 +241,7 @@ Última carga: %s \n Número de cargas: %s Tu sueño + Dormir una semana Pasos por semana Tu actividad y sueño Actualizando firmware... @@ -308,22 +309,12 @@ Firmware no enviado Pulsaciones Pulsaciones - - Importar Base de Datos - Importar datos de actividad antiguos - Desde Gadgetbridge 0.12.0 usamos un nuevo formato de base de datos. -Se pueden importar los antiguos datos de actividad y asociarlos con el dispositivo al que se está conectando (%1$s).\n -\n -Si no importas los antiguos datos de actividad ahora, siempre lo podrás hacer después seleccionando \"MERGE OLD ACTIVITY DATA\" en el apartado de gestión de base de datos de actividad.\n -\n -Por favor, ten en cuenta que puedes importar datos desde Mi Band, Pebble Health y Morpheuz pero NO desde Pebble Misfit. Almacenar datos en bruto en la base de datos Seleccionado, los datos archivados se guardan en bruto y están disponibles para ser interpretados más tarde. La base de datos será más grande. Administración de Bases de Datos Administración de Bases de Datos La base de datos usa la siguiente ubicación en su dispositivo. \nEsta ubicación está accesible para otras aplicaciones Android y para su ordenador. \nEncontrará sus bases de datos exportadas (o la que quiere importar) aquí: - Los datos de actividad grabados con versiones anteriores de Gadgetbridge a 0.12 deben ser convertidos a un nuevo formato. \nPuede hacerlo utilizando el botón de abajo. ¡Tenga en cuenta que debe estar conectado con el dispositivo al que desea asociar los antiguos datos de la actividad! \nSi ya importó sus datos y está satisfecho con el resultado, es posible eliminar la base de datos antigua. - Importar/Borrar Base de Datos Antigua + Borrar la base de datos antigua No se puede acceder a la ruta para exportar . Por favor, contacta con los desarrolladores. Exportado a: %1$s Error exportando DB: %1$s @@ -331,12 +322,6 @@ Por favor, ten en cuenta que puedes importar datos desde Mi Band, Pebble Health ¿Quiere sobreescribir la base de datos actual? Todos sus datos actuales (si los hay) se borrarán. Importado con éxito. Error importando DB: %1$s - No se ha encontrado una base de datos con actividad antigua, no se importará nada. - No hay ningún dispositivo conectado al que asociar la base de datos antigua. - Fusionando los datos de actividad - Por favor, espere mientras se unen las bases de datos. - Error importando los datos antiguos a la nueva base de datos. - Asociar los datos antiguos al dispositivo ¿Quieres borrar los datos de actividad? ¿Quieres borrar la base de datos? Todos tus datos de actividad y la información sobre tus dispositivos se borrarán. Datos borrados. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 2ab027771..2e5207597 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -241,6 +241,7 @@ Dernière charge: %s \n Nombre de charges: %s Votre sommeil + Dormir une semaine Pas de la semaine Votre activité et sommeil Mise à jour du micrologiciel... @@ -308,25 +309,13 @@ Échec lors de l\'écriture du micrologiciel Rythme cardiaque Rythme cardiaque - - Importer la base de donnée - Importer des données d\'activité anciennes - Depuis Gadgetbridge 0.12.0, nous utilisons un nouveau format de base de données. -Vous êtes en mesure d\'importer des données d\'activité anciennes et de les associer à l\'appareil auquel vous vous connectez (%1$s).\n -\n -Si vous ne voulez pas importer les anciennes données maintenant, vous pouvez toujours le faire plus tard en appuyant sur le bouton \"FUSIONNER LES ANCIENNES DONNÉES D’ACTIVITÉ\" dans le gestionnaire de base de données\n -\n -Notez que vous pouvez importer des données de Mi Band, Pebble Health et Morpheuz mais PAS de Pebble Misfit. Stockez les enregistrements brut dans la base de données Si coché, les données sont stockées \"telles quelles\" et seront disponibles pour une interprétation ultérieure. NOTE: la base de données sera bien évidement plus grande ! Gestion de base de données Gestion de base de données Les opérations sur la base de donnée ont utilisé le chemin suivant sur votre appareil.\n Ce chemin n\'est pas accessible par d\'autres applications Android ou par votre ordinateur./nVous trouverez votre base de données (ou celle que vous souhaitez importer) ici: - Les données d\'activité enregistrées avec les versions antérieures à la 0.12 de Gadgetbridge doivent être converties en un nouveau format.\n -Vous pouvez le faire en utilisant le bouton ci-dessous. Soyez conscient que vous devez être connecté à l\'appareil que vous souhaitez associer avec les anciennes données d\'activité !\n -Si vous avez déjà importé vos données et êtes satisfait du résultat, vous pouvez supprimer l\'ancienne base de données. - Import / Suppression des anciennes bases de données. + Effacer l\'ancienne base de données Impossible d\'accéder au fichier d\'export. Merci de contacter les développeurs. Exporter vers : %1$s Erreur d\'exportation BD: %1$s @@ -334,12 +323,6 @@ Si vous avez déjà importé vos données et êtes satisfait du résultat, vous Voulez-vous vraiment effacer la base de données actuelle ? Toutes vos données (si vous en avez) seront perdues. Importation réussie. Erreur lors de l\'importation BD: %1$s - Aucune ancienne base de données trouvée, rien à importer. - Pas d\'appareil connecté à associer avec l\'ancienne base de données. - Fusion des données d\'activité - Merci d\'attendre pendant la fusion de vos données. - Échec de l\'import des anciennes données d\'activité dans la nouvelle base de données. - Association des anciennes données avec le nouvel appareil. Détruire les anciennes données ? Voulez-vous vraiment détruire entièrement la base de données ? Toutes vos données d\'activité et vos informations issues de vos appareils seront perdues. Les données ont été effacées. diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml new file mode 100644 index 000000000..7804c1345 --- /dev/null +++ b/app/src/main/res/values-he/strings.xml @@ -0,0 +1,349 @@ + + + Gadgetbridge + Gadgetbridge + הגדרות + ניפוי שגיאות + יציאה + סנכרון + מעקב שינה (בבדיקה) + איתור התקן שאבד… + צילום המסך + ניתוק + מחיקת התקן + מחיקת %1$s + פעולה זו תמחק את ההתקן ואת כל המידע המשויך אליו! + ניפוי שגיאות + + מנהל יישומונים + יישומונים במטמון + יישומונים מותקנים + מסיכות שעון מותקנות + מחיקה + מחיקה והסרה מהמטמון + התקנה מחדש + חיפוש בחנות היישומונים של Pebble + הפעלה + נטרול + הפעלת + נטרול + הפעלת יישומון מזג האוויר של המערכת + נטרול יישומון מזג האוויר של המערכת + התקנת יישומון דיווח מזג האוויר + הגדרה + העברה למעלה + + חסימת דיווחים + + התקנת קושחה/יישומון + הקושחה המועמדת להתקנה היא %s במקום זו המותקנת על ה־Mi Band שלך נכון לעכשיו. + הקושחות המועמדות להתקנה הנן %1$s ו־%2$s במקום אלו המותקנת על ה־Mi Band שלך נכון לעכשיו. + קושחה זו נבדקה וידוע כי היא נתמכת ב־Gadgetbridge. + קושחה זו לא נבדקה ויתכן כי אינה נתמכת ב־Gadgetbridge.\n\nלא מומלץ להתקין אותה על ה־Mi Band שלך! + אם בכל זאת בחרת להמשיך והדברים ממשיכים לעבוד כרגיל, נא לספר למפתחים של Gadgetbridge להוסיף לרשימת ההיתר את גרסת הקושחה: %s + + הגדרות + הגדרות כלליות + התחברות להתקן כאשר ה־Bluetooth פועל + התחלה אוטומטית + התחברות אוטומטית מחדש + נגן מדיה מועדף + בררת מחדל + שעה ותאריך + סנכרון השעה + סנכרון השעה בהתקן בעת ההתחברות וכאשר השעה או אזור הזמן משתנים באנדרואיד. + ערכת עיצוב + בהירה + כהה + שפה + הסתרת ההתרעות של Gadgetbridge + הסמל בשורת המצב והדיווח במסך הנעילה מופיעים + הסמל בשורת המצב והדיווח במסך הנעילה מוסתרים + דיווחים + חזרות + שיחות טלפון + מסרונים + הודעות + תמיכה ביישומונים ששולחים דיווחים ל־Pebble באמצעות PebbleKit. + תמיכה בדיווחים גנריים + …גם כאשר המסך פעיל + לא להפריע + חסימת שליחה של דיווחים בלתי רצויים בהתבסס על המצב לא להפריע. + תעתיק + יש להפעיל זו אם להתקן שלך אין תמיכה בגופן השפה שלך (קירילית ועברית בלבד) + תמיד + כאשר המסך כבוי + לעולם לא + פרטיות + מצב פרטיות שיחה + להציג שם ומספר + להסתיר את השם אך להציג את המספר + להסתיר את השם והמספר + רשימת יישומונים שחורה + הודעות מוגדרות + תגובות + סיומת משותפת + התעלמות משיחות + עדכון ב־Pebble + אפשרויות פיתוח + כתובת + הגדרות + עוקבי פעילות + עוקב פעילות מועדף + סנכרון Pebble Health + סנכרון Misfit + סנכרון Morpheuz + תמיכה בשיחות יוצאות + נטרול אפשרות זו גם תנטרל את הרטט לשיחות יוצאות ב־Pebble 2/LE + לאפשר גישה ליישומוני צד שלישי באנדרואיד + הפעלת תמיכה ניסיונית ביישומוני אנדרואיד באמצעות PebbleKit + זריחה ושקיעה + שליחת מועדי זריחה ושקיעה בהתבסס על המיקום לציר הזמן של pebble + הסרה אוטומטית של דיווחים שהתעלמת מהם + דיווחים מוסרים אוטומטית מה־Pebble כשהתעלמת מהם בהתקן האנדרואיד + מצב פרטיות + דיווחים רגילים + החלקת טקסט הדיווח אל מחוץ למסך + הצגת סמל הדיווח בלבד + מיקום + קבלת המיקום + רוחב + אורך + להשאיר את המיקום מעודכן + לנסות לקבל את המיקום הנוכחי בזמן ההפעלה, יש להשתמש במיקום שנשמר רק כגיבוי + נא להפעיל את החיבור לרשת + המיקום התקבל + אילוץ פרוטוקול דיווח + אפשרות זו מאלצת את השימוש בפרוטוקול הדיווח העדכני ביותר בהתאם לגרסת החומרה. יש להפעיל רק אם ההשלכות ברורות לך לחלוטין! + הפעלת תכונות שלא נבדקו + הפעלת תכונות שלא נבדקו. יש להפעיל רק אם ההשלכות ברורות לך לחלוטין!! + תמיד להעדיף BLE + שימוש בתמיכה ניסיונית ב־Pebble LE עבור כל סוגי ה־Pebble במקום ה־Bluetooth הקלסי, נדרש צימוד „Pebble LE“ לאחר שנוצר חיבור שאינו LE בעבר. + מגבלת ה־MTU של GATT ל־Pebble 2/LE + אם ה־Pebble 2/Pebble LE שלך אינו עובד כצפוי, יש לנסות אפשרות זאת כדי להגביל את כמות הנתונים המועברת - MTU (טווח תקני 20–512) + הפעלת מעקב רישום אחר יישומון השעון + יגרום לרישומים מיישומי השעון להיות מתועדים ב־Gadgetbridge (נדרשת הפעלה מחדש) + אישור מסירה מוקדם מצד PebbleKit + יגרום להודעות שנשלחות ליישומוני צד שלישי לקבל אישור מסירה תמיד ובאופן מיידי + ניסיונות חיבור מחדש + יחידות + תבנית הזמן + משך מסך פעיל + מדידת דופק במשך כל היום + הגדרות HPlus/Makibes + לא מחובר + מחובר + מתחבר + מצב לא ידוע + חומרה: %1$s קושחה: %2$s + קושחה: %1$s + (לא ידוע) + בדיקה + דיווח לבדיקה + זהו דיווח לבדיקה מ־Gadgetbridge + אין תמיכה ב־Bluetooth. + ה־Bluetooth מנוטרל. + נקישה על ההתקן המחובר למנהל היישומים + נקישה על ההתקן המחובר לפעילות + נקישה על ההתקן המחובר לרטט + יש לגעת בהתקן כדי להתחבר + לא ניתן להתחבר. כתובת ה־BT שגויה? + Gadgetbridge פעיל + התקנת הבינרי %1$d/%2$d + ההתקנה נכשלה! + ההתקנה הצליחה + זהו ניסיון להתקנת קושחה, ניתן להמשיך אם ברורות לך ההשלכות.\n\n\n קושחה זו מיועדת לחומרה במהדורה: %s + היישומון המועמד להתקנה הוא:\n\n\n%1$s גרסה %2$s מאת %3$s\n + לא זמין + מאותחל + %1$s מאת %2$s + גילוי התקנים + להפסיק את הסריקה + להתחיל בסריקה + חיבור התקן חדש + %1$s (%2$s) + צימוד התקן + יש להשתמש בדו־שיח צימוד ה־Bluetooth לאנדרואיד כדי ליצור צימוד להתקן. + צימוד ה־Mi Band שלך + מתבצע צימוד עם %s… + נוצר איגוד עם %1$s‏ (%2$s) + לא ניתן ליצור צימוד עם %1$s ‏(%2$s) + מתבצע איגוד: %1$s‏ (%2$s) + כבר נוצר איגוד עם %1$s (%2$s), מתבצעת התחברות… + לא הועברה כתובת חומרה, לא ניתן לצמד. + הגדרות ייעודיות להתקן + הגדרות Mi Band + זכר + נקבה + אחר + שמא + ימין + לא ניתנו נתוני משתמש, נעשה שימוש בנתוני דמה לבינתיים. + כאשר ה־Mi Band שלך רוטט ומהבהב, יש לגעת בו מספר פעמים ברצף. + התקנה + נא לוודא שההתקן שלך פתוח לגילוי. התקנים שכבר חוברו לא יופיעו ברשימה. באנדרואיד 6 ומעלה, עליך להפעיל את המיקום (למשל GPS). אם ההתקן שלך לא מופיע לאחר למעלה משתי דקות, יש לנסות שוב לאחר הפעלה מחדש של הטלפון שלך. + לתשומת לבך: + תמונת ההתקן + שם/כינוי + ספירת רטט + מעקב שינה + כתיבת קובצי יומן + מתבצע אתחול + נתוני הפעילות מתקבלים + מ־%1$s עד %2$s + על יד ימין או שמאל? + פרופיל רטט + סטקטו + קצר + בינוני + ארוך + טיפת מים + צלצול + שעון מעורר + רטט + בדיקה + דיווח על מסרון + הגדרות רטט + דיווחים כלליים + דיווח על דוא״ל + דיווח על שיחה נכנסת + צ׳אט + ניווט + רשת חברתית + איתור התקן שאבד + יש לבטל כדי לעצור את הרטט. + הפעילות שלך + הגדרת שעון מעורר + הגדרת שעון מעורר + פרטי ההתראה + יום א׳ + יום ב׳ + יום ג׳ + יום ד׳ + יום ה + יום ו׳ + שבת + השכמה חכמה + אירעה שגיאה בעת הגדרת ההתראות, נא לנסות שוב! + ההתראות נשלחו להתקן! + אין נתונים. לסנכרן מול ההתקן? + בהכנות להעברת %1$s של נתונים החל מ־%2$s + יעד צעדים בכל יום + שגיאה בהפעלת ‚%1$s‘ + הפעילות שלך (ניסיוני) + לא ניתן להתחבר: %1$s + לא ניתן למצוא מנגנון להתקנת הקובץ הזה. + לא ניתן להתקין את הקובץ הנתון: %1$s + לא ניתן להתקין את החומרה הנתונה: היא אינה תואמת את מהדורת החומרה של ה־Pebble שלך. + נא להמתין בעת איתור מצב ההתקנה… + הסוללה של הגאדג׳ט חלשה! + נותר בסוללה של %1$s:‏ %2$s%% + טעינה אחרונה: %s \n + מספר טעינות: %s + השינה שלך + שינה של שבוע + צעדים של שבוע + הפעילות והשינה שלך + הקושחה מתעדכנת… + לא ניתן להתקין את הקובץ, ההתקן לא מוכן. + הקושחה של ה־Mi Band‏ %1$s + גרסה תואמת + גרסה שלא נבדקה! + חיבור להתקן: %1$s + הקושחה של ה־Pebble‏ %1$s + מהדורת החומרה הנכונה + מהדורת החומרה אינה תואמת! + %1$s‏ (%2$s) + אירעה תקלה עם העברת הקושחה. נא לא להפעיל מחדש את ה־Mi Band שלך! + אירעה תקלה עם העברת נתוני העל של הקושחה + התקנת הקושחה הושלמה + התקנת הקושחה הושלמה, ההתקן מופעל מחדש… + כתיבת הקושחה נכשלה + צעדים + פעילות חיה + צעדים היום, יעד: %1$s + לא לשלוח אישור על העברת נתוני פעילות + אם נתוני הפעילות לא יקבלו אישור על ההעברה הם לא יימחקו. שימושי אם נעשה שימוש ביישומונים שונים למעט Gadgetbridge. + תכונה זו תגרום לשמירת נתוני הפעילות על ה־Mi Band גם לאחר הסנכרון. שימושי אם נעשה שימוש ביישומונים שונים למעט Gadgetbridge. + שימוש במצב חיבור מהיר לעדכוני קושחה + הפעלת אפשרות זו עשויה לסייע במקרים שבהם עדכון הקושחה נכשל + היסטוריית הצעדים + צעדים/דקה נכון לעכשיו + סך כל הצעדים + היסטוריית צעדים בדקה + התחלת הפעילות שלך + פעילות + שינה קלה + שינה עמוקה + לא נענד + לא מחובר. + כל ההתראות מנוטרלות + להשאיר את נתוני הפעילות בהתקן + קושחה בלתי נתמכת + קושחה זו אינה נתמכת בהתקן + התראות לשמירה עבור אירועים עתידיים + ניתן להשתמש בחיישן הדופק כדי לשפר את איתור השינה + הפרש זמן בהתקן בשעות (לזיהוי שינה של עובדי משמרות) + Mi2: תבנית זמן + זמן + + הפעלת התצוגה עם הנפת היד + עומדת להתרחש העברה מאז %1$s + בהמתנה לחיבור מחדש + עליך + שנת הלידה + מגדר + גובה בס״מ + משקל בק״ג + מתבצע אימות + נדרש אימות + חררר + הוספת וידג׳ט + משך השינה המועדף בשעות + הוגדרה התרעה לשעה %1$02d:%2$02d + חומרה: %1$s + קושחה: %1$s + אירעה שגיאה ביצירת תיקייה לקובצי הרישום: %1$s + דופק: + מתבצע עדכון קושחה + לא הוגדרה קושחה + דופק + דופק + אחסון נתונים גולמיים במסד הנתונים + אם אפשרות זו מסומנת הנתונים מאוחסנים כמו שהם ויהיו זמינים לפרשנות עתידית. לתשומת לבך: מסד הנתונים יהיה גדול יותר במצב כזה! + ניהול מסד נתונים + ניהול מסד נתונים + פעולות מסד הנתונים משתמשות בנתיב הבא בהתקן שלך. \nנתיב זה נגיש ליישומונים אחרים של אנדרואיד ולמחשב שלך. \nאת הנתונים שייצאת ממסד הנתונים (ואת מסדי הנתונים שמיועדים לייבוא) ניתן למצוא שם: + מחיקת מסד נתונים מיושן + לא ניתן לגשת לנתיב הייצוא. נא ליצור קשר עם המפתחים. + ייוצא אל: %1$s + שגיאה בייצוא מסד הנתונים: %1$s + לייבא נתונים? + באמת לשכתב על מסד הנתונים הנוכחי? כל נתונים הפעילות הנוכחיים שלך (אם יש כאלה) ילכו לאיבוד. + הייבוא הצליח. + שגיאה בייבוא מסד הנתונים: %1$s + למחוק את נתוני הפעילות? + באמת למחוק את כל מסד הנתונים? כל נתוני הפעילות והמידע על ההתקנים שלך ילך לאיבוד. + הנתונים נמחקו בהצלחה. + מחיקת מסד הנתונים נכשלה. + למחוק את מסד נתוני הפעילות המיושן? + ללמחוק את מסד נתוני הפעילות המיושן? נתוני פעילות שלא ייובאו ילכו לאיבוד. + נתוני פעילות ישנים נמחקו בהצלחה. + מחיקת מסד נתוני הפעילות הישן נכשל. + שכתוב + ביטול + מחיקה + + רטטרטט + + צימוד Pebble + במסך של התקן האנדרואיד שלך אמורה לקפוץ חלונית צימוד. אם החלונית לא מופיעה, יש לחפש במגירת הדיווחים ולאשר את בקשת הצימוד. לאחר מכן יש לאשר את בקשת הצימוד ב־Pebble שלך + נא לוודא שערכת עיצוב זו מופעלת ביישומון דיווח מזג האוויר כדי לקבל נתוני מזג אוויר ל־Pebble שלך.\n\nלא נדרשות כאן הגדרות.\n\nניתן להפעיל את יישומון מזג האוויר המערכתי של ה־Pebble שלך ממנהל היישומונים.\n\nמסיכות השעון התומכות יציגו את מזג האוויר אוטומטית. + הפעלת צימוד Bluetooth + יש לנטרל זאת אם עולות תקלות בחיבור + מטרית + אימפריאלית + 24ש׳ + AM/PM + שעון מעורר + diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000..23bab4486 --- /dev/null +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,347 @@ + + + Gadgetbridge + Gadgetbridge + Configurações + Depurar + Sair + Sincronizar + Monitor de sono (ALPHA) + Buscando dispositivo perdido... + Print da tela + Desconectar + Apagar dispositivo + Apagar %1$s + Isto irá apagar o dispositivo e apagar os dados associados! + Depurar + + Administrador de App + Apps em cache + Apps instalados + Visores instalados + Apagar + Apagar e remover do cache + Reinstalar + Buscar na loja Pebble + Ativar + Desativar + Ativar HRM + Desativar HRM + Ativas app de clima do sistema + Desativar app de clima do sistema + Instalar notificações do app de clima + Configurar + Mover para o topo + + Blacklist de notificações + + Instalador FW/App + Você está prestes a instalar o firmware %s no lugar do atual em sua Mi Band. + Você está prestes a instalar os firmwares %1$s e %2$s no lugar dos que estão atualmente na sua Mi Band. + O firmware foi testado e é compatível com Gadgetbridge. + Este firmware não foi testado e pode não ser compatível com o Gadgetbridge..\n\nNÃO recomendamos que instale em seu Mi Band! + Se você ainda quiser continuar e as coisas continuarem a funcionar corretamente depois, informe os desenvolvedores do Gadgetbridge para autorizar a versão do firmware: %s + + Configurações + Configurações Gerais + Conecte o dispositivo com o ligar o Bluetooth + Iniciar automaticamente + Reconectar automaticamente + Player de música preferencial + Padrão + Data e Hora + Sincronizar hora + Sincronizar horário quando o dispositivo estiver conectando ou quando o fuso horário mudar no android + Tema + Claro + Escuro + Idioma + Ocultar notificações do Gadgetbridge + Exibir ícone na barra de status e nas notificações na tela inicial + Ocultar ícone na barra de status e nas notificações na tela inicial + Notificações + Repetições + Chamadas de telefone + SMS + Mensagens do Pebble + Suportar notificações de aplicações que enviam notificações pelo PebbleKit. + Suportar notificações genéricas + ... e quando a tela estiver ligada + Não perturbe + Parar com notificações indesejadas enquanto estiver no modo Não Perturbe. + Representação + Ativar isso se o dispositivo não tiver suporte para seu idioma (Atualmente Cirílico apenas) + sempre + quando a tela estiver desligada + nunca + Privacidade + Modo de chamada privada + Exibir nome e número + Ocultar nome e exibir número + Ocultar nome e número + Apps em Blacklist + Histórico de mensagens + Respostas + Sufixo comum + Chamadas recusadas + Atualizar no Pebble + Opções do desenvolvedor + Endereço do Mi Band + Configurações Pebble + Ativar monitores + Monitor de atividades preferido + Sincronizar com Pebble Health + Sincronizar com Misfit + Sincronizar com Morpheuz + Suporta originar chamadas + Desabilitar isso também irá impedir o Pebble 2/LE vibrar ao originar chamadas + Permitir acesso a APPs Android de terceiros + Habilitar suporte experimental ao App Android que use PebbleKit + Despertar e pôr do sol + Enviar despertar e pôr do sol baseado na localização do pebble + Auto remover notificações rejeitadas + Notificações são automaticamente removidas quando rejeitadas no Android + Modo de privacidade + Notificações + Deslocar texto de notificações que extrapolar a tela + Apenas mostrar ícone de notificações + Localização + Obter localização + Latitude + Longitude + Mantenha a localização atualizada + Tente obter a localização online, use dados armazenados como fallback + Por favor, habilite localização de rede + localização obtida + Forçar o protocolo de notificação + Esta opção força o uso do protocolo de notificação mais recente. HABILITE APENAS SE SABE O QUE ESTÁ FAZENDO! + Habilitar recursos não certificados + Habilitar recursos não certificados. FAÇA ISSO SE SOUBER O QUE REALMENTE ESTÁ FAZENDO! + Sempre preferir BLE + Use suporte experimental do Pebble LE em vez do Bluetooth clássico, requer parear um \"Pebble LE\" depois de que nenhum LE tenha sido conectado + Pebble 2/LE GATT MTU limite + Se seu Pebble 2/Pebble LE não funciona como esperado, tente esta configuração para limitar o MTU (faixa válida 20–512) + Ativas registro de Log do App do Relógio + Faz com que os logs de aplicativos de monitoramento sejam registrados por Gadgetbridge (exige reconectar) + Prematuramente ACK PebbleKit + Isso fará com que as mensagens enviadas para aplicativos de terceiros sejam reconhecidas sempre e imediatamente + Tentativas de Reconexão + Unidades + Formato da hora + Duração de tela + Medição da frequência cardíaca durante todo o dia + Configurações do HPlus/Makibes + desconectado + conectando + conectado + estado desconhecido + HW: %1$s FW: %2$s + FW: %1$s + (desconhecido) + Teste + Teste de notificação + Esta é uma Notificação de Teste de Gadgetbridge + Bluetooth não suportado + Bluetooth desabilitado + Toque no dispositivo conectado + Toque no dispositivo conectado + Toque no dispositivo conectado para Vibração + Toque num dispositivo para ligar + Não pode conectar. Endereço BT inválido? + Gadgetbridge em execução + Instalação binária %1$d/%2$d + falha na instalação! + instalação bem sucedida + VOCÊ ESTÁ TENTANDO INSTALAR UM FIRMWARE, A SEU PRÓPRIO RISCO. \n\n\nEste firmware é para HW Revisão: %s + Você está prestes a instalar o seguinte aplicativo: \n\n\n %1$s Versão %2$s por %3$s\n + N/A + inicializado + %1$s de %2$s + Dispositivo encontrado + Parar com a busca + Iniciar busca + Conecte novo dispositivo + %1$s (%2$s) + Parear dispositivo + Use a caixa de diálogo Android Bluetooth para emparelhar o dispositivo. + Parear sua Mi Band + Pareando com %s... + Criar vínculo com %1$s (%2$s) + Não é possível emparelhar com %1$s (%2$s) + Vinculação em andamento: %1$s (%2$s) + Já ligado com %1$s (%2$s), conectando ... + Nenhum endereço do mac passou, não pode emparelhar. + Configurações Específicas do Dispositivo + Configurações da Mi Band + masculino + feminino + outro + esquerda + direita + Nenhum dado válido informado, usando dados fictícios por enquanto. + Quando a sua Mi Band vibra e pisca, toque nele algumas vezes seguidas. + Instalar + Torne o dispositivo detectável. Os dispositivos atualmente conectados provavelmente não serão descobertos. No Android 6 ou posterior, é necessário ativar o local (por exemplo, GPS). Se o dispositivo não aparecer após dois minutos, tente novamente após reiniciar o dispositivo móvel. + Nota: + Imagem do Dispositivo + Nome/Apelido + Quantidade de vibrações + Monitor de sono + Escrever arquivos de Log + Inicializando + Adquirindo Dados de Atividades + De %1$s a %2$s + Dispositivo na esquerda ou direita? + Prefil de Vibração + Destacado + Pequeno + Médio + Longo + Pingo D\'água + Anel + Alarme + Vibração + Tente + Notificações SMS + Configurações de vibrações + Notificação genérica + Notificação de email + Notificações de chamadas + Bate papo + Navegação + Rede social + Busca Dispositivo Perdido + Cancele para parar a vibração + Sua atividade + Configurar Alarmes + Configurar alarmes + Detalhes do alarme + Dom + Seg + Ter + Qua + Qui + Sex + Sab + despertar inteligente + Tem algum erro ao definir o alarme, tente novamente! + Alarme enviado para o dispositivo! + Sem data. Sincronizar com dispositivo? + Transferir %1$s dados a partir de %2$s + Objetivo de passos por dia + Erro executando \'%1$s\' + Sua Atividade (ALPHA) + Impossível conectar: %1$s + Não foi possível encontrar um manipulador para instalar o arquivo. + Impossível instalar o arquivo fornecido: %1$s + Não é possível instalar o firmware fornecido: ele não corresponde à revisão do hardware do seu Pebble. + Aguarde enquanto é determinado o status da instalação ... + Gadget com bateria baixa! + %1$s bateria a: %2$s%% + Última carga: %s \n + Número de cargas: %s + Seu Sono + Passos na semana + Sua Atividade e Sono + Atualizando Firmware... + Arquivo não pode ser instalado, o dispositivo não está pronto. + Mi Band Firmware %1$s + Versão compatível + Versão não testada! + Conexão com o dispositivo: %1$s + Pebble Firmware %1$s + Corrigir a revisão do hardware + Incompatibilidade de revisão de hardware! + %1$s (%2$s) + Problema com a transferência do firmware. NÃO REBOTAR sua Mi Band! + Problemas ao transferir os metadados do firmware + Instalação do Firmware completa + Instalação do Firmware completa, reiniciando o dispositivo... + Falha ao instalar o Firmware + Passos + Atividade ao vivo + Etapas de hoje, meta: %1$s + Não transferir dados da atividade ack + Se os dados da atividade não forem chamados para a pulseira, eles não serão apagados. Útil se GB for usado em conjunto com outros aplicativos. + Manterão os dados da atividade no Mi Band mesmo após a sincronização. Útil se GB for usado em conjunto com outros aplicativos. + Use o modo de baixa latência para atualizações FW + Isso pode ajudar em dispositivos nos quais as atualizações de firmware falham + Histórico de passos + Passos/min atuais + Total de passos + Histórico de passos por minuto + Iniciar sua atividade + Atividade + Sono leve + Sono pesado + Não utilizado + Desconectado. + Todos os alarmes desabilitados + Manter dados de atividade no dispositivo + Firmware incompatível + Este firmware não é compatível com seu dispositivo + Alarmes reservados para eventos próximos + Use o sensor de freqüência cardíaca para melhorar a detecção do sono + Desvio do tempo do dispositivo em horas (para detectar o sono dos trabalhadores por turnos) + Mi2: Formato de data + Hora + + Ativar exibição ao levantar + Sobre para transferir dados desde %1$s + aguarde para reconectar + Sobre você + Ano de anoversário + Gênero + Altura em cm + Peso em kg + autenticando + autenticação requerida + Zzz + Adicionar widget + Preferir duração de sono em horas + Um alarme foi definido para %1$02d:%2$02d + HW: %1$s + FW: %1$s + Erro ao criar o diretório para arquivos de log: %1$s + FC: + Atualização de Firmware em progresso + Firmware não enviado + Frequência cardíaca + Frequência cardíaca + Armazenar registro bruto no banco de dados + Se marcado, os dados são armazenados \"como\" e estão disponíveis para interpretação posterior. NB: a base de dados será maior neste caso! + Gerenciamento de banco de dados + Gerenciamento de banco de dados + As operações do banco de dados usam o seguinte caminho no dispositivo.\nEste caminho está acessível a outras aplicações Android e ao seu computador.\nApós encontrar o banco de dados exportado (ou colocar o banco de dados que você deseja importar): + Não é possível acessar o caminho de exportação. Entre em contato com os desenvolvedores. + Exportado para: %1$s + Erro ao exportar BD: %1$s + Importar dados? + Realmente sobrescrever o banco de dados atual? Todos os seus dados atuais de atividade (se houver) serão perdidos. + Sucesso ao importar. + Erro ao importar BD: %1$s + Excluir Dados de Atividade? + Excluir realmente o banco de dados inteiro? Todos os seus dados de atividade e informações sobre seus dispositivos serão perdidos. + Dados eliminados com êxito. + Falha na eliminação do banco de dados. + Excluir antigo banco de dados de atividades? + Excluir realmente o banco de dados de atividade antigo? Os dados da atividade que não foram importados serão perdidos. + Dados de atividade antiga excluídos com êxito. + Falha na eliminação da base de dados da Actividade Antiga. + Sobrepor + Cancelar + Apagar + + Vibração + + Pareando Pebble + Espera-se que um diálogo de emparelhamento apareça no seu dispositivo Android. Se isso não acontecer, procure na gaveta de notificação e aceite o pedido de emparelhamento. Depois que aceitar o pedido de emparelhamento em seu Pebble + Certifique-se de que esta capa está ativada no aplicativo Notificação de Tempo para obter informações sobre o tempo em seu Pebble.\n\nNão é necessário configurar aqui.\n\nVocê pode ativar o aplicativo de tempo do sistema de seu Pebble do gerenciamento de aplicativos.\n\nOs relógios assistidos mostrarão o tempo automaticamente. + Ativar o emparelhamento Bluetooth + Desactive esta opção se tiver problemas para + Métrico + Imperial + 24H + AM/PM + Alarme + diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml new file mode 100644 index 000000000..a4752e630 --- /dev/null +++ b/app/src/main/res/values-pt/strings.xml @@ -0,0 +1,228 @@ + + + Configurações + Depurar + Sair + Sincronizar + Monitor de sono (ALPHA) + Buscando dispositivo perdido... + Print da tela + Desconectar + Apagar dispositivo + Apagar %1$s + Isto irá apagar o dispositivo e apagar os dados associados! + Depurar + + Administrador de App + Apps em cache + Apps instalados + Visores instalados + Apagar + Apagar e remover do cache + Reinstalar + Buscar na loja Pebble + Ativar + Desativar + Ativar HRM + Desativar HRM + Ativas app de clima do sistema + Desativar app de clima do sistema + Instalar notificações do app de clima + Configurar + Mover para o topo + + Blacklist de notificações + + Instalador FW/App + Você está prestes a instalar o firmware %s no lugar do atual em sua Mi Band. + O firmware foi testado e é compatível com Gadgetbridge. + + Configurações + Configurações Gerais + Conecte o dispositivo com o ligar o Bluetooth + Iniciar automaticamente + Reconectar automaticamente + Player de música preferencial + Padrão + Data e Hora + Sincronizar hora + Tema + Claro + Escuro + Idioma + Ocultar notificações do Gadgetbridge + Exibir ícone na barra de status e nas notificações na tela inicial + Ocultar ícone na barra de status e nas notificações na tela inicial + Notificações + Repetições + Chamadas de telefone + SMS + Mensagens do Pebble + Suportar notificações de aplicações que enviam notificações pelo PebbleKit. + Suportar notificações genéricas + ... e quando a tela estiver ligada + Não perturbe + Parar com notificações indesejadas enquanto estiver no modo Não Perturbe. + sempre + quando a tela estiver desligada + nunca + Privacidade + Modo de chamada privada + Exibir nome e número + Ocultar nome e exibir número + Ocultar nome e número + Apps em Blacklist + Histórico de mensagens + Respostas + Sufixo comum + Chamadas recusadas + Atualizar no Pebble + Opções do desenvolvedor + Endereço do Mi Band + Configurações Pebble + Ativar monitores + Monitor de atividades preferido + Sincronizar com Pebble Health + Sincronizar com Misfit + Sincronizar com Morpheuz + Habilitar suporte experimental ao App Android que use PebbleKit + Despertar e pôr do sol + Enviar despertar e pôr do sol baseado na localização do pebble + Auto remover notificações rejeitadas + Notificações são automaticamente removidas quando rejeitadas no Android + Modo de privacidade + Notificações + Deslocar texto de notificações que extrapolar a tela + Apenas mostrar ícone de notificações + Localização + Obter localização + Latitude + Longitude + Mantenha a localização atualizada + Tente obter a localização online, use dados armazenados como fallback + Por favor, habilite localização de rede + localização obtida + Forçar o protocolo de notificação + Esta opção força o uso do protocolo de notificação mais recente. HABILITE APENAS SE SABE O QUE ESTÁ FAZENDO! + Habilitar recursos não certificados + Habilitar recursos não certificados. FAÇA ISSO SE SOUBER O QUE REALMENTE ESTÁ FAZENDO! + Sempre preferir BLE + Unidades + Formato da hora + Duração de tela + desconectado + conectando + conectado + estado desconhecido + Teste + Teste de notificação + Bluetooth não suportado + Bluetooth desabilitado + falha na instalação! + instalação bem sucedida + inicializado + Dispositivo encontrado + Parar com a busca + Iniciar busca + Conecte novo dispositivo + Parear dispositivo + Pareando com %s... + masculino + feminino + outro + esquerda + direita + Instalar + Nota: + Nome/Apelido + Quantidade de vibrações + Monitor de sono + Escrever arquivos de Log + Inicializando + Pequeno + Médio + Longo + Alarme + Vibração + Tente + Notificações SMS + Configurações de vibrações + Notificação genérica + Notificação de email + Notificações de chamadas + Bate papo + Navegação + Rede social + Sua atividade + Configurar Alarmes + Configurar alarmes + Detalhes do alarme + Dom + Seg + Ter + Qua + Qui + Sex + Sab + despertar inteligente + Tem algum erro ao definir o alarme, tente novamente! + Alarme enviado para o dispositivo! + Sem data. Sincronizar com dispositivo? + Objetivo de passos por dia + Sua Atividade (ALPHA) + Não foi possível encontrar um manipulador para instalar o arquivo. + Gadget com bateria baixa! + Seu Sono + Passos na semana + Sua Atividade e Sono + Atualizando Firmware... + Arquivo não pode ser instalado, o dispositivo não está pronto. + Versão compatível + Versão não testada! + Problemas ao transferir os metadados do firmware + Instalação do Firmware completa + Instalação do Firmware completa, reiniciando o dispositivo... + Falha ao instalar o Firmware + Passos + Atividade ao vivo + Histórico de passos + Passos/min atuais + Total de passos + Histórico de passos por minuto + Iniciar sua atividade + Atividade + Sono leve + Sono pesado + Não utilizado + Desconectado. + Todos os alarmes desabilitados + Manter dados de atividade no dispositivo + Firmware incompatível + Este firmware não é compatível com seu dispositivo + Alarmes reservados para eventos próximos + Hora + aguarde para reconectar + Sobre você + Ano de anoversário + Gênero + Altura em cm + Peso em kg + autenticando + autenticação requerida + Adicionar widget + Preferir duração de sono em horas + Atualização de Firmware em progresso + Firmware não enviado + Importar dados? + Sucesso ao importar. + Sobrepor + Cancelar + Apagar + + Vibração + + Pareando Pebble + Métrico + Imperial + Alarme + diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 57f1da2e4..254e7ad16 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -10,19 +10,28 @@ Знайти загублений пристрій… Зробити знімок екрану Від\'єднатися + Вилучити пристрій + Вилучити %1$s + Це вилучить пристрій та всі пов\'язані з ним дані! Зневадження App Manager + Встановлені додатки Вилучити + Вилучити та очистити з кешу Перевстановити + Пошук в Pebble Appstore Увімкнути Вимкнути + Увімкнути HRM + Вимкнути HRM Конфігурація Перелік заблокованих сповіщень Встановлення мікропрограми Ви збираєтесь встановити мікропрограму %s на заміну поточній Вашого Mi–Band + Ви збираєтесь встановити мікропрограми %1$s та %2$s на заміну поточній Вашого Mi–Band Ця мікропрограма була перевірена на сумісність із Gadgetbridge Ця мікропрограма не перевірялася і може бути не сумісною із Gadgetbridge.\n\nНе рекомендується встановлювати її на Ваш Mi–Band Якщо ж Ви вирішили продовжити та все працює, будь ласка, повідомте про це розробникам, аби відмітити цю версію мікропрограми сумісною: %s @@ -30,6 +39,7 @@ Параметри Загальні параметри З\'єднання із пристроєм при активації Bluetooth + Запускатися автоматично Перепід\'єднуватись автоматично Переважний музичний програвач Типовий @@ -51,6 +61,7 @@ завжди коли екран вимкнуто ніколи + Приавтність Перелік заблокованих додатків Відповіді Загальний суфікс @@ -74,6 +85,7 @@ Увімкнути не перевірені можливості Увімкнути функції, які ще не перевірені. ВМИКАЙТЕ НА СВІЙ СТРАХ ТА РИЗИК! Спроби повторного з\'єднання + Формат часу немає з\'єднання з\'єднання… з\'єднано @@ -137,6 +149,9 @@ Параметри вібро Загальні сповіщення Сповіщення під час вхідного дзвінку + Чат + Навігація + Соціальні мережі Знайти загублений пристрій Скасуйте, аби зупинити вібро Ваша активність @@ -214,8 +229,11 @@ Додати віджет Пристрій: %1$s ПЗ: %1$s - + Скасувати Вилучити + Вібрація + 24г + ДП/ПП diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7e3d0d247..c3fa7eff0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -278,6 +278,7 @@ Number of charges: %s Your Sleep Sleep a week + Sleep today, target: %1$s Steps a week Your Activity and Sleep Updating Firmware… @@ -393,4 +394,7 @@ 24H AM/PM Alarm Clock + (%1$s) + You found it! + Mi2: Time Format diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml index 65bb17597..1c8856822 100644 --- a/app/src/main/res/xml/miband_preferences.xml +++ b/app/src/main/res/xml/miband_preferences.xml @@ -56,7 +56,6 @@ android:title="@string/miband2_prefs_dateformat" android:summary="%s" /> -