1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-02 03:16:07 +02:00

added support for sony swr12

This commit is contained in:
opavlov 2020-09-01 23:15:20 +03:00
parent 8394928b94
commit 06a12300a1
82 changed files with 2024 additions and 4 deletions

View File

@ -77,6 +77,7 @@ public class GBDaoGenerator {
addLefunActivitySample(schema, user, device); addLefunActivitySample(schema, user, device);
addLefunBiometricSample(schema,user,device); addLefunBiometricSample(schema,user,device);
addLefunSleepSample(schema, user, device); addLefunSleepSample(schema, user, device);
addSonySWR12Sample(schema, user, device);
addHybridHRActivitySample(schema, user, device); addHybridHRActivitySample(schema, user, device);
addCalendarSyncState(schema, device); addCalendarSyncState(schema, device);
@ -407,6 +408,17 @@ public class GBDaoGenerator {
return activitySample; return activitySample;
} }
private static Entity addSonySWR12Sample(Schema schema, Entity user, Entity device) {
Entity activitySample = addEntity(schema, "SonySWR12Sample");
activitySample.implementsSerializable();
addCommonActivitySampleProperties("AbstractActivitySample", activitySample, user, device);
addHeartRateProperties(activitySample);
activitySample.addIntProperty(SAMPLE_STEPS).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_RAW_KIND).notNull().codeBeforeGetterAndSetter(OVERRIDE);
activitySample.addIntProperty(SAMPLE_RAW_INTENSITY).notNull().codeBeforeGetterAndSetter(OVERRIDE);
return activitySample;
}
private static Entity addLefunActivitySample(Schema schema, Entity user, Entity device) { private static Entity addLefunActivitySample(Schema schema, Entity user, Entity device) {
Entity activitySample = addEntity(schema, "LefunActivitySample"); Entity activitySample = addEntity(schema, "LefunActivitySample");
activitySample.implementsSerializable(); activitySample.implementsSerializable();

View File

@ -567,5 +567,8 @@
<activity <activity
android:name=".devices.qhybrid.ImageEditActivity" android:name=".devices.qhybrid.ImageEditActivity"
android:exported="true" /> android:exported="true" />
<activity
android:name=".devices.sonyswr12.SonySWR12PrefActivity"
android:exported="true" />
</application> </application>
</manifest> </manifest>

View File

@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.PeriodicExporter;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.ConfigActivity; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.ConfigActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12.SonySWR12PrefActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.zetime.ZeTimePreferenceActivity; import nodomain.freeyourgadget.gadgetbridge.devices.zetime.ZeTimePreferenceActivity;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils; import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
@ -137,6 +138,15 @@ public class SettingsActivity extends AbstractSettingsActivity {
} }
}); });
pref = findPreference("pref_key_sonyswr12");
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
Intent intent = new Intent(SettingsActivity.this, SonySWR12PrefActivity.class);
startActivity(intent);
return true;
}
});
pref = findPreference("pref_key_blacklist"); pref = findPreference("pref_key_blacklist");
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {

View File

@ -0,0 +1,122 @@
package nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public class SonySWR12DeviceCoordinator extends AbstractDeviceCoordinator {
@Override
public DeviceType getDeviceType() {
return DeviceType.SONY_SWR12;
}
@NonNull
@Override
public DeviceType getSupportedType(GBDeviceCandidate candidate) {
String name = candidate.getDevice().getName();
if (!name.isEmpty() && name.toLowerCase().contains("swr12"))
return getDeviceType();
return DeviceType.UNKNOWN;
}
@Override
public String getManufacturer() {
return "Sony";
}
@Override
protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException {
}
@Nullable
@Override
public Class<? extends Activity> getPairingActivity() {
return null;
}
@Override
public boolean supportsActivityDataFetching() {
return true;
}
@Override
public boolean supportsActivityTracking() {
return true;
}
@Override
public SampleProvider<? extends ActivitySample> getSampleProvider(GBDevice device, DaoSession session) {
return new SonySWR12SampleProvider(device, session);
}
@Override
public InstallHandler findInstallHandler(Uri uri, Context context) {
return null;
}
@Override
public boolean supportsScreenshots() {
return false;
}
@Override
public int getAlarmSlotCount() {
return 5;
}
@Override
public boolean supportsSmartWakeup(GBDevice device) {
return true;
}
@Override
public boolean supportsHeartRateMeasurement(GBDevice device) {
return true;
}
@Override
public boolean supportsAppsManagement() {
return false;
}
@Override
public Class<? extends Activity> getAppsManagementActivity() {
return null;
}
@Override
public boolean supportsCalendarEvents() {
return false;
}
@Override
public boolean supportsRealtimeData() {
return true;
}
@Override
public boolean supportsWeather() {
return false;
}
@Override
public boolean supportsFindDevice() {
return false;
}
}

View File

@ -0,0 +1,98 @@
package nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CompoundButton;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.appcompat.widget.SwitchCompat;
import java.util.Arrays;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.SonySWR12Constants;
public class SonySWR12PrefActivity extends AbstractGBActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sonyswr12_settings);
setTitle(getString(R.string.sonyswr12_settings_title));
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
}
setVibrationSetting();
setStaminaSetting();
setAlarmIntervalSetting();
GBDevice device = GBApplication.app().getDeviceManager().getSelectedDevice();
int disablerVisibility = (device != null
&& device.isConnected()
&& device.getType() == DeviceType.SONY_SWR12) ? View.GONE : View.VISIBLE;
findViewById(R.id.settingsDisabler).setVisibility(disablerVisibility);
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
private void setVibrationSetting() {
boolean isLow = GBApplication.getPrefs().getBoolean(SonySWR12Constants.VIBRATION_PREFERENCE, false);
SwitchCompat switchVibration = ((SwitchCompat) findViewById(R.id.lowVibration));
switchVibration.setChecked(isLow);
switchVibration.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
GBApplication.getPrefs().getPreferences().edit()
.putBoolean(SonySWR12Constants.VIBRATION_PREFERENCE, isChecked).apply();
GBApplication.deviceService().onSendConfiguration(SonySWR12Constants.VIBRATION_PREFERENCE);
}
});
}
private void setStaminaSetting() {
boolean isOn = GBApplication.getPrefs().getBoolean(SonySWR12Constants.STAMINA_PREFERENCE, false);
SwitchCompat switchStamina = ((SwitchCompat) findViewById(R.id.staminaOn));
switchStamina.setChecked(isOn);
switchStamina.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
GBApplication.getPrefs().getPreferences().edit()
.putBoolean(SonySWR12Constants.STAMINA_PREFERENCE, isChecked).apply();
GBApplication.deviceService().onSendConfiguration(SonySWR12Constants.STAMINA_PREFERENCE);
}
});
}
private void setAlarmIntervalSetting() {
String interval = GBApplication.getPrefs().getString(SonySWR12Constants.SMART_ALARM_INTERVAL_PREFERENCE, "0");
List<String> intervalsArray = Arrays.asList(GBApplication.getContext().getResources().getStringArray(R.array.sonyswr12_smart_alarm_intervals));
int position = intervalsArray.indexOf(interval);
final AppCompatSpinner spinner = ((AppCompatSpinner) findViewById(R.id.smartAlarmSpinner));
spinner.setSelection(position);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String interval = (String) spinner.getItemAtPosition(position);
GBApplication.getPrefs().getPreferences().edit()
.putString(SonySWR12Constants.SMART_ALARM_INTERVAL_PREFERENCE, interval).apply();
GBApplication.deviceService().onSendConfiguration(SonySWR12Constants.SMART_ALARM_INTERVAL_PREFERENCE);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
}

View File

@ -0,0 +1,83 @@
package nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.SonySWR12Sample;
import nodomain.freeyourgadget.gadgetbridge.entities.SonySWR12SampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.SonySWR12Constants;
public class SonySWR12SampleProvider extends AbstractSampleProvider<SonySWR12Sample> {
public SonySWR12SampleProvider(GBDevice device, DaoSession session) {
super(device, session);
}
@Override
public AbstractDao<SonySWR12Sample, ?> getSampleDao() {
return getSession().getSonySWR12SampleDao();
}
@Nullable
@Override
protected Property getRawKindSampleProperty() {
return SonySWR12SampleDao.Properties.RawKind;
}
@NonNull
@Override
protected Property getTimestampSampleProperty() {
return SonySWR12SampleDao.Properties.Timestamp;
}
@NonNull
@Override
protected Property getDeviceIdentifierSampleProperty() {
return SonySWR12SampleDao.Properties.DeviceId;
}
@Override
public int normalizeType(int rawType) {
switch (rawType) {
case SonySWR12Constants.TYPE_ACTIVITY:
return ActivityKind.TYPE_ACTIVITY;
case SonySWR12Constants.TYPE_LIGHT:
return ActivityKind.TYPE_LIGHT_SLEEP;
case SonySWR12Constants.TYPE_DEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
case SonySWR12Constants.TYPE_NOT_WORN:
return ActivityKind.TYPE_NOT_WORN;
}
return ActivityKind.TYPE_UNKNOWN;
}
@Override
public int toRawActivityKind(int activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_ACTIVITY:
return SonySWR12Constants.TYPE_ACTIVITY;
case ActivityKind.TYPE_LIGHT_SLEEP:
return SonySWR12Constants.TYPE_LIGHT;
case ActivityKind.TYPE_DEEP_SLEEP:
return SonySWR12Constants.TYPE_DEEP;
case ActivityKind.TYPE_NOT_WORN:
return SonySWR12Constants.TYPE_NOT_WORN;
}
return SonySWR12Constants.TYPE_ACTIVITY;
}
@Override
public float normalizeIntensity(int rawIntensity) {
return rawIntensity;
}
@Override
public SonySWR12Sample createActivitySample() {
return new SonySWR12Sample();
}
}

View File

