1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-18 06:37:47 +01:00

Rework the Daily Widget:

- make layout transparent rather then red, update the preview image
- move battery to top row to reduce size, add status indicators with icons
- add preference settings, to choose for which device this widget is
- data is no longer calculated for all devices but for a selected device
- add debug items to view and erase widget settings and registrations
  (debug items are intentionally not translatable yet)
This commit is contained in:
vanous 2020-12-07 22:13:49 +01:00
parent ec95766d1f
commit 502f689862
14 changed files with 657 additions and 98 deletions

View File

@ -528,6 +528,8 @@
android:label="@string/widget_listing_label"> android:label="@string/widget_listing_label">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
<action android:name="nodomain.freeyourgadget.gadgetbridge.WidgetClick" /> <action android:name="nodomain.freeyourgadget.gadgetbridge.WidgetClick" />
</intent-filter> </intent-filter>
@ -541,6 +543,13 @@
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:theme="@style/Theme.AppCompat.Light.Dialog" /> android:theme="@style/Theme.AppCompat.Light.Dialog" />
<activity android:name=".activities.WidgetConfigurationActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<activity <activity
android:name=".activities.ExternalPebbleJSActivity" android:name=".activities.ExternalPebbleJSActivity"
android:allowTaskReparenting="true" android:allowTaskReparenting="true"

View File

