mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-27 12:26:48 +01:00
added support for sony swr12
This commit is contained in:
parent
8394928b94
commit
06a12300a1
@ -77,6 +77,7 @@ public class GBDaoGenerator {
|
||||
addLefunActivitySample(schema, user, device);
|
||||
addLefunBiometricSample(schema,user,device);
|
||||
addLefunSleepSample(schema, user, device);
|
||||
addSonySWR12Sample(schema, user, device);
|
||||
|
||||
addHybridHRActivitySample(schema, user, device);
|
||||
addCalendarSyncState(schema, device);
|
||||
@ -407,6 +408,17 @@ public class GBDaoGenerator {
|
||||
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) {
|
||||
Entity activitySample = addEntity(schema, "LefunActivitySample");
|
||||
activitySample.implementsSerializable();
|
||||
|
@ -567,5 +567,8 @@
|
||||
<activity
|
||||
android:name=".devices.qhybrid.ImageEditActivity"
|
||||
android:exported="true" />
|
||||
<activity
|
||||
android:name=".devices.sonyswr12.SonySWR12PrefActivity"
|
||||
android:exported="true" />
|
||||
</application>
|
||||
</manifest>
|
@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.PeriodicExporter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPreferencesActivity;
|
||||
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.model.CannedMessagesSpec;
|
||||
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.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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) {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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),
|
||||
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),
|
||||
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);
|
||||
private final int key;
|
||||
@DrawableRes
|
||||
|
@ -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.qhybrid.QHybridSupport;
|
||||
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.vibratissimo.VibratissimoSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.watch9.Watch9DeviceSupport;
|
||||
@ -264,6 +265,9 @@ public class DeviceSupportFactory {
|
||||
case LEFUN:
|
||||
deviceSupport = new ServiceDeviceSupport(new LefunDeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||
break;
|
||||
case SONY_SWR12:
|
||||
deviceSupport = new ServiceDeviceSupport(new SonySWR12DeviceSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING));
|
||||
break;
|
||||
}
|
||||
if (deviceSupport != null) {
|
||||
deviceSupport.setContext(gbDevice, mBtAdapter, mContext);
|
||||
|
@ -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;
|
||||
}
|
@ -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) {
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -82,6 +82,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.pinetime.PineTimeJFCoordinat
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi1Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.roidmi.Roidmi3Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.sonyswr12.SonySWR12DeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.tlw64.TLW64Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.vibratissimo.VibratissimoCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.watch9.Watch9DeviceCoordinator;
|
||||
@ -258,6 +259,7 @@ public class DeviceHelper {
|
||||
result.add(new PineTimeJFCoordinator());
|
||||
result.add(new SG2Coordinator());
|
||||
result.add(new LefunDeviceCoordinator());
|
||||
result.add(new SonySWR12DeviceCoordinator());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
55
app/src/main/res/layout/activity_sonyswr12_settings.xml
Normal file
55
app/src/main/res/layout/activity_sonyswr12_settings.xml
Normal 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>
|
@ -595,4 +595,9 @@
|
||||
<string name="off">Изкл.</string>
|
||||
<string name="on">Вкл.</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>
|
@ -874,4 +874,9 @@
|
||||
<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="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>
|
@ -1047,4 +1047,10 @@
|
||||
<string name="activity_type_cricket">Kriket</string>
|
||||
<string name="activity_type_rowing_machine">Veslovací trenažér</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>
|
@ -1059,4 +1059,10 @@
|
||||
<string name="activity_filter_to_placeholder">Heute</string>
|
||||
<string name="activity_filter_from_placeholder">Vergangenheit</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>
|
@ -988,4 +988,10 @@
|
||||
<string name="activity_type_elliptical_trainer">Ελλειπτικό μηχάνημα</string>
|
||||
<string name="activity_type_indoor_cycling">Ποδηλασία εσωτερικού χώρου</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>
|
@ -896,4 +896,10 @@
|
||||
<string name="bip_prefs_shotcuts_summary">Choose the shortcuts on the band screen</string>
|
||||
<string name="bip_prefs_shortcuts">Shortcuts</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>
|
@ -851,4 +851,10 @@
|
||||
<string name="pref_header_notifications_and_calls">Llamadas y Notificaciones</string>
|
||||
<string name="title_activity_LenovoWatch_calibration">Calibracion Watch X Plus</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>
|
@ -855,4 +855,10 @@
|
||||
<string name="activity_filter_name_contains">Nimi</string>
|
||||
<string name="activity_filter_filter_title">Filter</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>
|
@ -125,4 +125,5 @@
|
||||
<string name="pref_title_weather_location">مکان تعیین شده برای هواشناسی (CM/LOS)</string>
|
||||
<string name="pref_blacklist">اضافه کردن برنامهها به لیست سیاه</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>
|
@ -36,4 +36,9 @@
|
||||
<string name="app_configure">Määritä</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="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>
|
@ -885,4 +885,10 @@
|
||||
<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="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>
|
@ -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_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="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>
|
@ -515,4 +515,9 @@
|
||||
<string name="menuitem_settings">Axustes</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="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>
|
@ -1058,4 +1058,10 @@
|
||||
<string name="lefun_prefs_hydration_reminder_interval_title">הפרש תזכורת שתייה (בדקות)</string>
|
||||
<string name="lefun_prefs_hydration_reminder_summary">הצמיד ירטוט כדי להזכיר לך לשתות מים</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>
|
@ -152,4 +152,6 @@
|
||||
<string name="pref_title_keep_data_on_device">अपनी गतिविधि को युक्ति में रखें</string>
|
||||
<string name="user_feedback_all_alarms_disabled">सभी अलार्म बंद है</string>
|
||||
<string name="device_not_connected">कनेक्ट नहीं.</string>
|
||||
<string name="sonyswr12_settings_alarm_interval">मिनटों में स्मार्ट अलार्म अंतराल</string>
|
||||
<string name="sonyswr12_settings_alarm_warning">सेटिंग्स बदलने के लिए आपको पहले डिवाइस से कनेक्ट करना चाहिए!</string>
|
||||
</resources>
|
@ -61,4 +61,7 @@
|
||||
<string name="controlcenter_fetch_activity_data">Sinkroniziraj</string>
|
||||
<string name="action_donate">Doniraj</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>
|
@ -495,4 +495,9 @@
|
||||
<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="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>
|
@ -34,4 +34,7 @@
|
||||
<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="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>
|
@ -1041,4 +1041,10 @@
|
||||
<string name="activity_type_swimming_openwater">Nuoto (all\'aperto)</string>
|
||||
<string name="no">No</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>
|
@ -755,4 +755,10 @@
|
||||
<string name="indonesian">インドネシア語</string>
|
||||
<string name="prefs_disconnect_notification">切断通知</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>
|
@ -30,4 +30,7 @@
|
||||
<string name="appmanager_health_activate">გააქტიურება</string>
|
||||
<string name="appmanager_health_deactivate">გამორტვა</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>
|
@ -609,4 +609,5 @@
|
||||
<string name="pref_invalid_frequency_title">올바르지 않은 주파수</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="devicetype_sonyswr12">Sony SWR12</string>
|
||||
</resources>
|
@ -308,4 +308,10 @@
|
||||
<string name="alarm_snooze">Snūstelti</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="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>
|
@ -37,4 +37,6 @@
|
||||
<string name="save_configuration">အခ်က္အလက္မ်ားကိုသိမ္းဆည္းမည္</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="sonyswr12_settings_alarm_interval">မိနစ်အတွင်းစမတ်နှိုးဆော်သံကြားကာလ</string>
|
||||
<string name="sonyswr12_settings_alarm_warning">ချိန်ညှိချက်များကိုပြောင်းလဲရန်သင်ပထမ ဦး ဆုံးကိရိယာနှင့်ချိတ်ဆက်သင့်သည်!</string>
|
||||
</resources>
|
@ -1016,4 +1016,10 @@
|
||||
<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="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>
|
@ -956,4 +956,10 @@
|
||||
<string name="activity_type_elliptical_trainer">Elliptische Trainer</string>
|
||||
<string name="activity_type_indoor_cycling">Binnenshuis fietsen</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>
|
@ -1029,4 +1029,10 @@
|
||||
<string name="activity_type_cricket">Krykiet</string>
|
||||
<string name="activity_type_rowing_machine">Wiosłująca maszyna</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>
|
@ -1056,4 +1056,10 @@
|
||||
<string name="activity_filter_to_placeholder">hoje</string>
|
||||
<string name="activity_filter_from_placeholder">passado distante</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>
|
@ -1046,4 +1046,10 @@
|
||||
<string name="averageLapPace">Ritmo médio de voltas</string>
|
||||
<string name="averageStrokesPerSecond">Média de 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>
|
@ -129,4 +129,8 @@
|
||||
<string name="save_configuration">Salvare Configurație</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="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>
|
@ -1064,4 +1064,10 @@
|
||||
<string name="devicetype_lefun">Lefun</string>
|
||||
<string name="lefun_prefs_interface_language_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>
|
@ -491,4 +491,10 @@
|
||||
<string name="controlcenter_connect">Pripojiť</string>
|
||||
<string name="on">Zap.</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>
|
@ -48,4 +48,9 @@
|
||||
<string name="appmanager_hrm_activate">Aktivera pulsmätare</string>
|
||||
<string name="appmanager_hrm_deactivate">Avaktivera pulsmätare</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>
|
@ -296,7 +296,7 @@
|
||||
\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.
|
||||
\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İ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.
|
||||
@ -950,7 +950,7 @@
|
||||
\n
|
||||
\nLütfen önce .fw dosyasını, sonra .res dosyasın kurun. .fw dosyasını kurduktan sonra bilekliğiniz yeniden başlatılacak.
|
||||
\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İLERLEMENİZ DURUMUNDA RİSK SİZE AİTTİR!</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_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="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>
|
@ -1052,4 +1052,10 @@
|
||||
\nПримітка: вам не потрібно встановлювати .res файл, якщо він такий самий був встановлений раніше.
|
||||
\n
|
||||
\nДІЄТЕ НА ВЛАСНИЙ РИЗИК!</string>
|
||||
<string name="devicetype_sonyswr12">Sony SWR12</string>
|
||||
<string name="sonyswr12_settings_title">Sony SWR12 налаштування</string>
|
||||
<string name="sonyswr12_settings_low_vibration">Cлабка вібрація</string>
|
||||
<string name="sonyswr12_settings_stamina">Режим енергозбереження ввімкнено</string>
|
||||
<string name="sonyswr12_settings_alarm_interval">Інтелектуальний інтервал тривоги в хвилинах</string>
|
||||
<string name="sonyswr12_settings_alarm_warning">Щоб змінити налаштування, спочатку слід підключитися до пристрою!</string>
|
||||
</resources>
|
@ -190,4 +190,8 @@
|
||||
<string name="dateformat_time">Giờ</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="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>
|
@ -1069,4 +1069,10 @@
|
||||
<string name="lefun_prefs_hydration_reminder_interval_title">水合提醒间隔(分钟)</string>
|
||||
<string name="lefun_prefs_hydration_reminder_summary">当需要提醒喝水时,手环会震动</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>
|
@ -585,4 +585,6 @@
|
||||
<string name="activity_type_swimming">游泳</string>
|
||||
<string name="this_is_a_test_notification_from_gadgetbridge">這是一個來自 Gadgetbridge 的測試通知</string>
|
||||
<string name="test_notification">測試通知</string>
|
||||
<string name="devicetype_sonyswr12">Sony SWR12</string>
|
||||
<string name="sonyswr12_settings_title">Sony SWR12 設定</string>
|
||||
</resources>
|
@ -986,4 +986,13 @@
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
</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>
|
@ -785,6 +785,7 @@
|
||||
<string name="devicetype_banglejs">Bangle.js</string>
|
||||
<string name="devicetype_tlw64">TLW64</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="notification_channel_name">Gadgetbridge notifications</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_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="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-->
|
||||
<string name="distanceMeters">Distance</string>
|
||||
<string name="ascentMeters">Uphill</string>
|
||||
|
@ -581,10 +581,14 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
<Preference
|
||||
<Preference
|
||||
android:icon="@drawable/ic_device_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
|
||||
|
Loading…
Reference in New Issue
Block a user