@ -76,6 +76,7 @@ public enum DeviceType {
LEFUN(210, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_lefun), LEFUN(210, R.drawable.ic_device_h30_h10, R.drawable.ic_device_h30_h10_disabled, R.string.devicetype_lefun),
ITAG(250, R.drawable.ic_device_itag, R.drawable.ic_device_itag_disabled, R.string.devicetype_itag), ITAG(250, R.drawable.ic_device_itag, R.drawable.ic_device_itag_disabled, R.string.devicetype_itag),
VIBRATISSIMO(300, R.drawable.ic_device_lovetoy, R.drawable.ic_device_lovetoy_disabled, R.string.devicetype_vibratissimo), VIBRATISSIMO(300, R.drawable.ic_device_lovetoy, R.drawable.ic_device_lovetoy_disabled, R.string.devicetype_vibratissimo),
SONY_SWR12(310, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_sonyswr12),
TEST(1000, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_test); TEST(1000, R.drawable.ic_device_default, R.drawable.ic_device_default_disabled, R.string.devicetype_test);
private final int key; private final int key;
@DrawableRes @DrawableRes

View File

@ -62,6 +62,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleSupport
import nodomain.freeyourgadget.gadgetbridge.service.devices.pinetime.PineTimeJFSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.pinetime.PineTimeJFSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.roidmi.RoidmiSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.roidmi.RoidmiSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.SonySWR12DeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.tlw64.TLW64Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.tlw64.TLW64Support;
import nodomain.freeyourgadget.gadgetbridge.service.devices.vibratissimo.VibratissimoSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.vibratissimo.VibratissimoSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.watch9.Watch9DeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.watch9.Watch9DeviceSupport;
@ -264,6 +265,9 @@ public class DeviceSupportFactory {
case LEFUN: case LEFUN:
deviceSupport = new ServiceDeviceSupport(new LefunDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); deviceSupport = new ServiceDeviceSupport(new LefunDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
break; break;
case SONY_SWR12:
deviceSupport = new ServiceDeviceSupport(new SonySWR12DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
break;
} }
if (deviceSupport != null) { if (deviceSupport != null) {
deviceSupport.setContext(gbDevice, mBtAdapter, mContext); deviceSupport.setContext(gbDevice, mBtAdapter, mContext);

View File

@ -0,0 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12;
import java.util.UUID;
public class SonySWR12Constants {
//accessory host service
public static final String BASE_UUID_AHS = "0000%s-37CB-11E3-8682-0002A5D5C51B";
public static final UUID UUID_SERVICE_AHS = UUID.fromString(String.format(BASE_UUID_AHS, "0200"));
public static final UUID UUID_CHARACTERISTIC_ALARM = UUID.fromString(String.format(BASE_UUID_AHS, "0204"));
public static final UUID UUID_CHARACTERISTIC_EVENT = UUID.fromString(String.format(BASE_UUID_AHS, "0205"));
public static final UUID UUID_CHARACTERISTIC_TIME = UUID.fromString(String.format(BASE_UUID_AHS, "020B"));
public static final UUID UUID_CHARACTERISTIC_CONTROL_POINT = UUID.fromString(String.format(BASE_UUID_AHS, "0208"));
public static final String VIBRATION_PREFERENCE = "vibration_preference";
public static final String STAMINA_PREFERENCE = "stamina_preference";
public static final String SMART_ALARM_INTERVAL_PREFERENCE = "smart_alarm_interval_preference";
public static final int TYPE_ACTIVITY = 0;
public static final int TYPE_LIGHT = 1;
public static final int TYPE_DEEP = 2;
public static final int TYPE_NOT_WORN = 3;
}

View File

@ -0,0 +1,351 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.IntentListener;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.battery.BatteryInfoProfile;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.EventBase;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.EventFactory;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.alarm.BandAlarm;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.alarm.BandAlarms;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control.CommandCode;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control.ControlPointLowVibration;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control.ControlPointWithValue;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.time.BandTime;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
// done:
// - time sync
// - alarms (also smart)
// - fetching activity(walking, sleep)
// - stamina mode
// - vibration intensity
// - realtime heart rate
// todo options:
// - "get moving"
// - get notified: -call, -notification, -notification from, -do not disturb
// - media control: media/find phone(tap once for play pause, tap twice for next, tap triple for previous)
public class SonySWR12DeviceSupport extends AbstractBTLEDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(SonySWR12DeviceSupport.class);
private SonySWR12HandlerThread processor = null;
private final BatteryInfoProfile<SonySWR12DeviceSupport> batteryInfoProfile;
private final IntentListener mListener = new IntentListener() {
@Override
public void notify(Intent intent) {
if (intent.getAction().equals(BatteryInfoProfile.ACTION_BATTERY_INFO)) {
BatteryInfo info = intent.getParcelableExtra(BatteryInfoProfile.EXTRA_BATTERY_INFO);
GBDeviceEventBatteryInfo gbInfo = new GBDeviceEventBatteryInfo();
gbInfo.level = (short) info.getPercentCharged();
handleGBDeviceEvent(gbInfo);
}
}
};
public SonySWR12DeviceSupport() {
super(LOG);
addSupportedService(GattService.UUID_SERVICE_BATTERY_SERVICE);
addSupportedService(SonySWR12Constants.UUID_SERVICE_AHS);
batteryInfoProfile = new BatteryInfoProfile<>(this);
batteryInfoProfile.addListener(mListener);
addSupportedProfile(batteryInfoProfile);
}
@Override
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
initialize();
setTime(builder);
batteryInfoProfile.requestBatteryInfo(builder);
return builder;
}
private SonySWR12HandlerThread getProcessor() {
if (processor == null) {
processor = new SonySWR12HandlerThread(getDevice(), getContext());
processor.start();
}
return processor;
}
private void initialize() {
if (gbDevice.getState() != GBDevice.State.INITIALIZED) {
gbDevice.setFirmwareVersion("N/A");
gbDevice.setFirmwareVersion2("N/A");
gbDevice.setState(GBDevice.State.INITIALIZED);
gbDevice.sendDeviceUpdateIntent(getContext());
}
}
@Override
public boolean useAutoConnect() {
return false;
}
@Override
public void onNotification(NotificationSpec notificationSpec) {
}
@Override
public void onDeleteNotification(int id) {
}
@Override
public void onSetTime() {
try {
TransactionBuilder builder = performInitialized("setTime");
setTime(builder);
builder.queue(getQueue());
} catch (Exception e) {
GB.toast(getContext(), "Error setting time: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR);
}
}
private void setTime(TransactionBuilder builder) {
BluetoothGattCharacteristic timeCharacteristic = getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_TIME);
builder.write(timeCharacteristic, new BandTime(Calendar.getInstance()).toByteArray());
}
@Override
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
try {
BluetoothGattCharacteristic alarmCharacteristic = getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_ALARM);
TransactionBuilder builder = performInitialized("alarm");
int prefInterval = Integer.valueOf(GBApplication.getPrefs().getString(SonySWR12Constants.SMART_ALARM_INTERVAL_PREFERENCE, "0"));
ArrayList<BandAlarm> bandAlarmList = new ArrayList<>();
for (Alarm alarm : alarms) {
BandAlarm bandAlarm = BandAlarm.fromAppAlarm(alarm, bandAlarmList.size(), alarm.getSmartWakeup() ? prefInterval : 0);
if (bandAlarm != null)
bandAlarmList.add(bandAlarm);
}
builder.write(alarmCharacteristic, new BandAlarms(bandAlarmList).toByteArray());
builder.queue(getQueue());
} catch (Exception e) {
GB.toast(getContext(), "Error setting alarms: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR);
}
}
@Override
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
return super.onCharacteristicRead(gatt, characteristic, status);
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (super.onCharacteristicChanged(gatt, characteristic))
return true;
UUID uuid = characteristic.getUuid();
if (uuid.equals(SonySWR12Constants.UUID_CHARACTERISTIC_EVENT)) {
try {
EventBase event = EventFactory.readEventFromByteArray(characteristic.getValue());
getProcessor().process(event);
} catch (Exception e) {
return false;
}
return true;
}
return false;
}
@Override
public void onSetCallState(CallSpec callSpec) {
}
@Override
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
}
@Override
public void onSetMusicState(MusicStateSpec stateSpec) {
}
@Override
public void onSetMusicInfo(MusicSpec musicSpec) {
}
@Override
public void onEnableRealtimeSteps(boolean enable) {
//doesn't support realtime steps
//supports only realtime heart rate
}
@Override
public void onInstallApp(Uri uri) {
}
@Override
public void onAppInfoReq() {
}
@Override
public void onAppStart(UUID uuid, boolean start) {
}
@Override
public void onAppDelete(UUID uuid) {
}
@Override
public void onAppConfiguration(UUID appUuid, String config, Integer id) {
}
@Override
public void onAppReorder(UUID[] uuids) {
}
@Override
public void onFetchRecordedData(int dataTypes) {
try {
TransactionBuilder builder = performInitialized("fetchActivity");
builder.notify(getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_EVENT), true);
ControlPointWithValue flushControl = new ControlPointWithValue(CommandCode.FLUSH_ACTIVITY, 0);
builder.write(getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_CONTROL_POINT), flushControl.toByteArray());
builder.queue(getQueue());
} catch (Exception e) {
LOG.error("failed to fetch activity data", e);
}
}
@Override
public void onReset(int flags) {
}
@Override
public void onHeartRateTest() {
}
@Override
public void onEnableRealtimeHeartRateMeasurement(boolean enable) {
try {
TransactionBuilder builder = performInitialized("HeartRateTest");
builder.notify(getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_EVENT), enable);
ControlPointWithValue controlPointHeart = new ControlPointWithValue(CommandCode.HEARTRATE_REALTIME, enable ? 1 : 0);
builder.write(getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_CONTROL_POINT), controlPointHeart.toByteArray());
builder.queue(getQueue());
} catch (IOException ex) {
LOG.error("Unable to read heart rate from Sony device", ex);
}
}
@Override
public void onFindDevice(boolean start) {
}
@Override
public void onSetConstantVibration(int integer) {
}
@Override
public void onScreenshotReq() {
}
@Override
public void onEnableHeartRateSleepSupport(boolean enable) {
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
}
@Override
public void onDeleteCalendarEvent(byte type, long id) {
}
@Override
public void onSendConfiguration(String config) {
try {
switch (config) {
case SonySWR12Constants.STAMINA_PREFERENCE: {
//stamina can be:
//disabled = 0, enabled = 1 or todo auto on low battery = 2
int status = GBApplication.getPrefs().getBoolean(config, false) ? 1 : 0;
TransactionBuilder builder = performInitialized(config);
ControlPointWithValue vibrationControl = new ControlPointWithValue(CommandCode.STAMINA_MODE, status);
builder.write(getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_CONTROL_POINT), vibrationControl.toByteArray());
builder.queue(getQueue());
break;
}
case SonySWR12Constants.VIBRATION_PREFERENCE: {
boolean isEnabled = GBApplication.getPrefs().getBoolean(config, false);
TransactionBuilder builder = performInitialized(config);
ControlPointLowVibration vibrationControl = new ControlPointLowVibration(isEnabled);
builder.write(getCharacteristic(SonySWR12Constants.UUID_CHARACTERISTIC_CONTROL_POINT), vibrationControl.toByteArray());
builder.queue(getQueue());
break;
}
case SonySWR12Constants.SMART_ALARM_INTERVAL_PREFERENCE: {
onSetAlarms(new ArrayList(DBHelper.getAlarms(gbDevice)));
}
}
} catch (Exception exc) {
LOG.error("failed to send config " + config, exc);
}
}
@Override
public void onReadConfiguration(String config) {
}
@Override
public void onTestNewFunction() {
}
@Override
public void onSendWeather(WeatherSpec weatherSpec) {
}
}

View File