@ -11,11 +11,30 @@
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
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/>. */
/* Copyright (C) 2019-2020 Andreas Shimokawa, vanous
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.
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License 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/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge; package nodomain.freeyourgadget.gadgetbridge;
import android.annotation.SuppressLint;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider; import android.appwidget.AppWidgetProvider;
@ -24,6 +43,8 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.RemoteViews; import android.widget.RemoteViews;
import android.widget.Toast; import android.widget.Toast;
@ -32,40 +53,55 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.activities.WidgetAlarmsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.WidgetAlarmsActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals; import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils; import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.WidgetPreferenceStorage;
public class Widget extends AppWidgetProvider { public class Widget extends AppWidgetProvider {
public static final String WIDGET_CLICK = "nodomain.freeyourgadget.gadgetbridge.WidgetClick"; public static final String WIDGET_CLICK = "nodomain.freeyourgadget.gadgetbridge.WidgetClick";
public static final String APPWIDGET_DELETED = "nodomain.freeyourgadget.gadgetbridge.APPWIDGET_DELETED"; public static final String APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
public static final String APPWIDGET_CONFIGURE = "nodomain.freeyourgadget.gadgetbridge.APPWIDGET_CONFIGURE";
private static final Logger LOG = LoggerFactory.getLogger(Widget.class); private static final Logger LOG = LoggerFactory.getLogger(Widget.class);
static BroadcastReceiver broadcastReceiver = null; static BroadcastReceiver broadcastReceiver = null;
GBDevice selectedDevice;
private GBDevice getSelectedDevice() { private GBDevice getSelectedDevice() {
Context context = GBApplication.getContext(); Context context = GBApplication.getContext();
if (!(context instanceof GBApplication)) { if (!(context instanceof GBApplication)) {
return null; return null;
} }
GBApplication gbApp = (GBApplication) context; GBApplication gbApp = (GBApplication) context;
return gbApp.getDeviceManager().getSelectedDevice(); return gbApp.getDeviceManager().getSelectedDevice();
} }
private GBDevice getDeviceByMAC(Context appContext, String HwAddress) {
GBApplication gbApp = (GBApplication) appContext;
List<? extends GBDevice> devices = gbApp.getDeviceManager().getDevices();
for (GBDevice device : devices) {
if (device.getAddress().equals(HwAddress)) {
return device;
}
}
return null;
}
private long[] getSteps() { private long[] getSteps() {
Context context = GBApplication.getContext(); Context context = GBApplication.getContext();
Calendar day = GregorianCalendar.getInstance(); Calendar day = GregorianCalendar.getInstance();
@ -74,7 +110,10 @@ public class Widget extends AppWidgetProvider {
return new long[]{0, 0, 0}; return new long[]{0, 0, 0};
} }
DailyTotals ds = new DailyTotals(); DailyTotals ds = new DailyTotals();
return ds.getDailyTotalsForAllDevices(day); return ds.getDailyTotalsForDevice(selectedDevice, day);
//return ds.getDailyTotalsForAllDevices(day);
} }
private String getHM(long value) { private String getHM(long value) {
@ -84,16 +123,23 @@ public class Widget extends AppWidgetProvider {
private void updateAppWidget(Context context, AppWidgetManager appWidgetManager, private void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) { int appWidgetId) {
GBDevice device = getSelectedDevice(); selectedDevice = getSelectedDevice();
WidgetPreferenceStorage widgetPreferenceStorage = new WidgetPreferenceStorage();
String savedDeviceAddress = widgetPreferenceStorage.getSavedDeviceAddress(context, appWidgetId);
if (savedDeviceAddress != null) {
selectedDevice = getDeviceByMAC(context.getApplicationContext(), savedDeviceAddress); //this would probably only happen if device no longer exists in GB
}
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
//onclick refresh //onclick refresh
Intent intent = new Intent(context, Widget.class); Intent intent = new Intent(context, Widget.class);
intent.setAction(WIDGET_CLICK); intent.setAction(WIDGET_CLICK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent refreshDataIntent = PendingIntent.getBroadcast( PendingIntent refreshDataIntent = PendingIntent.getBroadcast(
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//views.setOnClickPendingIntent(R.id.todaywidget_bottom_layout, refreshDataIntent); //views.setOnClickPendingIntent(R.id.todaywidget_bottom_layout, refreshDataIntent);
views.setOnClickPendingIntent(R.id.todaywidget_header_bar, refreshDataIntent); views.setOnClickPendingIntent(R.id.todaywidget_header_container, refreshDataIntent);
//open GB main window //open GB main window
Intent startMainIntent = new Intent(context, ControlCenterv2.class); Intent startMainIntent = new Intent(context, ControlCenterv2.class);
@ -103,33 +149,55 @@ public class Widget extends AppWidgetProvider {
//alarms popup menu //alarms popup menu
Intent startAlarmListIntent = new Intent(context, WidgetAlarmsActivity.class); Intent startAlarmListIntent = new Intent(context, WidgetAlarmsActivity.class);
PendingIntent startAlarmListPIntent = PendingIntent.getActivity(context, 0, startAlarmListIntent, 0); PendingIntent startAlarmListPIntent = PendingIntent.getActivity(context, 0, startAlarmListIntent, 0);
views.setOnClickPendingIntent(R.id.todaywidget_header_plus, startAlarmListPIntent); views.setOnClickPendingIntent(R.id.todaywidget_header_alarm_icon, startAlarmListPIntent);
//charts, requires device //charts, requires device
if (device != null) { if (selectedDevice != null) {
Intent startChartsIntent = new Intent(context, ChartsActivity.class); Intent startChartsIntent = new Intent(context, ChartsActivity.class);
startChartsIntent.putExtra(GBDevice.EXTRA_DEVICE, device); startChartsIntent.putExtra(GBDevice.EXTRA_DEVICE, selectedDevice);
PendingIntent startChartsPIntent = PendingIntent.getActivity(context, 0, startChartsIntent, 0); PendingIntent startChartsPIntent = PendingIntent.getActivity(context, 0, startChartsIntent, 0);
views.setOnClickPendingIntent(R.id.todaywidget_bottom_layout, startChartsPIntent); views.setOnClickPendingIntent(R.id.todaywidget_bottom_layout, startChartsPIntent);
} }
long[] dailyTotals = getSteps(); long[] dailyTotals = getSteps();
int steps = (int) dailyTotals[0];
int sleep = (int) dailyTotals[1];
views.setTextViewText(R.id.todaywidget_steps, context.getString(R.string.widget_steps_label, dailyTotals[0])); ActivityUser activityUser = new ActivityUser();
views.setTextViewText(R.id.todaywidget_sleep, context.getString(R.string.widget_sleep_label, getHM(dailyTotals[1]))); int stepGoal = activityUser.getStepsGoal();
int sleepGoal = activityUser.getSleepDuration();
int sleepGoalMinutes = sleepGoal * 60;
int distanceGoal = activityUser.getDistanceMeters() * 100;
int stepLength = activityUser.getStepLengthCm();
int distanceFormatted = (int) (dailyTotals[0] * stepLength / 100);
if (device != null) { String unit = "###m";
String status = String.format("%1s", device.getStateString()); if (distanceFormatted > 2000) {
if (device.isConnected()) { distanceFormatted = distanceFormatted / 1000;
if (device.getBatteryLevel() > 1) { unit = "###.#km";
status = String.format("Battery %1s%%", device.getBatteryLevel()); }
DecimalFormat df = new DecimalFormat(unit);
views.setTextViewText(R.id.todaywidget_steps, String.format("%1s", steps));
views.setTextViewText(R.id.todaywidget_sleep, String.format("%1s", getHM(sleep)));
views.setTextViewText(R.id.todaywidget_distance, df.format(distanceFormatted));
views.setProgressBar(R.id.todaywidget_steps_progress, stepGoal, steps, false);
views.setProgressBar(R.id.todaywidget_sleep_progress, sleepGoalMinutes, sleep, false);
views.setProgressBar(R.id.todaywidget_distance_progress, distanceGoal, steps * stepLength, false);
views.setViewVisibility(R.id.todaywidget_battery_icon, View.GONE);
if (selectedDevice != null) {
String status = String.format("%1s", selectedDevice.getStateString());
if (selectedDevice.isConnected()) {
if (selectedDevice.getBatteryLevel() > 1) {
views.setViewVisibility(R.id.todaywidget_battery_icon, View.VISIBLE);
status = String.format("%1s%%", selectedDevice.getBatteryLevel());
} }
} }
String deviceName = selectedDevice.getAlias() != null ? selectedDevice.getAlias() : selectedDevice.getName();
views.setTextViewText(R.id.todaywidget_device_status, status); views.setTextViewText(R.id.todaywidget_device_status, status);
views.setTextViewText(R.id.todaywidget_device_name, device.getName()); views.setTextViewText(R.id.todaywidget_device_name, deviceName);
} }
// Instruct the widget manager to update the widget // Instruct the widget manager to update the widget
@ -160,13 +228,15 @@ public class Widget extends AppWidgetProvider {
public void updateWidget() { public void updateWidget() {
Context context = GBApplication.getContext(); Context context = GBApplication.getContext();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), Widget.class.getName()); ComponentName thisAppWidget = new ComponentName(context.getPackageName(), Widget.class.getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget); int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
onUpdate(context, appWidgetManager, appWidgetIds); onUpdate(context, appWidgetManager, appWidgetIds);
}
public void removeWidget(Context context, int appWidgetId) {
WidgetPreferenceStorage widgetPreferenceStorage = new WidgetPreferenceStorage();
widgetPreferenceStorage.removeWidgetById(context, appWidgetId);
} }
@Override @Override
@ -177,7 +247,6 @@ public class Widget extends AppWidgetProvider {
} }
} }
@Override @Override
public void onEnabled(Context context) { public void onEnabled(Context context) {
if (broadcastReceiver == null) { if (broadcastReceiver == null) {
@ -198,9 +267,8 @@ public class Widget extends AppWidgetProvider {
@Override @Override
public void onDisabled(Context context) { public void onDisabled(Context context) {
if (broadcastReceiver != null) { if (broadcastReceiver != null) {
AndroidUtils.safeUnregisterBroadcastReceiver(context,broadcastReceiver); AndroidUtils.safeUnregisterBroadcastReceiver(context, broadcastReceiver);
broadcastReceiver = null; broadcastReceiver = null;
} }
} }
@ -208,16 +276,25 @@ public class Widget extends AppWidgetProvider {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent); super.onReceive(context, intent);
LOG.debug("gbwidget LOCAL onReceive, action: " + intent.getAction()); LOG.debug("gbwidget LOCAL onReceive, action: " + intent.getAction() + intent);
Bundle extras = intent.getExtras();
int appWidgetId = -1;
if (extras != null) {
appWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
//this handles widget re-connection after apk updates //this handles widget re-connection after apk updates
if (WIDGET_CLICK.equals(intent.getAction())) { if (WIDGET_CLICK.equals(intent.getAction())) {
if (broadcastReceiver == null) { if (broadcastReceiver == null) {
onEnabled(context); onEnabled(context);
} }
refreshData(); refreshData();
//updateWidget(); //updateWidget();
} else if (APPWIDGET_DELETED.equals(intent.getAction())) { } else if (APPWIDGET_DELETED.equals(intent.getAction())) {
onDisabled(context); onDisabled(context);
removeWidget(context, appWidgetId);
} }
} }

View File

@ -381,7 +381,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
update_filter_fields(); update_filter_fields();
} }
private LinkedHashMap getAllDevices(Context appContext) { public LinkedHashMap getAllDevices(Context appContext) {
DaoSession daoSession; DaoSession daoSession;
GBApplication gbApp = (GBApplication) appContext; GBApplication gbApp = (GBApplication) appContext;
LinkedHashMap<String, Pair<Long, Integer>> newMap = new LinkedHashMap<>(1); LinkedHashMap<String, Pair<Long, Integer>> newMap = new LinkedHashMap<>(1);

View File

@ -22,7 +22,10 @@ import android.app.AlertDialog;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
@ -55,6 +58,7 @@ import java.util.Objects;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.Widget;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@ -66,6 +70,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.WidgetPreferenceStorage;
import static android.content.Intent.EXTRA_SUBJECT; import static android.content.Intent.EXTRA_SUBJECT;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID; import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID;
@ -333,6 +338,76 @@ public class DebugActivity extends AbstractGBActivity {
showWarning(); showWarning();
} }
}); });
Button showWidgetsButton = findViewById(R.id.showWidgetsButton);
showWidgetsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showAllRegisteredAppWidgets();
}
});
Button unregisterWidgetsButton = findViewById(R.id.deleteWidgets);
unregisterWidgetsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
unregisterAllRegisteredAppWidgets();
}
});
Button showWidgetsPrefsButton = findViewById(R.id.showWidgetsPrefs);
showWidgetsPrefsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showAppWidgetsPrefs();
}
});
Button deleteWidgetsPrefsButton = findViewById(R.id.deleteWidgetsPrefs);
deleteWidgetsPrefsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
deleteWidgetsPrefs();
}
});
}
private void deleteWidgetsPrefs() {
WidgetPreferenceStorage widgetPreferenceStorage = new WidgetPreferenceStorage();
widgetPreferenceStorage.deleteWidgetsPrefs(DebugActivity.this);
widgetPreferenceStorage.showAppWidgetsPrefs(DebugActivity.this);
}
private void showAppWidgetsPrefs() {
WidgetPreferenceStorage widgetPreferenceStorage = new WidgetPreferenceStorage();
widgetPreferenceStorage.showAppWidgetsPrefs(DebugActivity.this);
}
private void showAllRegisteredAppWidgets() {
//https://stackoverflow.com/questions/17387191/check-if-a-widget-is-exists-on-homescreen-using-appwidgetid
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(DebugActivity.this);
AppWidgetHost appWidgetHost = new AppWidgetHost(DebugActivity.this, 1); // for removing phantoms
int[] appWidgetIDs = appWidgetManager.getAppWidgetIds(new ComponentName(DebugActivity.this, Widget.class));
GB.toast("Number of registered app widgets: " + appWidgetIDs.length, Toast.LENGTH_SHORT, GB.INFO);
for (int appWidgetID : appWidgetIDs) {
GB.toast("Widget: " + appWidgetID, Toast.LENGTH_SHORT, GB.INFO);
}
}
private void unregisterAllRegisteredAppWidgets() {
//https://stackoverflow.com/questions/17387191/check-if-a-widget-is-exists-on-homescreen-using-appwidgetid
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(DebugActivity.this);
AppWidgetHost appWidgetHost = new AppWidgetHost(DebugActivity.this, 1); // for removing phantoms
int[] appWidgetIDs = appWidgetManager.getAppWidgetIds(new ComponentName(DebugActivity.this, Widget.class));
GB.toast("Number of registered app widgets: " + appWidgetIDs.length, Toast.LENGTH_SHORT, GB.INFO);
for (int appWidgetID : appWidgetIDs) {
appWidgetHost.deleteAppWidgetId(appWidgetID);
GB.toast("Removing widget: " + appWidgetID, Toast.LENGTH_SHORT, GB.INFO);
}
} }
private void showWarning() { private void showWarning() {

View File

@ -0,0 +1,132 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity;
import android.app.AlertDialog;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Pair;
import android.widget.ListView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.Widget;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.WidgetPreferenceStorage;
public class WidgetConfigurationActivity extends Activity {
private static final Logger LOG = LoggerFactory.getLogger(Widget.class);
int mAppWidgetId;
LinkedHashMap<String, Pair<String, Integer>> allDevices;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
// make the result intent and set the result to canceled
Intent resultValue; resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_CANCELED, resultValue);
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
AlertDialog.Builder builder = new AlertDialog.Builder(WidgetConfigurationActivity.this);
builder.setTitle("Select device");
allDevices = getAllDevices(getApplicationContext());
List<String> list = new ArrayList<>();
for (Map.Entry<String, Pair<String, Integer>> item : allDevices.entrySet()) {
list.add(item.getKey());
}
String[] allDevicesString = list.toArray(new String[0]);
builder.setSingleChoiceItems(allDevicesString, 0, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ListView lw = ((AlertDialog) dialog).getListView();
int selectedItemPosition = lw.getCheckedItemPosition();
if (selectedItemPosition > -1) {
Map.Entry<String, Pair<String, Integer>> selectedItem =
(Map.Entry<String, Pair<String, Integer>>) allDevices.entrySet().toArray()[selectedItemPosition];
WidgetPreferenceStorage widgetPreferenceStorage = new WidgetPreferenceStorage();
widgetPreferenceStorage.saveWidgetPrefs(getApplicationContext(), String.valueOf(mAppWidgetId), selectedItem.getValue().first);
}
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent resultValue; resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_CANCELED, resultValue);
finish();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
public LinkedHashMap getAllDevices(Context appContext) {
DaoSession daoSession;
GBApplication gbApp = (GBApplication) appContext;
LinkedHashMap<String, Pair<String, Integer>> newMap = new LinkedHashMap<>(1);
List<? extends GBDevice> devices = gbApp.getDeviceManager().getDevices();
try (DBHandler handler = GBApplication.acquireDB()) {
daoSession = handler.getDaoSession();
for (GBDevice device : devices) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
Device dbDevice = DBHelper.findDevice(device, daoSession);
int icon = device.isInitialized() ? device.getType().getIcon() : device.getType().getDisabledIcon();
if (dbDevice != null && coordinator != null
&& coordinator.supportsActivityTracks()
&& !newMap.containsKey(device.getAliasOrName())) {
newMap.put(device.getAliasOrName(), new Pair(device.getAddress(), icon));
}
}
} catch (Exception e) {
LOG.error("Error getting list of all devices: " + e);
}
return newMap;
}
}

View File

@ -56,7 +56,7 @@ public class DailyTotals {
} }
long[] all_daily = getDailyTotalsForDevice(device, day); long[] all_daily = getDailyTotalsForDevice(device, day);
all_steps += all_daily[0]; all_steps += all_daily[0];
all_sleep += all_daily[1] + all_daily[2]; all_sleep += all_daily[1];
} }
} }
//LOG.debug("gbwidget daily totals, all steps:" + all_steps); //LOG.debug("gbwidget daily totals, all steps:" + all_steps);
@ -78,12 +78,11 @@ public class DailyTotals {
long[] sleep = getTotalsSleepForActivityAmounts(amountsSleep); long[] sleep = getTotalsSleepForActivityAmounts(amountsSleep);
long steps = getTotalsStepsForActivityAmounts(amountsSteps); long steps = getTotalsStepsForActivityAmounts(amountsSteps);
return new long[]{steps, sleep[0], sleep[1]}; return new long[]{steps, sleep[0] + sleep[1]};
} catch (Exception e) { } catch (Exception e) {
//GB.toast("Error loading sleep/steps widget data for device: " + device, Toast.LENGTH_SHORT, GB.ERROR, e);
GB.toast("Error loading activity summaries.", Toast.LENGTH_SHORT, GB.ERROR, e); return new long[]{0, 0};
return new long[]{0, 0, 0};
} }
} }

View File

@ -0,0 +1,139 @@
package nodomain.freeyourgadget.gadgetbridge.util;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.Widget;
public class WidgetPreferenceStorage {
private static final Logger LOG = LoggerFactory.getLogger(WidgetPreferenceStorage.class);
boolean isWidgetInPrefs = false;
String PREFS_WIDGET_SETTINGS = "widget_settings";
public String getSavedDeviceAddress(Context context, int appWidgetId) {
String savedDeviceAddress = null;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String savedWidgetsPreferencesData = sharedPrefs.getString(PREFS_WIDGET_SETTINGS, "");
JSONArray savedWidgetsPreferencesDataArray = null;
try {
savedWidgetsPreferencesDataArray = new JSONArray(savedWidgetsPreferencesData);
savedWidgetsPreferencesDataArray = new JSONArray("fdsfdsfsffs");
} catch (
JSONException e) {
LOG.error(e.getMessage());
}
LOG.debug("widget JSON loaded: " + savedWidgetsPreferencesDataArray);
if (savedWidgetsPreferencesDataArray == null) {
return null;
}
for (int i = 0; i < savedWidgetsPreferencesDataArray.length(); i++) {
try {
JSONArray a = savedWidgetsPreferencesDataArray.getJSONArray(i);
if (appWidgetId == a.getInt(0)) {
isWidgetInPrefs = true;
savedDeviceAddress = a.getString(1);
}
} catch (JSONException e) {
LOG.error(e.getMessage());
}
}
return savedDeviceAddress;
}
public void removeWidgetById(Context context, int appWidgetId) {
LOG.debug("widget trying to remove: " + appWidgetId);
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String savedWidgetsPreferencesData = sharedPrefs.getString(PREFS_WIDGET_SETTINGS, "");
JSONArray savedWidgetsPreferencesDataArray = null;
try {
savedWidgetsPreferencesDataArray = new JSONArray(savedWidgetsPreferencesData);
} catch (
JSONException e) {
LOG.error(e.getMessage());
}
if (savedWidgetsPreferencesDataArray == null) {
return;
}
for (int i = 0; i < savedWidgetsPreferencesDataArray.length(); i++) {
try {
JSONArray a = savedWidgetsPreferencesDataArray.getJSONArray(i);
if (appWidgetId == a.getInt(0)) {
GB.toast("Removing widget preferences: " + appWidgetId, Toast.LENGTH_SHORT, GB.INFO);
savedWidgetsPreferencesDataArray.remove(i);
}
} catch (JSONException e) {
LOG.error(e.getMessage());
}
}
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(PREFS_WIDGET_SETTINGS, savedWidgetsPreferencesDataArray.toString());
editor.commit();
editor.apply();
}
public void saveWidgetPrefs(Context context, String AppWidgetId, String HwAddress) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String savedWidgetsPreferencesData = sharedPrefs.getString(PREFS_WIDGET_SETTINGS, "");
JSONArray savedWidgetsPreferencesDataArray = null;
try {
savedWidgetsPreferencesDataArray = new JSONArray(savedWidgetsPreferencesData);
} catch (
JSONException e) {
LOG.error(e.getMessage());
}
if (savedWidgetsPreferencesDataArray == null) {
savedWidgetsPreferencesDataArray = new JSONArray();
}
try {
savedWidgetsPreferencesDataArray.put(new JSONArray(new String[]{AppWidgetId, HwAddress}));
} catch (JSONException e) {
LOG.error(e.getMessage());
}
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(PREFS_WIDGET_SETTINGS, savedWidgetsPreferencesDataArray.toString());
editor.commit();
editor.apply();
}
public boolean isWidgetInPrefs() {
return isWidgetInPrefs;
}
public void deleteWidgetsPrefs(Context context) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putString(PREFS_WIDGET_SETTINGS, "");
editor.commit();
editor.apply();
}
public void showAppWidgetsPrefs(Context context) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String savedWidgetsPreferencesData = sharedPrefs.getString(PREFS_WIDGET_SETTINGS, "");
JSONArray savedWidgetsPreferencesDataArray = null;
try {
savedWidgetsPreferencesDataArray = new JSONArray(savedWidgetsPreferencesData);
} catch (
JSONException e) {
LOG.error(e.getMessage());
}
GB.toast("Saved app widget preferences: " + savedWidgetsPreferencesDataArray, Toast.LENGTH_SHORT, GB.INFO);
}
}

View File

@ -1,3 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:viewportHeight="24" android:viewportWidth="24" android:tint="#7E7E7E" android:width="24dp"> <vector xmlns:android="http://schemas.android.com/apk/res/android"
<path android:fillColor="#000" android:pathData="M10.74 11.72c0.47 1.23 0.42 2.51-0.99 3.02-2.9 1.07-3.55-1.74-3.59-1.88l4.58-1.14m-5.03-0.81l4.32-1.07c-0.19-1.05 0.1-2.1 0.1-3.34 0-1.68-1.33-4.97-3.45-4.44C4.26 2.66 3.91 5.35 4 6.65c0.12 1.3 1.64 4.08 1.71 4.26m12.14 8.94c-0.03 0.15-0.69 2.95-3.59 1.89-1.4-0.52-1.46-1.8-0.99-3.03l4.58 1.14m2.15-6.2c0.1-1.3-0.24-4-2.67-4.6-2.11-0.55-3.44 2.76-3.44 4.45 0 1.23 0.28 2.28 0.11 3.33l4.3 1.07c0.08-0.18 1.59-2.96 1.7-4.25z"/> android:width="24dp"
android:height="24dp"
android:tint="#7E7E7E"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000"
android:pathData="M10.74 11.72c0.47 1.23 0.42 2.51-0.99 3.02-2.9 1.07-3.55-1.74-3.59-1.88l4.58-1.14m-5.03-0.81l4.32-1.07c-0.19-1.05 0.1-2.1 0.1-3.34 0-1.68-1.33-4.97-3.45-4.44C4.26 2.66 3.91 5.35 4 6.65c0.12 1.3 1.64 4.08 1.71 4.26m12.14 8.94c-0.03 0.15-0.69 2.95-3.59 1.89-1.4-0.52-1.46-1.8-0.99-3.03l4.58 1.14m2.15-6.2c0.1-1.3-0.24-4-2.67-4.6-2.11-0.55-3.44 2.76-3.44 4.45 0 1.23 0.28 2.28 0.11 3.33l4.3 1.07c0.08-0.18 1.59-2.96 1.7-4.25z" />
</vector> </vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -166,6 +166,35 @@
grid:layout_columnSpan="2" grid:layout_columnSpan="2"
grid:layout_gravity="fill_horizontal" grid:layout_gravity="fill_horizontal"
android:text="@string/share_log" /> android:text="@string/share_log" />
<Button
android:id="@+id/showWidgetsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
grid:layout_columnSpan="2"
grid:layout_gravity="fill_horizontal"
android:text="Show all registered app widgets IDs" />
<Button
android:id="@+id/deleteWidgets"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
grid:layout_columnSpan="2"
grid:layout_gravity="fill_horizontal"
android:text="Delete all registered app widgets IDs" />
<Button
android:id="@+id/showWidgetsPrefs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
grid:layout_columnSpan="2"
grid:layout_gravity="fill_horizontal"
android:text="Show app Widgets Preferences" />
<Button
android:id="@+id/deleteWidgetsPrefs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
grid:layout_columnSpan="2"
grid:layout_gravity="fill_horizontal"
android:text="Delete app Widgets Preferences" />
</androidx.gridlayout.widget.GridLayout> </androidx.gridlayout.widget.GridLayout>
</ScrollView> </ScrollView>

View File

@ -1,8 +1,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/alarm_list_top_layout" android:id="@+id/alarm_list_top_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/primary_dark"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
@ -24,33 +24,44 @@
android:src="@drawable/ic_notification" /> android:src="@drawable/ic_notification" />
<LinearLayout <TextView
android:id="@+id/todaywidget_header_bar" android:id="@+id/todaywidget_device_name"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1" android:layout_weight="1"
android:gravity="start" android:drawablePadding="4dp"
android:paddingLeft="0dp" android:ellipsize="end"
android:paddingRight="0dp"> android:gravity="center_vertical"
android:maxLines="1"
<TextView android:text="@string/app_name"
android:id="@+id/todaywidget_device_name" android:textColor="@color/primarytext_dark"
android:layout_width="wrap_content" android:textSize="18sp" />
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:drawablePadding="4dp"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/app_name"
android:textColor="@color/primarytext_dark"
android:textSize="18sp" />
</LinearLayout>
<ImageView <ImageView
android:id="@+id/todaywidget_header_plus" android:id="@+id/todaywidget_battery_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="start|center_vertical"
android:backgroundTint="#FFFFFF"
android:background="@drawable/ic_battery_full"
android:contentDescription="@string/icon_placeholder"
android:padding="0dp" />
<TextView
android:id="@+id/todaywidget_device_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:foregroundGravity="right"
android:gravity="end"
android:text="@string/device_not_connected"
android:textColor="@color/primarytext_dark"
android:textSize="18sp" />
<ImageView
android:id="@+id/todaywidget_header_alarm_icon"
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
@ -65,55 +76,137 @@
<LinearLayout <LinearLayout
android:id="@+id/todaywidget_bottom_layout" android:id="@+id/todaywidget_bottom_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:background="#2BE3DBDB"
android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingLeft="3dp" android:paddingLeft="3dp"
android:paddingRight="3dp"> android:paddingRight="3dp"
android:paddingBottom="5dp">
<LinearLayout <LinearLayout
android:id="@+id/todaywidget_bottom_vertical"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:id="@+id/todaywidget_steps_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="start|center_vertical"
android:backgroundTint="#FFFFFF"
android:background="@drawable/ic_shoe_print"
android:contentDescription="@string/icon_placeholder"
android:padding="0dp" />
<TextView <LinearLayout
android:id="@+id/todaywidget_steps" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/widget_steps_label" android:orientation="vertical"
android:gravity="center_vertical|center_horizontal" android:paddingStart="10dp"
android:text="@string/widget_steps_label" android:paddingEnd="10dp">
android:textColor="@color/primarytext_dark"
android:textSize="18sp" /> <TextView
android:id="@+id/todaywidget_steps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textColor="@color/primarytext_dark"
android:textSize="18sp" />
<ProgressBar
android:id="@+id/todaywidget_steps_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#FFFFFF" />
</LinearLayout>
<TextView
android:id="@+id/todaywidget_sleep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/widget_sleep_label"
android:gravity="center_vertical|center_horizontal"
android:text="@string/widget_sleep_label"
android:textColor="@color/primarytext_dark"
android:textSize="18sp" />
</LinearLayout> </LinearLayout>
<TextView <LinearLayout
android:id="@+id/empty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/todaywidget_device_status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_weight="1"
android:foregroundGravity="right" android:orientation="horizontal">
android:gravity="end"
android:text="@string/device_not_connected" <ImageView
android:textColor="@color/primarytext_dark" android:id="@+id/todaywidget_distance_icon"
android:textSize="18sp" /> android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="start|center_vertical"
android:backgroundTint="#FFFFFF"
android:background="@drawable/ic_distance"
android:contentDescription="@string/icon_placeholder"
android:padding="0dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<TextView
android:id="@+id/todaywidget_distance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textColor="@color/primarytext_dark"
android:textSize="18sp" />
<ProgressBar
android:id="@+id/todaywidget_distance_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#FFFFFF" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:id="@+id/todaywidget_sleep_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="start|center_vertical"
android:backgroundTint="#FFFFFF"
android:background="@drawable/ic_activity_sleep"
android:contentDescription="@string/icon_placeholder" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="10dp"
android:paddingEnd="10dp">
<TextView
android:id="@+id/todaywidget_sleep"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textColor="@color/primarytext_dark"
android:textSize="18sp" />
<ProgressBar
android:id="@+id/todaywidget_sleep_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_weight="1"
android:background="#FFFFFF" />
</LinearLayout>
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -8,7 +8,7 @@
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/todaywidget_header_container" android:id="@+id/todaywidget_alarm_header_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="40dp"
android:background="@color/accent" android:background="@color/accent"
@ -17,7 +17,7 @@
<LinearLayout <LinearLayout
android:id="@+id/todaywidget_header_bar" android:id="@+id/todaywidget_alarm_header_bar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"

View File

@ -900,8 +900,6 @@
<string name="add_widget">Add widget</string> <string name="add_widget">Add widget</string>
<string name="appwidget_setting_alarm">Setting alarm for %1$02d:%2$02d</string> <string name="appwidget_setting_alarm">Setting alarm for %1$02d:%2$02d</string>
<string name="appwidget_sleep_alarm_widget_label">Sleep Alarm</string> <string name="appwidget_sleep_alarm_widget_label">Sleep Alarm</string>
<string name="widget_steps_label">Steps: %1$02d</string>
<string name="widget_sleep_label">Sleep: %1$s</string>
<string name="widget_listing_label">Status and Alarms</string> <string name="widget_listing_label">Status and Alarms</string>
<string name="widget_set_alarm_after">Set alarm after:</string> <string name="widget_set_alarm_after">Set alarm after:</string>
<string name="widget_5_minutes">5 minutes</string> <string name="widget_5_minutes">5 minutes</string>

View File

@ -9,6 +9,7 @@
android:resizeMode="horizontal|vertical" android:resizeMode="horizontal|vertical"
android:previewImage="@drawable/widget_preview" android:previewImage="@drawable/widget_preview"
android:updatePeriodMillis="86400000" android:updatePeriodMillis="86400000"
android:configure="nodomain.freeyourgadget.gadgetbridge.activities.WidgetConfigurationActivity"
android:widgetCategory="home_screen|keyguard|searchbox"> android:widgetCategory="home_screen|keyguard|searchbox">
</appwidget-provider> </appwidget-provider>