mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-26 18:45:49 +01:00
Merge branch 'master' into background-javascript
# Conflicts: # app/src/main/assets/app_config/js/gadgetbridge_boilerplate.js # app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java # app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java
This commit is contained in:
commit
5c0c5581bb
8
.github/ISSUE_TEMPLATE.md
vendored
8
.github/ISSUE_TEMPLATE.md
vendored
@ -1,3 +1,7 @@
|
|||||||
|
#### Before opening an issue please confirm the following:
|
||||||
|
- [ ] I have read the [wiki](https://github.com/Freeyourgadget/Gadgetbridge/wiki), and I didn't find a solution to my problem / an answer to my question.
|
||||||
|
- [ ] I have searched the [issues](https://github.com/Freeyourgadget/Gadgetbridge/issues), and I didn't find a solution to my problem / an answer to my question.
|
||||||
|
|
||||||
#### Your issue is:
|
#### Your issue is:
|
||||||
*In case of a bug, do not forget to attach logs!*
|
*In case of a bug, do not forget to attach logs!*
|
||||||
|
|
||||||
@ -8,3 +12,7 @@
|
|||||||
#### Your android version is:
|
#### Your android version is:
|
||||||
|
|
||||||
#### Your Gadgetbridge version is:
|
#### Your Gadgetbridge version is:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*New issues about already solved/documented topics could be closed without further comments. Same for too generic or incomplete reports.*
|
||||||
|
29
CHANGELOG.md
29
CHANGELOG.md
@ -1,5 +1,26 @@
|
|||||||
###Changelog
|
###Changelog
|
||||||
|
|
||||||
|
###Version next
|
||||||
|
* Applied some material design guidelines to Charts and (pebble) app management
|
||||||
|
* Pebble: improve compatiblity with watchapp configuration pages
|
||||||
|
|
||||||
|
###Version 0.18.4
|
||||||
|
* Mi Band 2: Display realtime steps in Live Activity
|
||||||
|
* Mi Band: Attempt to recognize Mi Band model with hwVersion = 8
|
||||||
|
* Alarms activity improvements and fixes
|
||||||
|
* Make Buttons in the main activity easier to hit
|
||||||
|
|
||||||
|
###Version 0.18.3
|
||||||
|
* Fix bug that caused the same value in weekly charts for every day on Android 6 and older
|
||||||
|
|
||||||
|
###Version 0.18.2
|
||||||
|
* Mi Band 2: Fix crash on "chat" or "social network" text notification (#603)
|
||||||
|
|
||||||
|
###Version 0.18.1
|
||||||
|
* Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0)
|
||||||
|
* Start VibrationActivity when using "find device" button with Vibratissimo
|
||||||
|
* Support material fork of K9
|
||||||
|
|
||||||
###Version 0.18.0
|
###Version 0.18.0
|
||||||
* All new GUI for the control center
|
* All new GUI for the control center
|
||||||
* Add Portuguese pt_PT and pt_BR translations
|
* Add Portuguese pt_PT and pt_BR translations
|
||||||
@ -10,10 +31,10 @@
|
|||||||
* Huge speedup for weekly charts when changing days
|
* Huge speedup for weekly charts when changing days
|
||||||
* Drop support for importing pre Gadgetbridge 0.12.0 database
|
* Drop support for importing pre Gadgetbridge 0.12.0 database
|
||||||
* Pebble: allow configuration web pages (clay) to access device location
|
* Pebble: allow configuration web pages (clay) to access device location
|
||||||
* Mi2: Initial support for text notifications, caller ID, and icons (requires font installation) (#560)
|
* Mi Band 2: Initial support for text notifications, caller ID, and icons (requires font installation) (#560)
|
||||||
* Mi2: Support for flashing Mili_pro.ft* font files
|
* Mi Band 2: Support for flashing Mili_pro.ft* font files
|
||||||
* Mi2: Improved firmware/font updated
|
* Mi Band 2: Improved firmware/font updated
|
||||||
* Mi2: Set 12h/24h time format, following the Android configuration (#573)
|
* Mi Band 2: Set 12h/24h time format, following the Android configuration (#573)
|
||||||
* Improved BLE discovery and connectivity
|
* Improved BLE discovery and connectivity
|
||||||
|
|
||||||
####Version 0.17.5
|
####Version 0.17.5
|
||||||
|
10
README.md
10
README.md
@ -14,13 +14,13 @@ need to create an account and transmit any of your data to the vendor's servers.
|
|||||||
[List of changes](CHANGELOG.md)
|
[List of changes](CHANGELOG.md)
|
||||||
|
|
||||||
## Supported Devices
|
## Supported Devices
|
||||||
* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round
|
* Pebble, Pebble Steel, Pebble Time, Pebble Time Steel, Pebble Time Round [Wiki section about this device](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble)
|
||||||
* Pebble 2, Pebble Time 2 (experimental, PAIR WITHIN GADGETBRIDGE)
|
* Pebble 2, Pebble Time 2 (experimental, PAIR WITHIN GADGETBRIDGE) [Wiki section about pebble](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Pebble), most parts apply to Pebble 2 as well
|
||||||
* Mi Band, Mi Band 1A, Mi Band 1S
|
* Mi Band, Mi Band 1A, Mi Band 1S [Wiki section about this device](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band)
|
||||||
* Mi Band 2
|
* Mi Band 2 [Wiki section about mi band](https://github.com/Freeyourgadget/Gadgetbridge/wiki/Mi-Band), some parts apply to mi band 2 as well
|
||||||
* Vibratissimo (experimental)
|
* Vibratissimo (experimental)
|
||||||
* Liveview
|
* Liveview
|
||||||
* HPlus Devices (e.g. ZeBand)
|
* HPlus Devices (e.g. ZeBand) [Wiki section about this device](https://github.com/Freeyourgadget/Gadgetbridge/wiki/HPlus)
|
||||||
|
|
||||||
## Features (Pebble)
|
## Features (Pebble)
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ android {
|
|||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
|
|
||||||
// note: always bump BOTH versionCode and versionName!
|
// note: always bump BOTH versionCode and versionName!
|
||||||
versionName "0.18.0"
|
versionName "0.18.4"
|
||||||
versionCode 87
|
versionCode 91
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@ -64,19 +64,18 @@ dependencies {
|
|||||||
testCompile "org.robolectric:robolectric:3.2.2"
|
testCompile "org.robolectric:robolectric:3.2.2"
|
||||||
|
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
compile 'com.android.support:appcompat-v7:25.2.0'
|
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||||
compile 'com.android.support:cardview-v7:25.2.0'
|
compile 'com.android.support:cardview-v7:25.3.1'
|
||||||
compile 'com.android.support:recyclerview-v7:25.2.0'
|
compile 'com.android.support:recyclerview-v7:25.3.1'
|
||||||
compile 'com.android.support:support-v4:25.2.0'
|
compile 'com.android.support:support-v4:25.3.1'
|
||||||
compile 'com.android.support:design:25.2.0'
|
compile 'com.android.support:design:25.3.1'
|
||||||
compile 'com.github.tony19:logback-android-classic:1.1.1-4'
|
compile 'com.github.tony19:logback-android-classic:1.1.1-4'
|
||||||
compile 'org.slf4j:slf4j-api:1.7.7'
|
compile 'org.slf4j:slf4j-api:1.7.7'
|
||||||
compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
|
compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'
|
||||||
compile 'com.github.pfichtner:durationformatter:0.1.1'
|
compile 'com.github.pfichtner:durationformatter:0.1.1'
|
||||||
compile 'de.cketti.library.changelog:ckchangelog:1.2.2'
|
compile 'de.cketti.library.changelog:ckchangelog:1.2.2'
|
||||||
compile 'net.e175.klaus:solarpositioning:0.0.9'
|
compile 'net.e175.klaus:solarpositioning:0.0.9'
|
||||||
compile 'com.github.freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341'
|
compile 'com.github.freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341'
|
||||||
compile 'com.github.woxthebox:draglistview:1.2.9'
|
|
||||||
compile 'org.apache.commons:commons-lang3:3.4'
|
compile 'org.apache.commons:commons-lang3:3.4'
|
||||||
|
|
||||||
// compile project(":DaoCore")
|
// compile project(":DaoCore")
|
||||||
|
@ -341,6 +341,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".activities.AlarmDetails"
|
android:name=".activities.AlarmDetails"
|
||||||
android:label="@string/title_activity_alarm_details"
|
android:label="@string/title_activity_alarm_details"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:parentActivityName=".activities.ConfigureAlarms" />
|
android:parentActivityName=".activities.ConfigureAlarms" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.VibrationActivity"
|
android:name=".activities.VibrationActivity"
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
navigator.geolocation.getCurrentPosition = function(success, failure) { //override because default implementation requires GPS permission
|
var reportedPositionFailures = 0;
|
||||||
success(JSON.parse(GBjs.getCurrentPosition()))
|
navigator.geolocation.getCurrentPosition = function(success, failure, options) { //override because default implementation requires GPS permission
|
||||||
|
geoposition = JSON.parse(GBjs.getCurrentPosition());
|
||||||
|
|
||||||
|
if(options && options.maximumAge && (geoposition.timestamp < Date.now() - options.maximumAge) && reportedPositionFailures <= 10 ) {
|
||||||
|
reportedPositionFailures++;
|
||||||
|
failure({ code: 2, message: "POSITION_UNAVAILABLE"});
|
||||||
|
} else {
|
||||||
|
reportedPositionFailures = 0;
|
||||||
|
success(geoposition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.Storage){
|
if (window.Storage){
|
||||||
@ -205,7 +214,7 @@ var storedPreset = GBjs.getAppStoredPreset();
|
|||||||
document.addEventListener('DOMContentLoaded', function(){
|
document.addEventListener('DOMContentLoaded', function(){
|
||||||
if (jsConfigFile != null) {
|
if (jsConfigFile != null) {
|
||||||
loadScript(jsConfigFile, function() {
|
loadScript(jsConfigFile, function() {
|
||||||
Pebble.evaluate('ready');
|
Pebble.evaluate('ready', [{'type': "ready"}]); //callback object apparently needed by some watchfaces
|
||||||
if(document.hasFocus() && !(getURLVariable('config') == 'true')) {
|
if(document.hasFocus() && !(getURLVariable('config') == 'true')) {
|
||||||
Pebble.evaluate('showConfiguration');
|
Pebble.evaluate('showConfiguration');
|
||||||
} else {
|
} else {
|
||||||
|
@ -445,7 +445,7 @@ public class GBApplication extends Application {
|
|||||||
public static int getTextColor(Context context) {
|
public static int getTextColor(Context context) {
|
||||||
TypedValue typedValue = new TypedValue();
|
TypedValue typedValue = new TypedValue();
|
||||||
Resources.Theme theme = context.getTheme();
|
Resources.Theme theme = context.getTheme();
|
||||||
theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
|
theme.resolveAttribute(R.attr.textColorPrimary, typedValue, true);
|
||||||
return typedValue.data;
|
return typedValue.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
|
|||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for fragments. Provides hooks that are called when
|
* Abstract base class for fragments. Provides hooks that are called when
|
||||||
@ -28,7 +27,7 @@ import android.support.v4.app.FragmentActivity;
|
|||||||
* @see AbstractGBFragmentActivity
|
* @see AbstractGBFragmentActivity
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractGBFragment extends Fragment {
|
public abstract class AbstractGBFragment extends Fragment {
|
||||||
private boolean mVisibleInactivity;
|
private boolean mVisibleInActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when this fragment has been fully scrolled into the activity.
|
* Called when this fragment has been fully scrolled into the activity.
|
||||||
@ -37,7 +36,6 @@ public abstract class AbstractGBFragment extends Fragment {
|
|||||||
* @see #onMadeInvisibleInActivity()
|
* @see #onMadeInvisibleInActivity()
|
||||||
*/
|
*/
|
||||||
protected void onMadeVisibleInActivity() {
|
protected void onMadeVisibleInActivity() {
|
||||||
updateActivityTitle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +45,7 @@ public abstract class AbstractGBFragment extends Fragment {
|
|||||||
* @see #onMadeVisibleInActivity()
|
* @see #onMadeVisibleInActivity()
|
||||||
*/
|
*/
|
||||||
protected void onMadeInvisibleInActivity() {
|
protected void onMadeInvisibleInActivity() {
|
||||||
mVisibleInactivity = false;
|
mVisibleInActivity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,16 +53,7 @@ public abstract class AbstractGBFragment extends Fragment {
|
|||||||
* activity, not taking into account whether the screen is enabled at all.
|
* activity, not taking into account whether the screen is enabled at all.
|
||||||
*/
|
*/
|
||||||
public boolean isVisibleInActivity() {
|
public boolean isVisibleInActivity() {
|
||||||
return mVisibleInactivity;
|
return mVisibleInActivity;
|
||||||
}
|
|
||||||
|
|
||||||
protected void updateActivityTitle() {
|
|
||||||
FragmentActivity activity = getActivity();
|
|
||||||
if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
|
|
||||||
if (getTitle() != null) {
|
|
||||||
activity.setTitle(getTitle());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -76,7 +65,7 @@ public abstract class AbstractGBFragment extends Fragment {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void onMadeVisibleInActivityInternal() {
|
public void onMadeVisibleInActivityInternal() {
|
||||||
mVisibleInactivity = true;
|
mVisibleInActivity = true;
|
||||||
if (isVisible()) {
|
if (isVisible()) {
|
||||||
onMadeVisibleInActivity();
|
onMadeVisibleInActivity();
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ public class AlarmDetails extends GBActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateAlarm() {
|
private void updateAlarm() {
|
||||||
alarm.setSmartWakeup(cbSmartWakeup.isChecked());
|
alarm.setSmartWakeup(supportsSmartWakeup() && cbSmartWakeup.isChecked());
|
||||||
alarm.setRepetition(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
|
alarm.setRepetition(cbMonday.isChecked(), cbTuesday.isChecked(), cbWednesday.isChecked(), cbThursday.isChecked(), cbFriday.isChecked(), cbSaturday.isChecked(), cbSunday.isChecked());
|
||||||
alarm.setHour(timePicker.getCurrentHour());
|
alarm.setHour(timePicker.getCurrentHour());
|
||||||
alarm.setMinute(timePicker.getCurrentMinute());
|
alarm.setMinute(timePicker.getCurrentMinute());
|
||||||
|
@ -19,8 +19,9 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.ListView;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -64,8 +65,10 @@ public class ConfigureAlarms extends GBActivity {
|
|||||||
|
|
||||||
mGBAlarmListAdapter = new GBAlarmListAdapter(this, preferencesAlarmListSet);
|
mGBAlarmListAdapter = new GBAlarmListAdapter(this, preferencesAlarmListSet);
|
||||||
|
|
||||||
ListView listView = (ListView) findViewById(R.id.alarm_list);
|
RecyclerView alarmsRecyclerView = (RecyclerView) findViewById(R.id.alarm_list);
|
||||||
listView.setAdapter(mGBAlarmListAdapter);
|
alarmsRecyclerView.setHasFixedSize(true);
|
||||||
|
alarmsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
alarmsRecyclerView.setAdapter(mGBAlarmListAdapter);
|
||||||
updateAlarmsFromPrefs();
|
updateAlarmsFromPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,15 +250,6 @@ public class ControlCenterv2 extends AppCompatActivity
|
|||||||
|
|
||||||
private void refreshPairedDevices() {
|
private void refreshPairedDevices() {
|
||||||
List<GBDevice> deviceList = deviceManager.getDevices();
|
List<GBDevice> deviceList = deviceManager.getDevices();
|
||||||
GBDevice connectedDevice = null;
|
|
||||||
|
|
||||||
for (GBDevice device : deviceList) {
|
|
||||||
if (device.isConnected() || device.isConnecting()) {
|
|
||||||
connectedDevice = device;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deviceList.isEmpty()) {
|
if (deviceList.isEmpty()) {
|
||||||
background.setVisibility(View.VISIBLE);
|
background.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,8 +20,10 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
import android.support.v4.app.NavUtils;
|
import android.support.v4.app.NavUtils;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -33,6 +35,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
@ -40,10 +43,13 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.ImportExportSharedPreferences;
|
||||||
|
|
||||||
|
|
||||||
public class DbManagementActivity extends GBActivity {
|
public class DbManagementActivity extends GBActivity {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DbManagementActivity.class);
|
private static final Logger LOG = LoggerFactory.getLogger(DbManagementActivity.class);
|
||||||
|
private static SharedPreferences sharedPrefs;
|
||||||
|
private ImportExportSharedPreferences shared_file = new ImportExportSharedPreferences();
|
||||||
|
|
||||||
private Button exportDBButton;
|
private Button exportDBButton;
|
||||||
private Button importDBButton;
|
private Button importDBButton;
|
||||||
@ -95,6 +101,8 @@ public class DbManagementActivity extends GBActivity {
|
|||||||
deleteActivityDatabase();
|
deleteActivityDatabase();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasOldActivityDatabase() {
|
private boolean hasOldActivityDatabase() {
|
||||||
@ -110,8 +118,33 @@ public class DbManagementActivity extends GBActivity {
|
|||||||
return getString(R.string.dbmanagementactivvity_cannot_access_export_path);
|
return getString(R.string.dbmanagementactivvity_cannot_access_export_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void exportShared() {
|
||||||
|
// BEGIN EXAMPLE
|
||||||
|
File myPath = null;
|
||||||
|
try {
|
||||||
|
myPath = FileUtils.getExternalFilesDir();
|
||||||
|
File myFile = new File(myPath, "Export_preference");
|
||||||
|
shared_file.exportToFile(sharedPrefs,myFile,null);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
GB.toast(this, getString(R.string.dbmanagementactivity_error_exporting_shared, ex.getMessage()), Toast.LENGTH_LONG, GB.ERROR, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void importShared() {
|
||||||
|
// BEGIN EXAMPLE
|
||||||
|
File myPath = null;
|
||||||
|
try {
|
||||||
|
myPath = FileUtils.getExternalFilesDir();
|
||||||
|
File myFile = new File(myPath, "Export_preference");
|
||||||
|
shared_file.importFromFile(sharedPrefs,myFile );
|
||||||
|
} catch (Exception ex) {
|
||||||
|
GB.toast(DbManagementActivity.this, getString(R.string.dbmanagementactivity_error_importing_db, ex.getMessage()), Toast.LENGTH_LONG, GB.ERROR, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void exportDB() {
|
private void exportDB() {
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
|
exportShared();
|
||||||
DBHelper helper = new DBHelper(this);
|
DBHelper helper = new DBHelper(this);
|
||||||
File dir = FileUtils.getExternalFilesDir();
|
File dir = FileUtils.getExternalFilesDir();
|
||||||
File destFile = helper.exportDB(dbHandler, dir);
|
File destFile = helper.exportDB(dbHandler, dir);
|
||||||
@ -130,6 +163,7 @@ public class DbManagementActivity extends GBActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
|
importShared();
|
||||||
DBHelper helper = new DBHelper(DbManagementActivity.this);
|
DBHelper helper = new DBHelper(DbManagementActivity.this);
|
||||||
File dir = FileUtils.getExternalFilesDir();
|
File dir = FileUtils.getExternalFilesDir();
|
||||||
SQLiteOpenHelper sqLiteOpenHelper = dbHandler.getHelper();
|
SQLiteOpenHelper sqLiteOpenHelper = dbHandler.getHelper();
|
||||||
|
@ -20,6 +20,7 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
|
|||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothManager;
|
import android.bluetooth.BluetoothManager;
|
||||||
@ -30,6 +31,7 @@ import android.bluetooth.le.ScanResult;
|
|||||||
import android.bluetooth.le.ScanSettings;
|
import android.bluetooth.le.ScanSettings;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
@ -123,7 +125,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
|
|||||||
}
|
}
|
||||||
case BluetoothDevice.ACTION_BOND_STATE_CHANGED: {
|
case BluetoothDevice.ACTION_BOND_STATE_CHANGED: {
|
||||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||||
if (device != null && device.getAddress().equals(bondingAddress)) {
|
if (device != null && bondingDevice != null && device.getAddress().equals(bondingDevice.getMacAddress())) {
|
||||||
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
|
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
|
||||||
if (bondState == BluetoothDevice.BOND_BONDED) {
|
if (bondState == BluetoothDevice.BOND_BONDED) {
|
||||||
handleDeviceBonded();
|
handleDeviceBonded();
|
||||||
@ -134,11 +136,57 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void handleDeviceBonded() {
|
private void connectAndFinish(GBDevice device) {
|
||||||
GB.toast(DiscoveryActivity.this, "Successfully bonded with: " + bondingAddress, Toast.LENGTH_SHORT, GB.INFO);
|
GB.toast(DiscoveryActivity.this, getString(R.string.discovery_trying_to_connect_to, device.getName()), Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
GBApplication.deviceService().connect(device, true);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createBond(final GBDeviceCandidate deviceCandidate, int bondingStyle) {
|
||||||
|
if (bondingStyle == DeviceCoordinator.BONDING_STYLE_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bondingStyle == DeviceCoordinator.BONDING_STYLE_ASK) {
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setCancelable(true)
|
||||||
|
.setTitle(DiscoveryActivity.this.getString(R.string.discovery_pair_title, deviceCandidate.getName()))
|
||||||
|
.setMessage(DiscoveryActivity.this.getString(R.string.discovery_pair_question))
|
||||||
|
.setPositiveButton(DiscoveryActivity.this.getString(R.string.discovery_yes_pair), new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
doCreatePair(deviceCandidate);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.discovery_dont_pair, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
|
||||||
|
connectAndFinish(device);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
} else {
|
||||||
|
doCreatePair(deviceCandidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doCreatePair(GBDeviceCandidate deviceCandidate) {
|
||||||
|
GB.toast(DiscoveryActivity.this, getString(R.string.discovery_attempting_to_pair, deviceCandidate.getName()), Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
if (deviceCandidate.getDevice().createBond()) {
|
||||||
|
// async, wait for bonding event to finish this activity
|
||||||
|
LOG.info("Bonding in progress...");
|
||||||
|
bondingDevice = deviceCandidate;
|
||||||
|
} else {
|
||||||
|
GB.toast(DiscoveryActivity.this, getString(R.string.discovery_bonding_failed_immediately, deviceCandidate.getName()), Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDeviceBonded() {
|
||||||
|
GB.toast(DiscoveryActivity.this, getString(R.string.discovery_successfully_bonded, bondingDevice.getName()), Toast.LENGTH_SHORT, GB.INFO);
|
||||||
|
GBDevice device = DeviceHelper.getInstance().toSupportedDevice(bondingDevice);
|
||||||
|
connectAndFinish(device);
|
||||||
|
}
|
||||||
|
|
||||||
private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
|
private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||||
@ -203,7 +251,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
|
|||||||
private DeviceCandidateAdapter cadidateListAdapter;
|
private DeviceCandidateAdapter cadidateListAdapter;
|
||||||
private Button startButton;
|
private Button startButton;
|
||||||
private Scanning isScanning = Scanning.SCANNING_OFF;
|
private Scanning isScanning = Scanning.SCANNING_OFF;
|
||||||
private String bondingAddress;
|
private GBDeviceCandidate bondingDevice;
|
||||||
|
|
||||||
private enum Scanning {
|
private enum Scanning {
|
||||||
SCANNING_BT,
|
SCANNING_BT,
|
||||||
@ -358,7 +406,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
discoveryFinished();
|
discoveryFinished();
|
||||||
Toast.makeText(this, "Enable Bluetooth to discover devices.", Toast.LENGTH_LONG).show();
|
GB.toast(DiscoveryActivity.this, getString(R.string.discovery_enable_bluetooth), Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,19 +583,24 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
|
|||||||
intent.putExtra(DeviceCoordinator.EXTRA_DEVICE_CANDIDATE, deviceCandidate);
|
intent.putExtra(DeviceCoordinator.EXTRA_DEVICE_CANDIDATE, deviceCandidate);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
} else {
|
} else {
|
||||||
|
GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
|
||||||
|
int bondingStyle = coordinator.getBondingStyle(deviceCandidate);
|
||||||
|
if (bondingStyle == DeviceCoordinator.BONDING_STYLE_NONE) {
|
||||||
|
LOG.info("No bonding needed, according to coordinator, so connecting right away");
|
||||||
|
connectAndFinish(device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BluetoothDevice btDevice = adapter.getRemoteDevice(deviceCandidate.getMacAddress());
|
BluetoothDevice btDevice = adapter.getRemoteDevice(deviceCandidate.getMacAddress());
|
||||||
switch (btDevice.getBondState()) {
|
switch (btDevice.getBondState()) {
|
||||||
case BluetoothDevice.BOND_NONE: {
|
case BluetoothDevice.BOND_NONE: {
|
||||||
if (btDevice.createBond()) {
|
createBond(deviceCandidate, bondingStyle);
|
||||||
// async, wait for bonding event to finish this activity
|
|
||||||
bondingAddress = btDevice.getAddress();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BluetoothDevice.BOND_BONDING:
|
case BluetoothDevice.BOND_BONDING:
|
||||||
// async, wait for bonding event to finish this activity
|
// async, wait for bonding event to finish this activity
|
||||||
bondingAddress = btDevice.getAddress();
|
bondingDevice = deviceCandidate;
|
||||||
break;
|
break;
|
||||||
case BluetoothDevice.BOND_BONDED:
|
case BluetoothDevice.BOND_BONDED:
|
||||||
handleDeviceBonded();
|
handleDeviceBonded();
|
||||||
|
@ -24,10 +24,12 @@ import android.content.IntentFilter;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
@ -35,8 +37,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
|
|
||||||
import com.woxthebox.draglistview.DragListView;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -65,6 +65,8 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
= "nodomain.freeyourgadget.gadgetbridge.appmanager.action.refresh_applist";
|
= "nodomain.freeyourgadget.gadgetbridge.appmanager.action.refresh_applist";
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractAppManagerFragment.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AbstractAppManagerFragment.class);
|
||||||
|
|
||||||
|
private ItemTouchHelper appManagementTouchHelper;
|
||||||
|
|
||||||
protected abstract List<GBDeviceApp> getSystemAppsInCategory();
|
protected abstract List<GBDeviceApp> getSystemAppsInCategory();
|
||||||
|
|
||||||
protected abstract String getSortFilename();
|
protected abstract String getSortFilename();
|
||||||
@ -73,9 +75,13 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
|
|
||||||
protected abstract boolean filterApp(GBDeviceApp gbDeviceApp);
|
protected abstract boolean filterApp(GBDeviceApp gbDeviceApp);
|
||||||
|
|
||||||
|
public void startDragging(RecyclerView.ViewHolder viewHolder) {
|
||||||
|
appManagementTouchHelper.startDrag(viewHolder);
|
||||||
|
}
|
||||||
|
|
||||||
protected void onChangedAppOrder() {
|
protected void onChangedAppOrder() {
|
||||||
List<UUID> uuidList = new ArrayList<>();
|
List<UUID> uuidList = new ArrayList<>();
|
||||||
for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getItemList()) {
|
for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getAppList()) {
|
||||||
uuidList.add(gbDeviceApp.getUUID());
|
uuidList.add(gbDeviceApp.getUUID());
|
||||||
}
|
}
|
||||||
AppManagerActivity.rewriteAppOrderFile(getSortFilename(), uuidList);
|
AppManagerActivity.rewriteAppOrderFile(getSortFilename(), uuidList);
|
||||||
@ -134,7 +140,6 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private DragListView appListView;
|
|
||||||
protected final List<GBDeviceApp> appList = new ArrayList<>();
|
protected final List<GBDeviceApp> appList = new ArrayList<>();
|
||||||
private GBDeviceAppAdapter mGBDeviceAppAdapter;
|
private GBDeviceAppAdapter mGBDeviceAppAdapter;
|
||||||
protected GBDevice mGBDevice = null;
|
protected GBDevice mGBDevice = null;
|
||||||
@ -238,10 +243,6 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
mGBDevice = ((AppManagerActivity) getActivity()).getGBDevice();
|
mGBDevice = ((AppManagerActivity) getActivity()).getGBDevice();
|
||||||
|
|
||||||
if (PebbleUtils.getFwMajor(mGBDevice.getFirmwareVersion()) < 3 && !isCacheManager()) {
|
|
||||||
appListView.setDragEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(ACTION_REFRESH_APPLIST);
|
filter.addAction(ACTION_REFRESH_APPLIST);
|
||||||
|
|
||||||
@ -260,33 +261,35 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
final FloatingActionButton appListFab = ((FloatingActionButton) getActivity().findViewById(R.id.fab));
|
||||||
View rootView = inflater.inflate(R.layout.activity_appmanager, container, false);
|
View rootView = inflater.inflate(R.layout.activity_appmanager, container, false);
|
||||||
|
|
||||||
appListView = (DragListView) (rootView.findViewById(R.id.appListView));
|
RecyclerView appListView = (RecyclerView) (rootView.findViewById(R.id.appListView));
|
||||||
appListView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
|
||||||
mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_with_details, R.id.item_image, this.getContext(), this);
|
|
||||||
appListView.setAdapter(mGBDeviceAppAdapter, false);
|
|
||||||
appListView.setCanDragHorizontally(false);
|
|
||||||
appListView.setDragListListener(new DragListView.DragListListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemDragStarted(int position) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
appListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemDragging(int itemPosition, float x, float y) {
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||||
|
if (dy > 0) {
|
||||||
|
appListFab.hide();
|
||||||
|
} else if (dy < 0) {
|
||||||
|
appListFab.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemDragEnded(int fromPosition, int toPosition) {
|
|
||||||
onChangedAppOrder();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
appListView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||||
|
mGBDeviceAppAdapter = new GBDeviceAppAdapter(appList, R.layout.item_with_details_and_drag_handle, this);
|
||||||
|
appListView.setAdapter(mGBDeviceAppAdapter);
|
||||||
|
|
||||||
|
ItemTouchHelper.Callback appItemTouchHelperCallback = new AppItemTouchHelperCallback(mGBDeviceAppAdapter);
|
||||||
|
appManagementTouchHelper = new ItemTouchHelper(appItemTouchHelperCallback);
|
||||||
|
|
||||||
|
appManagementTouchHelper.attachToRecyclerView(appListView);
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void sendOrderToDevice(String concatFilename) {
|
protected void sendOrderToDevice(String concatFilename) {
|
||||||
ArrayList<UUID> uuids = new ArrayList<>();
|
ArrayList<UUID> uuids = new ArrayList<>();
|
||||||
for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getItemList()) {
|
for (GBDeviceApp gbDeviceApp : mGBDeviceAppAdapter.getAppList()) {
|
||||||
uuids.add(gbDeviceApp.getUUID());
|
uuids.add(gbDeviceApp.getUUID());
|
||||||
}
|
}
|
||||||
if (concatFilename != null) {
|
if (concatFilename != null) {
|
||||||
@ -296,11 +299,11 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
GBApplication.deviceService().onAppReorder(uuids.toArray(new UUID[uuids.size()]));
|
GBApplication.deviceService().onAppReorder(uuids.toArray(new UUID[uuids.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean openPopupMenu(View view, int position) {
|
public boolean openPopupMenu(View view, GBDeviceApp deviceApp) {
|
||||||
PopupMenu popupMenu = new PopupMenu(getContext(), view);
|
PopupMenu popupMenu = new PopupMenu(getContext(), view);
|
||||||
popupMenu.getMenuInflater().inflate(R.menu.appmanager_context, popupMenu.getMenu());
|
popupMenu.getMenuInflater().inflate(R.menu.appmanager_context, popupMenu.getMenu());
|
||||||
Menu menu = popupMenu.getMenu();
|
Menu menu = popupMenu.getMenu();
|
||||||
final GBDeviceApp selectedApp = appList.get(position);
|
final GBDeviceApp selectedApp = deviceApp;
|
||||||
|
|
||||||
if (!selectedApp.isInCache()) {
|
if (!selectedApp.isInCache()) {
|
||||||
menu.removeItem(R.id.appmanager_app_reinstall);
|
menu.removeItem(R.id.appmanager_app_reinstall);
|
||||||
@ -353,12 +356,11 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
|
||||||
popupMenu.show();
|
popupMenu.show();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onContextItemSelected(MenuItem item, GBDeviceApp selectedApp) {
|
private boolean onContextItemSelected(MenuItem item, GBDeviceApp selectedApp) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.appmanager_app_delete_cache:
|
case R.id.appmanager_app_delete_cache:
|
||||||
String baseName;
|
String baseName;
|
||||||
@ -441,4 +443,46 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
|||||||
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mReceiver);
|
LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mReceiver);
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AppItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||||
|
|
||||||
|
private final GBDeviceAppAdapter gbDeviceAppAdapter;
|
||||||
|
|
||||||
|
public AppItemTouchHelperCallback(GBDeviceAppAdapter gbDeviceAppAdapter) {
|
||||||
|
this.gbDeviceAppAdapter = gbDeviceAppAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
|
//app reordering is not possible on old firmwares
|
||||||
|
if (PebbleUtils.getFwMajor(mGBDevice.getFirmwareVersion()) < 3 && !isCacheManager()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//we only support up and down movement and only for moving, not for swiping apps away
|
||||||
|
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLongPressDragEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
|
||||||
|
gbDeviceAppAdapter.onItemMove(source.getAdapterPosition(), target.getAdapterPosition());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||||
|
//nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
|
super.clearView(recyclerView, viewHolder);
|
||||||
|
onChangedAppOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,11 +154,11 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
mIntentFilterActions = new HashSet<>();
|
mIntentFilterActions = new HashSet<>();
|
||||||
if (intentFilterActions != null) {
|
if (intentFilterActions != null) {
|
||||||
mIntentFilterActions.addAll(Arrays.asList(intentFilterActions));
|
mIntentFilterActions.addAll(Arrays.asList(intentFilterActions));
|
||||||
|
}
|
||||||
mIntentFilterActions.add(ChartsHost.DATE_NEXT);
|
mIntentFilterActions.add(ChartsHost.DATE_NEXT);
|
||||||
mIntentFilterActions.add(ChartsHost.DATE_PREV);
|
mIntentFilterActions.add(ChartsHost.DATE_PREV);
|
||||||
mIntentFilterActions.add(ChartsHost.REFRESH);
|
mIntentFilterActions.add(ChartsHost.REFRESH);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -182,9 +182,9 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
HEARTRATE_FILL_COLOR = ContextCompat.getColor(getContext(), R.color.chart_heartrate_fill);
|
HEARTRATE_FILL_COLOR = ContextCompat.getColor(getContext(), R.color.chart_heartrate_fill);
|
||||||
getContext().getTheme().resolveAttribute(R.attr.chart_activity, runningColor, true);
|
getContext().getTheme().resolveAttribute(R.attr.chart_activity, runningColor, true);
|
||||||
AK_ACTIVITY_COLOR = runningColor.data;
|
AK_ACTIVITY_COLOR = runningColor.data;
|
||||||
getContext().getTheme().resolveAttribute(R.attr.chart_light_sleep, runningColor, true);
|
|
||||||
AK_DEEP_SLEEP_COLOR = runningColor.data;
|
|
||||||
getContext().getTheme().resolveAttribute(R.attr.chart_deep_sleep, runningColor, true);
|
getContext().getTheme().resolveAttribute(R.attr.chart_deep_sleep, runningColor, true);
|
||||||
|
AK_DEEP_SLEEP_COLOR = runningColor.data;
|
||||||
|
getContext().getTheme().resolveAttribute(R.attr.chart_light_sleep, runningColor, true);
|
||||||
AK_LIGHT_SLEEP_COLOR = runningColor.data;
|
AK_LIGHT_SLEEP_COLOR = runningColor.data;
|
||||||
getContext().getTheme().resolveAttribute(R.attr.chart_not_worn, runningColor, true);
|
getContext().getTheme().resolveAttribute(R.attr.chart_not_worn, runningColor, true);
|
||||||
AK_NOT_WORN_COLOR = runningColor.data;
|
AK_NOT_WORN_COLOR = runningColor.data;
|
||||||
@ -234,7 +234,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void showDateBar(boolean show) {
|
protected void showDateBar(boolean show) {
|
||||||
getChartsHost().getDateBar().setVisibility(show ? View.VISIBLE : View.GONE);
|
getChartsHost().getDateBar().setVisibility(show ? View.VISIBLE : View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,7 +25,6 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.github.mikephil.charting.charts.BarChart;
|
import com.github.mikephil.charting.charts.BarChart;
|
||||||
import com.github.mikephil.charting.charts.Chart;
|
|
||||||
import com.github.mikephil.charting.charts.PieChart;
|
import com.github.mikephil.charting.charts.PieChart;
|
||||||
import com.github.mikephil.charting.components.LimitLine;
|
import com.github.mikephil.charting.components.LimitLine;
|
||||||
import com.github.mikephil.charting.components.XAxis;
|
import com.github.mikephil.charting.components.XAxis;
|
||||||
@ -81,13 +80,12 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
|||||||
protected void updateChartsnUIThread(ChartsData chartsData) {
|
protected void updateChartsnUIThread(ChartsData chartsData) {
|
||||||
MyChartsData mcd = (MyChartsData) chartsData;
|
MyChartsData mcd = (MyChartsData) chartsData;
|
||||||
|
|
||||||
// setupLegend(mWeekChart);
|
setupLegend(mWeekChart);
|
||||||
mTodayPieChart.setCenterText(mcd.getDayData().centerText);
|
mTodayPieChart.setCenterText(mcd.getDayData().centerText);
|
||||||
mTodayPieChart.setData(mcd.getDayData().data);
|
mTodayPieChart.setData(mcd.getDayData().data);
|
||||||
|
|
||||||
mWeekChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
mWeekChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
|
||||||
mWeekChart.setData(mcd.getWeekBeforeData().getData());
|
mWeekChart.setData(mcd.getWeekBeforeData().getData());
|
||||||
mWeekChart.getLegend().setEnabled(false);
|
|
||||||
mWeekChart.getXAxis().setValueFormatter(mcd.getWeekBeforeData().getXValueFormatter());
|
mWeekChart.getXAxis().setValueFormatter(mcd.getWeekBeforeData().getXValueFormatter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,23 +131,35 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
|
ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
|
||||||
float totalValues[] = getTotalsForActivityAmounts(amounts);
|
float totalValues[] = getTotalsForActivityAmounts(amounts);
|
||||||
|
String[] pieLabels = getPieLabels();
|
||||||
float totalValue = 0;
|
float totalValue = 0;
|
||||||
for (float value : totalValues) {
|
for (int i = 0; i < totalValues.length; i++) {
|
||||||
|
float value = totalValues[i];
|
||||||
totalValue += value;
|
totalValue += value;
|
||||||
entries.add(new PieEntry(value));
|
entries.add(new PieEntry(value, pieLabels[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
set.setValueFormatter(getPieValueFormatter());
|
|
||||||
set.setColors(getColors());
|
set.setColors(getColors());
|
||||||
|
|
||||||
|
if (totalValues.length < 2) {
|
||||||
if (totalValue < mTargetValue) {
|
if (totalValue < mTargetValue) {
|
||||||
entries.add(new PieEntry((mTargetValue - totalValue)));
|
entries.add(new PieEntry((mTargetValue - totalValue)));
|
||||||
set.addColor(Color.GRAY);
|
set.addColor(Color.GRAY);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data.setDataSet(set);
|
data.setDataSet(set);
|
||||||
//this hides the values (numeric) added to the set. These would be shown aside the strings set with addXValue above
|
|
||||||
|
if (totalValues.length < 2) {
|
||||||
data.setDrawValues(false);
|
data.setDrawValues(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||||
|
set.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||||
|
set.setValueTextColor(DESCRIPTION_COLOR);
|
||||||
|
set.setValueTextSize(13f);
|
||||||
|
set.setValueFormatter(getPieValueFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
return new DayData(data, formatPieValue((int) totalValue));
|
return new DayData(data, formatPieValue((int) totalValue));
|
||||||
}
|
}
|
||||||
@ -181,11 +191,11 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
|||||||
private void setupTodayPieChart() {
|
private void setupTodayPieChart() {
|
||||||
mTodayPieChart.setBackgroundColor(BACKGROUND_COLOR);
|
mTodayPieChart.setBackgroundColor(BACKGROUND_COLOR);
|
||||||
mTodayPieChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
mTodayPieChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
||||||
|
mTodayPieChart.setEntryLabelColor(DESCRIPTION_COLOR);
|
||||||
mTodayPieChart.getDescription().setText(getPieDescription(mTargetValue));
|
mTodayPieChart.getDescription().setText(getPieDescription(mTargetValue));
|
||||||
// mTodayPieChart.setNoDataTextDescription("");
|
// mTodayPieChart.setNoDataTextDescription("");
|
||||||
mTodayPieChart.setNoDataText("");
|
mTodayPieChart.setNoDataText("");
|
||||||
mTodayPieChart.getLegend().setEnabled(false);
|
mTodayPieChart.getLegend().setEnabled(false);
|
||||||
// setupLegend(mTodayPieChart);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWeekChart() {
|
private void setupWeekChart() {
|
||||||
@ -222,16 +232,6 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
|||||||
yAxisRight.setTextColor(CHART_TEXT_COLOR);
|
yAxisRight.setTextColor(CHART_TEXT_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setupLegend(Chart chart) {
|
|
||||||
// List<Integer> legendColors = new ArrayList<>(1);
|
|
||||||
// List<String> legendLabels = new ArrayList<>(1);
|
|
||||||
// legendColors.add(akActivity.color);
|
|
||||||
// legendLabels.add(getContext().getString(R.string.chart_steps));
|
|
||||||
// chart.getLegend().setCustom(legendColors, legendLabels);
|
|
||||||
// chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<? extends ActivitySample> getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) {
|
private List<? extends ActivitySample> getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) {
|
||||||
int startTs;
|
int startTs;
|
||||||
int endTs;
|
int endTs;
|
||||||
@ -287,16 +287,17 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
|||||||
ActivityAmounts amounts = null;
|
ActivityAmounts amounts = null;
|
||||||
|
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
|
int key = (int) (day.getTimeInMillis() / 1000) + (mOffsetHours * 3600);
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
activityAmountCache = ((ChartsActivity) activity).mActivityAmountCache;
|
activityAmountCache = ((ChartsActivity) activity).mActivityAmountCache;
|
||||||
amounts = (ActivityAmounts) (activityAmountCache.lookup(day.hashCode() ^ mOffsetHours));
|
amounts = (ActivityAmounts) (activityAmountCache.lookup(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amounts == null) {
|
if (amounts == null) {
|
||||||
ActivityAnalysis analysis = new ActivityAnalysis();
|
ActivityAnalysis analysis = new ActivityAnalysis();
|
||||||
amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, mOffsetHours, device));
|
amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, mOffsetHours, device));
|
||||||
if (activityAmountCache != null) {
|
if (activityAmountCache != null) {
|
||||||
activityAmountCache.add(day.hashCode() ^ mOffsetHours, amounts);
|
activityAmountCache.add(key, amounts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +312,8 @@ public abstract class AbstractWeekChartFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
abstract String formatPieValue(int value);
|
abstract String formatPieValue(int value);
|
||||||
|
|
||||||
|
abstract String[] getPieLabels();
|
||||||
|
|
||||||
abstract IValueFormatter getPieValueFormatter();
|
abstract IValueFormatter getPieValueFormatter();
|
||||||
|
|
||||||
abstract IValueFormatter getBarValueFormatter();
|
abstract IValueFormatter getBarValueFormatter();
|
||||||
|
@ -27,7 +27,6 @@ import android.support.v4.app.Fragment;
|
|||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v4.view.PagerTabStrip;
|
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v4.widget.SwipeRefreshLayout;
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -67,7 +66,6 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts
|
|||||||
private Date mStartDate;
|
private Date mStartDate;
|
||||||
private Date mEndDate;
|
private Date mEndDate;
|
||||||
private SwipeRefreshLayout swipeLayout;
|
private SwipeRefreshLayout swipeLayout;
|
||||||
private PagerTabStrip mPagerTabStrip;
|
|
||||||
private ViewPager viewPager;
|
private ViewPager viewPager;
|
||||||
|
|
||||||
LimitedQueue mActivityAmountCache = new LimitedQueue(60);
|
LimitedQueue mActivityAmountCache = new LimitedQueue(60);
|
||||||
@ -200,7 +198,6 @@ public class ChartsActivity extends AbstractGBFragmentActivity implements Charts
|
|||||||
handleNextButtonClicked();
|
handleNextButtonClicked();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mPagerTabStrip = (PagerTabStrip) findViewById(R.id.charts_pagerTabStrip);
|
|
||||||
|
|
||||||
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.charts_main_layout);
|
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.charts_main_layout);
|
||||||
}
|
}
|
||||||
|
@ -282,13 +282,14 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
|
enableRealtimeTracking(false);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
stopActivityPulse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
enableRealtimeTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScheduledExecutorService startActivityPulse() {
|
private ScheduledExecutorService startActivityPulse() {
|
||||||
@ -345,23 +346,34 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMadeVisibleInActivity() {
|
protected void onMadeVisibleInActivity() {
|
||||||
GBApplication.deviceService().onEnableRealtimeSteps(true);
|
|
||||||
GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(true);
|
|
||||||
super.onMadeVisibleInActivity();
|
super.onMadeVisibleInActivity();
|
||||||
|
enableRealtimeTracking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableRealtimeTracking(boolean enable) {
|
||||||
|
if (enable && pulseScheduler != null) {
|
||||||
|
// already running
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GBApplication.deviceService().onEnableRealtimeSteps(enable);
|
||||||
|
GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(enable);
|
||||||
|
if (enable) {
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
}
|
}
|
||||||
pulseScheduler = startActivityPulse();
|
pulseScheduler = startActivityPulse();
|
||||||
|
} else {
|
||||||
|
stopActivityPulse();
|
||||||
|
if (getActivity() != null) {
|
||||||
|
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMadeInvisibleInActivity() {
|
protected void onMadeInvisibleInActivity() {
|
||||||
stopActivityPulse();
|
enableRealtimeTracking(false);
|
||||||
GBApplication.deviceService().onEnableRealtimeSteps(false);
|
|
||||||
GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(false);
|
|
||||||
if (getActivity() != null) {
|
|
||||||
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
|
||||||
}
|
|
||||||
super.onMadeInvisibleInActivity();
|
super.onMadeInvisibleInActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +105,10 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
set.setColors(colors);
|
set.setColors(colors);
|
||||||
|
set.setValueTextColor(DESCRIPTION_COLOR);
|
||||||
|
set.setValueTextSize(13f);
|
||||||
|
set.setXValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||||
|
set.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
|
||||||
data.setDataSet(set);
|
data.setDataSet(set);
|
||||||
|
|
||||||
//setupLegend(pieChart);
|
//setupLegend(pieChart);
|
||||||
@ -162,6 +166,7 @@ public class SleepChartFragment extends AbstractChartFragment {
|
|||||||
private void setupSleepAmountChart() {
|
private void setupSleepAmountChart() {
|
||||||
mSleepAmountChart.setBackgroundColor(BACKGROUND_COLOR);
|
mSleepAmountChart.setBackgroundColor(BACKGROUND_COLOR);
|
||||||
mSleepAmountChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
mSleepAmountChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
||||||
|
mSleepAmountChart.setEntryLabelColor(DESCRIPTION_COLOR);
|
||||||
mSleepAmountChart.getDescription().setText("");
|
mSleepAmountChart.getDescription().setText("");
|
||||||
// mSleepAmountChart.getDescription().setNoDataTextDescription("");
|
// mSleepAmountChart.getDescription().setNoDataTextDescription("");
|
||||||
mSleepAmountChart.setNoDataText("");
|
mSleepAmountChart.setNoDataText("");
|
||||||
|
@ -16,12 +16,16 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||||
|
|
||||||
|
import com.github.mikephil.charting.charts.Chart;
|
||||||
import com.github.mikephil.charting.components.AxisBase;
|
import com.github.mikephil.charting.components.AxisBase;
|
||||||
|
import com.github.mikephil.charting.components.LegendEntry;
|
||||||
import com.github.mikephil.charting.data.Entry;
|
import com.github.mikephil.charting.data.Entry;
|
||||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||||
import com.github.mikephil.charting.utils.ViewPortHandler;
|
import com.github.mikephil.charting.utils.ViewPortHandler;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
@ -72,6 +76,11 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
return DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.MINUTES);
|
return DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String[] getPieLabels() {
|
||||||
|
return new String[]{getString(R.string.abstract_chart_fragment_kind_deep_sleep), getString(R.string.abstract_chart_fragment_kind_light_sleep)};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
IValueFormatter getPieValueFormatter() {
|
IValueFormatter getPieValueFormatter() {
|
||||||
return new IValueFormatter() {
|
return new IValueFormatter() {
|
||||||
@ -106,4 +115,22 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
int[] getColors() {
|
int[] getColors() {
|
||||||
return new int[]{akDeepSleep.color, akLightSleep.color};
|
return new int[]{akDeepSleep.color, akLightSleep.color};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupLegend(Chart chart) {
|
||||||
|
List<LegendEntry> legendEntries = new ArrayList<>(2);
|
||||||
|
|
||||||
|
LegendEntry lightSleepEntry = new LegendEntry();
|
||||||
|
lightSleepEntry.label = akLightSleep.label;
|
||||||
|
lightSleepEntry.formColor = akLightSleep.color;
|
||||||
|
legendEntries.add(lightSleepEntry);
|
||||||
|
|
||||||
|
LegendEntry deepSleepEntry = new LegendEntry();
|
||||||
|
deepSleepEntry.label = akDeepSleep.label;
|
||||||
|
deepSleepEntry.formColor = akDeepSleep.color;
|
||||||
|
legendEntries.add(deepSleepEntry);
|
||||||
|
|
||||||
|
chart.getLegend().setCustom(legendEntries);
|
||||||
|
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||||
|
|
||||||
|
import com.github.mikephil.charting.charts.Chart;
|
||||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
|
||||||
import com.github.mikephil.charting.formatter.IValueFormatter;
|
import com.github.mikephil.charting.formatter.IValueFormatter;
|
||||||
|
|
||||||
@ -62,6 +63,11 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment {
|
|||||||
return String.valueOf(value);
|
return String.valueOf(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String[] getPieLabels() {
|
||||||
|
return new String[]{""};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
IValueFormatter getPieValueFormatter() {
|
IValueFormatter getPieValueFormatter() {
|
||||||
return null;
|
return null;
|
||||||
@ -81,4 +87,10 @@ public class WeekStepsChartFragment extends AbstractWeekChartFragment {
|
|||||||
int[] getColors() {
|
int[] getColors() {
|
||||||
return new int[]{akActivity.color};
|
return new int[]{akActivity.color};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupLegend(Chart chart) {
|
||||||
|
// no legend here, it is all about the steps here
|
||||||
|
chart.getLegend().setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,20 +19,21 @@ package nodomain.freeyourgadget.gadgetbridge.adapter;
|
|||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.support.v7.widget.CardView;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.CheckedTextView;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
||||||
@ -41,22 +42,18 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
|||||||
/**
|
/**
|
||||||
* Adapter for displaying GBAlarm instances.
|
* Adapter for displaying GBAlarm instances.
|
||||||
*/
|
*/
|
||||||
public class GBAlarmListAdapter extends ArrayAdapter<GBAlarm> {
|
public class GBAlarmListAdapter extends RecyclerView.Adapter<GBAlarmListAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private ArrayList<GBAlarm> alarmList;
|
private List<GBAlarm> alarmList;
|
||||||
|
|
||||||
public GBAlarmListAdapter(Context context, ArrayList<GBAlarm> alarmList) {
|
|
||||||
super(context, 0, alarmList);
|
|
||||||
|
|
||||||
|
public GBAlarmListAdapter(Context context, List<GBAlarm> alarmList) {
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
this.alarmList = alarmList;
|
this.alarmList = alarmList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBAlarmListAdapter(Context context, Set<String> preferencesAlarmListSet) {
|
public GBAlarmListAdapter(Context context, Set<String> preferencesAlarmListSet) {
|
||||||
super(context, 0, new ArrayList<GBAlarm>());
|
|
||||||
|
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
alarmList = new ArrayList<>();
|
alarmList = new ArrayList<>();
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ public class GBAlarmListAdapter extends ArrayAdapter<GBAlarm> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<? extends Alarm> getAlarmList() {
|
public ArrayList<? extends Alarm> getAlarmList() {
|
||||||
return alarmList;
|
return (ArrayList) alarmList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -95,53 +92,26 @@ public class GBAlarmListAdapter extends ArrayAdapter<GBAlarm> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCount() {
|
public GBAlarmListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
if (alarmList != null) {
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.alarm_item, parent, false);
|
||||||
return alarmList.size();
|
ViewHolder vh = new ViewHolder(view);
|
||||||
}
|
return vh;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GBAlarm getItem(int position) {
|
public void onBindViewHolder(ViewHolder holder, final int position) {
|
||||||
if (alarmList != null) {
|
|
||||||
return alarmList.get(position);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
final GBAlarm alarm = alarmList.get(position);
|
||||||
public long getItemId(int position) {
|
|
||||||
if (alarmList != null) {
|
|
||||||
return alarmList.get(position).getIndex();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
holder.alarmDayMonday.setChecked(alarm.getRepetition(Alarm.ALARM_MON));
|
||||||
public View getView(int position, View view, ViewGroup parent) {
|
holder.alarmDayTuesday.setChecked(alarm.getRepetition(Alarm.ALARM_TUE));
|
||||||
|
holder.alarmDayWednesday.setChecked(alarm.getRepetition(Alarm.ALARM_WED));
|
||||||
|
holder.alarmDayThursday.setChecked(alarm.getRepetition(Alarm.ALARM_THU));
|
||||||
|
holder.alarmDayFriday.setChecked(alarm.getRepetition(Alarm.ALARM_FRI));
|
||||||
|
holder.alarmDaySaturday.setChecked(alarm.getRepetition(Alarm.ALARM_SAT));
|
||||||
|
holder.alarmDaySunday.setChecked(alarm.getRepetition(Alarm.ALARM_SUN));
|
||||||
|
|
||||||
final GBAlarm alarm = getItem(position);
|
holder.isEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||||
|
|
||||||
if (view == null) {
|
|
||||||
LayoutInflater inflater = (LayoutInflater) mContext
|
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
view = inflater.inflate(R.layout.alarm_item, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView alarmTime = (TextView) view.findViewById(R.id.alarm_item_time);
|
|
||||||
Switch isEnabled = (Switch) view.findViewById(R.id.alarm_item_toggle);
|
|
||||||
TextView isSmartWakeup = (TextView) view.findViewById(R.id.alarm_smart_wakeup);
|
|
||||||
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_sunday), alarm.getRepetition(Alarm.ALARM_SUN));
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_monday), alarm.getRepetition(Alarm.ALARM_MON));
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_tuesday), alarm.getRepetition(Alarm.ALARM_TUE));
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_wednesday), alarm.getRepetition(Alarm.ALARM_WED));
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_thursday), alarm.getRepetition(Alarm.ALARM_THU));
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_friday), alarm.getRepetition(Alarm.ALARM_FRI));
|
|
||||||
highlightDay((TextView) view.findViewById(R.id.alarm_item_saturday), alarm.getRepetition(Alarm.ALARM_SAT));
|
|
||||||
|
|
||||||
isEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
alarm.setEnabled(isChecked);
|
alarm.setEnabled(isChecked);
|
||||||
@ -149,28 +119,62 @@ public class GBAlarmListAdapter extends ArrayAdapter<GBAlarm> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
view.setOnClickListener(new View.OnClickListener() {
|
holder.container.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
((ConfigureAlarms) mContext).configureAlarm(alarm);
|
((ConfigureAlarms) mContext).configureAlarm(alarm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
alarmTime.setText(alarm.getTime());
|
holder.alarmTime.setText(alarm.getTime());
|
||||||
isEnabled.setChecked(alarm.isEnabled());
|
holder.isEnabled.setChecked(alarm.isEnabled());
|
||||||
if (alarm.isSmartWakeup()) {
|
if (alarm.isSmartWakeup()) {
|
||||||
isSmartWakeup.setVisibility(TextView.VISIBLE);
|
holder.isSmartWakeup.setVisibility(TextView.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
isSmartWakeup.setVisibility(TextView.GONE);
|
holder.isSmartWakeup.setVisibility(TextView.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return alarmList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void highlightDay(TextView view, boolean isOn) {
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
if (isOn) {
|
|
||||||
view.setTextColor(Color.BLUE);
|
CardView container;
|
||||||
} else {
|
|
||||||
view.setTextColor(GBApplication.getTextColor(mContext));
|
TextView alarmTime;
|
||||||
|
Switch isEnabled;
|
||||||
|
TextView isSmartWakeup;
|
||||||
|
|
||||||
|
CheckedTextView alarmDayMonday;
|
||||||
|
CheckedTextView alarmDayTuesday;
|
||||||
|
CheckedTextView alarmDayWednesday;
|
||||||
|
CheckedTextView alarmDayThursday;
|
||||||
|
CheckedTextView alarmDayFriday;
|
||||||
|
CheckedTextView alarmDaySaturday;
|
||||||
|
CheckedTextView alarmDaySunday;
|
||||||
|
|
||||||
|
ViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
|
||||||
|
container = (CardView) view.findViewById(R.id.card_view);
|
||||||
|
|
||||||
|
alarmTime = (TextView) view.findViewById(R.id.alarm_item_time);
|
||||||
|
isEnabled = (Switch) view.findViewById(R.id.alarm_item_toggle);
|
||||||
|
isSmartWakeup = (TextView) view.findViewById(R.id.alarm_smart_wakeup);
|
||||||
|
|
||||||
|
alarmDayMonday = (CheckedTextView) view.findViewById(R.id.alarm_item_monday);
|
||||||
|
alarmDayTuesday = (CheckedTextView) view.findViewById(R.id.alarm_item_tuesday);
|
||||||
|
alarmDayWednesday = (CheckedTextView) view.findViewById(R.id.alarm_item_wednesday);
|
||||||
|
alarmDayThursday = (CheckedTextView) view.findViewById(R.id.alarm_item_thursday);
|
||||||
|
alarmDayFriday = (CheckedTextView) view.findViewById(R.id.alarm_item_friday);
|
||||||
|
alarmDaySaturday = (CheckedTextView) view.findViewById(R.id.alarm_item_saturday);
|
||||||
|
alarmDaySunday = (CheckedTextView) view.findViewById(R.id.alarm_item_sunday);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,15 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.adapter;
|
package nodomain.freeyourgadget.gadgetbridge.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.woxthebox.draglistview.DragItemAdapter;
|
import java.util.Collections;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -37,40 +37,41 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
|||||||
* Adapter for displaying GBDeviceApp instances.
|
* Adapter for displaying GBDeviceApp instances.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GBDeviceAppAdapter extends DragItemAdapter<GBDeviceApp, GBDeviceAppAdapter.ViewHolder> {
|
public class GBDeviceAppAdapter extends RecyclerView.Adapter<GBDeviceAppAdapter.AppViewHolder> {
|
||||||
|
|
||||||
private final int mLayoutId;
|
private final int mLayoutId;
|
||||||
private final int mGrabHandleId;
|
private final List<GBDeviceApp> appList;
|
||||||
private final Context mContext;
|
|
||||||
private final AbstractAppManagerFragment mParentFragment;
|
private final AbstractAppManagerFragment mParentFragment;
|
||||||
|
|
||||||
public GBDeviceAppAdapter(List<GBDeviceApp> list, int layoutId, int grabHandleId, Context context, AbstractAppManagerFragment parentFragment) {
|
public List<GBDeviceApp> getAppList() {
|
||||||
super(true); // longpress
|
return appList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GBDeviceAppAdapter(List<GBDeviceApp> list, int layoutId, AbstractAppManagerFragment parentFragment) {
|
||||||
mLayoutId = layoutId;
|
mLayoutId = layoutId;
|
||||||
mGrabHandleId = grabHandleId;
|
appList = list;
|
||||||
mContext = context;
|
|
||||||
mParentFragment = parentFragment;
|
mParentFragment = parentFragment;
|
||||||
setHasStableIds(true);
|
|
||||||
setItemList(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getItemId(int position) {
|
public long getItemId(int position) {
|
||||||
return mItemList.get(position).getUUID().getLeastSignificantBits();
|
return appList.get(position).getUUID().getLeastSignificantBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public int getItemCount() {
|
||||||
|
return appList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GBDeviceAppAdapter.AppViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false);
|
View view = LayoutInflater.from(parent.getContext()).inflate(mLayoutId, parent, false);
|
||||||
return new ViewHolder(view);
|
return new AppViewHolder(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
public void onBindViewHolder(final AppViewHolder holder, int position) {
|
||||||
super.onBindViewHolder(holder, position);
|
final GBDeviceApp deviceApp = appList.get(position);
|
||||||
GBDeviceApp deviceApp = mItemList.get(position);
|
|
||||||
|
|
||||||
|
|
||||||
holder.mDeviceAppVersionAuthorLabel.setText(GBApplication.getContext().getString(R.string.appversion_by_creator, deviceApp.getVersion(), deviceApp.getCreator()));
|
holder.mDeviceAppVersionAuthorLabel.setText(GBApplication.getContext().getString(R.string.appversion_by_creator, deviceApp.getVersion(), deviceApp.getCreator()));
|
||||||
// FIXME: replace with small icons
|
// FIXME: replace with small icons
|
||||||
@ -93,29 +94,51 @@ public class GBDeviceAppAdapter extends DragItemAdapter<GBDeviceApp, GBDeviceApp
|
|||||||
default:
|
default:
|
||||||
holder.mDeviceImageView.setImageResource(R.drawable.ic_watchapp);
|
holder.mDeviceImageView.setImageResource(R.drawable.ic_watchapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
UUID uuid = deviceApp.getUUID();
|
||||||
|
GBApplication.deviceService().onAppStart(uuid, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onLongClick(View view) {
|
||||||
|
return mParentFragment.openPopupMenu(view, deviceApp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.mDragHandle.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||||
|
mParentFragment.startDragging(holder);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ViewHolder extends DragItemAdapter<GBDeviceApp, GBDeviceAppAdapter.ViewHolder>.ViewHolder {
|
public void onItemMove(int from, int to) {
|
||||||
TextView mDeviceAppVersionAuthorLabel;
|
Collections.swap(appList, from, to);
|
||||||
TextView mDeviceAppNameLabel;
|
notifyItemMoved(from, to);
|
||||||
ImageView mDeviceImageView;
|
}
|
||||||
|
|
||||||
public ViewHolder(final View itemView) {
|
public class AppViewHolder extends RecyclerView.ViewHolder {
|
||||||
super(itemView, mGrabHandleId);
|
final TextView mDeviceAppVersionAuthorLabel;
|
||||||
|
final TextView mDeviceAppNameLabel;
|
||||||
|
final ImageView mDeviceImageView;
|
||||||
|
final ImageView mDragHandle;
|
||||||
|
|
||||||
|
AppViewHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
mDeviceAppVersionAuthorLabel = (TextView) itemView.findViewById(R.id.item_details);
|
mDeviceAppVersionAuthorLabel = (TextView) itemView.findViewById(R.id.item_details);
|
||||||
mDeviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name);
|
mDeviceAppNameLabel = (TextView) itemView.findViewById(R.id.item_name);
|
||||||
mDeviceImageView = (ImageView) itemView.findViewById(R.id.item_image);
|
mDeviceImageView = (ImageView) itemView.findViewById(R.id.item_image);
|
||||||
|
mDragHandle = (ImageView) itemView.findViewById(R.id.drag_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onItemClicked(View view) {
|
|
||||||
UUID uuid = mItemList.get(getAdapterPosition()).getUUID();
|
|
||||||
GBApplication.deviceService().onAppStart(uuid, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onItemLongClicked(View view) {
|
|
||||||
return mParentFragment.openPopupMenu(view, getAdapterPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -124,4 +124,9 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
|||||||
public boolean needsBackgroundWebView(GBDevice device) {
|
public boolean needsBackgroundWebView(GBDevice device) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBondingStyle(GBDeviceCandidate deviceCandidate) {
|
||||||
|
return BONDING_STYLE_ASK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,21 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|||||||
*/
|
*/
|
||||||
public interface DeviceCoordinator {
|
public interface DeviceCoordinator {
|
||||||
String EXTRA_DEVICE_CANDIDATE = "nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate.EXTRA_DEVICE_CANDIDATE";
|
String EXTRA_DEVICE_CANDIDATE = "nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate.EXTRA_DEVICE_CANDIDATE";
|
||||||
|
/**
|
||||||
|
* Do not attempt to bond after discovery.
|
||||||
|
*/
|
||||||
|
int BONDING_STYLE_NONE = 0;
|
||||||
|
/**
|
||||||
|
* Bond after discovery.
|
||||||
|
* This is not recommended, as there are mobile devices on which bonding does not work.
|
||||||
|
* Prefer to use #BONDING_STYLE_ASK instead.
|
||||||
|
*/
|
||||||
|
int BONDING_STYLE_BOND = 1;
|
||||||
|
/**
|
||||||
|
* Let the user decide whether to bond or not after discovery.
|
||||||
|
* Prefer this over #BONDING_STYLE_BOND
|
||||||
|
*/
|
||||||
|
int BONDING_STYLE_ASK = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether this coordinator handles the given candidate.
|
* Checks whether this coordinator handles the given candidate.
|
||||||
@ -215,4 +230,10 @@ public interface DeviceCoordinator {
|
|||||||
* @param device
|
* @param device
|
||||||
*/
|
*/
|
||||||
boolean needsBackgroundWebView(GBDevice device);
|
boolean needsBackgroundWebView(GBDevice device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns how/if the given device should be bonded before connecting to it.
|
||||||
|
* @param deviceCandidate
|
||||||
|
*/
|
||||||
|
int getBondingStyle(GBDeviceCandidate deviceCandidate);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
|
|
||||||
@ -88,6 +91,12 @@ public class DeviceManager {
|
|||||||
} else {
|
} else {
|
||||||
deviceList.add(dev);
|
deviceList.add(dev);
|
||||||
}
|
}
|
||||||
|
if (dev.isInitialized()) {
|
||||||
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
|
DBHelper.getDevice(dev, dbHandler.getDaoSession()); // implicitly creates the device in database if not present, and updates device attributes
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateSelectedDevice(dev);
|
updateSelectedDevice(dev);
|
||||||
refreshPairedDevices();
|
refreshPairedDevices();
|
||||||
|
@ -34,24 +34,10 @@ import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
|
|||||||
* @param <T> the device/provider specific sample type (must extend AbstractActivitySample)
|
* @param <T> the device/provider specific sample type (must extend AbstractActivitySample)
|
||||||
*/
|
*/
|
||||||
public interface SampleProvider<T extends AbstractActivitySample> {
|
public interface SampleProvider<T extends AbstractActivitySample> {
|
||||||
// TODO: these constants can all be removed
|
// These are only used for SharedPreferences
|
||||||
int PROVIDER_MIBAND = 0;
|
|
||||||
int PROVIDER_PEBBLE_MORPHEUZ = 1;
|
int PROVIDER_PEBBLE_MORPHEUZ = 1;
|
||||||
int PROVIDER_PEBBLE_GADGETBRIDGE = 2; // removed
|
|
||||||
int PROVIDER_PEBBLE_MISFIT = 3;
|
int PROVIDER_PEBBLE_MISFIT = 3;
|
||||||
int PROVIDER_PEBBLE_HEALTH = 4;
|
int PROVIDER_PEBBLE_HEALTH = 4;
|
||||||
int PROVIDER_MIBAND2 = 5;
|
|
||||||
int PROVIDER_HPLUS = 6;
|
|
||||||
|
|
||||||
int PROVIDER_UNKNOWN = 100;
|
|
||||||
// TODO: can also be removed
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the "id" of this sample provider, as used in Gadgetbridge versions < 0.12.0.
|
|
||||||
* Only used for importing old samples.
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
int getID();
|
|
||||||
|
|
||||||
int normalizeType(int rawType);
|
int normalizeType(int rawType);
|
||||||
|
|
||||||
|
@ -87,11 +87,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
|
|||||||
public AbstractActivitySample getLatestActivitySample() {
|
public AbstractActivitySample getLatestActivitySample() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getID() {
|
|
||||||
return PROVIDER_UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnknownDeviceCoordinator() {
|
public UnknownDeviceCoordinator() {
|
||||||
|
@ -21,7 +21,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -34,7 +33,6 @@ import de.greenrobot.dao.Property;
|
|||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.HPlusHealthActivityOverlay;
|
import nodomain.freeyourgadget.gadgetbridge.entities.HPlusHealthActivityOverlay;
|
||||||
@ -58,11 +56,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
mDevice = device;
|
mDevice = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getID() {
|
|
||||||
|
|
||||||
return SampleProvider.PROVIDER_HPLUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int normalizeType(int rawType) {
|
public int normalizeType(int rawType) {
|
||||||
switch (rawType){
|
switch (rawType){
|
||||||
case HPlusDataRecord.TYPE_DAY_SLOT:
|
case HPlusDataRecord.TYPE_DAY_SLOT:
|
||||||
@ -200,6 +193,9 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
for (HPlusHealthActivitySample sample : samples) {
|
for (HPlusHealthActivitySample sample : samples) {
|
||||||
|
|
||||||
if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) {
|
if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) {
|
||||||
|
if(overlay.getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP || overlay.getRawKind() == ActivityKind.TYPE_DEEP_SLEEP)
|
||||||
|
sample.setRawIntensity(10);
|
||||||
|
|
||||||
sample.setRawKind(overlay.getRawKind());
|
sample.setRawKind(overlay.getRawKind());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao;
|
||||||
@ -63,12 +62,6 @@ public class MiBand2SampleProvider extends AbstractMiBandSampleProvider {
|
|||||||
super(device, session);
|
super(device, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getID() {
|
|
||||||
return SampleProvider.PROVIDER_MIBAND2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MiBandActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
|
protected List<MiBandActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
|
||||||
List<MiBandActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
|
List<MiBandActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
|
||||||
|
@ -43,7 +43,7 @@ public class MiBand2Service {
|
|||||||
public static final UUID UUID_UNKNOWN_CHARACTERISTIC4 = UUID.fromString("00000004-0000-3512-2118-0009af100700");
|
public static final UUID UUID_UNKNOWN_CHARACTERISTIC4 = UUID.fromString("00000004-0000-3512-2118-0009af100700");
|
||||||
public static final UUID UUID_CHARACTERISTIC_5_ACTIVITY_DATA = UUID.fromString("00000005-0000-3512-2118-0009af100700");
|
public static final UUID UUID_CHARACTERISTIC_5_ACTIVITY_DATA = UUID.fromString("00000005-0000-3512-2118-0009af100700");
|
||||||
public static final UUID UUID_CHARACTERISTIC_6_BATTERY_INFO = UUID.fromString("00000006-0000-3512-2118-0009af100700");
|
public static final UUID UUID_CHARACTERISTIC_6_BATTERY_INFO = UUID.fromString("00000006-0000-3512-2118-0009af100700");
|
||||||
public static final UUID UUID_UNKNOWN_CHARACTERISTIC7 = UUID.fromString("00000007-0000-3512-2118-0009af100700");
|
public static final UUID UUID_CHARACTERISTIC_7_REALTIME_STEPS = UUID.fromString("00000007-0000-3512-2118-0009af100700");
|
||||||
public static final UUID UUID_UNKNOWN_CHARACTERISTIC8 = UUID.fromString("00000008-0000-3512-2118-0009af100700");
|
public static final UUID UUID_UNKNOWN_CHARACTERISTIC8 = UUID.fromString("00000008-0000-3512-2118-0009af100700");
|
||||||
// service uuid fee1
|
// service uuid fee1
|
||||||
public static final UUID UUID_CHARACTERISTIC_AUTH = UUID.fromString("00000009-0000-3512-2118-0009af100700");
|
public static final UUID UUID_CHARACTERISTIC_AUTH = UUID.fromString("00000009-0000-3512-2118-0009af100700");
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
@ -42,11 +41,6 @@ public class MiBandSampleProvider extends AbstractMiBandSampleProvider {
|
|||||||
super(device, session);
|
super(device, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getID() {
|
|
||||||
return SampleProvider.PROVIDER_MIBAND;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public int normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
|
@ -97,10 +97,14 @@ public class PBWReader {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String platformDir = determinePlatformDir(uriHelper, platform);
|
String platformDir = "";
|
||||||
|
if (!uriHelper.getFileName().endsWith(".pbz")) {
|
||||||
|
platformDir = determinePlatformDir(uriHelper, platform);
|
||||||
|
|
||||||
if (platform.equals("chalk") && platformDir.equals("")) {
|
if (platform.equals("chalk") && platformDir.equals("")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG.info("using platformdir: '" + platformDir + "'");
|
LOG.info("using platformdir: '" + platformDir + "'");
|
||||||
String appName = null;
|
String appName = null;
|
||||||
@ -237,9 +241,6 @@ public class PBWReader {
|
|||||||
private String determinePlatformDir(UriHelper uriHelper, String platform) throws IOException {
|
private String determinePlatformDir(UriHelper uriHelper, String platform) throws IOException {
|
||||||
String platformDir = "";
|
String platformDir = "";
|
||||||
|
|
||||||
if (uriHelper.getFileName().endsWith(".pbz")) {
|
|
||||||
return platformDir;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* for aplite and basalt it is possible to install 2.x apps which have no subfolder
|
* for aplite and basalt it is possible to install 2.x apps which have no subfolder
|
||||||
* we still prefer the subfolders if present.
|
* we still prefer the subfolders if present.
|
||||||
|
@ -25,7 +25,6 @@ import de.greenrobot.dao.Property;
|
|||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay;
|
||||||
@ -139,9 +138,4 @@ public class PebbleHealthSampleProvider extends AbstractSampleProvider<PebbleHea
|
|||||||
public float normalizeIntensity(int rawIntensity) {
|
public float normalizeIntensity(int rawIntensity) {
|
||||||
return rawIntensity / movementDivisor;
|
return rawIntensity / movementDivisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getID() {
|
|
||||||
return SampleProvider.PROVIDER_PEBBLE_HEALTH;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
|
|||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSampleDao;
|
||||||
@ -53,11 +52,6 @@ public class PebbleMisfitSampleProvider extends AbstractSampleProvider<PebbleMis
|
|||||||
return new PebbleMisfitSample();
|
return new PebbleMisfitSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getID() {
|
|
||||||
return SampleProvider.PROVIDER_PEBBLE_MISFIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AbstractDao<PebbleMisfitSample, ?> getSampleDao() {
|
public AbstractDao<PebbleMisfitSample, ?> getSampleDao() {
|
||||||
return getSession().getPebbleMisfitSampleDao();
|
return getSession().getPebbleMisfitSampleDao();
|
||||||
|
@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
|
|||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSampleDao;
|
||||||
@ -64,11 +63,6 @@ public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider<PebbleM
|
|||||||
return rawIntensity / movementDivisor;
|
return rawIntensity / movementDivisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getID() {
|
|
||||||
return SampleProvider.PROVIDER_PEBBLE_MORPHEUZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public int normalizeType(int rawType) {
|
||||||
return rawType;
|
return rawType;
|
||||||
|
@ -417,6 +417,10 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
@Override
|
@Override
|
||||||
public void onNotificationRemoved(StatusBarNotification sbn) {
|
public void onNotificationRemoved(StatusBarNotification sbn) {
|
||||||
//FIXME: deduplicate code
|
//FIXME: deduplicate code
|
||||||
|
if (!isServiceRunning() || sbn == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String source = sbn.getPackageName();
|
String source = sbn.getPackageName();
|
||||||
Notification notification = sbn.getNotification();
|
Notification notification = sbn.getNotification();
|
||||||
if ((notification.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT) {
|
if ((notification.flags & Notification.FLAG_ONGOING_EVENT) == Notification.FLAG_ONGOING_EVENT) {
|
||||||
|
@ -41,9 +41,6 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver;
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
|
||||||
@ -207,14 +204,6 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
|
|||||||
boolean enableReceivers = mDeviceSupport != null && (mDeviceSupport.useAutoConnect() || mGBDevice.isInitialized());
|
boolean enableReceivers = mDeviceSupport != null && (mDeviceSupport.useAutoConnect() || mGBDevice.isInitialized());
|
||||||
setReceiversEnableState(enableReceivers);
|
setReceiversEnableState(enableReceivers);
|
||||||
GB.updateNotification(mGBDevice.getName() + " " + mGBDevice.getStateString(), mGBDevice.isInitialized(), context);
|
GB.updateNotification(mGBDevice.getName() + " " + mGBDevice.getStateString(), mGBDevice.isInitialized(), context);
|
||||||
|
|
||||||
if (device.isInitialized()) {
|
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
|
||||||
DaoSession session = dbHandler.getDaoSession();
|
|
||||||
DBHelper.getDevice(device, session); // implicitly creates the device in database if not present, and updates device attributes
|
|
||||||
} catch (Exception ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG.error("Got ACTION_DEVICE_CHANGED from unexpected device: " + mGBDevice);
|
LOG.error("Got ACTION_DEVICE_CHANGED from unexpected device: " + mGBDevice);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
@ -52,6 +53,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
@ -72,6 +74,8 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
public BluetoothGattCharacteristic ctrlCharacteristic = null;
|
public BluetoothGattCharacteristic ctrlCharacteristic = null;
|
||||||
public BluetoothGattCharacteristic measureCharacteristic = null;
|
public BluetoothGattCharacteristic measureCharacteristic = null;
|
||||||
|
|
||||||
|
private final GBDeviceEventBatteryInfo batteryCmd = new GBDeviceEventBatteryInfo();
|
||||||
|
|
||||||
private HPlusHandlerThread syncHelper;
|
private HPlusHandlerThread syncHelper;
|
||||||
private DeviceType deviceType = DeviceType.UNKNOWN;
|
private DeviceType deviceType = DeviceType.UNKNOWN;
|
||||||
|
|
||||||
@ -826,7 +830,11 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
return syncHelper.processVersion(data);
|
return syncHelper.processVersion(data);
|
||||||
|
|
||||||
case HPlusConstants.DATA_STATS:
|
case HPlusConstants.DATA_STATS:
|
||||||
return syncHelper.processRealtimeStats(data);
|
boolean result = syncHelper.processRealtimeStats(data);
|
||||||
|
if (result) {
|
||||||
|
processExtraInfo (data);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
case HPlusConstants.DATA_SLEEP:
|
case HPlusConstants.DATA_SLEEP:
|
||||||
return syncHelper.processIncomingSleepData(data);
|
return syncHelper.processIncomingSleepData(data);
|
||||||
@ -844,4 +852,44 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processExtraInfo (byte[] data) {
|
||||||
|
try {
|
||||||
|
HPlusDataRecordRealtime record = new HPlusDataRecordRealtime(data);
|
||||||
|
|
||||||
|
handleBatteryInfo(record.battery);
|
||||||
|
|
||||||
|
String DEVINFO_STEP = getContext().getString(R.string.chart_steps) + ": ";
|
||||||
|
String DEVINFO_DISTANCE = getContext().getString(R.string.distance) + ": ";
|
||||||
|
String DEVINFO_CALORY = getContext().getString(R.string.calories) + ": ";
|
||||||
|
String DEVINFO_HEART = "HR: ";
|
||||||
|
|
||||||
|
String info = "";
|
||||||
|
if (record.steps > 0) {
|
||||||
|
info += DEVINFO_STEP + String.valueOf(record.steps) + " ";
|
||||||
|
}
|
||||||
|
if (record.distance > 0) {
|
||||||
|
info += DEVINFO_DISTANCE + String.valueOf(record.distance) + " ";
|
||||||
|
}
|
||||||
|
if (record.calories > 0) {
|
||||||
|
info += DEVINFO_CALORY + String.valueOf(record.calories) + " ";
|
||||||
|
}
|
||||||
|
if (record.heartRate > 0) {
|
||||||
|
info += DEVINFO_HEART + String.valueOf(record.heartRate) + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!info.equals("")) {
|
||||||
|
getDevice().addDeviceInfo(new GenericItem("", info));
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
LOG.debug((e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleBatteryInfo(byte data) {
|
||||||
|
if (batteryCmd.level != (short) data) {
|
||||||
|
batteryCmd.level = (short) data;
|
||||||
|
handleGBDeviceEvent(batteryCmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ public class DeviceInfo extends AbstractInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMili1() {
|
public boolean isMili1() {
|
||||||
return hwVersion == 2;
|
return hwVersion == 2 || (feature == 0 && appearance == 0 && hwVersion == 8 && fw2Version == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMili1A() {
|
public boolean isMili1A() {
|
||||||
|
@ -73,6 +73,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
||||||
@ -965,7 +966,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleRealtimeSteps(byte[] value) {
|
private void handleRealtimeSteps(byte[] value) {
|
||||||
int steps = 0xff & value[0] | (0xff & value[1]) << 8;
|
int steps = BLETypeConversions.toUint16(value);
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("realtime steps: " + steps);
|
LOG.debug("realtime steps: " + steps);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
@ -84,9 +85,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.OverflowStrategy;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotification;
|
||||||
@ -689,6 +687,17 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnableRealtimeSteps(boolean enable) {
|
public void onEnableRealtimeSteps(boolean enable) {
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized(enable ? "Enabling realtime steps notifications" : "Disabling realtime steps notifications");
|
||||||
|
if (enable) {
|
||||||
|
builder.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS));
|
||||||
|
}
|
||||||
|
builder.notify(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS), enable);
|
||||||
|
builder.queue(getQueue());
|
||||||
|
enableRealtimeSamplesTimer(enable);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Unable to change realtime steps notification to: " + enable, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getHighLatency() {
|
private byte[] getHighLatency() {
|
||||||
@ -783,9 +792,6 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
} else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
|
} else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
|
||||||
handleHeartrate(characteristic.getValue());
|
handleHeartrate(characteristic.getValue());
|
||||||
return true;
|
return true;
|
||||||
// } else if (MiBand2Service.UUID_UNKNOQN_CHARACTERISTIC0.equals(characteristicUUID)) {
|
|
||||||
// handleUnknownCharacteristic(characteristic.getValue());
|
|
||||||
// return true;
|
|
||||||
} else if (MiBand2Service.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) {
|
} else if (MiBand2Service.UUID_CHARACTERISTIC_AUTH.equals(characteristicUUID)) {
|
||||||
LOG.info("AUTHENTICATION?? " + characteristicUUID);
|
LOG.info("AUTHENTICATION?? " + characteristicUUID);
|
||||||
logMessageContent(characteristic.getValue());
|
logMessageContent(characteristic.getValue());
|
||||||
@ -793,6 +799,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
} else if (MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON.equals(characteristicUUID)) {
|
} else if (MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON.equals(characteristicUUID)) {
|
||||||
handleButtonPressed(characteristic.getValue());
|
handleButtonPressed(characteristic.getValue());
|
||||||
return true;
|
return true;
|
||||||
|
} else if (MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) {
|
||||||
|
handleRealtimeSteps(characteristic.getValue());
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
||||||
logMessageContent(characteristic.getValue());
|
logMessageContent(characteristic.getValue());
|
||||||
@ -824,6 +833,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
} else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
|
} else if (GattCharacteristic.UUID_CHARACTERISTIC_HEART_RATE_MEASUREMENT.equals(characteristicUUID)) {
|
||||||
logHeartrate(characteristic.getValue(), status);
|
logHeartrate(characteristic.getValue(), status);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) {
|
||||||
|
handleRealtimeSteps(characteristic.getValue());
|
||||||
|
return true;
|
||||||
} else if (MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON.equals(characteristicUUID)) {
|
} else if (MiBand2Service.UUID_CHARACTERISTIC_10_BUTTON.equals(characteristicUUID)) {
|
||||||
handleButtonPressed(characteristic.getValue());
|
handleButtonPressed(characteristic.getValue());
|
||||||
return true;
|
return true;
|
||||||
@ -874,11 +886,21 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleRealtimeSteps(byte[] value) {
|
private void handleRealtimeSteps(byte[] value) {
|
||||||
int steps = 0xff & value[0] | (0xff & value[1]) << 8;
|
if (value == null) {
|
||||||
|
LOG.error("realtime steps: value is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.length == 13) {
|
||||||
|
byte[] stepsValue = new byte[] {value[1], value[2]};
|
||||||
|
int steps = BLETypeConversions.toUint16(stepsValue);
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("realtime steps: " + steps);
|
LOG.debug("realtime steps: " + steps);
|
||||||
}
|
}
|
||||||
getRealtimeSamplesSupport().setSteps(steps);
|
getRealtimeSamplesSupport().setSteps(steps);
|
||||||
|
} else {
|
||||||
|
LOG.warn("Unrecognized realtime steps value: " + Logging.formatBytes(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableRealtimeSamplesTimer(boolean enable) {
|
private void enableRealtimeSamplesTimer(boolean enable) {
|
||||||
@ -1073,10 +1095,8 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
|
|||||||
@Override
|
@Override
|
||||||
public void onTestNewFunction() {
|
public void onTestNewFunction() {
|
||||||
try {
|
try {
|
||||||
TransactionBuilder builder = performInitialized("incoming call from peter");
|
TransactionBuilder builder = performInitialized("test realtime steps");
|
||||||
NewAlert alert = new NewAlert(AlertCategory.Custom, 1, new String(new byte[] {0x19}));
|
builder.read(getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_7_REALTIME_STEPS));
|
||||||
AlertNotificationProfile<MiBand2Support> profile = new AlertNotificationProfile<>(this);
|
|
||||||
profile.newAlert(builder, alert, OverflowStrategy.MAKE_MULTIPLE);
|
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.pebble.GBDeviceEventDataLogging;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.pebble.GBDeviceEventDataLogging;
|
||||||
|
|
||||||
class DatalogSession {
|
class DatalogSession {
|
||||||
@ -44,15 +45,15 @@ class DatalogSession {
|
|||||||
this.itemSize = itemSize;
|
this.itemSize = itemSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean handleMessage(ByteBuffer buf, int length) {
|
GBDeviceEvent[] handleMessage(ByteBuffer buf, int length) {
|
||||||
return true;
|
return new GBDeviceEvent[]{null};
|
||||||
}
|
}
|
||||||
|
|
||||||
String getTaginfo() {
|
String getTaginfo() {
|
||||||
return taginfo;
|
return taginfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
GBDeviceEventDataLogging handleMessageForPebbleKit(ByteBuffer buf, int length) {
|
GBDeviceEvent[] handleMessageForPebbleKit(ByteBuffer buf, int length) {
|
||||||
if (0 != (length % itemSize)) {
|
if (0 != (length % itemSize)) {
|
||||||
LOG.warn("invalid length");
|
LOG.warn("invalid length");
|
||||||
return null;
|
return null;
|
||||||
@ -89,6 +90,6 @@ class DatalogSession {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dataLogging;
|
return new GBDeviceEvent[]{dataLogging, null};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/* Copyright (C) 2016-2017 Daniele Gobbetti
|
||||||
|
|
||||||
|
This file is part of Gadgetbridge.
|
||||||
|
|
||||||
|
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Gadgetbridge is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.pebble;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
|
class DatalogSessionAnalytics extends DatalogSession {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(DatalogSessionAnalytics.class);
|
||||||
|
private GBDeviceEventBatteryInfo mGBDeviceEventBatteryInfo = new GBDeviceEventBatteryInfo();
|
||||||
|
private GBDevice mGBDevice;
|
||||||
|
|
||||||
|
DatalogSessionAnalytics(byte id, UUID uuid, int timestamp, int tag, byte itemType, short itemSize, GBDevice device) {
|
||||||
|
super(id, uuid, timestamp, tag, itemType, itemSize);
|
||||||
|
if (mGBDevice == null || !device.equals(mGBDevice)) { //prevent showing information of other pebble watches when switching devices
|
||||||
|
mGBDevice = device;
|
||||||
|
mGBDeviceEventBatteryInfo.state = BatteryState.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default notification should not be too bad (one per hour) but we can override this if needed
|
||||||
|
//mGBDevice.setBatteryThresholdPercent((short) 5);
|
||||||
|
|
||||||
|
taginfo = "(analytics - " + tag + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) {
|
||||||
|
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
||||||
|
|
||||||
|
datalogMessage.position(datalogMessage.position() + 3);
|
||||||
|
int messageTS = datalogMessage.getInt();
|
||||||
|
|
||||||
|
datalogMessage.position(datalogMessage.position() + 12);
|
||||||
|
short reportedMilliVolts = datalogMessage.getShort();
|
||||||
|
|
||||||
|
LOG.info("Battery reading for TS " + messageTS + " is: " + reportedMilliVolts + " milliVolts, mapped to percentage: " + milliVoltstoPercentage(reportedMilliVolts));
|
||||||
|
|
||||||
|
if (messageTS > 0 && reportedMilliVolts < 5000) { //some safety checks
|
||||||
|
// mGBDeviceEventBatteryInfo.state = BatteryState.BATTERY_NORMAL; //uncoomment this to show the battery status in the control center
|
||||||
|
mGBDeviceEventBatteryInfo.level = milliVoltstoPercentage(reportedMilliVolts);
|
||||||
|
|
||||||
|
return new GBDeviceEvent[]{mGBDeviceEventBatteryInfo, null};
|
||||||
|
} else { //invalid data, but we ack nevertheless
|
||||||
|
return new GBDeviceEvent[]{null};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private short milliVoltstoPercentage(short batteryMilliVolts) {
|
||||||
|
if (batteryMilliVolts > 4145) { //(4146 is still 100, next reported value is already 90)
|
||||||
|
return 100;
|
||||||
|
} else if (batteryMilliVolts > 4053) { //(4054 is still 90, next reported value is already 80)
|
||||||
|
return 90;
|
||||||
|
} else if (batteryMilliVolts > 4000) { //guessed
|
||||||
|
return 80;
|
||||||
|
} else if (batteryMilliVolts > 3890) { //3890 was already 60
|
||||||
|
return 70;
|
||||||
|
} else if (batteryMilliVolts > 3855) { //probably
|
||||||
|
return 60;
|
||||||
|
} else if (batteryMilliVolts > 3780) { //3781 is still 50, next reading is 3776 but percentage on pebble unknown
|
||||||
|
return 50;
|
||||||
|
} else if (batteryMilliVolts >= 3750) { //3750 is still 40, next reported value is 3746 and already 30
|
||||||
|
return 40;
|
||||||
|
} else if (batteryMilliVolts > 3720) { //3723 is still 30, next reported value is 3719 and already 20
|
||||||
|
return 30;
|
||||||
|
} else if (batteryMilliVolts > 3680) { //3683 is still 20, next reported value is 3675 and already 10
|
||||||
|
return 20;
|
||||||
|
} else if (batteryMilliVolts > 3650) { //3657 is still 10
|
||||||
|
return 10;
|
||||||
|
} else {
|
||||||
|
return 0; //or -1 for invalid?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
@ -35,9 +36,9 @@ class DatalogSessionHealthHR extends DatalogSessionPebbleHealth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(ByteBuffer datalogMessage, int length) {
|
public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) {
|
||||||
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
||||||
|
|
||||||
return isPebbleHealthEnabled();
|
return isPebbleHealthEnabled() ? new GBDeviceEvent[]{null} : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,6 +29,7 @@ import java.util.UUID;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlayDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlayDao;
|
||||||
@ -45,11 +46,11 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(ByteBuffer datalogMessage, int length) {
|
public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) {
|
||||||
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
||||||
|
|
||||||
if (!isPebbleHealthEnabled()) {
|
if (!isPebbleHealthEnabled()) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int initialPosition = datalogMessage.position();
|
int initialPosition = datalogMessage.position();
|
||||||
@ -58,7 +59,7 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth {
|
|||||||
short recordType; //probably: 1=sleep, 2=deep sleep, 5=??run??ignored for now
|
short recordType; //probably: 1=sleep, 2=deep sleep, 5=??run??ignored for now
|
||||||
|
|
||||||
if (0 != (length % itemSize))
|
if (0 != (length % itemSize))
|
||||||
return false;//malformed message?
|
return null;//malformed message?
|
||||||
|
|
||||||
int recordCount = length / itemSize;
|
int recordCount = length / itemSize;
|
||||||
OverlayRecord[] overlayRecords = new OverlayRecord[recordCount];
|
OverlayRecord[] overlayRecords = new OverlayRecord[recordCount];
|
||||||
@ -72,7 +73,7 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
store(overlayRecords);
|
store(overlayRecords);
|
||||||
return true;
|
return new GBDeviceEvent[]{null};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void store(OverlayRecord[] overlayRecords) {
|
private void store(OverlayRecord[] overlayRecords) {
|
||||||
|
@ -29,6 +29,7 @@ import java.util.UUID;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlay;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlayDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivityOverlayDao;
|
||||||
@ -45,11 +46,11 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(ByteBuffer datalogMessage, int length) {
|
public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) {
|
||||||
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
||||||
|
|
||||||
if (!isPebbleHealthEnabled()) {
|
if (!isPebbleHealthEnabled()) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int initialPosition = datalogMessage.position();
|
int initialPosition = datalogMessage.position();
|
||||||
@ -57,7 +58,7 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth {
|
|||||||
short recordVersion; //probably
|
short recordVersion; //probably
|
||||||
|
|
||||||
if (0 != (length % itemSize))
|
if (0 != (length % itemSize))
|
||||||
return false;//malformed message?
|
return null;//malformed message?
|
||||||
|
|
||||||
int recordCount = length / itemSize;
|
int recordCount = length / itemSize;
|
||||||
SleepRecord[] sleepRecords = new SleepRecord[recordCount];
|
SleepRecord[] sleepRecords = new SleepRecord[recordCount];
|
||||||
@ -72,7 +73,7 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
store(sleepRecords);
|
store(sleepRecords);
|
||||||
return true;
|
return new GBDeviceEvent[]{null};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void store(SleepRecord[] sleepRecords) {
|
private void store(SleepRecord[] sleepRecords) {
|
||||||
|
@ -28,6 +28,7 @@ import java.util.UUID;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleHealthSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleHealthSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleHealthActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
@ -43,11 +44,11 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handleMessage(ByteBuffer datalogMessage, int length) {
|
public GBDeviceEvent[] handleMessage(ByteBuffer datalogMessage, int length) {
|
||||||
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
LOG.info("DATALOG " + taginfo + GB.hexdump(datalogMessage.array(), datalogMessage.position(), length));
|
||||||
|
|
||||||
if (!isPebbleHealthEnabled()) {
|
if (!isPebbleHealthEnabled()) {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timestamp;
|
int timestamp;
|
||||||
@ -57,7 +58,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth {
|
|||||||
|
|
||||||
int initialPosition = datalogMessage.position();
|
int initialPosition = datalogMessage.position();
|
||||||
if (0 != (length % itemSize))
|
if (0 != (length % itemSize))
|
||||||
return false;//malformed message?
|
return null;//malformed message?
|
||||||
|
|
||||||
int packetCount = length / itemSize;
|
int packetCount = length / itemSize;
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth {
|
|||||||
recordVersion = datalogMessage.getShort();
|
recordVersion = datalogMessage.getShort();
|
||||||
|
|
||||||
if ((recordVersion != 5) && (recordVersion != 6) && (recordVersion != 7) && (recordVersion != 12) && (recordVersion != 13))
|
if ((recordVersion != 5) && (recordVersion != 6) && (recordVersion != 7) && (recordVersion != 12) && (recordVersion != 13))
|
||||||
return false; //we don't know how to deal with the data TODO: this is not ideal because we will get the same message again and again since we NACK it
|
return null; //we don't know how to deal with the data TODO: this is not ideal because we will get the same message again and again since we NACK it
|
||||||
|
|
||||||
timestamp = datalogMessage.getInt();
|
timestamp = datalogMessage.getInt();
|
||||||
datalogMessage.get(); //unknown, throw away
|
datalogMessage.get(); //unknown, throw away
|
||||||
@ -88,7 +89,7 @@ class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth {
|
|||||||
|
|
||||||
store(stepsRecords);
|
store(stepsRecords);
|
||||||
}
|
}
|
||||||
return true;//ACK by default
|
return new GBDeviceEvent[]{null};//ACK by default
|
||||||
}
|
}
|
||||||
|
|
||||||
private void store(StepsRecord[] stepsRecords) {
|
private void store(StepsRecord[] stepsRecords) {
|
||||||
|
@ -2232,10 +2232,9 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private GBDeviceEvent[] decodeDatalog(ByteBuffer buf, short length) {
|
private GBDeviceEvent[] decodeDatalog(ByteBuffer buf, short length) {
|
||||||
boolean ack = true;
|
|
||||||
byte command = buf.get();
|
byte command = buf.get();
|
||||||
byte id = buf.get();
|
byte id = buf.get();
|
||||||
GBDeviceEventDataLogging devEvtDataLogging = null;
|
GBDeviceEvent[] devEvtsDataLogging = null;
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case DATALOG_TIMEOUT:
|
case DATALOG_TIMEOUT:
|
||||||
LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring");
|
LOG.info("DATALOG TIMEOUT. id=" + (id & 0xff) + " - ignoring");
|
||||||
@ -2249,12 +2248,9 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
if (datalogSession != null) {
|
if (datalogSession != null) {
|
||||||
LOG.info("DATALOG UUID=" + datalogSession.uuid + ", tag=" + datalogSession.tag + datalogSession.getTaginfo() + ", itemSize=" + datalogSession.itemSize + ", itemType=" + datalogSession.itemType);
|
LOG.info("DATALOG UUID=" + datalogSession.uuid + ", tag=" + datalogSession.tag + datalogSession.getTaginfo() + ", itemSize=" + datalogSession.itemSize + ", itemType=" + datalogSession.itemType);
|
||||||
if (!datalogSession.uuid.equals(UUID_ZERO) && datalogSession.getClass().equals(DatalogSession.class) && mEnablePebbleKit) {
|
if (!datalogSession.uuid.equals(UUID_ZERO) && datalogSession.getClass().equals(DatalogSession.class) && mEnablePebbleKit) {
|
||||||
devEvtDataLogging = datalogSession.handleMessageForPebbleKit(buf, length - 10);
|
devEvtsDataLogging = datalogSession.handleMessageForPebbleKit(buf, length - 10);
|
||||||
if (devEvtDataLogging == null) {
|
|
||||||
ack = false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ack = datalogSession.handleMessage(buf, length - 10);
|
devEvtsDataLogging = datalogSession.handleMessage(buf, length - 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2267,7 +2263,9 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
short item_size = buf.getShort();
|
short item_size = buf.getShort();
|
||||||
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", log_tag=" + log_tag + ", item_type=" + item_type + ", itemSize=" + item_size);
|
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", log_tag=" + log_tag + ", item_type=" + item_type + ", itemSize=" + item_size);
|
||||||
if (!mDatalogSessions.containsKey(id)) {
|
if (!mDatalogSessions.containsKey(id)) {
|
||||||
if (uuid.equals(UUID_ZERO) && log_tag == 81) {
|
if (uuid.equals(UUID_ZERO) && log_tag == 78) {
|
||||||
|
mDatalogSessions.put(id, new DatalogSessionAnalytics(id, uuid, timestamp, log_tag, item_type, item_size, getDevice()));
|
||||||
|
} else if (uuid.equals(UUID_ZERO) && log_tag == 81) {
|
||||||
mDatalogSessions.put(id, new DatalogSessionHealthSteps(id, uuid, timestamp, log_tag, item_type, item_size, getDevice()));
|
mDatalogSessions.put(id, new DatalogSessionHealthSteps(id, uuid, timestamp, log_tag, item_type, item_size, getDevice()));
|
||||||
} else if (uuid.equals(UUID_ZERO) && log_tag == 83) {
|
} else if (uuid.equals(UUID_ZERO) && log_tag == 83) {
|
||||||
mDatalogSessions.put(id, new DatalogSessionHealthSleep(id, uuid, timestamp, log_tag, item_type, item_size, getDevice()));
|
mDatalogSessions.put(id, new DatalogSessionHealthSleep(id, uuid, timestamp, log_tag, item_type, item_size, getDevice()));
|
||||||
@ -2279,6 +2277,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
mDatalogSessions.put(id, new DatalogSession(id, uuid, timestamp, log_tag, item_type, item_size));
|
mDatalogSessions.put(id, new DatalogSession(id, uuid, timestamp, log_tag, item_type, item_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
devEvtsDataLogging = new GBDeviceEvent[]{null};
|
||||||
break;
|
break;
|
||||||
case DATALOG_CLOSE:
|
case DATALOG_CLOSE:
|
||||||
LOG.info("DATALOG_CLOSE. id=" + (id & 0xff));
|
LOG.info("DATALOG_CLOSE. id=" + (id & 0xff));
|
||||||
@ -2289,7 +2288,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
dataLogging.command = GBDeviceEventDataLogging.COMMAND_FINISH_SESSION;
|
dataLogging.command = GBDeviceEventDataLogging.COMMAND_FINISH_SESSION;
|
||||||
dataLogging.appUUID = datalogSession.uuid;
|
dataLogging.appUUID = datalogSession.uuid;
|
||||||
dataLogging.tag = datalogSession.tag;
|
dataLogging.tag = datalogSession.tag;
|
||||||
devEvtDataLogging = dataLogging;
|
devEvtsDataLogging = new GBDeviceEvent[]{dataLogging, null};
|
||||||
}
|
}
|
||||||
mDatalogSessions.remove(id);
|
mDatalogSessions.remove(id);
|
||||||
}
|
}
|
||||||
@ -2299,15 +2298,18 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
if (ack) {
|
|
||||||
|
if (devEvtsDataLogging != null) {
|
||||||
|
// append ack
|
||||||
LOG.info("sending ACK (0x85)");
|
LOG.info("sending ACK (0x85)");
|
||||||
sendBytes.encodedBytes = encodeDatalog(id, DATALOG_ACK);
|
sendBytes.encodedBytes = encodeDatalog(id, DATALOG_ACK);
|
||||||
|
devEvtsDataLogging[devEvtsDataLogging.length - 1] = sendBytes;
|
||||||
} else {
|
} else {
|
||||||
LOG.info("sending NACK (0x86)");
|
LOG.info("sending NACK (0x86)");
|
||||||
sendBytes.encodedBytes = encodeDatalog(id, DATALOG_NACK);
|
sendBytes.encodedBytes = encodeDatalog(id, DATALOG_NACK);
|
||||||
|
devEvtsDataLogging = new GBDeviceEvent[]{sendBytes};
|
||||||
}
|
}
|
||||||
// append ack/nack
|
return devEvtsDataLogging;
|
||||||
return new GBDeviceEvent[]{devEvtDataLogging, sendBytes};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private GBDeviceEvent decodeAppReorder(ByteBuffer buf) {
|
private GBDeviceEvent decodeAppReorder(ByteBuffer buf) {
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlSerializer;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.util.Xml;
|
||||||
|
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.GBApplication.blacklist;
|
||||||
|
|
||||||
|
public class ImportExportSharedPreferences {
|
||||||
|
|
||||||
|
private static final String BOOLEAN = Boolean.class.getSimpleName();
|
||||||
|
private static final String FLOAT = Float.class.getSimpleName();
|
||||||
|
private static final String INTEGER = Integer.class.getSimpleName();
|
||||||
|
private static final String LONG = Long.class.getSimpleName();
|
||||||
|
private static final String STRING = String.class.getSimpleName();
|
||||||
|
private static final String HASTSET = HashSet.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final String NAME = "name";
|
||||||
|
private static final String PREFERENCES = "preferences";
|
||||||
|
|
||||||
|
public static void exportToFile(SharedPreferences sharedPreferences, File outFile,
|
||||||
|
Set<String> doNotExport) throws IOException {
|
||||||
|
export(sharedPreferences, new FileWriter(outFile), doNotExport);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void export(SharedPreferences sharedPreferences, Writer writer,
|
||||||
|
Set<String> doNotExport) throws IOException {
|
||||||
|
XmlSerializer serializer = Xml.newSerializer();
|
||||||
|
serializer.setOutput(writer);
|
||||||
|
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
|
||||||
|
serializer.startDocument("UTF-8", true);
|
||||||
|
serializer.startTag("", PREFERENCES);
|
||||||
|
for (Map.Entry<String, ?> entry : sharedPreferences.getAll().entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (doNotExport != null && doNotExport.contains(key)) continue;
|
||||||
|
|
||||||
|
Object valueObject = entry.getValue();
|
||||||
|
// Skip this entry if the value is null;
|
||||||
|
if (valueObject == null) continue;
|
||||||
|
|
||||||
|
String valueType = valueObject.getClass().getSimpleName();
|
||||||
|
String value = valueObject.toString();
|
||||||
|
serializer.startTag("", valueType);
|
||||||
|
serializer.attribute("", NAME, key);
|
||||||
|
serializer.text(value);
|
||||||
|
serializer.endTag("", valueType);
|
||||||
|
|
||||||
|
}
|
||||||
|
serializer.endTag("", PREFERENCES);
|
||||||
|
serializer.endDocument();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean importFromFile(SharedPreferences sharedPreferences, File inFile)
|
||||||
|
throws Exception {
|
||||||
|
return importFromReader(sharedPreferences, new FileReader(inFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param sharedPreferences
|
||||||
|
* @param in
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static boolean importFromReader(SharedPreferences sharedPreferences, Reader in)
|
||||||
|
throws Exception {
|
||||||
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||||
|
editor.clear();
|
||||||
|
XmlPullParser parser = Xml.newPullParser();
|
||||||
|
parser.setInput(in);
|
||||||
|
int eventType = parser.getEventType();
|
||||||
|
String name = null;
|
||||||
|
String key = null;
|
||||||
|
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||||
|
switch (eventType) {
|
||||||
|
case XmlPullParser.START_TAG:
|
||||||
|
name = parser.getName();
|
||||||
|
key = parser.getAttributeValue("", NAME);
|
||||||
|
break;
|
||||||
|
case XmlPullParser.TEXT:
|
||||||
|
// The parser is reading text outside an element if name is null,
|
||||||
|
// so simply ignore this text part (which is usually something like '\n')
|
||||||
|
if (name == null) break;
|
||||||
|
String text = parser.getText();
|
||||||
|
if (BOOLEAN.equals(name)) {
|
||||||
|
editor.putBoolean(key, Boolean.parseBoolean(text));
|
||||||
|
} else if (FLOAT.equals(name)) {
|
||||||
|
editor.putFloat(key, Float.parseFloat(text));
|
||||||
|
} else if (INTEGER.equals(name)) {
|
||||||
|
editor.putInt(key, Integer.parseInt(text));
|
||||||
|
} else if (LONG.equals(name)) {
|
||||||
|
editor.putLong(key, Long.parseLong(text));
|
||||||
|
} else if (STRING.equals(name)) {
|
||||||
|
editor.putString(key, text);
|
||||||
|
} else if (HASTSET.equals(name)) {
|
||||||
|
if (key.equals("package_blacklist")) {
|
||||||
|
blacklist.clear();
|
||||||
|
text=text.replace("[","").replace("]","");
|
||||||
|
for (int z=0;z<text.split(",").length;z++){
|
||||||
|
blacklist.add(text.split(",")[z].trim());
|
||||||
|
}
|
||||||
|
editor.putStringSet(key, blacklist);
|
||||||
|
}
|
||||||
|
} else if (!PREFERENCES.equals(name)) {
|
||||||
|
throw new Exception("Unkown type " + name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XmlPullParser.END_TAG:
|
||||||
|
name = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eventType = parser.next();
|
||||||
|
}
|
||||||
|
return editor.commit();
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ public class NotificationUtils {
|
|||||||
case CONVERSATIONS:
|
case CONVERSATIONS:
|
||||||
case FACEBOOK:
|
case FACEBOOK:
|
||||||
case FACEBOOK_MESSENGER:
|
case FACEBOOK_MESSENGER:
|
||||||
return notificationSpec.body;
|
return StringUtils.ensureNotNull(notificationSpec.body);
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import android.support.annotation.NonNull;
|
|||||||
|
|
||||||
public class StringUtils {
|
public class StringUtils {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public static String truncate(String s, int maxLength){
|
public static String truncate(String s, int maxLength){
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return "";
|
return "";
|
||||||
|
9
app/src/main/res/drawable/ic_drag_handle_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_drag_handle_black_24dp.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20,9H4v2h16V9zM4,15h16v-2H4v2z" />
|
||||||
|
</vector>
|
@ -5,10 +5,17 @@
|
|||||||
<item android:maxLevel="110" android:drawable="@drawable/ic_device_miband_disabled" />
|
<item android:maxLevel="110" android:drawable="@drawable/ic_device_miband_disabled" />
|
||||||
<item android:maxLevel="111" android:drawable="@drawable/ic_device_miband_disabled" />
|
<item android:maxLevel="111" android:drawable="@drawable/ic_device_miband_disabled" />
|
||||||
<item android:maxLevel="120" android:drawable="@drawable/ic_device_lovetoy_disabled" />
|
<item android:maxLevel="120" android:drawable="@drawable/ic_device_lovetoy_disabled" />
|
||||||
|
<item android:maxLevel="130" android:drawable="@drawable/ic_device_default_disabled" />
|
||||||
|
<item android:maxLevel="140" android:drawable="@drawable/ic_device_hplus_disabled" />
|
||||||
|
<item android:maxLevel="141" android:drawable="@drawable/ic_device_hplus_disabled" />
|
||||||
|
|
||||||
<item android:maxLevel="199" android:drawable="@drawable/ic_launcher" />
|
<item android:maxLevel="199" android:drawable="@drawable/ic_launcher" />
|
||||||
<item android:maxLevel="201" android:drawable="@drawable/ic_device_pebble" />
|
<item android:maxLevel="201" android:drawable="@drawable/ic_device_pebble" />
|
||||||
<item android:maxLevel="210" android:drawable="@drawable/ic_device_miband" />
|
<item android:maxLevel="210" android:drawable="@drawable/ic_device_miband" />
|
||||||
<item android:maxLevel="211" android:drawable="@drawable/ic_device_miband" />
|
<item android:maxLevel="211" android:drawable="@drawable/ic_device_miband" />
|
||||||
<item android:maxLevel="220" android:drawable="@drawable/ic_device_lovetoy" />
|
<item android:maxLevel="220" android:drawable="@drawable/ic_device_lovetoy" />
|
||||||
|
<item android:maxLevel="230" android:drawable="@drawable/ic_launcher" />
|
||||||
|
<item android:maxLevel="240" android:drawable="@drawable/ic_device_hplus" />
|
||||||
|
<item android:maxLevel="241" android:drawable="@drawable/ic_device_hplus" />
|
||||||
|
|
||||||
</level-list>
|
</level-list>
|
@ -1,209 +1,211 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.AlarmDetails">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.AlarmDetails">
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="10dp">
|
android:layout_marginBottom="10dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
|
android:id="@+id/alarm_cb_smart_wakeup"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:id="@+id/alarm_cb_smart_wakeup"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/alarm_label_smart_wakeup"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/alarm_smart_wakeup"
|
android:labelFor="@id/alarm_cb_smart_wakeup"
|
||||||
android:id="@+id/alarm_label_smart_wakeup"
|
android:text="@string/alarm_smart_wakeup" />
|
||||||
android:labelFor="@id/alarm_cb_smart_wakeup" />
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TimePicker
|
<TimePicker
|
||||||
android:id="@+id/alarm_time_picker"
|
android:id="@+id/alarm_time_picker"
|
||||||
android:timePickerMode="clock"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="20dp" />
|
android:layout_marginBottom="20dp"
|
||||||
|
android:timePickerMode="clock" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:id="@+id/dowSelector"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:baselineAligned="false"
|
android:baselineAligned="false"
|
||||||
android:id="@+id/dowSelector">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/alarm_cb_mon"
|
android:id="@+id/alarm_cb_mon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center_horizontal|bottom" />
|
android:gravity="center_horizontal|bottom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/alarm_mon_short"
|
|
||||||
android:id="@+id/alarm_label_cb_mon"
|
android:id="@+id/alarm_label_cb_mon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_mon"
|
android:labelFor="@id/alarm_cb_mon"
|
||||||
android:gravity="center_horizontal|top"/>
|
android:text="@string/alarm_mon_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/alarm_cb_tue"
|
android:id="@+id/alarm_cb_tue"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center_horizontal|bottom" />
|
android:gravity="center_horizontal|bottom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/alarm_tue_short"
|
|
||||||
android:id="@+id/alarm_label_cb_tue"
|
android:id="@+id/alarm_label_cb_tue"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_tue"
|
android:labelFor="@id/alarm_cb_tue"
|
||||||
android:gravity="center_horizontal|top" />
|
android:text="@string/alarm_tue_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/alarm_cb_wed"
|
android:id="@+id/alarm_cb_wed"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center_horizontal|bottom" />
|
android:gravity="center_horizontal|bottom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/alarm_wed_short"
|
|
||||||
android:id="@+id/alarm_label_cb_wed"
|
android:id="@+id/alarm_label_cb_wed"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_wed"
|
android:labelFor="@id/alarm_cb_wed"
|
||||||
android:gravity="center_horizontal|top" />
|
android:text="@string/alarm_wed_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/alarm_cb_thu"
|
android:id="@+id/alarm_cb_thu"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center_horizontal|bottom" />
|
android:gravity="center_horizontal|bottom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/alarm_thu_short"
|
|
||||||
android:id="@+id/alarm_label_cb_thu"
|
android:id="@+id/alarm_label_cb_thu"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_thu"
|
android:labelFor="@id/alarm_cb_thu"
|
||||||
android:gravity="center_horizontal|top" />
|
android:text="@string/alarm_thu_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/alarm_cb_fri"
|
android:id="@+id/alarm_cb_fri"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center_horizontal|bottom" />
|
android:gravity="center_horizontal|bottom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/alarm_fri_short"
|
|
||||||
android:id="@+id/alarm_label_cb_fri"
|
android:id="@+id/alarm_label_cb_fri"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_fri"
|
android:labelFor="@id/alarm_cb_fri"
|
||||||
android:gravity="center_horizontal|top" />
|
android:text="@string/alarm_fri_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
|
android:id="@+id/alarm_cb_sat"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/alarm_cb_sat"
|
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center_horizontal|bottom" />
|
android:gravity="center_horizontal|bottom" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/alarm_label_cb_sat"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/alarm_sat_short"
|
|
||||||
android:id="@+id/alarm_label_cb_sat"
|
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_sat"
|
android:labelFor="@id/alarm_cb_sat"
|
||||||
android:gravity="center_horizontal|top" />
|
android:text="@string/alarm_sat_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
|
android:id="@+id/alarm_cb_sun"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/alarm_cb_sun"
|
|
||||||
android:layout_gravity="center_horizontal" />
|
android:layout_gravity="center_horizontal" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/alarm_label_cb_sun"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/alarm_sun_short"
|
|
||||||
android:id="@+id/alarm_label_cb_sun"
|
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center_horizontal|top"
|
||||||
android:labelFor="@id/alarm_cb_sun"
|
android:labelFor="@id/alarm_cb_sun"
|
||||||
android:gravity="center_horizontal|top" />
|
android:text="@string/alarm_sun_short" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.AndroidPairingActivity">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.AndroidPairingActivity">
|
||||||
|
|
||||||
<TextView android:text="@string/android_pairing_hint" android:layout_width="wrap_content"
|
<TextView
|
||||||
|
android:text="@string/android_pairing_hint"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
android:id="@+id/itemListView"
|
android:id="@+id/itemListView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="false">
|
android:layout_alignParentEnd="false"></ListView>
|
||||||
</ListView>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/infoTextView"
|
android:id="@+id/infoTextView"
|
||||||
@ -67,8 +66,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/installButton"
|
android:layout_below="@+id/installButton"
|
||||||
android:layout_alignParentEnd="false">
|
android:layout_alignParentEnd="false"></ListView>
|
||||||
</ListView>
|
|
||||||
|
|
||||||
<android.widget.Space
|
<android.widget.Space
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -3,8 +3,12 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AbstractAppManagerFragment">
|
||||||
<com.woxthebox.draglistview.DragListView
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/appListView"
|
android:id="@+id/appListView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="fill_parent" />
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:divider="@null" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -1,36 +1,52 @@
|
|||||||
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/activity_swipe_layout"
|
android:id="@+id/activity_swipe_layout"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity"
|
|
||||||
android:paddingLeft="0px"
|
|
||||||
android:paddingRight="0px"
|
|
||||||
android:paddingTop="0px"
|
|
||||||
android:paddingBottom="0px"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity">
|
||||||
|
|
||||||
<LinearLayout android:layout_width="match_parent"
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
|
||||||
android:id="@+id/charts_main_layout"
|
android:id="@+id/charts_main_layout"
|
||||||
android:layout_height="match_parent">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.support.v4.view.ViewPager
|
||||||
|
android:id="@+id/charts_pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity">
|
||||||
|
|
||||||
|
<android.support.design.widget.TabLayout
|
||||||
|
android:id="@+id/charts_pagerTabStrip"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
app:tabMode="scrollable" />
|
||||||
|
</android.support.v4.view.ViewPager>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/charts_date_bar"
|
android:id="@+id/charts_date_bar"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="fill_horizontal"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/charts_previous"
|
android:id="@+id/charts_previous"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="<" />
|
android:text="<" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/charts_text_date"
|
android:id="@+id/charts_text_date"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="5"
|
android:gravity="center_horizontal"
|
||||||
android:text="Today"
|
android:layout_weight="1"
|
||||||
/>
|
android:text="Today" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/charts_next"
|
android:id="@+id/charts_next"
|
||||||
@ -39,18 +55,5 @@
|
|||||||
android:text=">" />
|
android:text=">" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<android.support.v4.view.ViewPager android:id="@+id/charts_pager"
|
|
||||||
android:layout_width="match_parent" android:layout_height="match_parent"
|
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity">
|
|
||||||
<android.support.v4.view.PagerTabStrip
|
|
||||||
android:id="@+id/charts_pagerTabStrip"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="bottom" />
|
|
||||||
</android.support.v4.view.ViewPager>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical" android:layout_width="match_parent"
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/charts_duration_label"
|
android:id="@+id/charts_duration_label"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"></TextView>
|
||||||
</TextView>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,14 +1,17 @@
|
|||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:layout_height="match_parent"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms">
|
||||||
|
|
||||||
<ListView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:descendantFocusability="blocksDescendants"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:divider="@null"
|
||||||
android:id="@+id/alarm_list" />
|
android:id="@+id/alarm_list" />
|
||||||
</FrameLayout>
|
</RelativeLayout>
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
app:elevation="6dp"
|
app:elevation="6dp"
|
||||||
app:pressedTranslationZ="12dp"
|
app:pressedTranslationZ="12dp"
|
||||||
android:layout_marginBottom="30dp"
|
android:layout_marginBottom="30dp"
|
||||||
android:layout_marginRight="10dp"/>
|
android:layout_marginEnd="10dp" />
|
||||||
|
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
@ -3,14 +3,10 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:paddingBottom="0px"
|
|
||||||
android:paddingLeft="0px"
|
|
||||||
android:paddingRight="0px"
|
|
||||||
android:paddingTop="0px"
|
|
||||||
tools:context=".activities.appmanager.AppManagerActivity">
|
tools:context=".activities.appmanager.AppManagerActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/charts_main_layout"
|
android:id="@+id/appmanager_main_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -21,14 +17,15 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".activities.appmanager.AppManagerActivity">
|
tools:context=".activities.appmanager.AppManagerActivity">
|
||||||
|
|
||||||
<android.support.v4.view.PagerTabStrip
|
<android.support.design.widget.TabLayout
|
||||||
android:id="@+id/charts_pagerTabStrip"
|
android:id="@+id/charts_pagerTabStrip"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom" />
|
android:layout_gravity="top" />
|
||||||
</android.support.v4.view.ViewPager>
|
</android.support.v4.view.ViewPager>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -39,7 +36,7 @@
|
|||||||
android:src="@drawable/ic_add_white"
|
android:src="@drawable/ic_add_white"
|
||||||
app:elevation="6dp"
|
app:elevation="6dp"
|
||||||
app:pressedTranslationZ="12dp"
|
app:pressedTranslationZ="12dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="30dp"
|
||||||
android:layout_marginRight="10dp" />
|
android:layout_marginEnd="10dp" />
|
||||||
|
|
||||||
</android.widget.RelativeLayout>
|
</android.widget.RelativeLayout>
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPairingActivity">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandPairingActivity">
|
||||||
|
|
||||||
<TextView android:text="@string/pairing" android:layout_width="wrap_content"
|
<TextView
|
||||||
|
android:text="@string/pairing"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/miband_pair_message" />
|
android:id="@+id/miband_pair_message" />
|
||||||
|
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebblePairingActivity">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebblePairingActivity">
|
||||||
|
|
||||||
<TextView android:text="@string/pairing" android:layout_width="wrap_content"
|
<TextView
|
||||||
|
android:text="@string/pairing"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/pebble_pair_message" />
|
android:id="@+id/pebble_pair_message" />
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical" android:layout_width="match_parent"
|
android:orientation="vertical"
|
||||||
android:layout_height="match_parent" android:layout_margin="10dp">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="10dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:text="Weather on your Pebble"
|
android:text="Weather on your Pebble"
|
||||||
@ -19,7 +21,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/weather_notification_label"
|
android:id="@+id/weather_notification_label"
|
||||||
android:text="@string/weather_notification_label"
|
android:text="@string/weather_notification_label" />
|
||||||
/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,8 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent" android:layout_height="wrap_content">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
|
||||||
|
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/card_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
card_view:cardCornerRadius="4dp"
|
||||||
|
card_view:cardElevation="4dp"
|
||||||
|
card_view:contentPadding="8dp">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -12,98 +23,123 @@
|
|||||||
android:id="@+id/alarm_item_time"
|
android:id="@+id/alarm_item_time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_margin="8dp"
|
||||||
android:text="00:00"
|
android:text="00:00"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="(Smart)"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_time"
|
|
||||||
android:id="@+id/alarm_smart_wakeup"
|
android:id="@+id/alarm_smart_wakeup"
|
||||||
android:visibility="invisible"
|
|
||||||
android:layout_alignBaseline="@+id/alarm_item_time" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_monday"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignBaseline="@+id/alarm_item_time"
|
||||||
android:layout_below="@+id/alarm_item_time"
|
android:layout_toEndOf="@+id/alarm_item_time"
|
||||||
android:layout_marginLeft="4dp"
|
android:text="(Smart)"
|
||||||
android:text="@string/alarm_mon_short"
|
android:visibility="invisible" />
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_tuesday"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_monday"
|
|
||||||
android:layout_below="@+id/alarm_item_time"
|
|
||||||
android:layout_marginLeft="4dp"
|
|
||||||
android:text="@string/alarm_tue_short"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_wednesday"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_tuesday"
|
|
||||||
android:layout_below="@+id/alarm_item_time"
|
|
||||||
android:layout_marginLeft="4dp"
|
|
||||||
android:text="@string/alarm_wed_short"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_thursday"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_wednesday"
|
|
||||||
android:layout_below="@+id/alarm_item_time"
|
|
||||||
android:layout_marginLeft="4dp"
|
|
||||||
android:text="@string/alarm_thu_short"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_friday"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_thursday"
|
|
||||||
android:layout_below="@+id/alarm_item_time"
|
|
||||||
android:layout_marginLeft="4dp"
|
|
||||||
android:text="@string/alarm_fri_short"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_saturday"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_friday"
|
|
||||||
android:layout_below="@+id/alarm_item_time"
|
|
||||||
android:layout_marginLeft="4dp"
|
|
||||||
android:text="@string/alarm_sat_short"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/alarm_item_sunday"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_toRightOf="@+id/alarm_item_saturday"
|
|
||||||
android:layout_below="@+id/alarm_item_time"
|
|
||||||
android:layout_marginLeft="4dp"
|
|
||||||
android:text="@string/alarm_sun_short"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/alarm_item_toggle"
|
android:id="@+id/alarm_item_toggle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_alignParentTop="true" />
|
android:layout_alignParentTop="true" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/dowSelector"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/alarm_item_time"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_monday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_mon_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_tuesday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_tue_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_wednesday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_wed_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_thursday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_thu_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_friday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_fri_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_saturday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_sat_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatCheckedTextView
|
||||||
|
android:id="@+id/alarm_item_sunday"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:checked="false"
|
||||||
|
android:drawableTop="?android:attr/listChoiceIndicatorMultiple"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/alarm_sun_short"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
</android.support.v7.widget.CardView>
|
||||||
|
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
</FrameLayout>
|
|
@ -22,7 +22,7 @@
|
|||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/device_item_infos_box"
|
android:id="@+id/device_item_infos_box"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="50dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
@ -48,7 +48,7 @@
|
|||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:contentDescription="@string/controlcenter_delete_device"
|
android:contentDescription="@string/controlcenter_delete_device"
|
||||||
android:tint="?android:textColorTertiary"
|
android:tint="?attr/textColorTertiary"
|
||||||
card_view:srcCompat="@drawable/ic_remove_device" />
|
card_view:srcCompat="@drawable/ic_remove_device" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
@ -62,7 +62,7 @@
|
|||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:longClickable="true"
|
android:longClickable="true"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
tools:src="@drawable/ic_device_pebble"
|
android:src="@drawable/ic_device_pebble"
|
||||||
android:layout_marginTop="8dp" />
|
android:layout_marginTop="8dp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -111,17 +111,16 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_marginEnd="0dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:minWidth="48dp"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_battery_status"
|
android:id="@+id/device_battery_status"
|
||||||
android:layout_width="48dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
android:tint="@color/secondarytext"
|
android:tint="@color/secondarytext"
|
||||||
card_view:srcCompat="@drawable/level_list_battery" />
|
card_view:srcCompat="@drawable/level_list_battery" />
|
||||||
|
|
||||||
@ -142,7 +141,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_toEndOf="@id/device_battery_status_box"
|
android:layout_toEndOf="@id/device_battery_status_box"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:minWidth="36dp"
|
android:minWidth="36dp"
|
||||||
@ -150,12 +149,14 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_action_fetch_activity"
|
android:id="@+id/device_action_fetch_activity"
|
||||||
android:layout_width="36dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:contentDescription="@string/controlcenter_fetch_activity_data"
|
android:contentDescription="@string/controlcenter_fetch_activity_data"
|
||||||
|
android:scaleType="fitXY"
|
||||||
android:tint="@color/secondarytext"
|
android:tint="@color/secondarytext"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
card_view:srcCompat="@drawable/ic_action_fetch_activity_data" />
|
card_view:srcCompat="@drawable/ic_action_fetch_activity_data" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
@ -171,65 +172,75 @@
|
|||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_action_take_screenshot"
|
android:id="@+id/device_action_take_screenshot"
|
||||||
android:layout_width="36dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_toEndOf="@id/device_action_fetch_activity_box"
|
android:layout_toEndOf="@id/device_action_fetch_activity_box"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:contentDescription="@string/controlcenter_take_screenshot"
|
android:contentDescription="@string/controlcenter_take_screenshot"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
android:tint="@color/secondarytext"
|
android:tint="@color/secondarytext"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
card_view:srcCompat="@drawable/ic_screenshot" />
|
card_view:srcCompat="@drawable/ic_screenshot" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_action_manage_apps"
|
android:id="@+id/device_action_manage_apps"
|
||||||
android:layout_width="36dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_toEndOf="@id/device_action_take_screenshot"
|
android:layout_toEndOf="@id/device_action_take_screenshot"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:contentDescription="@string/title_activity_appmanager"
|
android:contentDescription="@string/title_activity_appmanager"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
android:tint="@color/secondarytext"
|
android:tint="@color/secondarytext"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
card_view:srcCompat="@drawable/ic_action_manage_apps" />
|
card_view:srcCompat="@drawable/ic_action_manage_apps" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_action_set_alarms"
|
android:id="@+id/device_action_set_alarms"
|
||||||
android:layout_width="36dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_toEndOf="@id/device_action_manage_apps"
|
android:layout_toEndOf="@id/device_action_manage_apps"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:contentDescription="@string/controlcenter_start_configure_alarms"
|
android:contentDescription="@string/controlcenter_start_configure_alarms"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
android:tint="@color/secondarytext"
|
android:tint="@color/secondarytext"
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
card_view:srcCompat="@drawable/ic_device_set_alarms" />
|
card_view:srcCompat="@drawable/ic_device_set_alarms" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_action_show_activity_graphs"
|
android:id="@+id/device_action_show_activity_graphs"
|
||||||
android:layout_width="36dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_toEndOf="@id/device_action_set_alarms"
|
android:layout_toEndOf="@id/device_action_set_alarms"
|
||||||
android:clickable="true"
|
|
||||||
android:tint="@color/secondarytext"
|
|
||||||
card_view:srcCompat="@drawable/ic_activity_graphs"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:contentDescription="@string/controlcenter_start_activitymonitor" />
|
android:clickable="true"
|
||||||
|
android:contentDescription="@string/controlcenter_start_activitymonitor"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:tint="@color/secondarytext"
|
||||||
|
card_view:srcCompat="@drawable/ic_activity_graphs" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/device_action_find"
|
android:id="@+id/device_action_find"
|
||||||
android:layout_width="36dp"
|
android:layout_width="40dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="40dp"
|
||||||
android:layout_below="@id/device_image"
|
android:layout_below="@id/device_image"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="4dp"
|
||||||
android:layout_toEndOf="@id/device_action_show_activity_graphs"
|
android:layout_toEndOf="@id/device_action_show_activity_graphs"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:contentDescription="@string/controlcenter_find_device"
|
android:contentDescription="@string/controlcenter_find_device"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
android:tint="@color/secondarytext"
|
android:tint="@color/secondarytext"
|
||||||
card_view:srcCompat="@drawable/ic_action_find_lost_device" />
|
card_view:srcCompat="@drawable/ic_action_find_lost_device" />
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
||||||
|
|
||||||
@ -7,6 +8,6 @@
|
|||||||
android:id="@+id/activitysleepchart"
|
android:id="@+id/activitysleepchart"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
/>
|
android:layout_marginTop="@dimen/activity_vertical_margin" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment">
|
||||||
|
|
||||||
<TextView android:id="@+id/section_label" android:layout_width="wrap_content"
|
<TextView
|
||||||
|
android:id="@+id/section_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical" android:layout_width="fill_parent"
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent">
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -13,15 +14,13 @@
|
|||||||
android:id="@+id/livechart_steps_per_minute_current"
|
android:id="@+id/livechart_steps_per_minute_current"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="20">
|
android:layout_weight="20"></nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart>
|
||||||
</nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart>
|
|
||||||
|
|
||||||
<nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart
|
<nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart
|
||||||
android:id="@+id/livechart_steps_total"
|
android:id="@+id/livechart_steps_total"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="20">
|
android:layout_weight="20"></nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart>
|
||||||
</nodomain.freeyourgadget.gadgetbridge.activities.charts.CustomBarChart>
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<com.github.mikephil.charting.charts.PieChart
|
<com.github.mikephil.charting.charts.PieChart
|
||||||
@ -44,8 +43,7 @@
|
|||||||
android:id="@+id/livechart_steps_per_minute_history"
|
android:id="@+id/livechart_steps_per_minute_history"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="20">
|
android:layout_weight="20"></com.github.mikephil.charting.charts.LineChart>
|
||||||
</com.github.mikephil.charting.charts.LineChart>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,5 +1,6 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -8,8 +9,7 @@
|
|||||||
android:id="@+id/sleepchart_pie_light_deep"
|
android:id="@+id/sleepchart_pie_light_deep"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="20">
|
android:layout_weight="20"></com.github.mikephil.charting.charts.PieChart>
|
||||||
</com.github.mikephil.charting.charts.PieChart>
|
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.CombinedChart
|
<com.github.mikephil.charting.charts.CombinedChart
|
||||||
android:id="@+id/sleepchart"
|
android:id="@+id/sleepchart"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
|
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity$PlaceholderFragment"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -8,8 +9,7 @@
|
|||||||
android:id="@+id/todaystepschart"
|
android:id="@+id/todaystepschart"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="20">
|
android:layout_weight="20"></com.github.mikephil.charting.charts.PieChart>
|
||||||
</com.github.mikephil.charting.charts.PieChart>
|
|
||||||
|
|
||||||
<com.github.mikephil.charting.charts.BarChart
|
<com.github.mikephil.charting.charts.BarChart
|
||||||
android:id="@+id/weekstepschart"
|
android:id="@+id/weekstepschart"
|
||||||
|
@ -35,8 +35,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Base.TextAppearance.AppCompat.SearchResult"
|
style="@style/Base.TextAppearance.AppCompat.SearchResult"
|
||||||
android:text="Item Description"
|
android:text="Item Description" />
|
||||||
/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/activatedBackgroundIndicator"
|
||||||
|
android:minHeight="60dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/item_image"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:contentDescription="@string/candidate_item_device_image" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignWithParentIfMissing="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_toEndOf="@+id/item_image"
|
||||||
|
android:layout_toStartOf="@+id/drag_handle"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:paddingTop="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:scrollHorizontally="false"
|
||||||
|
android:text="Item Name"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_details"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Item Description"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/drag_handle"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:contentDescription="drag handle"
|
||||||
|
android:tint="@color/secondarytext"
|
||||||
|
app:srcCompat="@drawable/ic_drag_handle_black_24dp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -37,8 +37,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/secondarytext"
|
android:textColor="@color/secondarytext"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
android:text="Item Description"
|
android:text="Item Description" />
|
||||||
/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -35,8 +35,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Base.TextAppearance.AppCompat.Body2"
|
style="@style/Base.TextAppearance.AppCompat.Body2"
|
||||||
android:text="Item Description"
|
android:text="Item Description" />
|
||||||
/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -84,6 +84,7 @@
|
|||||||
<string name="pref_title_call_privacy_mode">Modo de privacidad de llamada</string>
|
<string name="pref_title_call_privacy_mode">Modo de privacidad de llamada</string>
|
||||||
<string name="pref_call_privacy_mode_off">Mostrar nombre y número</string>
|
<string name="pref_call_privacy_mode_off">Mostrar nombre y número</string>
|
||||||
<string name="pref_call_privacy_mode_name">Ocultar nombre pero mostrar número</string>
|
<string name="pref_call_privacy_mode_name">Ocultar nombre pero mostrar número</string>
|
||||||
|
<string name="pref_call_privacy_mode_number">Ocultar el número pero mostrar el nombre</string>
|
||||||
<string name="pref_call_privacy_mode_complete">Ocultar nombre y número</string>
|
<string name="pref_call_privacy_mode_complete">Ocultar nombre y número</string>
|
||||||
<string name="pref_blacklist">Excluir aplicaciones</string>
|
<string name="pref_blacklist">Excluir aplicaciones</string>
|
||||||
<string name="pref_header_cannned_messages">Mensajes predeterminados</string>
|
<string name="pref_header_cannned_messages">Mensajes predeterminados</string>
|
||||||
@ -247,7 +248,7 @@
|
|||||||
<string name="notif_battery_low_bigtext_last_charge_time">Última carga: %s \n</string>
|
<string name="notif_battery_low_bigtext_last_charge_time">Última carga: %s \n</string>
|
||||||
<string name="notif_battery_low_bigtext_number_of_charges">Número de cargas: %s</string>
|
<string name="notif_battery_low_bigtext_number_of_charges">Número de cargas: %s</string>
|
||||||
<string name="sleepchart_your_sleep">Tu sueño</string>
|
<string name="sleepchart_your_sleep">Tu sueño</string>
|
||||||
<string name="weeksleepchart_sleep_a_week">Dormir una semana</string>
|
<string name="weeksleepchart_sleep_a_week">Sueño esta semana</string>
|
||||||
<string name="weeksleepchart_today_sleep_description">Sueño hoy, objetivo: %1$s</string>
|
<string name="weeksleepchart_today_sleep_description">Sueño hoy, objetivo: %1$s</string>
|
||||||
<string name="weekstepschart_steps_a_week">Pasos por semana</string>
|
<string name="weekstepschart_steps_a_week">Pasos por semana</string>
|
||||||
<string name="activity_sleepchart_activity_and_sleep">Tu actividad y sueño</string>
|
<string name="activity_sleepchart_activity_and_sleep">Tu actividad y sueño</string>
|
||||||
@ -356,4 +357,8 @@
|
|||||||
<string name="StringUtils_sender">(%1$s)</string>
|
<string name="StringUtils_sender">(%1$s)</string>
|
||||||
<string name="find_device_you_found_it">¡Lo ha encontrado!</string>
|
<string name="find_device_you_found_it">¡Lo ha encontrado!</string>
|
||||||
<string name="miband2_prefs_timeformat">Mi2: formato de hora</string>
|
<string name="miband2_prefs_timeformat">Mi2: formato de hora</string>
|
||||||
|
<string name="mi2_fw_installhandler_fw53_hint">¡Debes instalar la versión %1$s antes de instalar este firmware!</string>
|
||||||
|
<string name="mi2_enable_text_notifications">Notificaciones textuales</string>
|
||||||
|
<string name="mi2_enable_text_notifications_summary"><![CDATA[Needs firmware >= 1.0.1.28 and Mili_pro.ft* installed.]]></string>
|
||||||
|
<string name="off">off</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
<string name="pref_title_call_privacy_mode">Mode de confidentialité d\'appel</string>
|
<string name="pref_title_call_privacy_mode">Mode de confidentialité d\'appel</string>
|
||||||
<string name="pref_call_privacy_mode_off">Afficher le nom et le numéro</string>
|
<string name="pref_call_privacy_mode_off">Afficher le nom et le numéro</string>
|
||||||
<string name="pref_call_privacy_mode_name">Masquer le nom mais afficher le numéro</string>
|
<string name="pref_call_privacy_mode_name">Masquer le nom mais afficher le numéro</string>
|
||||||
|
<string name="pref_call_privacy_mode_number">Masquer le numéro mais afficher le nom</string>
|
||||||
<string name="pref_call_privacy_mode_complete">Masquer le nom et le numéro</string>
|
<string name="pref_call_privacy_mode_complete">Masquer le nom et le numéro</string>
|
||||||
<string name="pref_blacklist">Applications bloquées</string>
|
<string name="pref_blacklist">Applications bloquées</string>
|
||||||
<string name="pref_header_cannned_messages">Modèles de messages</string>
|
<string name="pref_header_cannned_messages">Modèles de messages</string>
|
||||||
@ -247,7 +248,7 @@
|
|||||||
<string name="notif_battery_low_bigtext_last_charge_time">Dernière charge: %s \n</string>
|
<string name="notif_battery_low_bigtext_last_charge_time">Dernière charge: %s \n</string>
|
||||||
<string name="notif_battery_low_bigtext_number_of_charges">Nombre de charges: %s</string>
|
<string name="notif_battery_low_bigtext_number_of_charges">Nombre de charges: %s</string>
|
||||||
<string name="sleepchart_your_sleep">Votre sommeil</string>
|
<string name="sleepchart_your_sleep">Votre sommeil</string>
|
||||||
<string name="weeksleepchart_sleep_a_week">Dormir une semaine</string>
|
<string name="weeksleepchart_sleep_a_week">Sommeil cette semaine</string>
|
||||||
<string name="weeksleepchart_today_sleep_description">Sommeil aujourd\'hui, objectif: %1$s</string>
|
<string name="weeksleepchart_today_sleep_description">Sommeil aujourd\'hui, objectif: %1$s</string>
|
||||||
<string name="weekstepschart_steps_a_week">Pas de la semaine</string>
|
<string name="weekstepschart_steps_a_week">Pas de la semaine</string>
|
||||||
<string name="activity_sleepchart_activity_and_sleep">Votre activité et sommeil</string>
|
<string name="activity_sleepchart_activity_and_sleep">Votre activité et sommeil</string>
|
||||||
@ -306,7 +307,8 @@
|
|||||||
<string name="authentication_required">authentification requise</string>
|
<string name="authentication_required">authentification requise</string>
|
||||||
<string name="appwidget_text">ZzZz</string>
|
<string name="appwidget_text">ZzZz</string>
|
||||||
<string name="add_widget">Ajouter un widget</string>
|
<string name="add_widget">Ajouter un widget</string>
|
||||||
<string name="activity_prefs_sleep_duration">Préférer le mode heure pendant le sommeil</string>
|
<string name="activity_prefs_sleep_duration">
|
||||||
|
Temps de sommeil péféré en heures</string>
|
||||||
<string name="appwidget_alarms_set">Une alarme a été enregistré pour %1$02d:%2$02d</string>
|
<string name="appwidget_alarms_set">Une alarme a été enregistré pour %1$02d:%2$02d</string>
|
||||||
<string name="device_hw">Modèle: %1$s</string>
|
<string name="device_hw">Modèle: %1$s</string>
|
||||||
<string name="device_fw">Micrologiciel: %1$s</string>
|
<string name="device_fw">Micrologiciel: %1$s</string>
|
||||||
@ -357,4 +359,8 @@ NOTE: la base de données sera bien évidement plus grande !</string>
|
|||||||
<string name="StringUtils_sender">(%1$s)</string>
|
<string name="StringUtils_sender">(%1$s)</string>
|
||||||
<string name="find_device_you_found_it">Vous l\'avez trouvé!</string>
|
<string name="find_device_you_found_it">Vous l\'avez trouvé!</string>
|
||||||
<string name="miband2_prefs_timeformat">Mi2: format de l\'heure</string>
|
<string name="miband2_prefs_timeformat">Mi2: format de l\'heure</string>
|
||||||
|
<string name="mi2_fw_installhandler_fw53_hint">Vous devez installer la version %1$s avant d\'installer ce micrologiciel!</string>
|
||||||
|
<string name="mi2_enable_text_notifications">Notifications textuelles</string>
|
||||||
|
<string name="mi2_enable_text_notifications_summary"><![CDATA[Needs firmware >= 1.0.1.28 and Mili_pro.ft* installed.]]></string>
|
||||||
|
<string name="off">off</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -289,7 +289,7 @@
|
|||||||
<string name="FetchActivityOperation_about_to_transfer_since">Sobre para transferir dados desde %1$s</string>
|
<string name="FetchActivityOperation_about_to_transfer_since">Sobre para transferir dados desde %1$s</string>
|
||||||
<string name="waiting_for_reconnect">aguarde para reconectar</string>
|
<string name="waiting_for_reconnect">aguarde para reconectar</string>
|
||||||
<string name="activity_prefs_about_you">Sobre você</string>
|
<string name="activity_prefs_about_you">Sobre você</string>
|
||||||
<string name="activity_prefs_year_birth">Ano de anoversário</string>
|
<string name="activity_prefs_year_birth">Ano de aniversário</string>
|
||||||
<string name="activity_prefs_gender">Gênero</string>
|
<string name="activity_prefs_gender">Gênero</string>
|
||||||
<string name="activity_prefs_height_cm">Altura em cm</string>
|
<string name="activity_prefs_height_cm">Altura em cm</string>
|
||||||
<string name="activity_prefs_weight_kg">Peso em kg</string>
|
<string name="activity_prefs_weight_kg">Peso em kg</string>
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
<string name="action_quit">Sair</string>
|
<string name="action_quit">Sair</string>
|
||||||
<string name="controlcenter_fetch_activity_data">Sincronizar</string>
|
<string name="controlcenter_fetch_activity_data">Sincronizar</string>
|
||||||
<string name="controlcenter_start_sleepmonitor">Monitor de sono (ALPHA)</string>
|
<string name="controlcenter_start_sleepmonitor">Monitor de sono (ALPHA)</string>
|
||||||
<string name="controlcenter_find_device">Buscando dispositivo perdido...</string>
|
<string name="controlcenter_find_device">Procurando dispositivo perdido...</string>
|
||||||
<string name="controlcenter_take_screenshot">Print da tela</string>
|
<string name="controlcenter_take_screenshot">Captura de ecrã</string>
|
||||||
<string name="controlcenter_disconnect">Desconectar</string>
|
<string name="controlcenter_disconnect">Desligar</string>
|
||||||
<string name="controlcenter_delete_device">Apagar dispositivo</string>
|
<string name="controlcenter_delete_device">Apagar dispositivo</string>
|
||||||
<string name="controlcenter_delete_device_name">Apagar %1$s</string>
|
<string name="controlcenter_delete_device_name">Apagar %1$s</string>
|
||||||
<string name="controlcenter_delete_device_dialogmessage">Isto irá apagar o dispositivo e apagar os dados associados!</string>
|
<string name="controlcenter_delete_device_dialogmessage">Isto irá apagar o dispositivo e apagar os dados associados!</string>
|
||||||
@ -20,29 +20,29 @@
|
|||||||
<string name="appmananger_app_delete">Apagar</string>
|
<string name="appmananger_app_delete">Apagar</string>
|
||||||
<string name="appmananger_app_delete_cache">Apagar e remover do cache</string>
|
<string name="appmananger_app_delete_cache">Apagar e remover do cache</string>
|
||||||
<string name="appmananger_app_reinstall">Reinstalar</string>
|
<string name="appmananger_app_reinstall">Reinstalar</string>
|
||||||
<string name="appmanager_app_openinstore">Buscar na loja Pebble</string>
|
<string name="appmanager_app_openinstore">Procurar na loja Pebble</string>
|
||||||
<string name="appmanager_health_activate">Ativar</string>
|
<string name="appmanager_health_activate">Ativar</string>
|
||||||
<string name="appmanager_health_deactivate">Desativar</string>
|
<string name="appmanager_health_deactivate">Desativar</string>
|
||||||
<string name="appmanager_hrm_activate">Ativar HRM</string>
|
<string name="appmanager_hrm_activate">Ativar HRM</string>
|
||||||
<string name="appmanager_hrm_deactivate">Desativar HRM</string>
|
<string name="appmanager_hrm_deactivate">Desativar HRM</string>
|
||||||
<string name="appmanager_weather_activate">Ativas app de clima do sistema</string>
|
<string name="appmanager_weather_activate">Ativar app de clima do sistema</string>
|
||||||
<string name="appmanager_weather_deactivate">Desativar app de clima do sistema</string>
|
<string name="appmanager_weather_deactivate">Desativar app de clima do sistema</string>
|
||||||
<string name="appmanager_weather_install_provider">Instalar notificações do app de clima</string>
|
<string name="appmanager_weather_install_provider">Instalar notificações do app de clima</string>
|
||||||
<string name="app_configure">Configurar</string>
|
<string name="app_configure">Configurar</string>
|
||||||
<string name="app_move_to_top">Mover para o topo</string>
|
<string name="app_move_to_top">Mover para o topo</string>
|
||||||
<!--Strings related to AppBlacklist-->
|
<!--Strings related to AppBlacklist-->
|
||||||
<string name="title_activity_appblacklist">Blacklist de notificações</string>
|
<string name="title_activity_appblacklist">Bloqueio de notificações</string>
|
||||||
<!--Strings related to FwAppInstaller-->
|
<!--Strings related to FwAppInstaller-->
|
||||||
<string name="title_activity_fw_app_insaller">Instalador FW/App</string>
|
<string name="title_activity_fw_app_insaller">Instalador FW/App</string>
|
||||||
<string name="fw_upgrade_notice">Você está prestes a instalar o firmware %s no lugar do atual em sua Mi Band.</string>
|
<string name="fw_upgrade_notice">Está prestes a instalar o firmware %s no lugar do atual na sua Mi Band.</string>
|
||||||
<string name="miband_firmware_known">O firmware foi testado e é compatível com Gadgetbridge.</string>
|
<string name="miband_firmware_known">O firmware foi testado e é compatível com o Gadgetbridge.</string>
|
||||||
<!--Strings related to Settings-->
|
<!--Strings related to Settings-->
|
||||||
<string name="title_activity_settings">Configurações</string>
|
<string name="title_activity_settings">Configurações</string>
|
||||||
<string name="pref_header_general">Configurações Gerais</string>
|
<string name="pref_header_general">Configurações Gerais</string>
|
||||||
<string name="pref_title_general_autoconnectonbluetooth">Conecte o dispositivo com o ligar o Bluetooth</string>
|
<string name="pref_title_general_autoconnectonbluetooth">Ligar ao dispositivo ao ativar o Bluetooth</string>
|
||||||
<string name="pref_title_general_autostartonboot">Iniciar automaticamente</string>
|
<string name="pref_title_general_autostartonboot">Iniciar automaticamente</string>
|
||||||
<string name="pref_title_general_autocreonnect">Reconectar automaticamente</string>
|
<string name="pref_title_general_autocreonnect">Religar automaticamente</string>
|
||||||
<string name="pref_title_audo_player">Player de música preferencial</string>
|
<string name="pref_title_audo_player">Aplicação de música preferencial</string>
|
||||||
<string name="pref_default">Padrão</string>
|
<string name="pref_default">Padrão</string>
|
||||||
<string name="pref_header_datetime">Data e Hora</string>
|
<string name="pref_header_datetime">Data e Hora</string>
|
||||||
<string name="pref_title_datetime_syctimeonconnect">Sincronizar hora</string>
|
<string name="pref_title_datetime_syctimeonconnect">Sincronizar hora</string>
|
||||||
@ -51,33 +51,33 @@
|
|||||||
<string name="pref_theme_dark">Escuro</string>
|
<string name="pref_theme_dark">Escuro</string>
|
||||||
<string name="pref_title_language">Idioma</string>
|
<string name="pref_title_language">Idioma</string>
|
||||||
<string name="pref_title_minimize_priority">Ocultar notificações do Gadgetbridge</string>
|
<string name="pref_title_minimize_priority">Ocultar notificações do Gadgetbridge</string>
|
||||||
<string name="pref_summary_minimize_priority_off">Exibir ícone na barra de status e nas notificações na tela inicial</string>
|
<string name="pref_summary_minimize_priority_off">Exibir ícone na barra de status e nas notificações no ecrã inicial</string>
|
||||||
<string name="pref_summary_minimize_priority_on">Ocultar ícone na barra de status e nas notificações na tela inicial</string>
|
<string name="pref_summary_minimize_priority_on">Ocultar ícone na barra de status e nas notificações no ecrã inicial</string>
|
||||||
<string name="pref_header_notifications">Notificações</string>
|
<string name="pref_header_notifications">Notificações</string>
|
||||||
<string name="pref_title_notifications_repetitions">Repetições</string>
|
<string name="pref_title_notifications_repetitions">Repetições</string>
|
||||||
<string name="pref_title_notifications_call">Chamadas de telefone</string>
|
<string name="pref_title_notifications_call">Chamadas telefónicas</string>
|
||||||
<string name="pref_title_notifications_sms">SMS</string>
|
<string name="pref_title_notifications_sms">SMS</string>
|
||||||
<string name="pref_title_notifications_pebblemsg">Mensagens do Pebble</string>
|
<string name="pref_title_notifications_pebblemsg">Mensagens do Pebble</string>
|
||||||
<string name="pref_summary_notifications_pebblemsg">Suportar notificações de aplicações que enviam notificações pelo PebbleKit.</string>
|
<string name="pref_summary_notifications_pebblemsg">Suportar notificações de aplicações que enviam notificações pelo PebbleKit.</string>
|
||||||
<string name="pref_title_notifications_generic">Suportar notificações genéricas</string>
|
<string name="pref_title_notifications_generic">Suportar notificações genéricas</string>
|
||||||
<string name="pref_title_whenscreenon">... e quando a tela estiver ligada</string>
|
<string name="pref_title_whenscreenon">... e quando o ecrã estiver ligado</string>
|
||||||
<string name="pref_title_notification_filter">Não perturbe</string>
|
<string name="pref_title_notification_filter">Não perturbe</string>
|
||||||
<string name="pref_summary_notification_filter">Parar com notificações indesejadas enquanto estiver no modo Não Perturbe.</string>
|
<string name="pref_summary_notification_filter">Ignorar notificações indesejadas enquanto estiver no modo Não Perturbe.</string>
|
||||||
<string name="always">sempre</string>
|
<string name="always">sempre</string>
|
||||||
<string name="when_screen_off">quando a tela estiver desligada</string>
|
<string name="when_screen_off">quando o ecrã estiver desligado</string>
|
||||||
<string name="never">nunca</string>
|
<string name="never">nunca</string>
|
||||||
<string name="pref_header_privacy">Privacidade</string>
|
<string name="pref_header_privacy">Privacidade</string>
|
||||||
<string name="pref_title_call_privacy_mode">Modo de chamada privada</string>
|
<string name="pref_title_call_privacy_mode">Modo de chamada privada</string>
|
||||||
<string name="pref_call_privacy_mode_off">Exibir nome e número</string>
|
<string name="pref_call_privacy_mode_off">Exibir nome e número</string>
|
||||||
<string name="pref_call_privacy_mode_name">Ocultar nome e exibir número</string>
|
<string name="pref_call_privacy_mode_name">Ocultar nome e exibir número</string>
|
||||||
<string name="pref_call_privacy_mode_complete">Ocultar nome e número</string>
|
<string name="pref_call_privacy_mode_complete">Ocultar nome e número</string>
|
||||||
<string name="pref_blacklist">Apps em Blacklist</string>
|
<string name="pref_blacklist">Aplicações ignoradas</string>
|
||||||
<string name="pref_header_cannned_messages">Histórico de mensagens</string>
|
<string name="pref_header_cannned_messages">Histórico de mensagens</string>
|
||||||
<string name="pref_title_canned_replies">Respostas</string>
|
<string name="pref_title_canned_replies">Respostas</string>
|
||||||
<string name="pref_title_canned_reply_suffix">Sufixo comum</string>
|
<string name="pref_title_canned_reply_suffix">Sufixo comum</string>
|
||||||
<string name="pref_title_canned_messages_dismisscall">Chamadas recusadas</string>
|
<string name="pref_title_canned_messages_dismisscall">Chamadas recusadas</string>
|
||||||
<string name="pref_title_canned_messages_set">Atualizar no Pebble</string>
|
<string name="pref_title_canned_messages_set">Atualizar no Pebble</string>
|
||||||
<string name="pref_header_development">Opções do desenvolvedor</string>
|
<string name="pref_header_development">Opções do programador</string>
|
||||||
<string name="pref_title_development_miaddr">Endereço do Mi Band</string>
|
<string name="pref_title_development_miaddr">Endereço do Mi Band</string>
|
||||||
<string name="pref_title_pebble_settings">Configurações Pebble</string>
|
<string name="pref_title_pebble_settings">Configurações Pebble</string>
|
||||||
<string name="pref_header_activitytrackers">Ativar monitores</string>
|
<string name="pref_header_activitytrackers">Ativar monitores</string>
|
||||||
@ -85,48 +85,48 @@
|
|||||||
<string name="pref_title_pebble_sync_health">Sincronizar com Pebble Health</string>
|
<string name="pref_title_pebble_sync_health">Sincronizar com Pebble Health</string>
|
||||||
<string name="pref_title_pebble_sync_misfit">Sincronizar com Misfit</string>
|
<string name="pref_title_pebble_sync_misfit">Sincronizar com Misfit</string>
|
||||||
<string name="pref_title_pebble_sync_morpheuz">Sincronizar com Morpheuz</string>
|
<string name="pref_title_pebble_sync_morpheuz">Sincronizar com Morpheuz</string>
|
||||||
<string name="pref_summary_enable_pebblekit">Habilitar suporte experimental ao App Android que use PebbleKit</string>
|
<string name="pref_summary_enable_pebblekit">Ativar suporte experimental a Apps Android que usem PebbleKit</string>
|
||||||
<string name="pref_title_sunrise_sunset">Despertar e pôr do sol</string>
|
<string name="pref_title_sunrise_sunset">Despertar e pôr do sol</string>
|
||||||
<string name="pref_summary_sunrise_sunset">Enviar despertar e pôr do sol baseado na localização do pebble</string>
|
<string name="pref_summary_sunrise_sunset">Enviar despertar e pôr do sol com base na localização do pebble</string>
|
||||||
<string name="pref_title_autoremove_notifications">Auto remover notificações rejeitadas</string>
|
<string name="pref_title_autoremove_notifications">Auto remover notificações rejeitadas</string>
|
||||||
<string name="pref_summary_autoremove_notifications">Notificações são automaticamente removidas quando rejeitadas no Android</string>
|
<string name="pref_summary_autoremove_notifications">Notificações são automaticamente removidas quando rejeitadas no Android</string>
|
||||||
<string name="pref_title_pebble_privacy_mode">Modo de privacidade</string>
|
<string name="pref_title_pebble_privacy_mode">Modo de privacidade</string>
|
||||||
<string name="pref_pebble_privacy_mode_off">Notificações</string>
|
<string name="pref_pebble_privacy_mode_off">Notificações</string>
|
||||||
<string name="pref_pebble_privacy_mode_content">Deslocar texto de notificações que extrapolar a tela </string>
|
<string name="pref_pebble_privacy_mode_content">Deslocar texto de notificações que extravasar o ecrã </string>
|
||||||
<string name="pref_pebble_privacy_mode_complete">Apenas mostrar ícone de notificações</string>
|
<string name="pref_pebble_privacy_mode_complete">Apenas mostrar ícone de notificações</string>
|
||||||
<string name="pref_header_location">Localização</string>
|
<string name="pref_header_location">Localização</string>
|
||||||
<string name="pref_title_location_aquire">Obter localização</string>
|
<string name="pref_title_location_aquire">Obter localização</string>
|
||||||
<string name="pref_title_location_latitude">Latitude</string>
|
<string name="pref_title_location_latitude">Latitude</string>
|
||||||
<string name="pref_title_location_longitude">Longitude</string>
|
<string name="pref_title_location_longitude">Longitude</string>
|
||||||
<string name="pref_title_location_keep_uptodate">Mantenha a localização atualizada</string>
|
<string name="pref_title_location_keep_uptodate">Mantenha a localização atualizada</string>
|
||||||
<string name="pref_summary_location_keep_uptodate">Tente obter a localização online, use dados armazenados como fallback</string>
|
<string name="pref_summary_location_keep_uptodate">Tente obter a localização online, use dados armazenados como alternativa</string>
|
||||||
<string name="toast_enable_networklocationprovider">Por favor, habilite localização de rede</string>
|
<string name="toast_enable_networklocationprovider">Por favor, ative a localização de rede</string>
|
||||||
<string name="toast_aqurired_networklocation">localização obtida</string>
|
<string name="toast_aqurired_networklocation">localização obtida</string>
|
||||||
<string name="pref_title_pebble_forceprotocol">Forçar o protocolo de notificação</string>
|
<string name="pref_title_pebble_forceprotocol">Forçar o protocolo de notificação</string>
|
||||||
<string name="pref_summary_pebble_forceprotocol">Esta opção força o uso do protocolo de notificação mais recente. HABILITE APENAS SE SABE O QUE ESTÁ FAZENDO!</string>
|
<string name="pref_summary_pebble_forceprotocol">Esta opção força o uso do protocolo de notificação mais recente. APENAS ATIVE SE SOUBER O QUE ESTÁ A FAZER!</string>
|
||||||
<string name="pref_title_pebble_forceuntested">Habilitar recursos não certificados</string>
|
<string name="pref_title_pebble_forceuntested">Permitir recursos não certificados</string>
|
||||||
<string name="pref_summary_pebble_forceuntested">Habilitar recursos não certificados. FAÇA ISSO SE SOUBER O QUE REALMENTE ESTÁ FAZENDO!</string>
|
<string name="pref_summary_pebble_forceuntested">Permitir recursos não certificados. APENAS ATIVE SE SOUBER O QUE ESTÁ A FAZER!</string>
|
||||||
<string name="pref_title_pebble_forcele">Sempre preferir BLE</string>
|
<string name="pref_title_pebble_forcele">Preferir sempre BLE</string>
|
||||||
<string name="pref_title_unit_system">Unidades</string>
|
<string name="pref_title_unit_system">Unidades</string>
|
||||||
<string name="pref_title_timeformat">Formato da hora</string>
|
<string name="pref_title_timeformat">Formato da hora</string>
|
||||||
<string name="pref_title_screentime">Duração de tela</string>
|
<string name="pref_title_screentime">Duração do ecrã</string>
|
||||||
<string name="not_connected">desconectado</string>
|
<string name="not_connected">desligado</string>
|
||||||
<string name="connecting">conectando</string>
|
<string name="connecting">a ligar</string>
|
||||||
<string name="connected">conectado</string>
|
<string name="connected">ligado</string>
|
||||||
<string name="unknown_state">estado desconhecido</string>
|
<string name="unknown_state">estado desconhecido</string>
|
||||||
<string name="test">Teste</string>
|
<string name="test">Teste</string>
|
||||||
<string name="test_notification">Teste de notificação</string>
|
<string name="test_notification">Teste de notificações</string>
|
||||||
<string name="bluetooth_is_not_supported_">Bluetooth não suportado</string>
|
<string name="bluetooth_is_not_supported_">Bluetooth não suportado</string>
|
||||||
<string name="bluetooth_is_disabled_">Bluetooth desabilitado</string>
|
<string name="bluetooth_is_disabled_">Bluetooth desligado</string>
|
||||||
<string name="installation_failed_">falha na instalação!</string>
|
<string name="installation_failed_">falha na instalação!</string>
|
||||||
<string name="installation_successful">instalação bem sucedida</string>
|
<string name="installation_successful">instalação bem sucedida</string>
|
||||||
<string name="initialized">inicializado</string>
|
<string name="initialized">inicializado</string>
|
||||||
<string name="title_activity_discovery">Dispositivo encontrado</string>
|
<string name="title_activity_discovery">Dispositivo encontrado</string>
|
||||||
<string name="discovery_stop_scanning">Parar com a busca</string>
|
<string name="discovery_stop_scanning">Terminar a procura</string>
|
||||||
<string name="discovery_start_scanning">Iniciar busca</string>
|
<string name="discovery_start_scanning">Iniciar a procura</string>
|
||||||
<string name="action_discover">Conecte novo dispositivo</string>
|
<string name="action_discover">Ligue o novo dispositivo</string>
|
||||||
<string name="title_activity_android_pairing">Parear dispositivo</string>
|
<string name="title_activity_android_pairing">Emparelhar dispositivo</string>
|
||||||
<string name="pairing">Pareando com %s...</string>
|
<string name="pairing">A emparelhar com %s...</string>
|
||||||
<string name="male">masculino</string>
|
<string name="male">masculino</string>
|
||||||
<string name="female">feminino</string>
|
<string name="female">feminino</string>
|
||||||
<string name="other">outro</string>
|
<string name="other">outro</string>
|
||||||
@ -137,7 +137,7 @@
|
|||||||
<string name="miband_prefs_alias">Nome/Apelido</string>
|
<string name="miband_prefs_alias">Nome/Apelido</string>
|
||||||
<string name="pref_header_vibration_count">Quantidade de vibrações</string>
|
<string name="pref_header_vibration_count">Quantidade de vibrações</string>
|
||||||
<string name="title_activity_sleepmonitor">Monitor de sono</string>
|
<string name="title_activity_sleepmonitor">Monitor de sono</string>
|
||||||
<string name="pref_write_logfiles">Escrever arquivos de Log</string>
|
<string name="pref_write_logfiles">Escrever arquivos de registo</string>
|
||||||
<string name="initializing">Inicializando</string>
|
<string name="initializing">Inicializando</string>
|
||||||
<string name="vibration_profile_short">Pequeno</string>
|
<string name="vibration_profile_short">Pequeno</string>
|
||||||
<string name="vibration_profile_medium">Médio</string>
|
<string name="vibration_profile_medium">Médio</string>
|
||||||
@ -150,10 +150,10 @@
|
|||||||
<string name="pref_screen_notification_profile_generic">Notificação genérica</string>
|
<string name="pref_screen_notification_profile_generic">Notificação genérica</string>
|
||||||
<string name="pref_screen_notification_profile_email">Notificação de email</string>
|
<string name="pref_screen_notification_profile_email">Notificação de email</string>
|
||||||
<string name="pref_screen_notification_profile_incoming_call">Notificações de chamadas</string>
|
<string name="pref_screen_notification_profile_incoming_call">Notificações de chamadas</string>
|
||||||
<string name="pref_screen_notification_profile_generic_chat">Bate papo</string>
|
<string name="pref_screen_notification_profile_generic_chat">Conversas</string>
|
||||||
<string name="pref_screen_notification_profile_generic_navigation">Navegação</string>
|
<string name="pref_screen_notification_profile_generic_navigation">Navegação</string>
|
||||||
<string name="pref_screen_notification_profile_generic_social">Rede social</string>
|
<string name="pref_screen_notification_profile_generic_social">Rede social</string>
|
||||||
<string name="title_activity_charts">Sua atividade</string>
|
<string name="title_activity_charts">A sua atividade</string>
|
||||||
<string name="title_activity_set_alarm">Configurar Alarmes</string>
|
<string name="title_activity_set_alarm">Configurar Alarmes</string>
|
||||||
<string name="controlcenter_start_configure_alarms">Configurar alarmes</string>
|
<string name="controlcenter_start_configure_alarms">Configurar alarmes</string>
|
||||||
<string name="title_activity_alarm_details">Detalhes do alarme</string>
|
<string name="title_activity_alarm_details">Detalhes do alarme</string>
|
||||||
@ -165,16 +165,16 @@
|
|||||||
<string name="alarm_fri_short">Sex</string>
|
<string name="alarm_fri_short">Sex</string>
|
||||||
<string name="alarm_sat_short">Sab</string>
|
<string name="alarm_sat_short">Sab</string>
|
||||||
<string name="alarm_smart_wakeup">despertar inteligente</string>
|
<string name="alarm_smart_wakeup">despertar inteligente</string>
|
||||||
<string name="user_feedback_miband_set_alarms_failed">Tem algum erro ao definir o alarme, tente novamente!</string>
|
<string name="user_feedback_miband_set_alarms_failed">Existiu um erro ao definir o alarme, tente novamente!</string>
|
||||||
<string name="user_feedback_miband_set_alarms_ok">Alarme enviado para o dispositivo!</string>
|
<string name="user_feedback_miband_set_alarms_ok">Alarme enviado para o dispositivo!</string>
|
||||||
<string name="chart_no_data_synchronize">Sem data. Sincronizar com dispositivo?</string>
|
<string name="chart_no_data_synchronize">Sem data. Sincronizar com o dispositivo?</string>
|
||||||
<string name="miband_prefs_fitness_goal">Objetivo de passos por dia</string>
|
<string name="miband_prefs_fitness_goal">Objetivo de passos por dia</string>
|
||||||
<string name="controlcenter_start_activitymonitor">Sua Atividade (ALPHA)</string>
|
<string name="controlcenter_start_activitymonitor">A Sua Atividade (ALPHA)</string>
|
||||||
<string name="installer_activity_unable_to_find_handler">Não foi possível encontrar um manipulador para instalar o arquivo.</string>
|
<string name="installer_activity_unable_to_find_handler">Não foi possível encontrar um manipulador para instalar o arquivo.</string>
|
||||||
<string name="notif_battery_low_title">Gadget com bateria baixa!</string>
|
<string name="notif_battery_low_title">Dispositivo com bateria baixa!</string>
|
||||||
<string name="sleepchart_your_sleep">Seu Sono</string>
|
<string name="sleepchart_your_sleep">O Seu Sono</string>
|
||||||
<string name="weekstepschart_steps_a_week">Passos na semana</string>
|
<string name="weekstepschart_steps_a_week">Passos na semana</string>
|
||||||
<string name="activity_sleepchart_activity_and_sleep">Sua Atividade e Sono</string>
|
<string name="activity_sleepchart_activity_and_sleep">A Sua Atividade e Sono</string>
|
||||||
<string name="updating_firmware">Atualizando Firmware...</string>
|
<string name="updating_firmware">Atualizando Firmware...</string>
|
||||||
<string name="fwapp_install_device_not_ready">Arquivo não pode ser instalado, o dispositivo não está pronto.</string>
|
<string name="fwapp_install_device_not_ready">Arquivo não pode ser instalado, o dispositivo não está pronto.</string>
|
||||||
<string name="miband_fwinstaller_compatible_version">Versão compatível</string>
|
<string name="miband_fwinstaller_compatible_version">Versão compatível</string>
|
||||||
@ -184,44 +184,44 @@
|
|||||||
<string name="updatefirmwareoperation_update_complete_rebooting">Instalação do Firmware completa, reiniciando o dispositivo...</string>
|
<string name="updatefirmwareoperation_update_complete_rebooting">Instalação do Firmware completa, reiniciando o dispositivo...</string>
|
||||||
<string name="updatefirmwareoperation_write_failed">Falha ao instalar o Firmware</string>
|
<string name="updatefirmwareoperation_write_failed">Falha ao instalar o Firmware</string>
|
||||||
<string name="chart_steps">Passos</string>
|
<string name="chart_steps">Passos</string>
|
||||||
<string name="liveactivity_live_activity">Atividade ao vivo</string>
|
<string name="liveactivity_live_activity">Atividade em Tempo Real</string>
|
||||||
<string name="live_activity_steps_history">Histórico de passos</string>
|
<string name="live_activity_steps_history">Histórico de passos</string>
|
||||||
<string name="live_activity_current_steps_per_minute">Passos/min atuais</string>
|
<string name="live_activity_current_steps_per_minute">Passos/min atuais</string>
|
||||||
<string name="live_activity_total_steps">Total de passos</string>
|
<string name="live_activity_total_steps">Total de passos</string>
|
||||||
<string name="live_activity_steps_per_minute_history">Histórico de passos por minuto</string>
|
<string name="live_activity_steps_per_minute_history">Histórico de passos por minuto</string>
|
||||||
<string name="live_activity_start_your_activity">Iniciar sua atividade</string>
|
<string name="live_activity_start_your_activity">Iniciar a sua atividade</string>
|
||||||
<string name="abstract_chart_fragment_kind_activity">Atividade</string>
|
<string name="abstract_chart_fragment_kind_activity">Atividade</string>
|
||||||
<string name="abstract_chart_fragment_kind_light_sleep">Sono leve</string>
|
<string name="abstract_chart_fragment_kind_light_sleep">Sono leve</string>
|
||||||
<string name="abstract_chart_fragment_kind_deep_sleep">Sono pesado</string>
|
<string name="abstract_chart_fragment_kind_deep_sleep">Sono profundo</string>
|
||||||
<string name="abstract_chart_fragment_kind_not_worn">Não utilizado</string>
|
<string name="abstract_chart_fragment_kind_not_worn">Não utilizado</string>
|
||||||
<string name="device_not_connected">Desconectado.</string>
|
<string name="device_not_connected">Desligado.</string>
|
||||||
<string name="user_feedback_all_alarms_disabled">Todos os alarmes desabilitados</string>
|
<string name="user_feedback_all_alarms_disabled">Todos os alarmes desligados</string>
|
||||||
<string name="pref_title_keep_data_on_device">Manter dados de atividade no dispositivo</string>
|
<string name="pref_title_keep_data_on_device">Manter dados de atividade no dispositivo</string>
|
||||||
<string name="miband_fwinstaller_incompatible_version">Firmware incompatível</string>
|
<string name="miband_fwinstaller_incompatible_version">Firmware incompatível</string>
|
||||||
<string name="fwinstaller_firmware_not_compatible_to_device">Este firmware não é compatível com seu dispositivo</string>
|
<string name="fwinstaller_firmware_not_compatible_to_device">Este firmware não é compatível com seu dispositivo</string>
|
||||||
<string name="miband_prefs_reserve_alarm_calendar">Alarmes reservados para eventos próximos</string>
|
<string name="miband_prefs_reserve_alarm_calendar">Alarmes reservados para eventos próximos</string>
|
||||||
<string name="dateformat_time">Hora</string>
|
<string name="dateformat_time">Hora</string>
|
||||||
<string name="waiting_for_reconnect">aguarde para reconectar</string>
|
<string name="waiting_for_reconnect">aguarde para tornar a ligar</string>
|
||||||
<string name="activity_prefs_about_you">Sobre você</string>
|
<string name="activity_prefs_about_you">Sobre você</string>
|
||||||
<string name="activity_prefs_year_birth">Ano de anoversário</string>
|
<string name="activity_prefs_year_birth">Ano de nascimento</string>
|
||||||
<string name="activity_prefs_gender">Gênero</string>
|
<string name="activity_prefs_gender">Género</string>
|
||||||
<string name="activity_prefs_height_cm">Altura em cm</string>
|
<string name="activity_prefs_height_cm">Altura em cm</string>
|
||||||
<string name="activity_prefs_weight_kg">Peso em kg</string>
|
<string name="activity_prefs_weight_kg">Peso em kg</string>
|
||||||
<string name="authenticating">autenticando</string>
|
<string name="authenticating">a autenticar</string>
|
||||||
<string name="authentication_required">autenticação requerida</string>
|
<string name="authentication_required">autenticação necessária</string>
|
||||||
<string name="add_widget">Adicionar widget</string>
|
<string name="add_widget">Adicionar widget</string>
|
||||||
<string name="activity_prefs_sleep_duration">Preferir duração de sono em horas</string>
|
<string name="activity_prefs_sleep_duration">Preferir duração do sono em horas</string>
|
||||||
<string name="updatefirmwareoperation_update_in_progress">Atualização de Firmware em progresso</string>
|
<string name="updatefirmwareoperation_update_in_progress">Atualização de Firmware em curso</string>
|
||||||
<string name="updatefirmwareoperation_firmware_not_sent">Firmware não enviado</string>
|
<string name="updatefirmwareoperation_firmware_not_sent">Firmware não enviado</string>
|
||||||
<string name="dbmanagementactivity_import_data_title">Importar dados?</string>
|
<string name="dbmanagementactivity_import_data_title">Importar dados?</string>
|
||||||
<string name="dbmanagementactivity_import_successful">Sucesso ao importar.</string>
|
<string name="dbmanagementactivity_import_successful">Dados importados com sucesso.</string>
|
||||||
<string name="dbmanagementactivity_overwrite">Sobrepor</string>
|
<string name="dbmanagementactivity_overwrite">Escrever por cima</string>
|
||||||
<string name="Cancel">Cancelar</string>
|
<string name="Cancel">Cancelar</string>
|
||||||
<string name="Delete">Apagar</string>
|
<string name="Delete">Apagar</string>
|
||||||
<!--Strings related to Vibration Activity-->
|
<!--Strings related to Vibration Activity-->
|
||||||
<string name="title_activity_vibration">Vibração</string>
|
<string name="title_activity_vibration">Vibração</string>
|
||||||
<!--Strings related to Pebble Pairing Activity-->
|
<!--Strings related to Pebble Pairing Activity-->
|
||||||
<string name="title_activity_pebble_pairing">Pareando Pebble</string>
|
<string name="title_activity_pebble_pairing">A emparelhar Pebble</string>
|
||||||
<string name="unit_metric">Métrico</string>
|
<string name="unit_metric">Métrico</string>
|
||||||
<string name="unit_imperial">Imperial</string>
|
<string name="unit_imperial">Imperial</string>
|
||||||
<string name="pref_screen_notification_profile_alarm_clock">Alarme</string>
|
<string name="pref_screen_notification_profile_alarm_clock">Alarme</string>
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<style name="GadgetbridgeTheme.NoActionBar">
|
|
||||||
<item name="windowActionBar">false</item>
|
|
||||||
<item name="windowNoTitle">true</item>
|
|
||||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
|
||||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
@ -1,5 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
<attr name="textColorPrimary" format="color" />
|
||||||
|
<attr name="textColorSecondary" format="color" />
|
||||||
|
<attr name="textColorTertiary" format="color" />
|
||||||
|
|
||||||
<attr name="chart_deep_sleep" format="color" />
|
<attr name="chart_deep_sleep" format="color" />
|
||||||
<attr name="chart_light_sleep" format="color" />
|
<attr name="chart_light_sleep" format="color" />
|
||||||
<attr name="chart_activity" format="color" />
|
<attr name="chart_activity" format="color" />
|
||||||
|
@ -7,11 +7,14 @@
|
|||||||
<color name="primarydark_dark" type="color">#f0f03000</color>
|
<color name="primarydark_dark" type="color">#f0f03000</color>
|
||||||
|
|
||||||
<color name="accent" type="color">#0091ea</color>
|
<color name="accent" type="color">#0091ea</color>
|
||||||
|
|
||||||
<color name="primarytext_light" type="color">#000000</color>
|
<color name="primarytext_light" type="color">#000000</color>
|
||||||
<color name="primarytext_dark" type="color">#ffffff</color>
|
<color name="primarytext_dark" type="color">#ffffff</color>
|
||||||
|
|
||||||
<color name="secondarytext" type="color">#ff808080</color>
|
<color name="secondarytext" type="color">#ff808080</color>
|
||||||
<color name="tertiarytext_light" type="color">#ffd0d0d0</color>
|
<color name="tertiarytext_light" type="color">#ffd0d0d0</color>
|
||||||
<color name="tertiarytext_dark" type="color">#ff606060</color>
|
<color name="tertiarytext_dark" type="color">#ff606060</color>
|
||||||
|
|
||||||
<color name="divider" type="color">#1f000000</color>
|
<color name="divider" type="color">#1f000000</color>
|
||||||
|
|
||||||
<color name="chart_heartrate" type="color">#ffab40</color>
|
<color name="chart_heartrate" type="color">#ffab40</color>
|
||||||
|
@ -306,6 +306,8 @@
|
|||||||
<string name="updatefirmwareoperation_update_complete_rebooting">Firmware installation complete, rebooting device…</string>
|
<string name="updatefirmwareoperation_update_complete_rebooting">Firmware installation complete, rebooting device…</string>
|
||||||
<string name="updatefirmwareoperation_write_failed">Firmware write failed</string>
|
<string name="updatefirmwareoperation_write_failed">Firmware write failed</string>
|
||||||
<string name="chart_steps">Steps</string>
|
<string name="chart_steps">Steps</string>
|
||||||
|
<string name="calories">Calories</string>
|
||||||
|
<string name="distance">Distance</string>
|
||||||
<string name="liveactivity_live_activity">Live Activity</string>
|
<string name="liveactivity_live_activity">Live Activity</string>
|
||||||
<string name="weeksteps_today_steps_description">Steps today, target: %1$s</string>
|
<string name="weeksteps_today_steps_description">Steps today, target: %1$s</string>
|
||||||
<string name="pref_title_dont_ack_transfer">Do not ack activity data transfer</string>
|
<string name="pref_title_dont_ack_transfer">Do not ack activity data transfer</string>
|
||||||
@ -370,10 +372,12 @@
|
|||||||
<string name="dbmanagementactivvity_cannot_access_export_path">Cannot access export path. Please contact the developers.</string>
|
<string name="dbmanagementactivvity_cannot_access_export_path">Cannot access export path. Please contact the developers.</string>
|
||||||
<string name="dbmanagementactivity_exported_to">Exported to: %1$s</string>
|
<string name="dbmanagementactivity_exported_to">Exported to: %1$s</string>
|
||||||
<string name="dbmanagementactivity_error_exporting_db">"Error exporting DB: %1$s"</string>
|
<string name="dbmanagementactivity_error_exporting_db">"Error exporting DB: %1$s"</string>
|
||||||
|
<string name="dbmanagementactivity_error_exporting_shared">"Error exporting preference: %1$s"</string>
|
||||||
<string name="dbmanagementactivity_import_data_title">Import Data?</string>
|
<string name="dbmanagementactivity_import_data_title">Import Data?</string>
|
||||||
<string name="dbmanagementactivity_overwrite_database_confirmation">Really overwrite the current database? All your current activity data (if any) will be lost.</string>
|
<string name="dbmanagementactivity_overwrite_database_confirmation">Really overwrite the current database? All your current activity data (if any) will be lost.</string>
|
||||||
<string name="dbmanagementactivity_import_successful">Import successful.</string>
|
<string name="dbmanagementactivity_import_successful">Import successful.</string>
|
||||||
<string name="dbmanagementactivity_error_importing_db">"Error importing DB: %1$s"</string>
|
<string name="dbmanagementactivity_error_importing_db">"Error importing DB: %1$s"</string>
|
||||||
|
<string name="dbmanagementactivity_error_importing_shared">"Error importing preference: %1$s"</string>
|
||||||
<string name="dbmanagementactivity_delete_activity_data_title">Delete Activity Data?</string>
|
<string name="dbmanagementactivity_delete_activity_data_title">Delete Activity Data?</string>
|
||||||
<string name="dbmanagementactivity_really_delete_entire_db">Really delete the entire database? All your activity data and information about your devices will be lost.</string>
|
<string name="dbmanagementactivity_really_delete_entire_db">Really delete the entire database? All your activity data and information about your devices will be lost.</string>
|
||||||
<string name="dbmanagementactivity_database_successfully_deleted">Data successfully deleted.</string>
|
<string name="dbmanagementactivity_database_successfully_deleted">Data successfully deleted.</string>
|
||||||
@ -413,4 +417,13 @@
|
|||||||
<string name="mi2_enable_text_notifications">Text notifications</string>
|
<string name="mi2_enable_text_notifications">Text notifications</string>
|
||||||
<string name="mi2_enable_text_notifications_summary"><![CDATA[Needs firmware >= 1.0.1.28 and Mili_pro.ft* installed.]]></string>
|
<string name="mi2_enable_text_notifications_summary"><![CDATA[Needs firmware >= 1.0.1.28 and Mili_pro.ft* installed.]]></string>
|
||||||
<string name="off">off</string>
|
<string name="off">off</string>
|
||||||
|
<string name="discovery_attempting_to_pair">Attempting to pair with %1$s</string>
|
||||||
|
<string name="discovery_bonding_failed_immediately">Bonding with %1$s failed immediately.</string>
|
||||||
|
<string name="discovery_trying_to_connect_to">Trying to connect to: %1$s</string>
|
||||||
|
<string name="discovery_enable_bluetooth">Enable Bluetooth to discover devices.</string>
|
||||||
|
<string name="discovery_successfully_bonded">Successfully bonded with %1$s.</string>
|
||||||
|
<string name="discovery_pair_title">Pair with %1$s?</string>
|
||||||
|
<string name="discovery_pair_question">Select Pair to pair your devices. If this fails, try again without pairing.</string>
|
||||||
|
<string name="discovery_yes_pair">Pair</string>
|
||||||
|
<string name="discovery_dont_pair">Don\'t Pair</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="GadgetbridgeTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
<style name="GadgetbridgeTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
<item name="android:textColorPrimary">@color/primarytext_light</item>
|
<item name="textColorPrimary">@color/primarytext_light</item>
|
||||||
<item name="android:textColorSecondary">@color/secondarytext</item>
|
<item name="textColorSecondary">@color/secondarytext</item>
|
||||||
|
<item name="textColorTertiary">@color/tertiarytext_light</item>
|
||||||
|
|
||||||
<item name="colorPrimary">@color/primary_light</item>
|
<item name="colorPrimary">@color/primary_light</item>
|
||||||
<item name="colorPrimaryDark">@color/primarydark_light</item>
|
<item name="colorPrimaryDark">@color/primarydark_light</item>
|
||||||
<item name="android:textColorTertiary">@color/tertiarytext_light</item>
|
|
||||||
<item name="colorAccent">@color/accent</item>
|
<item name="colorAccent">@color/accent</item>
|
||||||
|
|
||||||
<item name="chart_deep_sleep">@color/chart_deep_sleep_light</item>
|
<item name="chart_deep_sleep">@color/chart_deep_sleep_light</item>
|
||||||
@ -21,11 +22,12 @@
|
|||||||
|
|
||||||
<!-- dark theme -->
|
<!-- dark theme -->
|
||||||
<style name="GadgetbridgeThemeDark" parent="Theme.AppCompat">
|
<style name="GadgetbridgeThemeDark" parent="Theme.AppCompat">
|
||||||
<item name="android:textColorPrimary">@color/primarytext_dark</item>
|
<item name="textColorPrimary">@color/primarytext_dark</item>
|
||||||
<item name="android:textColorSecondary">@color/secondarytext</item>
|
<item name="textColorSecondary">@color/secondarytext</item>
|
||||||
|
<item name="textColorTertiary">@color/tertiarytext_dark</item>
|
||||||
|
|
||||||
<item name="colorPrimary">@color/primary_dark</item>
|
<item name="colorPrimary">@color/primary_dark</item>
|
||||||
<item name="colorPrimaryDark">@color/primarydark_dark</item>
|
<item name="colorPrimaryDark">@color/primarydark_dark</item>
|
||||||
<item name="android:textColorTertiary">@color/tertiarytext_dark</item>
|
|
||||||
<item name="colorAccent">@color/accent</item>
|
<item name="colorAccent">@color/accent</item>
|
||||||
|
|
||||||
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
|
<item name="chart_deep_sleep">@color/chart_deep_sleep_dark</item>
|
||||||
|
@ -1,5 +1,28 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<changelog>
|
<changelog>
|
||||||
|
<release version="next">
|
||||||
|
<change>Applied some material design guidelines to Charts and (pebble) app management
|
||||||
|
</change>
|
||||||
|
<change>Pebble: improve compatiblity with watchapp configuration pages</change>
|
||||||
|
</release>
|
||||||
|
|
||||||
|
<release version="0.18.4" versioncode="91">
|
||||||
|
<change>Mi Band 2: Display realtime steps in Live Activity</change>
|
||||||
|
<change>Mi Band: Attempt to recognize Mi Band model with hwVersion = 8</change>
|
||||||
|
<change>Make Buttons in the main activity easier to hit</change>
|
||||||
|
<change>Alarms activity improvements and fixes</change>
|
||||||
|
</release>
|
||||||
|
<release version="0.18.3" versioncode="90">
|
||||||
|
<change>Fix bug that caused the same value in weekly charts for every day on Android 6 and older</change>
|
||||||
|
</release>
|
||||||
|
<release version="0.18.2" versioncode="89">
|
||||||
|
<change>Mi2: Fix crash on "chat" or "social network" text notification (#603)</change>
|
||||||
|
</release>
|
||||||
|
<release version="0.18.1" versioncode="88">
|
||||||
|
<change>Pebble: Fix Firmware insstallation on Pebble Time Round (broken since 0.16.0)</change>
|
||||||
|
<change>Start VibrationActivity when using "find device" button with Vibratissimo</change>
|
||||||
|
<change>Support material fork of K9</change>
|
||||||
|
</release>
|
||||||
<release version="0.18.0" versioncode="87">
|
<release version="0.18.0" versioncode="87">
|
||||||
<change>All new GUI for the control center</change>
|
<change>All new GUI for the control center</change>
|
||||||
<change>Add Portuguese pt_PT and pt_BR translations</change>
|
<change>Add Portuguese pt_PT and pt_BR translations</change>
|
||||||
|
@ -8,6 +8,7 @@ import java.util.GregorianCalendar;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
classpath 'com.android.tools.build:gradle:2.3.1'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
Loading…
Reference in New Issue
Block a user