mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-21 16:02:04 +02:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -15,6 +15,7 @@ Install [openScale-dev-build.apk](https://github.com/oliexdev/openScale/releases
|
||||
# Features
|
||||
|
||||
- Logs your body metrics (weight, body fat, body water, muscle percentage, lean body mass, bone mass, BMI, BMR, waist/hip circumference, waist-hip ratio, waist-to-height ratio)
|
||||
- Widget that can be added to the home screen showing any of the available metrics
|
||||
- Keep track of your diet process
|
||||
- Display all your data on a chart and table
|
||||
- Import or export your data from/into a CSV file
|
||||
|
@@ -36,6 +36,20 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".gui.widget.WidgetProvider">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_info" />
|
||||
</receiver>
|
||||
|
||||
<activity android:name=".gui.widget.WidgetConfigure">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
|
@@ -16,10 +16,13 @@
|
||||
|
||||
package com.health.openscale.core;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.arch.persistence.db.SupportSQLiteDatabase;
|
||||
import android.arch.persistence.room.Room;
|
||||
import android.arch.persistence.room.RoomDatabase;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabaseCorruptException;
|
||||
@@ -52,6 +55,7 @@ import com.health.openscale.gui.views.FatMeasurementView;
|
||||
import com.health.openscale.gui.views.LBMMeasurementView;
|
||||
import com.health.openscale.gui.views.MeasurementViewSettings;
|
||||
import com.health.openscale.gui.views.WaterMeasurementView;
|
||||
import com.health.openscale.gui.widget.WidgetProvider;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
@@ -166,6 +170,17 @@ public class OpenScale {
|
||||
scaleDB.close();
|
||||
}
|
||||
|
||||
public void triggerWidgetUpdate() {
|
||||
int[] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(
|
||||
new ComponentName(context, WidgetProvider.class));
|
||||
if (ids.length > 0) {
|
||||
Intent intent = new Intent(context, WidgetProvider.class);
|
||||
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
|
||||
public int addScaleUser(final ScaleUser user) {
|
||||
return (int)userDAO.insert(user);
|
||||
}
|
||||
@@ -247,6 +262,9 @@ public class OpenScale {
|
||||
return scaleMeasurementList;
|
||||
}
|
||||
|
||||
public ScaleMeasurement getLatestScaleMeasurement(int userId) {
|
||||
return measurementDAO.getLatest(userId);
|
||||
}
|
||||
|
||||
public ScaleMeasurement[] getTupleScaleData(int id)
|
||||
{
|
||||
@@ -324,6 +342,7 @@ public class OpenScale {
|
||||
}
|
||||
alarmHandler.entryChanged(context, scaleMeasurement);
|
||||
updateScaleData();
|
||||
triggerWidgetUpdate();
|
||||
} else {
|
||||
if (!silent) {
|
||||
Toast.makeText(context, context.getString(R.string.info_new_data_duplicated), Toast.LENGTH_LONG).show();
|
||||
@@ -374,6 +393,7 @@ public class OpenScale {
|
||||
alarmHandler.entryChanged(context, scaleMeasurement);
|
||||
|
||||
updateScaleData();
|
||||
triggerWidgetUpdate();
|
||||
}
|
||||
|
||||
public void deleteScaleData(int id)
|
||||
|
@@ -47,6 +47,9 @@ public interface ScaleMeasurementDAO {
|
||||
@Query("SELECT * FROM scaleMeasurements WHERE datetime >= :startYear AND datetime < :endYear AND userId = :userId AND enabled = 1 ORDER BY datetime DESC")
|
||||
List<ScaleMeasurement> getAllInRange(Date startYear, Date endYear, int userId);
|
||||
|
||||
@Query("SELECT * FROM scaleMeasurements WHERE userId = :userId AND enabled = 1 ORDER BY datetime DESC LIMIT 1")
|
||||
ScaleMeasurement getLatest(int userId);
|
||||
|
||||
@Insert (onConflict = OnConflictStrategy.IGNORE)
|
||||
long insert(ScaleMeasurement measurement);
|
||||
|
||||
|
@@ -196,6 +196,7 @@ public class MainActivity extends BaseAppCompatActivity
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (settingsActivityRunning) {
|
||||
recreate();
|
||||
OpenScale.getInstance().triggerWidgetUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -284,7 +284,7 @@ public class TableFragment extends Fragment implements FragmentUpdateListener {
|
||||
|
||||
SpannableStringBuilder string = new SpannableStringBuilder();
|
||||
string.append(visibleMeasurements.get(i).getValueAsString(false));
|
||||
visibleMeasurements.get(i).appendDiffValue(string);
|
||||
visibleMeasurements.get(i).appendDiffValue(string, true);
|
||||
|
||||
stringCache[position][i] = string;
|
||||
}
|
||||
|
@@ -405,7 +405,7 @@ public abstract class FloatMeasurementView extends MeasurementView {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendDiffValue(SpannableStringBuilder text) {
|
||||
public void appendDiffValue(SpannableStringBuilder text, boolean newLine) {
|
||||
if (previousValue < 0.0f) {
|
||||
return;
|
||||
}
|
||||
@@ -425,7 +425,9 @@ public abstract class FloatMeasurementView extends MeasurementView {
|
||||
color = Color.GRAY;
|
||||
}
|
||||
|
||||
text.append('\n');
|
||||
if (newLine) {
|
||||
text.append('\n');
|
||||
}
|
||||
int start = text.length();
|
||||
text.append(symbol);
|
||||
text.setSpan(new ForegroundColorSpan(color), start, text.length(),
|
||||
|
@@ -20,6 +20,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -65,6 +66,7 @@ public abstract class MeasurementView extends TableLayout {
|
||||
|
||||
private TableRow measurementRow;
|
||||
private ImageView iconView;
|
||||
private int iconId;
|
||||
private TextView nameView;
|
||||
private TextView valueView;
|
||||
private LinearLayout incDecLayout;
|
||||
@@ -84,6 +86,7 @@ public abstract class MeasurementView extends TableLayout {
|
||||
initView(context);
|
||||
|
||||
nameView.setText(textId);
|
||||
this.iconId = iconId;
|
||||
iconView.setImageResource(iconId);
|
||||
}
|
||||
|
||||
@@ -256,8 +259,9 @@ public abstract class MeasurementView extends TableLayout {
|
||||
|
||||
public CharSequence getName() { return nameView.getText(); }
|
||||
public abstract String getValueAsString(boolean withUnit);
|
||||
public void appendDiffValue(SpannableStringBuilder builder) { }
|
||||
public void appendDiffValue(SpannableStringBuilder builder, boolean newLine) { }
|
||||
public Drawable getIcon() { return iconView.getDrawable(); }
|
||||
public int getIconResource() { return iconId; }
|
||||
|
||||
protected boolean isEditable() {
|
||||
return true;
|
||||
@@ -319,6 +323,11 @@ public abstract class MeasurementView extends TableLayout {
|
||||
return valueView.getCurrentTextColor();
|
||||
}
|
||||
|
||||
public int getIndicatorColor() {
|
||||
ColorDrawable background = (ColorDrawable)indicatorView.getBackground();
|
||||
return background.getColor();
|
||||
}
|
||||
|
||||
protected void showEvaluatorRow(boolean show) {
|
||||
if (show) {
|
||||
evaluatorRow.setVisibility(View.VISIBLE);
|
||||
|
@@ -0,0 +1,120 @@
|
||||
/* Copyright (C) 2018 Erik Johansson <erik@ejohansson.se>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.health.openscale.gui.widget;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TableRow;
|
||||
|
||||
import com.health.openscale.R;
|
||||
import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.datatypes.ScaleUser;
|
||||
import com.health.openscale.gui.activities.BaseAppCompatActivity;
|
||||
import com.health.openscale.gui.views.MeasurementView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WidgetConfigure extends BaseAppCompatActivity {
|
||||
private int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
|
||||
Intent intent = getIntent();
|
||||
Bundle extras = intent.getExtras();
|
||||
if (extras != null) {
|
||||
appWidgetId = extras.getInt(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
}
|
||||
|
||||
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||
finish();
|
||||
}
|
||||
|
||||
setContentView(R.layout.widget_configuration);
|
||||
|
||||
OpenScale openScale = OpenScale.getInstance();
|
||||
|
||||
// Set up user spinner
|
||||
final Spinner userSpinner = findViewById(R.id.widget_user_spinner);
|
||||
List<String> users = new ArrayList<>();
|
||||
final List<Integer> userIds = new ArrayList<>();
|
||||
for (ScaleUser scaleUser : openScale.getScaleUserList()) {
|
||||
users.add(scaleUser.getUserName());
|
||||
userIds.add(scaleUser.getId());
|
||||
}
|
||||
ArrayAdapter<String> userAdapter = new ArrayAdapter<>(
|
||||
this, android.R.layout.simple_spinner_item, users);
|
||||
userAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
userSpinner.setAdapter(userAdapter);
|
||||
|
||||
// Hide user selector when there's only one user
|
||||
if (users.size() == 1) {
|
||||
TableRow row = (TableRow) userSpinner.getParent();
|
||||
row.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Set up measurement spinner
|
||||
final Spinner measurementSpinner = findViewById(R.id.widget_measurement_spinner);
|
||||
List<String> measurements = new ArrayList<>();
|
||||
final List<String> measurementKeys = new ArrayList<>();
|
||||
for (MeasurementView measurementView : MeasurementView.getMeasurementList(
|
||||
this, MeasurementView.DateTimeOrder.NONE)) {
|
||||
if (measurementView.isVisible()) {
|
||||
measurements.add(measurementView.getName().toString());
|
||||
measurementKeys.add(measurementView.getKey());
|
||||
}
|
||||
}
|
||||
ArrayAdapter<String> measurementAdapter = new ArrayAdapter<>(
|
||||
this, android.R.layout.simple_spinner_item, measurements);
|
||||
measurementAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
measurementSpinner.setAdapter(measurementAdapter);
|
||||
|
||||
findViewById(R.id.widget_save).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int userId = userIds.get(userSpinner.getSelectedItemPosition());
|
||||
String measurementKey = measurementKeys.get(measurementSpinner.getSelectedItemPosition());
|
||||
|
||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit()
|
||||
.putInt(WidgetProvider.getUserIdPreferenceName(appWidgetId), userId)
|
||||
.putString(WidgetProvider.getMeasurementPreferenceName(appWidgetId), measurementKey)
|
||||
.apply();
|
||||
|
||||
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {appWidgetId});
|
||||
sendBroadcast(intent);
|
||||
|
||||
Intent resultValue = new Intent();
|
||||
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
setResult(RESULT_OK, resultValue);
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,198 @@
|
||||
/* Copyright (C) 2018 Erik Johansson <erik@ejohansson.se>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package com.health.openscale.gui.widget;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.health.openscale.R;
|
||||
import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.datatypes.ScaleMeasurement;
|
||||
import com.health.openscale.gui.MainActivity;
|
||||
import com.health.openscale.gui.activities.BaseAppCompatActivity;
|
||||
import com.health.openscale.gui.views.MeasurementView;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class WidgetProvider extends AppWidgetProvider {
|
||||
List<MeasurementView> measurementViews;
|
||||
|
||||
public static final String getUserIdPreferenceName(int appWidgetId) {
|
||||
return String.format("widget_%d_userid", appWidgetId);
|
||||
}
|
||||
|
||||
public static final String getMeasurementPreferenceName(int appWidgetId) {
|
||||
return String.format("widget_%d_measurement", appWidgetId);
|
||||
}
|
||||
|
||||
private void updateWidget(Context context, AppWidgetManager appWidgetManager,
|
||||
int appWidgetId, Bundle newOptions) {
|
||||
// Make sure we use the correct language
|
||||
context = BaseAppCompatActivity.createBaseContext(context);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int userId = prefs.getInt(getUserIdPreferenceName(appWidgetId), -1);
|
||||
String key = prefs.getString(getMeasurementPreferenceName(appWidgetId), "");
|
||||
|
||||
if (measurementViews == null) {
|
||||
measurementViews = MeasurementView.getMeasurementList(
|
||||
context, MeasurementView.DateTimeOrder.NONE);
|
||||
}
|
||||
|
||||
MeasurementView measurementView = measurementViews.get(0);
|
||||
for (MeasurementView view : measurementViews) {
|
||||
if (view.getKey().equals(key)) {
|
||||
measurementView = view;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OpenScale openScale = OpenScale.getInstance();
|
||||
ScaleMeasurement latest = openScale.getLatestScaleMeasurement(userId);
|
||||
if (latest != null) {
|
||||
ScaleMeasurement previous = openScale.getTupleScaleData(latest.getId())[0];
|
||||
measurementView.loadFrom(latest, previous);
|
||||
}
|
||||
|
||||
final int minWidth = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
|
||||
// From https://developer.android.com/guide/practices/ui_guidelines/widget_design
|
||||
final int twoCellsMinWidth = 110;
|
||||
final int thirdCellsMinWidth = 180;
|
||||
final int fourCellsMinWidth = 250;
|
||||
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
|
||||
|
||||
views.setInt(R.id.indicator_view, "setBackgroundColor", measurementView.getIndicatorColor());
|
||||
|
||||
// Show icon in >= two cell mode
|
||||
if (minWidth >= twoCellsMinWidth) {
|
||||
views.setImageViewResource(R.id.widget_icon, measurementView.getIconResource());
|
||||
views.setViewVisibility(R.id.widget_icon, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.widget_icon_vertical, View.GONE);
|
||||
}
|
||||
else {
|
||||
views.setImageViewResource(R.id.widget_icon_vertical, measurementView.getIconResource());
|
||||
views.setViewVisibility(R.id.widget_icon_vertical, View.VISIBLE);
|
||||
views.setViewVisibility(R.id.widget_icon, View.GONE);
|
||||
}
|
||||
|
||||
// Show measurement name in >= four cell mode
|
||||
if (minWidth >= fourCellsMinWidth) {
|
||||
views.setTextViewText(R.id.widget_name, measurementView.getName());
|
||||
views.setTextViewText(R.id.widget_date,
|
||||
latest != null
|
||||
? DateFormat.getDateTimeInstance(
|
||||
DateFormat.LONG, DateFormat.SHORT).format(latest.getDateTime())
|
||||
: "");
|
||||
views.setViewVisibility(R.id.widget_name_date_layout, View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
views.setViewVisibility(R.id.widget_name_date_layout, View.GONE);
|
||||
}
|
||||
|
||||
// Always show value, but use smaller font in once cell mode
|
||||
views.setTextViewText(R.id.widget_value, measurementView.getValueAsString(true));
|
||||
SpannableStringBuilder delta = new SpannableStringBuilder();
|
||||
measurementView.appendDiffValue(delta, false);
|
||||
views.setTextViewText(R.id.widget_delta, delta.toString());
|
||||
|
||||
if (minWidth >= thirdCellsMinWidth) {
|
||||
views.setTextViewTextSize(R.id.widget_value, TypedValue.COMPLEX_UNIT_DIP, 18);
|
||||
views.setTextViewTextSize(R.id.widget_delta, TypedValue.COMPLEX_UNIT_DIP, 17);
|
||||
}
|
||||
else if (minWidth >= twoCellsMinWidth) {
|
||||
views.setTextViewTextSize(R.id.widget_value, TypedValue.COMPLEX_UNIT_DIP, 17);
|
||||
views.setTextViewTextSize(R.id.widget_delta, TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
}
|
||||
else {
|
||||
views.setTextViewTextSize(R.id.widget_value, TypedValue.COMPLEX_UNIT_DIP, 15);
|
||||
views.setTextViewTextSize(R.id.widget_delta, TypedValue.COMPLEX_UNIT_DIP, 13);
|
||||
}
|
||||
|
||||
// Start main activity when widget is clicked
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
|
||||
views.setOnClickPendingIntent(R.id.widget_layout, pendingIntent);
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
Bundle newOptions = appWidgetManager.getAppWidgetOptions(appWidgetId);
|
||||
updateWidget(context, appWidgetManager, appWidgetId, newOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
|
||||
int appWidgetId, Bundle newOptions) {
|
||||
updateWidget(context, appWidgetManager, appWidgetId, newOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||
SharedPreferences.Editor editor =
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit();
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
editor.remove(getUserIdPreferenceName(appWidgetId));
|
||||
editor.remove(getMeasurementPreferenceName(appWidgetId));
|
||||
}
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisabled(Context context) {
|
||||
measurementViews = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
|
||||
for (int i = 0; i < oldWidgetIds.length; ++i) {
|
||||
String oldKey = getUserIdPreferenceName(oldWidgetIds[i]);
|
||||
if (prefs.contains(oldKey)) {
|
||||
editor.putInt(getUserIdPreferenceName(newWidgetIds[i]),
|
||||
prefs.getInt(oldKey, -1));
|
||||
editor.remove(oldKey);
|
||||
}
|
||||
|
||||
oldKey = getMeasurementPreferenceName(oldWidgetIds[i]);
|
||||
if (prefs.contains(oldKey)) {
|
||||
editor.putString(getMeasurementPreferenceName(newWidgetIds[i]),
|
||||
prefs.getString(oldKey, ""));
|
||||
editor.remove(oldKey);
|
||||
}
|
||||
}
|
||||
|
||||
editor.apply();
|
||||
}
|
||||
}
|
BIN
android_app/app/src/main/res/drawable-hdpi/appwidget_bg.9.png
Normal file
BIN
android_app/app/src/main/res/drawable-hdpi/appwidget_bg.9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
android_app/app/src/main/res/drawable-mdpi/appwidget_bg.9.png
Normal file
BIN
android_app/app/src/main/res/drawable-mdpi/appwidget_bg.9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
BIN
android_app/app/src/main/res/drawable-xhdpi/appwidget_bg.9.png
Normal file
BIN
android_app/app/src/main/res/drawable-xhdpi/appwidget_bg.9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
94
android_app/app/src/main/res/layout/widget.xml
Normal file
94
android_app/app/src/main/res/layout/widget.xml
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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="match_parent"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/widget_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/appwidget_bg"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/widget_icon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:maxWidth="40dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/widget_name_date_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="3"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/widget_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:textColor="@color/widgetTextColor"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold" />
|
||||
<TextView
|
||||
android:id="@+id/widget_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:lines="1"
|
||||
android:textColor="@color/widgetTextColor"
|
||||
android:textSize="13sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="2"
|
||||
android:minWidth="40dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="4dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/widget_icon_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/widget_value"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:textColor="@color/widgetTextColor"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/widget_delta"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right"
|
||||
android:lines="1"
|
||||
android:textColor="@color/widgetTextColor" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/indicator_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.2" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
56
android_app/app/src/main/res/layout/widget_configuration.xml
Normal file
56
android_app/app/src/main/res/layout/widget_configuration.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/label_configure_widget" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:stretchColumns="*">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/label_select_user" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/widget_user_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/label_select_measurement" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/widget_measurement_spinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/widget_save"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save" />
|
||||
|
||||
</LinearLayout>
|
@@ -7,4 +7,6 @@
|
||||
<color name="primaryColor">#000000</color>
|
||||
<color name="primaryLightColor">@android:color/holo_blue_light</color>
|
||||
<color name="primaryDarkColor">#000000</color>
|
||||
|
||||
<color name="widgetTextColor">#555</color>
|
||||
</resources>
|
||||
|
@@ -220,4 +220,7 @@
|
||||
<string name="label_development">Development</string>
|
||||
<string name="label_debug_log">Save debug log to file</string>
|
||||
<string name="label_your_bluetooth_scale">Your Bluetooth scale</string>
|
||||
<string name="label_select_measurement">Select measurement</string>
|
||||
<string name="label_select_user">Select user</string>
|
||||
<string name="label_configure_widget">Configure widget</string>
|
||||
</resources>
|
||||
|
10
android_app/app/src/main/res/xml/widget_info.xml
Normal file
10
android_app/app/src/main/res/xml/widget_info.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:minWidth="250dp"
|
||||
android:minHeight="40dp"
|
||||
android:minResizeWidth="40dp"
|
||||
android:updatePeriodMillis="0"
|
||||
android:configure="com.health.openscale.gui.widget.WidgetConfigure"
|
||||
android:initialLayout="@layout/widget"
|
||||
android:resizeMode="horizontal"
|
||||
android:widgetCategory="home_screen">
|
||||
</appwidget-provider>
|
Reference in New Issue
Block a user