@ -0,0 +1,135 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12;
import android.content.Context;
import android.content.Intent;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12.SonySWR12SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.SonySWR12Sample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.ActivityBase;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.ActivitySleep;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.ActivityWithData;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.EventBase;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.EventCode;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.EventWithActivity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity.EventWithValue;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
public class SonySWR12HandlerThread extends GBDeviceIoThread {
private static final Logger LOG = LoggerFactory.getLogger(SonySWR12HandlerThread.class);
public SonySWR12HandlerThread(GBDevice gbDevice, Context context) {
super(gbDevice, context);
}
public void process(EventBase event) {
if (event instanceof EventWithValue) {
if (event.getCode() == EventCode.HEART_RATE) {
processRealTimeHeartRate((EventWithValue) event);
}
} else if (event instanceof EventWithActivity) {
processWithActivity((EventWithActivity) event);
}
}
private void processRealTimeHeartRate(EventWithValue event) {
try {
DBHandler dbHandler = GBApplication.acquireDB();
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
SonySWR12SampleProvider provider = new SonySWR12SampleProvider(getDevice(), dbHandler.getDaoSession());
int timestamp = getTimestamp();
SonySWR12Sample sample = new SonySWR12Sample(timestamp, deviceId, userId, (int) event.value, ActivitySample.NOT_MEASURED, 0, 1);
provider.addGBActivitySample(sample);
GBApplication.releaseDB();
Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES)
.putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample)
.putExtra(DeviceService.EXTRA_TIMESTAMP, timestamp);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
private int getTimestamp() {
return (int) (System.currentTimeMillis() / 1000);
}
private void processWithActivity(EventWithActivity event) {
List<ActivityBase> payloadList = event.activityList;
for (ActivityBase activity : payloadList) {
switch (activity.getType()) {
case WALK:
case RUN:
addActivity((ActivityWithData) activity);
break;
case SLEEP:
addSleep((ActivitySleep) activity);
break;
}
}
}
private void addActivity(ActivityWithData activity) {
try {
DBHandler dbHandler = GBApplication.acquireDB();
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
SonySWR12SampleProvider provider = new SonySWR12SampleProvider(getDevice(), dbHandler.getDaoSession());
int kind = SonySWR12Constants.TYPE_ACTIVITY;
SonySWR12Sample sample = new SonySWR12Sample(activity.getTimeStampSec(), deviceId, userId, ActivitySample.NOT_MEASURED, activity.data, kind, 1);
provider.addGBActivitySample(sample);
GBApplication.releaseDB();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
private void addSleep(ActivitySleep activity) {
try {
DBHandler dbHandler = GBApplication.acquireDB();
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
SonySWR12SampleProvider provider = new SonySWR12SampleProvider(getDevice(), dbHandler.getDaoSession());
int kind;
switch (activity.sleepLevel) {
case LIGHT:
kind = SonySWR12Constants.TYPE_LIGHT;
break;
case DEEP:
kind = SonySWR12Constants.TYPE_DEEP;
break;
default:
kind = SonySWR12Constants.TYPE_ACTIVITY;
break;
}
if (kind == SonySWR12Constants.TYPE_LIGHT || kind == SonySWR12Constants.TYPE_DEEP) {
//need so much samples because sleep has exact duration
//so empty samples are for right representation of sleep on activity charts
SonySWR12Sample sample = new SonySWR12Sample(activity.getTimeStampSec(), deviceId, userId, ActivitySample.NOT_MEASURED, 0, SonySWR12Constants.TYPE_NOT_WORN, 1);
provider.addGBActivitySample(sample);
sample = new SonySWR12Sample(activity.getTimeStampSec() + 2, deviceId, userId, ActivitySample.NOT_MEASURED, 0, kind, 1);
provider.addGBActivitySample(sample);
sample = new SonySWR12Sample(activity.getTimeStampSec() + activity.durationMin * 60 - 2, deviceId, userId, ActivitySample.NOT_MEASURED, 0, kind, 1);
provider.addGBActivitySample(sample);
sample = new SonySWR12Sample(activity.getTimeStampSec() + activity.durationMin * 60, deviceId, userId, ActivitySample.NOT_MEASURED, 0, SonySWR12Constants.TYPE_NOT_WORN, 1);
provider.addGBActivitySample(sample);
}
GBApplication.releaseDB();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class SonySWR12Util {
public static long secSince2013() {
//sony uses time on band since 2013 for some reason
final Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
instance.set(2013, 0, 1, 0, 0, 0);
instance.set(14, 0);
return instance.getTimeInMillis()/1000;
}
public static String timeToString(long sec) {
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss");
return format.format(new Date(sec * 1000));
}
}

View File

@ -0,0 +1,35 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
public abstract class ActivityBase {
protected final ActivityType type;
protected final int timeOffsetMin;
private final long timeStampSec;
public ActivityBase(ActivityType type, int timeOffsetMin, long timeStampSec) {
if (timeOffsetMin < 0 || timeOffsetMin > 1440) {
throw new IllegalArgumentException("activity time offset out of range: " + timeOffsetMin);
}
this.type = type;
this.timeOffsetMin = timeOffsetMin;
this.timeStampSec = timeStampSec + this.timeOffsetMin * 60;
}
public final int getTimeStampSec() {
return (int) (timeStampSec);
}
public final ActivityType getType() {
return this.type;
}
protected final UIntBitWriter getWriterWithTypeAndOffset() {
UIntBitWriter uIntBitWriter = new UIntBitWriter(32);
uIntBitWriter.append(4, this.type.value);
uIntBitWriter.append(12, this.timeOffsetMin);
return uIntBitWriter;
}
public abstract long toLong();
}

View File

@ -0,0 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
public class ActivityHeartRate extends ActivityBase {
public final int bpm;
public ActivityHeartRate(int timeOffsetMin, int bpm, Long timeStampSec) {
super(ActivityType.HEART_RATE, timeOffsetMin, timeStampSec);
if (bpm < 0 || bpm > 65535) {
throw new IllegalArgumentException("bpm out of range: " + bpm);
}
this.bpm = bpm;
}
@Override
public long toLong() {
UIntBitWriter writerWithTypeAndOffset = this.getWriterWithTypeAndOffset();
writerWithTypeAndOffset.append(16, this.bpm);
return writerWithTypeAndOffset.getValue();
}
}

View File

@ -0,0 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
public class ActivitySleep extends ActivityBase {
public final SleepLevel sleepLevel;
public final int durationMin;
public ActivitySleep(int timeOffsetMin, int durationMin, SleepLevel sleepLevel, Long timeStampSec) {
super(ActivityType.SLEEP, timeOffsetMin, timeStampSec);
this.durationMin = durationMin;
this.sleepLevel = sleepLevel;
}
@Override
public long toLong() {
UIntBitWriter writerWithTypeAndOffset = this.getWriterWithTypeAndOffset();
writerWithTypeAndOffset.append(14, this.durationMin);
writerWithTypeAndOffset.append(2, this.sleepLevel.value);
return writerWithTypeAndOffset.getValue();
}
}

View File

@ -0,0 +1,23 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
public enum ActivityType {
WALK(1),
RUN(2),
SLEEP(3),
HEART_RATE(10),
END(14);
final int value;
ActivityType(int value) {
this.value = value;
}
public static ActivityType fromInt(int i) {
for (ActivityType type : values()){
if (type.value == i)
return type;
}
throw new IllegalArgumentException("wrong activity type: " + i);
}
}

View File

@ -0,0 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
public class ActivityWithData extends ActivityBase {
public final int data;
public ActivityWithData(ActivityType activityType, int timeOffsetMin, int data, Long timeStampSec) {
super(activityType, timeOffsetMin, timeStampSec);
if (data < 0 || data > 65535) {
throw new IllegalArgumentException("data out of range: " + data);
}
this.data = data;
}
@Override
public long toLong() {
UIntBitWriter writerWithTypeAndOffset = this.getWriterWithTypeAndOffset();
writerWithTypeAndOffset.append(16, this.data);
return writerWithTypeAndOffset.getValue();
}
}

View File

@ -0,0 +1,21 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public abstract class EventBase {
protected final EventCode eventCode;
protected EventBase(EventCode eventCode) {
this.eventCode = eventCode;
}
public EventCode getCode() {
return this.eventCode;
}
protected ByteArrayWriter getValueWriter() {
ByteArrayWriter byteArrayWriter = new ByteArrayWriter();
byteArrayWriter.appendUint8(this.eventCode.value);
return byteArrayWriter;
}
}

View File

@ -0,0 +1,21 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
public enum EventCode {
STEPS(3),
ACTIVITY_DATA(5),
HEART_RATE(9);
final int value;
EventCode(int value) {
this.value = value;
}
static EventCode fromInt(int i) {
for (EventCode code : values()){
if (code.value == i)
return code;
}
throw new RuntimeException("wrong event code: " + i);
}
}

View File

@ -0,0 +1,26 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.IntFormat;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayReader;
public class EventFactory {
public static EventBase readEventFromByteArray(byte[] array) {
try {
ByteArrayReader byteArrayReader = new ByteArrayReader(array);
EventCode eventCode = EventCode.fromInt(byteArrayReader.readUint8());
switch (eventCode) {
case HEART_RATE: {
long value = byteArrayReader.readInt(IntFormat.UINT32);
return new EventWithValue(eventCode, value);
}
case ACTIVITY_DATA: {
return EventWithActivity.fromByteArray(byteArrayReader);
}
default: return null;
}
} catch (Exception ex) {
return null;
}
}
}

View File

@ -0,0 +1,62 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.SonySWR12Util;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.IntFormat;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitReader;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayReader;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public class EventWithActivity extends EventBase {
public final long timeStampSec;
public final List<ActivityBase> activityList;
private EventWithActivity(long timeStampSec, List<ActivityBase> activityList) {
super(EventCode.ACTIVITY_DATA);
this.timeStampSec = timeStampSec;
this.activityList = activityList;
}
public static EventWithActivity fromByteArray(ByteArrayReader byteArrayReader) {
long timeOffset = byteArrayReader.readInt(IntFormat.UINT32);
long timeStampSec = SonySWR12Util.secSince2013() + timeOffset;
ArrayList<ActivityBase> activities = new ArrayList<>();
while (byteArrayReader.getBytesLeft() > 0) {
UIntBitReader uIntBitReader = new UIntBitReader(byteArrayReader.readInt(IntFormat.UINT32), 32);
ActivityType activityType = ActivityType.fromInt(uIntBitReader.read(4));
int offsetMin = uIntBitReader.read(12);
ActivityBase activityPayload;
switch (activityType) {
case SLEEP: {
SleepLevel sleepLevel = SleepLevel.fromInt(uIntBitReader.read(2));
int duration = uIntBitReader.read(14);
activityPayload = new ActivitySleep(offsetMin, duration, sleepLevel, timeStampSec);
break;
}
case HEART_RATE: {
int bpm = uIntBitReader.read(16);
activityPayload = new ActivityHeartRate(offsetMin, bpm, timeStampSec);
break;
}
default: {
int data = uIntBitReader.read(16);
activityPayload = new ActivityWithData(activityType, offsetMin, data, timeStampSec);
break;
}
}
activities.add(activityPayload);
}
return new EventWithActivity(timeStampSec, activities);
}
public byte[] toByteArray() {
ByteArrayWriter byteArrayWriter = this.getValueWriter();
byteArrayWriter.appendUint32(this.timeStampSec);
for (ActivityBase activity : activityList){
byteArrayWriter.appendUint32(activity.toLong());
}
return byteArrayWriter.getByteArray();
}
}

View File

@ -0,0 +1,18 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public class EventWithValue extends EventBase {
public final long value;
public EventWithValue(EventCode eventCode, long value) {
super(eventCode);
this.value = value;
}
public byte[] toByteArray() {
ByteArrayWriter byteArrayWriter = this.getValueWriter();
byteArrayWriter.appendUint32(this.value);
return byteArrayWriter.getByteArray();
}
}

View File

@ -0,0 +1,21 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.activity;
public enum SleepLevel {
AWAKE(0),
LIGHT(1),
DEEP(2);
final int value;
SleepLevel(int value){
this.value = value;
}
public static SleepLevel fromInt(int i) {
for (SleepLevel level : values()){
if (level.value == i)
return level;
}
throw new RuntimeException("wrong sleep level: " + i);
}
}

View File

@ -0,0 +1,53 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.alarm;
import java.util.Arrays;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
public class AlarmRepeat {
private final boolean[] repeat = new boolean[7];
public AlarmRepeat(Alarm alarm) {
super();
setRepeatOnDay(0, alarm.getRepetition(Alarm.ALARM_MON));
setRepeatOnDay(1, alarm.getRepetition(Alarm.ALARM_TUE));
setRepeatOnDay(2, alarm.getRepetition(Alarm.ALARM_WED));
setRepeatOnDay(3, alarm.getRepetition(Alarm.ALARM_THU));
setRepeatOnDay(4, alarm.getRepetition(Alarm.ALARM_FRI));
setRepeatOnDay(5, alarm.getRepetition(Alarm.ALARM_SAT));
setRepeatOnDay(6, alarm.getRepetition(Alarm.ALARM_SUN));
}
@Override
public boolean equals(Object o) {
if (this != o) {
if (o == null || this.getClass() != o.getClass()) {
return false;
}
return Arrays.equals(this.repeat, ((AlarmRepeat) o).repeat);
}
return true;
}
@Override
public int hashCode() {
return Arrays.hashCode(this.repeat);
}
public void setRepeatOnDay(int i, boolean b) {
this.repeat[i] = b;
}
public int toInt() {
UIntBitWriter uIntBitWriter = new UIntBitWriter(7);
uIntBitWriter.appendBoolean(this.repeat[6]);
uIntBitWriter.appendBoolean(this.repeat[5]);
uIntBitWriter.appendBoolean(this.repeat[4]);
uIntBitWriter.appendBoolean(this.repeat[3]);
uIntBitWriter.appendBoolean(this.repeat[2]);
uIntBitWriter.appendBoolean(this.repeat[1]);
uIntBitWriter.appendBoolean(this.repeat[0]);
return (int) uIntBitWriter.getValue();
}
}

View File

@ -0,0 +1,13 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.alarm;
public enum AlarmState {
TRIGGERED( 0),
SNOOZED(1),
IDLE(2);
final int value;
AlarmState(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,60 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.alarm;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
public class BandAlarm {
public static BandAlarm fromAppAlarm(Alarm alarm, int index, int interval) {
if (!alarm.getEnabled()) return null;
//smart wakeup = (0,10..60 min)/5
int ahsInterval = interval / 5;
return new BandAlarm(AlarmState.IDLE, index, ahsInterval, alarm.getHour(), alarm.getMinute(), new AlarmRepeat(alarm));
}
public AlarmState state;
public int index;
public int interval;
public int hour;
public int minute;
public AlarmRepeat repeat;
public BandAlarm(AlarmState state, int index, int interval, int hour, int minute, AlarmRepeat repeat) {
this.state = state;
this.index = index;
this.interval = interval;
this.hour = hour;
this.minute = minute;
this.repeat = repeat;
}
@Override
public boolean equals(Object o) {
if (this != o) {
if (o == null || this.getClass() != o.getClass()) {
return false;
}
BandAlarm bandAlarm = (BandAlarm) o;
if (this.index != bandAlarm.index) {
return false;
}
if (this.hour != bandAlarm.hour) {
return false;
}
if (this.interval != bandAlarm.interval) {
return false;
}
if (this.minute != bandAlarm.minute) {
return false;
}
if (!this.repeat.equals(bandAlarm.repeat)) {
return false;
}
return this.state == bandAlarm.state;
}
return true;
}
@Override
public int hashCode() {
return ((((this.state.hashCode() * 31 + this.index) * 31 + this.interval) * 31 + this.hour) * 31 + this.minute) * 31 + this.repeat.hashCode();
}
}

View File

@ -0,0 +1,35 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.alarm;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public class BandAlarms {
public final List<BandAlarm> alarms;
public BandAlarms(List<BandAlarm> alarms) {
this.alarms = alarms;
}
public byte[] toByteArray() {
ByteArrayWriter byteArrayWriter = new ByteArrayWriter();
if (this.alarms.size() == 0) {
byteArrayWriter.appendUint32(1073741824L);
} else {
for (BandAlarm bandAlarm : this.alarms) {
UIntBitWriter uIntBitWriter = new UIntBitWriter(32);
uIntBitWriter.append(2, 0);
uIntBitWriter.append(4, bandAlarm.index);
uIntBitWriter.append(2, bandAlarm.state.value);
uIntBitWriter.append(4, bandAlarm.interval);
uIntBitWriter.append(6, bandAlarm.hour);
uIntBitWriter.append(6, bandAlarm.minute);
uIntBitWriter.append(1, 0);
uIntBitWriter.append(7, bandAlarm.repeat.toInt());
byteArrayWriter.appendUint32(uIntBitWriter.getValue());
}
}
return byteArrayWriter.getByteArray();
}
}

View File

@ -0,0 +1,15 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control;
public enum CommandCode {
FLUSH_ACTIVITY(7),
HEARTRATE_REALTIME(11),
STAMINA_MODE(17),
MANUAL_ALARM(19),
LOW_VIBRATION(25);
public final int value;
CommandCode(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,17 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public abstract class ControlPoint {
protected final CommandCode code;
public ControlPoint(CommandCode code) {
this.code = code;
}
protected final ByteArrayWriter getValueWriter() {
final ByteArrayWriter byteArrayWriter = new ByteArrayWriter();
byteArrayWriter.appendUint8(this.code.value);
return byteArrayWriter;
}
}

View File

@ -0,0 +1,28 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.UIntBitWriter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public final class ControlPointLowVibration extends ControlPoint {
public boolean smartWakeUp;
public boolean incomingCall;
public boolean notification;
public ControlPointLowVibration(boolean isEnabled){
super(CommandCode.LOW_VIBRATION);
this.smartWakeUp = isEnabled;
this.incomingCall = isEnabled;
this.notification = isEnabled;
}
public final byte[] toByteArray() {
final UIntBitWriter uIntBitWriter = new UIntBitWriter(16);
uIntBitWriter.append(13, 0);
uIntBitWriter.appendBoolean(this.smartWakeUp);
uIntBitWriter.appendBoolean(this.incomingCall);
uIntBitWriter.appendBoolean(this.notification);
final ByteArrayWriter byteArrayWriter = this.getValueWriter();
byteArrayWriter.appendUint16((int) uIntBitWriter.getValue());
return byteArrayWriter.getByteArray();
}
}

View File

@ -0,0 +1,21 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.control;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public class ControlPointWithValue extends ControlPoint {
protected final int value;
public ControlPointWithValue(final CommandCode commandCode, final int value) {
super(commandCode);
if (value < 0 || value > 65535) {
throw new IllegalArgumentException("command value out of range " + value);
}
this.value = value;
}
public final byte[] toByteArray() {
final ByteArrayWriter byteArrayWriter = this.getValueWriter();
byteArrayWriter.appendUint16(this.value);
return byteArrayWriter.getByteArray();
}
}

View File

@ -0,0 +1,24 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.time;
public enum BandDaylightSavingTime {
STANDARD_TIME(0, 0),
HALF_AN_HOUR_DST(2, 30),
DST(4, 60),
DOUBLE_DST( 8, 120);
final int key;
private final long saving;
BandDaylightSavingTime(int key, int min) {
this.key = key;
this.saving = 60000L * min;
}
public static BandDaylightSavingTime fromOffset(final int dstSaving) {
for (BandDaylightSavingTime dst: values()){
if (dst.saving == dstSaving)
return dst;
}
throw new RuntimeException("wrong dst saving: " + dstSaving);
}
}

View File

@ -0,0 +1,62 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.time;
import java.util.Calendar;
import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.IntFormat;
import nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util.ByteArrayWriter;
public class BandTime {
private final int year;
private final int month;
private final int dayOfMonth;
private final int hour;
private final int min;
private final int sec;
private final int dayOfWeek;
private final BandTimeZone timeZone;
private final BandDaylightSavingTime dst;
public BandTime(Calendar calendar) {
int dayOfWeek = 7;
if (calendar == null) {
throw new IllegalArgumentException("Calendar cant be null");
}
this.year = calendar.get(1);
if (this.year > 2099 || this.year < 2013) {
throw new RuntimeException("out of 2013-2099");
}
this.month = calendar.get(2) + 1;
this.dayOfMonth = calendar.get(5);
int value = calendar.get(7);
if (value != 1) {
dayOfWeek = value - 1;
}
this.dayOfWeek = dayOfWeek;
this.hour = calendar.get(11);
this.min = calendar.get(12);
this.sec = calendar.get(13);
TimeZone timeZone = calendar.getTimeZone();
this.timeZone = BandTimeZone.fromOffset(timeZone.getRawOffset());
if (timeZone.inDaylightTime(calendar.getTime())) {
this.dst = BandDaylightSavingTime.fromOffset(timeZone.getDSTSavings());
return;
}
this.dst = BandDaylightSavingTime.STANDARD_TIME;
}
public byte[] toByteArray() {
ByteArrayWriter byteArrayWriter = new ByteArrayWriter();
byteArrayWriter.appendUint16(this.year);
byteArrayWriter.appendUint8(this.month);
byteArrayWriter.appendUint8(this.dayOfMonth);
byteArrayWriter.appendUint8(this.hour);
byteArrayWriter.appendUint8(this.min);
byteArrayWriter.appendUint8(this.sec);
byteArrayWriter.appendUint8(this.dayOfWeek);
byteArrayWriter.appendValue(this.timeZone.key, IntFormat.SINT8);
byteArrayWriter.appendUint8(this.dst.key);
return byteArrayWriter.getByteArray();
}
}

View File

@ -0,0 +1,61 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.entities.time;
public enum BandTimeZone {
UTC_PLUS_06_30(26, 6, 30),
UTC_PLUS_07_00(28, 7, 0),
UTC_PLUS_08_00(32, 8, 0),
UTC_PLUS_08_45(35, 8, 45),
UTC_PLUS_09_00(36, 9, 0),
UTC_PLUS_09_30(38, 9, 30),
UTC_PLUS_10_00(40, 10, 0),
UTC_PLUS_10_30(42, 10, 30),
UTC_PLUS_11_00(44, 11, 0),
UTC_PLUS_11_30(46, 11, 30),
UTC_PLUS_12_00(48, 12, 0),
UTC_PLUS_12_45(51, 12, 45),
UTC_PLUS_13_00( 52, 13, 0),
UTC_PLUS_14_00(56, 14, 0),
UTC_MINUS_12_00(-48, -12, 0),
UTC_MINUS_11_00(-44, -11, 0),
UTC_MINUS_10_00(-40, -10, 0),
UTC_MINUS_09_30(-38, -9, -30),
UTC_MINUS_09_00(-36, -9, 0),
UTC_MINUS_08_00(-32, -8, 0),
UTC_MINUS_07_00(-28, -7, 0),
UTC_MINUS_06_00(-24, -6, 0),
UTC_MINUS_05_00(-20, -5, 0),
UTC_MINUS_04_30(-18, -4, -30),
UTC_MINUS_04_00(-16, -4, 0),
UTC_MINUS_03_30(-14, -3, -30),
UTC_MINUS_03_00(-12, -3, 0),
UTC_MINUS_02_00(-8, -2, 0),
UTC_MINUS_01_00(-4, -1, 0),
UTC_PLUS_00_00(0, 0, 0),
UTC_PLUS_01_00(4, 1, 0),
UTC_PLUS_02_00(8, 2, 0),
UTC_PLUS_03_00(12, 3, 0),
UTC_PLUS_03_30(14, 3, 30),
UTC_PLUS_04_00(16, 4, 0),
UTC_PLUS_04_30(18, 4, 30),
UTC_PLUS_05_00(20, 5, 0),
UTC_PLUS_05_30(22, 5, 30),
UTC_PLUS_05_45(23, 5, 45),
UTC_PLUS_06_00(24, 6, 0);
final int key;
private final long rawOffset;
BandTimeZone(int key, int hourOffset, int minOffset) {
this.key = key;
this.rawOffset = 3600000L * hourOffset + 60000L * minOffset;
}
public static BandTimeZone fromOffset(long rawOffset) {
for (BandTimeZone zone : values()){
if (zone.rawOffset == rawOffset)
return zone;
}
throw new RuntimeException("wrong raw offset: " + rawOffset);
}
}

View File

@ -0,0 +1,53 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util;
public class ByteArrayReader {
public final byte[] byteArray;
public int bytesRead;
public ByteArrayReader(byte[] array) {
this.bytesRead = 0;
if (array == null || array.length <= 0) {
throw new IllegalArgumentException("wrong byte array");
}
this.byteArray = array.clone();
}
public int getBytesLeft() {
return this.byteArray.length - this.bytesRead;
}
public long readInt(IntFormat intFormat) {
if (intFormat == null) {
throw new IllegalArgumentException("wrong intFormat");
}
int i = 0;
long n = 0L;
try {
while (i < intFormat.bytesCount) {
long n2 = this.byteArray[this.bytesRead++] & 0xFF;
int n3 = i + 1;
n += n2 << i * 8;
i = n3;
}
long n4 = n;
if (intFormat.isSigned) {
int n5 = intFormat.bytesCount * 8;
n4 = n;
if (((long) (1 << n5 - 1) & n) != 0x0L) {
n4 = ((1 << n5 - 1) - (n & (long) ((1 << n5 - 1) - 1))) * -1L;
}
}
return n4;
} catch (ArrayIndexOutOfBoundsException ex) {
throw new RuntimeException("reading outside of byte array", ex.getCause());
}
}
public int readUint16() {
return (int) this.readInt(IntFormat.UINT16);
}
public int readUint8() {
return (int) this.readInt(IntFormat.UINT8);
}
}

View File

@ -0,0 +1,61 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util;
import java.util.Arrays;
public class ByteArrayWriter {
public byte[] byteArray;
private int bytesWritten;
public ByteArrayWriter() {
this.bytesWritten = 0;
}
private void addIntToValue(long n, IntFormat intFormat) {
for (int i = 0; i < intFormat.bytesCount; ++i) {
this.byteArray[this.bytesWritten++] = (byte) (n >> i * 8 & 0xFFL);
}
}
public void appendUint16(int n) {
this.appendValue(n, IntFormat.UINT16);
}
public void appendUint32(long n) {
this.appendValue(n, IntFormat.UINT32);
}
public void appendUint8(int n) {
this.appendValue(n, IntFormat.UINT8);
}
public void appendValue(long lng, IntFormat intFormat) {
if (intFormat == null) {
throw new IllegalArgumentException("wrong int format");
}
if (lng > intFormat.max || lng < intFormat.min) {
throw new IllegalArgumentException("wrong value for intFormat. max: " + intFormat.max + " min: " + intFormat.min + " value: " + lng);
}
this.increaseByteArray(intFormat.bytesCount);
long n = lng;
if (intFormat.isSigned) {
int n2 = intFormat.bytesCount * 8;
n = lng;
if (lng < 0L) {
n = (1 << n2 - 1) + ((long) ((1 << n2 - 1) - 1) & lng);
}
}
this.addIntToValue(n, intFormat);
}
public void increaseByteArray(int n) {
if (this.byteArray == null) {
this.byteArray = new byte[n];
return;
}
this.byteArray = Arrays.copyOf(this.byteArray, this.byteArray.length + n);
}
public byte[] getByteArray() {
return this.byteArray.clone();
}
}

View File

@ -0,0 +1,35 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util;
public enum IntFormat {
UINT8(1, false),
SINT8(1, true),
UINT16( 2, false),
SINT16( 2, true),
UINT32(4, false),
SINT32(4, true);
final int bytesCount;
final boolean isSigned;
final long max;
final long min;
IntFormat(int bytesCount, boolean isSigned) {
this.bytesCount = bytesCount;
this.isSigned = isSigned;
int bitsCount = bytesCount * 8;
long max;
if (isSigned) {
max = (long) Math.pow(2.0, bitsCount - 1) - 1L;
} else {
max = (long) (Math.pow(2.0, bitsCount) - 1.0);
}
this.max = max;
long min;
if (isSigned) {
min = (long) (-1.0 * Math.pow(2.0, bitsCount - 1));
} else {
min = 0L;
}
this.min = min;
}
}

View File

@ -0,0 +1,27 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util;
public class UIntBitReader {
private final long value;
private int offset;
public UIntBitReader(long value, int offset) {
this.value = value;
this.offset = offset;
}
public int read(int offset) {
this.offset -= offset;
if (this.offset < 0) {
throw new IllegalArgumentException("Read out of range");
}
return (int) ((long) ((1 << offset) - 1) & this.value >>> this.offset);
}
public boolean readBoolean() {
boolean b = true;
if (this.read(1) == 0) {
b = false;
}
return b;
}
}

View File

@ -0,0 +1,37 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sonyswr12.util;
public class UIntBitWriter {
private long value;
private long offset;
public UIntBitWriter(int offset) {
this.value = 0L;
this.offset = offset;
}
public void append(int offset, int value) {
if (value < 0 || value > (1 << offset) - 1) {
throw new IllegalArgumentException("value is out of range: " + value);
}
this.offset -= offset;
if (this.offset < 0L) {
throw new IllegalArgumentException("Write offset out of range");
}
this.value |= (long) value << (int) this.offset;
}
public void appendBoolean(boolean b) {
if (b) {
this.append(1, 1);
return;
}
this.append(1, 0);
}
public long getValue() {
if (this.offset != 0L) {
throw new IllegalStateException("value is not complete yet: " + this.offset);
}
return this.value;
}
}

View File

@ -82,6 +82,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.pinetime.PineTimeJFCoordinat
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi1Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi1Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi3Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi3Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12.SonySWR12DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.tlw64.TLW64Coordinator; import nodomain.freeyourgadget.gadgetbridge.devices.tlw64.TLW64Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.vibratissimo.VibratissimoCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.vibratissimo.VibratissimoCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.watch9.Watch9DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.watch9.Watch9DeviceCoordinator;
@ -258,6 +259,7 @@ public class DeviceHelper {
result.add(new PineTimeJFCoordinator()); result.add(new PineTimeJFCoordinator());
result.add(new SG2Coordinator()); result.add(new SG2Coordinator());
result.add(new LefunDeviceCoordinator()); result.add(new LefunDeviceCoordinator());
result.add(new SonySWR12DeviceCoordinator());
return result; return result;
} }

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_marginHorizontal="@dimen/activity_horizontal_margin"
android:layout_marginVertical="@dimen/activity_vertical_margin">
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/lowVibration"
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="@string/sonyswr12_settings_low_vibration"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/staminaOn"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:text="@string/sonyswr12_settings_stamina"
app:layout_constraintTop_toBottomOf="@id/lowVibration" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/smartAlarmTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/sonyswr12_settings_alarm_interval"
android:textColor="@color/secondarytext"
app:layout_constraintTop_toBottomOf="@id/staminaOn" />
<androidx.appcompat.widget.AppCompatSpinner
android:id="@+id/smartAlarmSpinner"
android:layout_width="match_parent"
android:layout_height="40dp"
android:entries="@array/sonyswr12_smart_alarm_intervals"
app:layout_constraintTop_toBottomOf="@id/smartAlarmTitle" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/settingsDisabler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#cfff"
android:focusable="true"
android:clickable="true"
android:gravity="center"
android:textColor="@color/primarytext_light"
android:text="@string/sonyswr12_settings_alarm_warning"
android:visibility="gone"
tools:visibility="visible"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/smartAlarmSpinner" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -595,4 +595,9 @@
<string name="off">Изкл.</string> <string name="off">Изкл.</string>
<string name="on">Вкл.</string> <string name="on">Вкл.</string>
<string name="no_data">Няма данни</string> <string name="no_data">Няма данни</string>
<string name="sonyswr12_settings_title">Настройки Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Активирана ниска вибрация</string>
<string name="sonyswr12_settings_stamina">Режимът за пестене на енергия е включен</string>
<string name="sonyswr12_settings_alarm_interval">Интелигентен алармен интервал в минути</string>
<string name="sonyswr12_settings_alarm_warning">За да промените настройките, първо трябва да се свържете с устройството!</string>
</resources> </resources>

View File

@ -874,4 +874,9 @@
<string name="pref_title_notifications_and_calls_repeat_on_call">Repeteix la notificació de trucada</string> <string name="pref_title_notifications_and_calls_repeat_on_call">Repeteix la notificació de trucada</string>
<string name="pref_header_notifications_and_calls">Notificacions i trucades</string> <string name="pref_header_notifications_and_calls">Notificacions i trucades</string>
<string name="title_activity_LenovoWatch_calibration">Calibració del Watch X Plus</string> <string name="title_activity_LenovoWatch_calibration">Calibració del Watch X Plus</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Configuració de Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Vibració baixa activada</string>
<string name="sonyswr12_settings_alarm_interval">Interval d\'alarma intel·ligent en minuts</string>
<string name="sonyswr12_settings_alarm_warning">Per canviar la configuració, primer us heu de connectar al dispositiu.</string>
</resources> </resources>

View File

@ -1047,4 +1047,10 @@
<string name="activity_type_cricket">Kriket</string> <string name="activity_type_cricket">Kriket</string>
<string name="activity_type_rowing_machine">Veslovací trenažér</string> <string name="activity_type_rowing_machine">Veslovací trenažér</string>
<string name="activity_type_soccer">Fotbal</string> <string name="activity_type_soccer">Fotbal</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 nastavení</string>
<string name="sonyswr12_settings_low_vibration">Nízké vibrace povoleny</string>
<string name="sonyswr12_settings_stamina">Režim úspory energie je zapnutý</string>
<string name="sonyswr12_settings_alarm_interval">Interval inteligentního alarmu v minutách</string>
<string name="sonyswr12_settings_alarm_warning">Chcete-li změnit nastavení, měli byste se nejprve připojit k zařízení!</string>
</resources> </resources>

View File

@ -1059,4 +1059,10 @@
<string name="activity_filter_to_placeholder">Heute</string> <string name="activity_filter_to_placeholder">Heute</string>
<string name="activity_filter_from_placeholder">Vergangenheit</string> <string name="activity_filter_from_placeholder">Vergangenheit</string>
<string name="chart_no_active_data">Keine Aktivitäten gefunden.</string> <string name="chart_no_active_data">Keine Aktivitäten gefunden.</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 Einstellungen</string>
<string name="sonyswr12_settings_low_vibration">Geringe Vibration aktiviert</string>
<string name="sonyswr12_settings_stamina">Der Energiesparmodus ist aktiviert</string>
<string name="sonyswr12_settings_alarm_interval">Intelligentes Alarmintervall in Minuten</string>
<string name="sonyswr12_settings_alarm_warning">Um Einstellungen zu ändern, sollten Sie zuerst eine Verbindung zum Gerät herstellen!</string>
</resources> </resources>

View File

@ -988,4 +988,10 @@
<string name="activity_type_elliptical_trainer">Ελλειπτικό μηχάνημα</string> <string name="activity_type_elliptical_trainer">Ελλειπτικό μηχάνημα</string>
<string name="activity_type_indoor_cycling">Ποδηλασία εσωτερικού χώρου</string> <string name="activity_type_indoor_cycling">Ποδηλασία εσωτερικού χώρου</string>
<string name="activity_type_swimming_openwater">Κολύμβηση (ανοιχτό νερό)</string> <string name="activity_type_swimming_openwater">Κολύμβηση (ανοιχτό νερό)</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Ρυθμίσεις Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Ενεργοποιήθηκε χαμηλή δόνηση</string>
<string name="sonyswr12_settings_stamina">Η λειτουργία εξοικονόμησης ενέργειας είναι ενεργοποιημένη</string>
<string name="sonyswr12_settings_alarm_interval">Έξυπνο διάστημα συναγερμού σε λίγα λεπτά</string>
<string name="sonyswr12_settings_alarm_warning">Για να αλλάξετε τις ρυθμίσεις πρέπει πρώτα να συνδεθείτε στη συσκευή!</string>
</resources> </resources>

View File

@ -896,4 +896,10 @@
<string name="bip_prefs_shotcuts_summary">Choose the shortcuts on the band screen</string> <string name="bip_prefs_shotcuts_summary">Choose the shortcuts on the band screen</string>
<string name="bip_prefs_shortcuts">Shortcuts</string> <string name="bip_prefs_shortcuts">Shortcuts</string>
<string name="controlcenter_set_alias">Set Alias</string> <string name="controlcenter_set_alias">Set Alias</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 settings</string>
<string name="sonyswr12_settings_low_vibration">Low vibration enabled</string>
<string name="sonyswr12_settings_stamina">Power saving mode on</string>
<string name="sonyswr12_settings_alarm_interval">Smart alarm interval in minutes</string>
<string name="sonyswr12_settings_alarm_warning">To change settings you should first connect to device!</string>
</resources> </resources>

View File

@ -851,4 +851,10 @@
<string name="pref_header_notifications_and_calls">Llamadas y Notificaciones</string> <string name="pref_header_notifications_and_calls">Llamadas y Notificaciones</string>
<string name="title_activity_LenovoWatch_calibration">Calibracion Watch X Plus</string> <string name="title_activity_LenovoWatch_calibration">Calibracion Watch X Plus</string>
<string name="controlcenter_set_alias">Establecer Alias</string> <string name="controlcenter_set_alias">Establecer Alias</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Configuración de Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Baja vibración habilitada</string>
<string name="sonyswr12_settings_stamina">El modo de ahorro de energía está activado</string>
<string name="sonyswr12_settings_alarm_interval">Intervalo de alarma inteligente en minutos</string>
<string name="sonyswr12_settings_alarm_warning">Para cambiar la configuración, primero debe conectarse al dispositivo.</string>
</resources> </resources>

View File

@ -855,4 +855,10 @@
<string name="activity_filter_name_contains">Nimi</string> <string name="activity_filter_name_contains">Nimi</string>
<string name="activity_filter_filter_title">Filter</string> <string name="activity_filter_filter_title">Filter</string>
<string name="activity_summaries_statistics">Statistika</string> <string name="activity_summaries_statistics">Statistika</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 sätted</string>
<string name="sonyswr12_settings_low_vibration">Madal vibratsioon on lubatud</string>
<string name="sonyswr12_settings_stamina">Energiasäästurežiim on sisse lülitatud</string>
<string name="sonyswr12_settings_alarm_interval">Nutika häire intervall minutites</string>
<string name="sonyswr12_settings_alarm_warning">Seadete muutmiseks peaksite kõigepealt seadmega ühenduse looma!</string>
</resources> </resources>

View File

@ -125,4 +125,5 @@
<string name="pref_title_weather_location">مکان تعیین شده برای هواشناسی (CM/LOS)</string> <string name="pref_title_weather_location">مکان تعیین شده برای هواشناسی (CM/LOS)</string>
<string name="pref_blacklist">اضافه کردن برنامه‌ها به لیست سیاه</string> <string name="pref_blacklist">اضافه کردن برنامه‌ها به لیست سیاه</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="sonyswr12_settings_alarm_warning">برای تغییر تنظیمات ابتدا باید به دستگاه متصل شوید!</string>
</resources> </resources>

View File

@ -36,4 +36,9 @@
<string name="app_configure">Määritä</string> <string name="app_configure">Määritä</string>
<string name="app_move_to_top">Siirrä ylös</string> <string name="app_move_to_top">Siirrä ylös</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="sonyswr12_settings_title">Sony SWR12 asetukset</string>
<string name="sonyswr12_settings_low_vibration">Matala tärinä käytössä</string>
<string name="sonyswr12_settings_stamina">Virransäästötila on päällä</string>
<string name="sonyswr12_settings_alarm_interval">Älykäs hälytysväli minuutteina</string>
<string name="sonyswr12_settings_alarm_warning">Muuta asetuksia muodostamalla ensin yhteys laitteeseen!</string>
</resources> </resources>

View File

@ -885,4 +885,10 @@
<string name="pref_header_notifications_and_calls">Notifications et appels</string> <string name="pref_header_notifications_and_calls">Notifications et appels</string>
<string name="title_activity_LenovoWatch_calibration">Calibrage de Watch X Plus</string> <string name="title_activity_LenovoWatch_calibration">Calibrage de Watch X Plus</string>
<string name="pref_theme_system">Système</string> <string name="pref_theme_system">Système</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Paramètres Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Faible vibration activée</string>
<string name="sonyswr12_settings_stamina">Le mode d\'économie d\'énergie est activé</string>
<string name="sonyswr12_settings_alarm_interval">Intervalle d\'alarme intelligente en minutes</string>
<string name="sonyswr12_settings_alarm_warning">Pour modifier les paramètres, vous devez d\'abord vous connecter à l\'appareil!</string>
</resources> </resources>

View File

@ -1057,4 +1057,10 @@ Temps de sommeil préféré en heures</string>
<string name="lefun_prefs_hydration_reminder_interval_title">Intervalle de rappel d\'hydratation (en minutes)</string> <string name="lefun_prefs_hydration_reminder_interval_title">Intervalle de rappel d\'hydratation (en minutes)</string>
<string name="lefun_prefs_hydration_reminder_summary">Le bracelet vibrera pour vous rappeler de boire de l\'eau</string> <string name="lefun_prefs_hydration_reminder_summary">Le bracelet vibrera pour vous rappeler de boire de l\'eau</string>
<string name="lefun_prefs_hydration_reminder_title">Rappel d\'hydratation</string> <string name="lefun_prefs_hydration_reminder_title">Rappel d\'hydratation</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Paramètres Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Faible vibration activée</string>
<string name="sonyswr12_settings_stamina">Le mode d\'économie d\'énergie est activé</string>
<string name="sonyswr12_settings_alarm_interval">Intervalle d\'alarme intelligente en minutes</string>
<string name="sonyswr12_settings_alarm_warning">Pour modifier les paramètres, vous devez d\'abord vous connecter à l\'appareil!</string>
</resources> </resources>

View File

@ -515,4 +515,9 @@
<string name="menuitem_settings">Axustes</string> <string name="menuitem_settings">Axustes</string>
<string name="menuitem_alipay">Alipay</string> <string name="menuitem_alipay">Alipay</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Axustes Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Vibración baixa habilitada</string>
<string name="sonyswr12_settings_alarm_interval">Intervalo de alarma intelixente en minutos</string>
<string name="sonyswr12_settings_alarm_warning">Para cambiar a configuración, primeiro debes conectarte ao dispositivo.</string>
</resources> </resources>

View File

@ -1058,4 +1058,10 @@
<string name="lefun_prefs_hydration_reminder_interval_title">הפרש תזכורת שתייה (בדקות)</string> <string name="lefun_prefs_hydration_reminder_interval_title">הפרש תזכורת שתייה (בדקות)</string>
<string name="lefun_prefs_hydration_reminder_summary">הצמיד ירטוט כדי להזכיר לך לשתות מים</string> <string name="lefun_prefs_hydration_reminder_summary">הצמיד ירטוט כדי להזכיר לך לשתות מים</string>
<string name="lefun_prefs_hydration_reminder_title">תזכורת שתייה</string> <string name="lefun_prefs_hydration_reminder_title">תזכורת שתייה</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 הגדרות</string>
<string name="sonyswr12_settings_low_vibration">רטט נמוך מופעל</string>
<string name="sonyswr12_settings_stamina">מצב חיסכון בחשמל פועל</string>
<string name="sonyswr12_settings_alarm_interval">מרווח אזעקה חכם בדקות</string>
<string name="sonyswr12_settings_alarm_warning">כדי לשנות הגדרות כדאי להתחבר תחילה למכשיר!</string>
</resources> </resources>

View File

@ -152,4 +152,6 @@
<string name="pref_title_keep_data_on_device">अपनी गतिविधि को युक्ति में रखें</string> <string name="pref_title_keep_data_on_device">अपनी गतिविधि को युक्ति में रखें</string>
<string name="user_feedback_all_alarms_disabled">सभी अलार्म बंद है</string> <string name="user_feedback_all_alarms_disabled">सभी अलार्म बंद है</string>
<string name="device_not_connected">कनेक्ट नहीं.</string> <string name="device_not_connected">कनेक्ट नहीं.</string>
<string name="sonyswr12_settings_alarm_interval">मिनटों में स्मार्ट अलार्म अंतराल</string>
<string name="sonyswr12_settings_alarm_warning">सेटिंग्स बदलने के लिए आपको पहले डिवाइस से कनेक्ट करना चाहिए!</string>
</resources> </resources>

View File

@ -61,4 +61,7 @@
<string name="controlcenter_fetch_activity_data">Sinkroniziraj</string> <string name="controlcenter_fetch_activity_data">Sinkroniziraj</string>
<string name="action_donate">Doniraj</string> <string name="action_donate">Doniraj</string>
<string name="action_settings">Postavke</string> <string name="action_settings">Postavke</string>
<string name="sonyswr12_settings_stamina">Uključen je način uštede energije</string>
<string name="sonyswr12_settings_alarm_interval">Pametni interval alarma u minutama</string>
<string name="sonyswr12_settings_alarm_warning">Da biste promijenili postavke, prvo se povežite s uređajem!</string>
</resources> </resources>

View File

@ -495,4 +495,9 @@
<string name="pref_title_notifications_timeout">Értesítések közötti legrövidebb idő</string> <string name="pref_title_notifications_timeout">Értesítések közötti legrövidebb idő</string>
<string name="pref_theme_system">Rendszer</string> <string name="pref_theme_system">Rendszer</string>
<string name="title_activity_calblacklist">Feketelistás Naptárak</string> <string name="title_activity_calblacklist">Feketelistás Naptárak</string>
<string name="sonyswr12_settings_title">Beállítások Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Alacsony rezgés engedélyezve</string>
<string name="sonyswr12_settings_stamina">Az energiatakarékos mód be van kapcsolva</string>
<string name="sonyswr12_settings_alarm_interval">Intelligens riasztási intervallum percekben</string>
<string name="sonyswr12_settings_alarm_warning">A beállítások módosításához először csatlakoznia kell az eszközhöz!</string>
</resources> </resources>

View File

@ -34,4 +34,7 @@
<string name="title_activity_appmanager">Manajer App</string> <string name="title_activity_appmanager">Manajer App</string>
<string name="debugactivity_really_factoryreset">Melakukan factory reset akan menghapus seluruh data dari perangkat terkoneksi (jika didukung). Perangkat Xiaomi/Huami juga mengganti MAC address Bluetooth, sehingga akan muncul sebagai aplikasi baru di GadgetBridge.</string> <string name="debugactivity_really_factoryreset">Melakukan factory reset akan menghapus seluruh data dari perangkat terkoneksi (jika didukung). Perangkat Xiaomi/Huami juga mengganti MAC address Bluetooth, sehingga akan muncul sebagai aplikasi baru di GadgetBridge.</string>
<string name="action_debug">Debug</string> <string name="action_debug">Debug</string>
<string name="sonyswr12_settings_title">Pengaturan Sony SWR12</string>
<string name="sonyswr12_settings_alarm_interval">Interval alarm pintar dalam beberapa menit</string>
<string name="sonyswr12_settings_alarm_warning">Untuk mengubah pengaturan, Anda harus menghubungkan ke perangkat terlebih dahulu!</string>
</resources> </resources>

View File

@ -1041,4 +1041,10 @@
<string name="activity_type_swimming_openwater">Nuoto (all\'aperto)</string> <string name="activity_type_swimming_openwater">Nuoto (all\'aperto)</string>
<string name="no">No</string> <string name="no">No</string>
<string name="km">km</string> <string name="km">km</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Impostazioni Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Bassa vibrazione abilitata</string>
<string name="sonyswr12_settings_stamina">La modalità di risparmio energetico è attiva</string>
<string name="sonyswr12_settings_alarm_interval">Intervallo di allarme intelligente in pochi minuti</string>
<string name="sonyswr12_settings_alarm_warning">Per modificare le impostazioni devi prima connetterti al dispositivo!</string>
</resources> </resources>

View File

@ -755,4 +755,10 @@
<string name="indonesian">インドネシア語</string> <string name="indonesian">インドネシア語</string>
<string name="prefs_disconnect_notification">切断通知</string> <string name="prefs_disconnect_notification">切断通知</string>
<string name="Distance">距離</string> <string name="Distance">距離</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 設定</string>
<string name="sonyswr12_settings_low_vibration">低振動対応</string>
<string name="sonyswr12_settings_stamina">省電力モードがオンになっている</string>
<string name="sonyswr12_settings_alarm_interval">分単位のスマートアラーム間隔</string>
<string name="sonyswr12_settings_alarm_warning">設定を変更するには、最初にデバイスに接続する必要があります!</string>
</resources> </resources>

View File

@ -30,4 +30,7 @@
<string name="appmanager_health_activate">გააქტიურება</string> <string name="appmanager_health_activate">გააქტიურება</string>
<string name="appmanager_health_deactivate">გამორტვა</string> <string name="appmanager_health_deactivate">გამორტვა</string>
<string name="app_configure">კონფიგურაცია</string> <string name="app_configure">კონფიგურაცია</string>
<string name="sonyswr12_settings_title">Sony SWR12 პარამეტრები</string>
<string name="sonyswr12_settings_alarm_interval">სიგნალის ჭკვიანი ინტერვალი წუთებში</string>
<string name="sonyswr12_settings_alarm_warning">პარამეტრების შესაცვლელად ჯერ უნდა დაუკავშირდეთ მოწყობილობას!</string>
</resources> </resources>

View File

@ -609,4 +609,5 @@
<string name="pref_invalid_frequency_title">올바르지 않은 주파수</string> <string name="pref_invalid_frequency_title">올바르지 않은 주파수</string>
<string name="pref_invalid_frequency_message">87.5와 108.0 사이의 주파수를 입력하세요</string> <string name="pref_invalid_frequency_message">87.5와 108.0 사이의 주파수를 입력하세요</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
</resources> </resources>

View File

@ -308,4 +308,10 @@
<string name="alarm_snooze">Snūstelti</string> <string name="alarm_snooze">Snūstelti</string>
<string name="pref_title_allow_high_mtu">Leisti didelį MTU</string> <string name="pref_title_allow_high_mtu">Leisti didelį MTU</string>
<string name="pref_summary_allow_high_mtu">Padidinti perkėlimo greitį, bet gali ir neveikti kai kuriuose android įrenginiuose..</string> <string name="pref_summary_allow_high_mtu">Padidinti perkėlimo greitį, bet gali ir neveikti kai kuriuose android įrenginiuose..</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 nustatymai</string>
<string name="sonyswr12_settings_low_vibration">Įjungta maža vibracija</string>
<string name="sonyswr12_settings_stamina">Įjungtas energijos taupymo režimas</string>
<string name="sonyswr12_settings_alarm_interval">Išmaniojo žadintuvo intervalas minutėmis</string>
<string name="sonyswr12_settings_alarm_warning">Norėdami pakeisti nustatymus, pirmiausia turite prisijungti prie įrenginio!</string>
</resources> </resources>

View File

@ -37,4 +37,6 @@
<string name="save_configuration">အခ်က္အလက္မ်ားကိုသိမ္းဆည္းမည္</string> <string name="save_configuration">အခ်က္အလက္မ်ားကိုသိမ္းဆည္းမည္</string>
<string name="appwidget_not_connected">မခ်ိတ္ဆက္ထားျခင္းမရွိပါ , သတိေပးခ်က္မထားရေသးပါ</string> <string name="appwidget_not_connected">မခ်ိတ္ဆက္ထားျခင္းမရွိပါ , သတိေပးခ်က္မထားရေသးပါ</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="sonyswr12_settings_alarm_interval">မိနစ်အတွင်းစမတ်နှိုးဆော်သံကြားကာလ</string>
<string name="sonyswr12_settings_alarm_warning">ချိန်ညှိချက်များကိုပြောင်းလဲရန်သင်ပထမ ဦး ဆုံးကိရိယာနှင့်ချိတ်ဆက်သင့်သည်!</string>
</resources> </resources>

View File

@ -1016,4 +1016,10 @@
<string name="lefun_prefs_hydration_reminder_interval_title">Drikkepåminnelseintervall (i minutter)</string> <string name="lefun_prefs_hydration_reminder_interval_title">Drikkepåminnelseintervall (i minutter)</string>
<string name="lefun_prefs_interface_language_title">Grensesnittspråk</string> <string name="lefun_prefs_interface_language_title">Grensesnittspråk</string>
<string name="pref_title_weather_summary">Brukt av LineageOS-værtilbyderen, andre Android-versjoner må bruke et program som «Ditt lokale vær». Mer info er å finne på Gadgetbridge-wiki-en.</string> <string name="pref_title_weather_summary">Brukt av LineageOS-værtilbyderen, andre Android-versjoner må bruke et program som «Ditt lokale vær». Mer info er å finne på Gadgetbridge-wiki-en.</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 innstillinger</string>
<string name="sonyswr12_settings_low_vibration">Lav vibrasjon aktivert</string>
<string name="sonyswr12_settings_stamina">Strømsparingsmodus er på</string>
<string name="sonyswr12_settings_alarm_interval">Smart alarmintervall på få minutter</string>
<string name="sonyswr12_settings_alarm_warning">For å endre innstillinger, bør du først koble til enheten!</string>
</resources> </resources>

View File

@ -956,4 +956,10 @@
<string name="activity_type_elliptical_trainer">Elliptische Trainer</string> <string name="activity_type_elliptical_trainer">Elliptische Trainer</string>
<string name="activity_type_indoor_cycling">Binnenshuis fietsen</string> <string name="activity_type_indoor_cycling">Binnenshuis fietsen</string>
<string name="activity_type_swimming_openwater">Zwemmen (Open water)</string> <string name="activity_type_swimming_openwater">Zwemmen (Open water)</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 instellingen</string>
<string name="sonyswr12_settings_low_vibration">Laag trillingsniveau ingeschakeld</string>
<string name="sonyswr12_settings_stamina">Energiebesparende modus is ingeschakeld</string>
<string name="sonyswr12_settings_alarm_interval">Slimme alarminterval in minuten</string>
<string name="sonyswr12_settings_alarm_warning">Om instellingen te wijzigen, moet u eerst verbinding maken met het apparaat!</string>
</resources> </resources>

View File

@ -1029,4 +1029,10 @@
<string name="activity_type_cricket">Krykiet</string> <string name="activity_type_cricket">Krykiet</string>
<string name="activity_type_rowing_machine">Wiosłująca maszyna</string> <string name="activity_type_rowing_machine">Wiosłująca maszyna</string>
<string name="activity_type_elliptical_trainer">Trener eliptyczny</string> <string name="activity_type_elliptical_trainer">Trener eliptyczny</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Ustawienia Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Włączono niski poziom wibracji</string>
<string name="sonyswr12_settings_stamina">Tryb oszczędzania energii jest włączony</string>
<string name="sonyswr12_settings_alarm_interval">Inteligentny interwał alarmu w minutach</string>
<string name="sonyswr12_settings_alarm_warning">Aby zmienić ustawienia, należy najpierw połączyć się z urządzeniem!</string>
</resources> </resources>

View File

@ -1056,4 +1056,10 @@
<string name="activity_filter_to_placeholder">hoje</string> <string name="activity_filter_to_placeholder">hoje</string>
<string name="activity_filter_from_placeholder">passado distante</string> <string name="activity_filter_from_placeholder">passado distante</string>
<string name="about_links">Links</string> <string name="about_links">Links</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Configurações de Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Baixa vibração habilitada</string>
<string name="sonyswr12_settings_stamina">O modo de economia de energia está ativado</string>
<string name="sonyswr12_settings_alarm_interval">Intervalo de alarme inteligente em minutos</string>
<string name="sonyswr12_settings_alarm_warning">Para alterar as configurações, você deve primeiro se conectar ao dispositivo!</string>
</resources> </resources>

View File

@ -1046,4 +1046,10 @@
<string name="averageLapPace">Ritmo médio de voltas</string> <string name="averageLapPace">Ritmo médio de voltas</string>
<string name="averageStrokesPerSecond">Média de braçadas</string> <string name="averageStrokesPerSecond">Média de braçadas</string>
<string name="averageStrokeDistance">Distância média das braçadas</string> <string name="averageStrokeDistance">Distância média das braçadas</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Configurações de Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Baixa vibração habilitada</string>
<string name="sonyswr12_settings_stamina">O modo de economia de energia está ativado</string>
<string name="sonyswr12_settings_alarm_interval">Intervalo de alarme inteligente em minutos</string>
<string name="sonyswr12_settings_alarm_warning">Para alterar as configurações, você deve primeiro se conectar ao dispositivo!</string>
</resources> </resources>

View File

@ -129,4 +129,8 @@
<string name="save_configuration">Salvare Configurație</string> <string name="save_configuration">Salvare Configurație</string>
<string name="appwidget_not_connected">Deconectat(ă), alarma nu este setată.</string> <string name="appwidget_not_connected">Deconectat(ă), alarma nu este setată.</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="sonyswr12_settings_title">Setari Sony SWR12</string>
<string name="sonyswr12_settings_stamina">Modul de economisire a energiei este activat</string>
<string name="sonyswr12_settings_alarm_interval">Interval de alarmă inteligentă în minute</string>
<string name="sonyswr12_settings_alarm_warning">Pentru a modifica setările, ar trebui să vă conectați mai întâi la dispozitiv!</string>
</resources> </resources>

View File

@ -1064,4 +1064,10 @@
<string name="devicetype_lefun">Lefun</string> <string name="devicetype_lefun">Lefun</string>
<string name="lefun_prefs_interface_language_title">Язык интерфейса</string> <string name="lefun_prefs_interface_language_title">Язык интерфейса</string>
<string name="lefun_prefs_antilost_title">Защита от потери</string> <string name="lefun_prefs_antilost_title">Защита от потери</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Настройки Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Слабая вибрация</string>
<string name="sonyswr12_settings_stamina">Режима энергосбережения включен</string>
<string name="sonyswr12_settings_alarm_interval">Интервал умного будильника в минутах</string>
<string name="sonyswr12_settings_alarm_warning">Для изменения настроек необходимо сначала подключиться к устройству!</string>
</resources> </resources>

View File

@ -491,4 +491,10 @@
<string name="controlcenter_connect">Pripojiť</string> <string name="controlcenter_connect">Pripojiť</string>
<string name="on">Zap.</string> <string name="on">Zap.</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Nastavenia Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Nízke vibrácie sú povolené</string>
<string name="sonyswr12_settings_stamina">Režim úspory energie je zapnutý</string>
<string name="sonyswr12_settings_alarm_interval">Interval inteligentného alarmu v minútach</string>
<string name="sonyswr12_settings_alarm_warning">Ak chcete zmeniť nastavenie, mali by ste sa najskôr pripojiť k zariadeniu!</string>
</resources> </resources>

View File

@ -48,4 +48,9 @@
<string name="appmanager_hrm_activate">Aktivera pulsmätare</string> <string name="appmanager_hrm_activate">Aktivera pulsmätare</string>
<string name="appmanager_hrm_deactivate">Avaktivera pulsmätare</string> <string name="appmanager_hrm_deactivate">Avaktivera pulsmätare</string>
<string name="app_configure">Konfigurera</string> <string name="app_configure">Konfigurera</string>
<string name="sonyswr12_settings_title">Inställningar Sony SWR12</string>
<string name="sonyswr12_settings_low_vibration">Låg vibration aktiverad</string>
<string name="sonyswr12_settings_stamina">Energisparläge är på</string>
<string name="sonyswr12_settings_alarm_interval">Smart larmintervall på några minuter</string>
<string name="sonyswr12_settings_alarm_warning">För att ändra inställningar bör du först ansluta till enheten!</string>
</resources> </resources>

View File

@ -296,7 +296,7 @@
\n \n
\nLütfen önce .fw dosyasını, sonra .res dosyasını, ve son olarak .gps dosyasını kurun. .fw dosyasını kurduktan sonra bilekliğiniz yeniden başlatılacak. \nLütfen önce .fw dosyasını, sonra .res dosyasını, ve son olarak .gps dosyasını kurun. .fw dosyasını kurduktan sonra bilekliğiniz yeniden başlatılacak.
\n \n
\nNote: Bu dosyalar önceden kurulanlarla tamamen aynıysa .res ve .gps dosyalarını kurmanız gerekmez. \nNote: Bu dosyalar önceden kurulanlarla tamamen aynıysa .res ve .gps dosyalarını kurmanız gerekmez.
\n \n
\nİLERLEMENİZ DURUMUNDA RİSK SİZE AİTTİR!</string> \nİLERLEMENİZ DURUMUNDA RİSK SİZE AİTTİR!</string>
<string name="fw_upgrade_notice_miband4">Mi Band 4 aygıtınıza %s ürün yazılımını kurmak üzeresiniz. <string name="fw_upgrade_notice_miband4">Mi Band 4 aygıtınıza %s ürün yazılımını kurmak üzeresiniz.
@ -950,7 +950,7 @@
\n \n
\nLütfen önce .fw dosyasını, sonra .res dosyasın kurun. .fw dosyasını kurduktan sonra bilekliğiniz yeniden başlatılacak. \nLütfen önce .fw dosyasını, sonra .res dosyasın kurun. .fw dosyasını kurduktan sonra bilekliğiniz yeniden başlatılacak.
\n \n
\nNote: Bu dosyalar önceden kurulanlarla tamamen aynıysa .res dosyasını kurmanız gerekmez. \nNote: Bu dosyalar önceden kurulanlarla tamamen aynıysa .res dosyasını kurmanız gerekmez.
\n \n
\nİLERLEMENİZ DURUMUNDA RİSK SİZE AİTTİR!</string> \nİLERLEMENİZ DURUMUNDA RİSK SİZE AİTTİR!</string>
<string name="devicetype_tlw64">TLW64</string> <string name="devicetype_tlw64">TLW64</string>
@ -1088,4 +1088,9 @@
<string name="lefun_prefs_hydration_reminder_interval_title">Sıvı alma hatırlatma aralığı (dakika olarak)</string> <string name="lefun_prefs_hydration_reminder_interval_title">Sıvı alma hatırlatma aralığı (dakika olarak)</string>
<string name="lefun_prefs_hydration_reminder_summary">Bileklik su içmenizi hatırlatmak için titreyecek</string> <string name="lefun_prefs_hydration_reminder_summary">Bileklik su içmenizi hatırlatmak için titreyecek</string>
<string name="lefun_prefs_hydration_reminder_title">Sıvı alma hatırlatıcı</string> <string name="lefun_prefs_hydration_reminder_title">Sıvı alma hatırlatıcı</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 Ayarları</string>
<string name="sonyswr12_settings_low_vibration">Düşük titreşim etkin</string>
<string name="sonyswr12_settings_alarm_interval">Dakikalar içinde akıllı alarm aralığı</string>
<string name="sonyswr12_settings_alarm_warning">Ayarları değiştirmek için önce cihaza bağlanmalısınız!</string>
</resources> </resources>

View File

@ -1052,4 +1052,10 @@
\nПримітка: вам не потрібно встановлювати .res файл, якщо він такий самий був встановлений раніше. \nПримітка: вам не потрібно встановлювати .res файл, якщо він такий самий був встановлений раніше.
\n \n
\nДІЄТЕ НА ВЛАСНИЙ РИЗИК!</string> \nДІЄТЕ НА ВЛАСНИЙ РИЗИК!</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 налаштування</string>
<string name="sonyswr12_settings_low_vibration">абка вібрація</string>
<string name="sonyswr12_settings_stamina">Режим енергозбереження ввімкнено</string>
<string name="sonyswr12_settings_alarm_interval">Інтелектуальний інтервал тривоги в хвилинах</string>
<string name="sonyswr12_settings_alarm_warning">Щоб змінити налаштування, спочатку слід підключитися до пристрою!</string>
</resources> </resources>

View File

@ -190,4 +190,8 @@
<string name="dateformat_time">Giờ</string> <string name="dateformat_time">Giờ</string>
<string name="dateformat_date_time">Giờ và ngày</string> <string name="dateformat_date_time">Giờ và ngày</string>
<string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string> <string name="mi2_prefs_button_press_broadcast_default_value" translatable="false">nodomain.freeyourgadget.gadgetbridge.ButtonPressed</string>
<string name="sonyswr12_settings_title">Cài đặt Sony SWR12</string>
<string name="sonyswr12_settings_stamina">Chế độ tiết kiệm pin đang bật</string>
<string name="sonyswr12_settings_alarm_interval">Khoảng thời gian báo thức thông minh trong vài phút</string>
<string name="sonyswr12_settings_alarm_warning">Để thay đổi cài đặt, trước tiên bạn nên kết nối với thiết bị!</string>
</resources> </resources>

View File

@ -1069,4 +1069,10 @@
<string name="lefun_prefs_hydration_reminder_interval_title">水合提醒间隔(分钟)</string> <string name="lefun_prefs_hydration_reminder_interval_title">水合提醒间隔(分钟)</string>
<string name="lefun_prefs_hydration_reminder_summary">当需要提醒喝水时,手环会震动</string> <string name="lefun_prefs_hydration_reminder_summary">当需要提醒喝水时,手环会震动</string>
<string name="lefun_prefs_hydration_reminder_title">水合提醒</string> <string name="lefun_prefs_hydration_reminder_title">水合提醒</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 设置</string>
<string name="sonyswr12_settings_low_vibration">低振动启用</string>
<string name="sonyswr12_settings_stamina">省电模式已开启</string>
<string name="sonyswr12_settings_alarm_interval">智能警报间隔(以分钟为单位)</string>
<string name="sonyswr12_settings_alarm_warning">要更改设置,您应该首先连接设备!</string>
</resources> </resources>

View File

@ -585,4 +585,6 @@
<string name="activity_type_swimming">游泳</string> <string name="activity_type_swimming">游泳</string>
<string name="this_is_a_test_notification_from_gadgetbridge">這是一個來自 Gadgetbridge 的測試通知</string> <string name="this_is_a_test_notification_from_gadgetbridge">這是一個來自 Gadgetbridge 的測試通知</string>
<string name="test_notification">測試通知</string> <string name="test_notification">測試通知</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="sonyswr12_settings_title">Sony SWR12 設定</string>
</resources> </resources>

View File

@ -986,4 +986,13 @@
<item>0</item> <item>0</item>
<item>1</item> <item>1</item>
</string-array> </string-array>
<string-array name="sonyswr12_smart_alarm_intervals">
<item>0</item>
<item>10</item>
<item>20</item>
<item>30</item>
<item>40</item>
<item>50</item>
<item>60</item>
</string-array>
</resources> </resources>

View File

@ -785,6 +785,7 @@
<string name="devicetype_banglejs">Bangle.js</string> <string name="devicetype_banglejs">Bangle.js</string>
<string name="devicetype_tlw64">TLW64</string> <string name="devicetype_tlw64">TLW64</string>
<string name="devicetype_pinetime_jf">PineTime (JF Firmware)</string> <string name="devicetype_pinetime_jf">PineTime (JF Firmware)</string>
<string name="devicetype_sonyswr12">Sony SWR12</string>
<string name="choose_auto_export_location">Choose export location</string> <string name="choose_auto_export_location">Choose export location</string>
<string name="notification_channel_name">Gadgetbridge notifications</string> <string name="notification_channel_name">Gadgetbridge notifications</string>
<string name="notification_channel_high_priority_name">Gadgetbridge notifications high priority</string> <string name="notification_channel_high_priority_name">Gadgetbridge notifications high priority</string>
@ -934,6 +935,11 @@
<string name="ignore_bonded_devices">Ignore bonded devices</string> <string name="ignore_bonded_devices">Ignore bonded devices</string>
<string name="ignore_bonded_devices_description">Enabling this option will ignore devices that have been bonded/paired already when scanning</string> <string name="ignore_bonded_devices_description">Enabling this option will ignore devices that have been bonded/paired already when scanning</string>
<string name="error_location_enabled_mandatory">Location must be turned on to scan for devices</string> <string name="error_location_enabled_mandatory">Location must be turned on to scan for devices</string>
<string name="sonyswr12_settings_title">Sony SWR12 Settings</string>
<string name="sonyswr12_settings_low_vibration">Low vibration enabled</string>
<string name="sonyswr12_settings_stamina">Power saving mode on</string>
<string name="sonyswr12_settings_alarm_interval">Smart alarm interval in minutes</string>
<string name="sonyswr12_settings_alarm_warning">To change settings you should first connect to device!</string>
<!-- activity summary labels--> <!-- activity summary labels-->
<string name="distanceMeters">Distance</string> <string name="distanceMeters">Distance</string>
<string name="ascentMeters">Uphill</string> <string name="ascentMeters">Uphill</string>

View File

@ -581,10 +581,14 @@
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>
<Preference <Preference
android:icon="@drawable/ic_device_zetime" android:icon="@drawable/ic_device_zetime"
android:key="pref_key_zetime" android:key="pref_key_zetime"
android:title="@string/zetime_title_settings"/> android:title="@string/zetime_title_settings" />
<Preference
android:icon="@drawable/ic_device_default"
android:key="pref_key_sonyswr12"
android:title="@string/sonyswr12_settings_title" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory