Initial version for Avatar Stats Widget

This commit is contained in:
Phillip Thelen 2016-09-09 21:19:51 +02:00
parent 09a99ab367
commit fc7ab5c319
18 changed files with 625 additions and 147 deletions

View file

@ -170,6 +170,15 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
<receiver android:name=".widget.AvatarStatsWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/avatar_widget_info" />
</receiver>
<service android:name=".widget.AvatarStatsWidgetService"/>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

View file

@ -0,0 +1,20 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Define the background properties like color etc -->
<item android:id="@android:id/background">
<shape>
<solid android:color="@color/brand_50" />
<corners android:radius="@dimen/bar_radius" />
</shape>
</item>
<!-- Define the progress properties like start color, end color etc -->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/xpColor" />
<corners android:radius="@dimen/bar_radius" />
</shape>
</clip>
</item>
</layer-list>

View file

@ -0,0 +1,20 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Define the background properties like color etc -->
<item android:id="@android:id/background">
<shape>
<solid android:color="@color/brand_50" />
<corners android:radius="@dimen/bar_radius" />
</shape>
</item>
<!-- Define the progress properties like start color, end color etc -->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/hpColor" />
<corners android:radius="@dimen/bar_radius" />
</shape>
</clip>
</item>
</layer-list>

View file

@ -0,0 +1,20 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Define the background properties like color etc -->
<item android:id="@android:id/background">
<shape>
<solid android:color="@color/brand_50" />
<corners android:radius="@dimen/bar_radius" />
</shape>
</item>
<!-- Define the progress properties like start color, end color etc -->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="@color/mpColor" />
<corners android:radius="@dimen/bar_radius" />
</shape>
</clip>
</item>
</layer-list>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- view background color -->
<solid
android:color="@color/widget_background" >
</solid>
<!-- Here is the corner radius -->
<corners
android:radius="5dp" >
</corners>
</shape>

View file

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_main_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@drawable/rounded_purple_square"
android:padding="8dp"
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<ImageView
android:id="@+id/avatar_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
android:layout_marginRight="8dp"
android:scaleType="centerInside"
android:adjustViewBounds="true"/>
<LinearLayout
android:id="@+id/LL_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_vertical">
<RelativeLayout
android:id="@+id/hp_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bar_padding"
android:orientation="horizontal">
<ImageView
android:id="@+id/ic_hp_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/bar_icon_padding"
android:layout_marginEnd="@dimen/bar_icon_padding"
android:layout_alignTop="@+id/hp_bar"
android:layout_alignBottom="@id/hp_bar"
android:scaleType="center"
android:contentDescription="@string/HP_default"
android:src="@drawable/ic_header_heart"/>
<ProgressBar
android:id="@+id/hp_bar"
android:layout_toRightOf="@id/ic_hp_header"
android:layout_toEndOf="@id/ic_hp_header"
android:layout_width="wrap_content"
android:layout_height="@dimen/bar_size_slim"
android:orientation="horizontal"
android:weightSum="1"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
style="@android:style/Widget.ProgressBar.Horizontal"
android:progressDrawable="@drawable/hp_progress"
android:paddingTop="1dp"
android:paddingBottom="1dp"/>
<LinearLayout
android:layout_below="@id/hp_bar"
android:layout_toRightOf="@id/ic_hp_header"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/TV_hp_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/brand_500"
android:textSize="11sp"/>
<TextView
android:id="@+id/TV_hp_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center|right"
android:layout_weight="1"
android:text="@string/HP_default"
android:textColor="@color/brand_500"
android:textSize="11sp"/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/exp_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/ic_exp_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/bar_icon_padding"
android:layout_marginEnd="@dimen/bar_icon_padding"
android:layout_alignTop="@+id/exp_bar"
android:layout_alignBottom="@+id/exp_bar"
android:scaleType="center"
android:contentDescription="Bar Icon"
android:src="@drawable/ic_header_exp"/>
<ProgressBar
android:id="@+id/exp_bar"
android:layout_toRightOf="@id/ic_exp_header"
android:layout_toEndOf="@id/ic_exp_header"
android:layout_width="wrap_content"
android:layout_height="@dimen/bar_size_slim"
android:orientation="horizontal"
android:weightSum="1"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
style="@android:style/Widget.ProgressBar.Horizontal"
android:progressDrawable="@drawable/exp_progress"
android:paddingTop="1dp"
android:paddingBottom="1dp"/>
<LinearLayout
android:layout_below="@id/exp_bar"
android:layout_toRightOf="@id/ic_exp_header"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/exp_TV_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/brand_500"
android:textSize="11sp"/>
<TextView
android:id="@+id/exp_TV_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center|right"
android:layout_weight="1"
android:text="@string/XP_default"
android:textColor="@color/brand_500"
android:textSize="11sp"/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/mp_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/bar_padding"
android:orientation="horizontal">
<ImageView
android:id="@+id/ic_mp_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/bar_icon_padding"
android:layout_marginEnd="@dimen/bar_icon_padding"
android:layout_alignTop="@+id/mp_bar"
android:layout_alignBottom="@+id/mp_bar"
android:scaleType="center"
android:contentDescription="Bar Icon"
android:src="@drawable/ic_header_magic" />
<ProgressBar
android:id="@+id/mp_bar"
android:layout_toRightOf="@id/ic_mp_header"
android:layout_toEndOf="@id/ic_mp_header"
android:layout_width="wrap_content"
android:layout_height="@dimen/bar_size_slim"
android:orientation="horizontal"
android:weightSum="1"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
style="@android:style/Widget.ProgressBar.Horizontal"
android:progressDrawable="@drawable/mp_progress"
android:paddingTop="1dp"
android:paddingBottom="1dp"/>
<LinearLayout
android:layout_below="@id/mp_bar"
android:layout_toRightOf="@id/ic_mp_header"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/mp_TV_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="@color/brand_500"
android:textSize="11sp"/>
<TextView
android:id="@+id/mp_TV_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center|right"
android:layout_weight="1"
android:text="@string/MP_default"
android:textColor="@color/brand_500"
android:textSize="11sp"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/detail_info_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/bar_padding_small">
<TextView
android:id="@+id/lvl_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="14sp"
android:textColor="@color/textColorSecondaryDark" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="@+id/gems_tv"
android:drawableLeft="@drawable/ic_header_gem"
android:drawableStart="@drawable/ic_header_gem"
android:layout_width="wrap_content"
android:gravity="center"
android:drawablePadding="8dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/textColorSecondaryDark"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
/>
<TextView
android:id="@+id/gold_tv"
android:drawableLeft="@drawable/ic_header_gold"
android:drawableStart="@drawable/ic_header_gold"
android:layout_width="wrap_content"
android:gravity="center"
android:drawablePadding="6dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/textColorSecondaryDark"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
/>
<TextView
android:id="@+id/silver_tv"
android:drawableLeft="@drawable/ic_header_silver"
android:drawableStart="@drawable/ic_header_silver"
android:layout_width="wrap_content"
android:gravity="center"
android:drawablePadding="6dp"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/textColorSecondaryDark"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -100,4 +100,6 @@
<color name="btn_warning">#fff0ad4e</color>
<color name="btn_danger">#ffd9534f</color>
<color name="widget_background">#c8432874</color>
</resources>

View file

@ -17,6 +17,7 @@
<dimen name="bar_size">15dp</dimen>
<dimen name="bar_padding">5dp</dimen>
<dimen name="bar_padding_small">2dp</dimen>
<dimen name="bar_radius">5dp</dimen>
<dimen name="avatar_width">140dp</dimen>
<dimen name="avatar_height">147dp</dimen>
@ -77,4 +78,5 @@
<dimen name="task_right_border_width">5dp</dimen>
<dimen name="header_bar_spacing">7dp</dimen>
<dimen name="habit_circle_background_size">40dp</dimen>
<dimen name="bar_size_slim">13dp</dimen>
</resources>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_avatar_stats"
android:minHeight="40dp"
android:minWidth="180dp"
android:updatePeriodMillis="1800000"
android:resizeMode="horizontal|vertical">
</appwidget-provider>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/simple_widget"
android:minHeight="40dp"
android:minWidth="180dp"
android:updatePeriodMillis="1800000" >
</appwidget-provider>

View file

@ -17,8 +17,6 @@ import com.magicmicky.habitrpgwrapper.lib.models.Customization;
import com.magicmicky.habitrpgwrapper.lib.models.FAQArticle;
import com.magicmicky.habitrpgwrapper.lib.models.Group;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest;
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
import com.magicmicky.habitrpgwrapper.lib.models.Purchases;
import com.magicmicky.habitrpgwrapper.lib.models.Skill;
import com.magicmicky.habitrpgwrapper.lib.models.TutorialStep;
@ -68,13 +66,12 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Build;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
@ -82,11 +79,9 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import okhttp3.Interceptor;
import okhttp3.MediaType;
@ -95,8 +90,6 @@ import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import retrofit2.Call;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.HttpException;

View file

@ -53,7 +53,7 @@ import com.habitrpg.android.habitica.ui.fragments.social.party.PartyInviteFragme
import com.habitrpg.android.habitica.ui.fragments.social.party.PartyMemberListFragment;
import com.habitrpg.android.habitica.ui.fragments.tasks.TaskRecyclerViewFragment;
import com.habitrpg.android.habitica.ui.fragments.tasks.TasksFragment;
import com.habitrpg.android.habitica.widget.UpdateWidgetService;
import com.habitrpg.android.habitica.widget.AvatarStatsWidgetService;
import javax.inject.Singleton;
@ -62,7 +62,7 @@ import dagger.Component;
@Singleton
@Component(modules = {AppModule.class, ApiModule.class})
public interface AppComponent {
void inject(UpdateWidgetService target);
void inject(AvatarStatsWidgetService target);
void inject(ClassSelectionActivity classSelectionActivity);

View file

@ -117,18 +117,15 @@ public class AvatarWithBarsViewModel implements View.OnClickListener {
switch (stats.get_class()) {
case warrior:
drawable = ResourcesCompat.getDrawable(res, R.drawable.ic_header_warrior, null);
break;
case rogue:
drawable = ResourcesCompat.getDrawable(res, R.drawable.ic_header_rogue, null);
break;
case wizard:
drawable = ResourcesCompat.getDrawable(res, R.drawable.ic_header_mage, null);
break;
case healer:
drawable = ResourcesCompat.getDrawable(res, R.drawable.ic_header_healer, null);
break;
case base:
default:

View file

@ -46,6 +46,7 @@ import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils;
import com.habitrpg.android.habitica.ui.helpers.UiUtils;
import com.habitrpg.android.habitica.ui.menu.MainDrawerBuilder;
import com.habitrpg.android.habitica.userpicture.BitmapUtils;
import com.habitrpg.android.habitica.widget.AvatarStatsWidgetProvider;
import com.magicmicky.habitrpgwrapper.lib.api.MaintenanceApiService;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.Preferences;
@ -97,6 +98,8 @@ import org.solovyev.android.checkout.Checkout;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@ -286,6 +289,20 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
}
}
@Override
protected void onPause() {
updateWidgets(AvatarStatsWidgetProvider.class);
super.onPause();
}
private void updateWidgets(Class widgetClass) {
Intent intent = new Intent(this,widgetClass);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
int ids[] = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), widgetClass));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,ids);
sendBroadcast(intent);
}
private void setupCheckout() {
checkout = Checkout.forActivity(this, HabiticaApplication.getInstance(this).getCheckout());
checkout.start();

View file

@ -0,0 +1,105 @@
package com.habitrpg.android.habitica.widget;
import com.habitrpg.android.habitica.R;
import android.annotation.TargetApi;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
public class AvatarStatsWidgetProvider extends AppWidgetProvider {
private static final String LOG = AvatarStatsWidgetProvider.class.getName();
/**
* Returns number of cells needed for given size of the widget.<br/>
* see http://stackoverflow.com/questions/14270138/dynamically-adjusting-widgets-content-and-layout-to-the-size-the-user-defined-t
*
* @param size Widget size in dp.
* @return Size in number of cells.
*/
private static int getCellsForSize(int size) {
int n = 2;
while (70 * n - 30 < size) {
++n;
}
return n - 1;
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
AvatarStatsWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
if (Build.VERSION.SDK_INT >= 16) {
for (int widgetId : allWidgetIds) {
Bundle options = appWidgetManager.getAppWidgetOptions(widgetId);
appWidgetManager.partiallyUpdateAppWidget(widgetId,
configureRemoteViews(context, options));
}
}
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
AvatarStatsWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
appWidgetManager.partiallyUpdateAppWidget(appWidgetId,
configureRemoteViews(context, options));
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId,
newOptions);
}
/**
* Determine appropriate view based on width provided.<br/>
* see http://stackoverflow.com/questions/14270138/dynamically-adjusting-widgets-content-and-layout-to-the-size-the-user-defined-t
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private RemoteViews configureRemoteViews(Context context, Bundle options) {
int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int minHeight = options
.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
// First find out rows and columns based on width provided.
int rows = getCellsForSize(minHeight);
int columns = getCellsForSize(minWidth);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_avatar_stats);
if (columns > 3) {
remoteViews.setViewVisibility(R.id.avatar_view, View.VISIBLE);
} else {
remoteViews.setViewVisibility(R.id.avatar_view, View.GONE);
}
if (rows > 1) {
remoteViews.setViewVisibility(R.id.mp_wrapper, View.VISIBLE);
remoteViews.setViewVisibility(R.id.detail_info_view, View.VISIBLE);
} else {
remoteViews.setViewVisibility(R.id.mp_wrapper, View.GONE);
remoteViews.setViewVisibility(R.id.detail_info_view, View.GONE);
}
return remoteViews;
}
}

View file

@ -0,0 +1,122 @@
package com.habitrpg.android.habitica.widget;
import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.HostConfig;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback;
import com.habitrpg.android.habitica.ui.AvatarView;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.Stats;
import com.raizlabs.android.dbflow.runtime.transaction.BaseTransaction;
import com.raizlabs.android.dbflow.runtime.transaction.TransactionListener;
import com.raizlabs.android.dbflow.sql.builder.Condition;
import com.raizlabs.android.dbflow.sql.language.Select;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import javax.inject.Inject;
/**
* The service that should update the simple widget
*
* @see com.habitrpg.android.habitica.widget.SimpleWidget
* Created by Mickael on 01/11/13.
*/
public class AvatarStatsWidgetService extends Service {
private static final String LOG = ".avatarwidget.service";
@Inject
public HostConfig hostConfig;
private AppWidgetManager appWidgetManager;
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
HabiticaApplication application = (HabiticaApplication) getApplication();
application.getComponent().inject(this);
this.appWidgetManager = AppWidgetManager.getInstance(this);
new Select().from(HabitRPGUser.class).where(Condition.column("id").eq(hostConfig.getUser())).async().querySingle(userTransactionListener);
stopSelf();
return START_STICKY;
}
private TransactionListener<HabitRPGUser> userTransactionListener = new TransactionListener<HabitRPGUser>() {
@Override
public void onResultReceived(HabitRPGUser habitRPGUser) {
updateData(habitRPGUser);
}
@Override
public boolean onReady(BaseTransaction<HabitRPGUser> baseTransaction) {
return true;
}
@Override
public boolean hasResult(BaseTransaction<HabitRPGUser> baseTransaction, HabitRPGUser habitRPGUser) {
return true;
}
};
private void updateData(HabitRPGUser user) {
if (user == null || user.getStats() == null) {
return;
}
Stats stats = user.getStats();
ComponentName thisWidget = new ComponentName(this, AvatarStatsWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
String healthValueString = "" + stats.getHp().intValue() + "/" + stats.getMaxHealth();
String expValueString = "" + stats.getExp().intValue() + "/" + stats.getToNextLevel();
String mpValueString = "" + stats.getMp().intValue() + "/" + stats.getMaxMP();
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.widget_avatar_stats);
remoteViews.setTextViewText(R.id.TV_hp_value, healthValueString);
remoteViews.setTextViewText(R.id.exp_TV_value, expValueString);
remoteViews.setTextViewText(R.id.mp_TV_value, mpValueString);
remoteViews.setProgressBar(R.id.hp_bar, stats.getMaxHealth(), stats.getHp().intValue(), false);
remoteViews.setProgressBar(R.id.exp_bar, stats.getToNextLevel(), stats.getExp().intValue(), false);
remoteViews.setProgressBar(R.id.mp_bar, stats.getMaxMP(), stats.getMp().intValue(), false);
remoteViews.setViewVisibility(R.id.mp_wrapper, (stats.get_class() == null || stats.getLvl() < 10 || user.getPreferences().getDisableClasses()) ? View.GONE : View.VISIBLE);
int gp = (stats.getGp().intValue());
int sp = (int) ((stats.getGp() - gp) * 100);
remoteViews.setTextViewText(R.id.gold_tv, String.valueOf(gp));
remoteViews.setTextViewText(R.id.silver_tv, String.valueOf(sp));
remoteViews.setTextViewText(R.id.gems_tv, String.valueOf((int)(user.getBalance() * 4)));
remoteViews.setTextViewText(R.id.lvl_tv, getString(R.string.user_level, user.getStats().getLvl()));
AvatarView avatarView = new AvatarView(this, true, true, true);;
avatarView.setUser(user);
avatarView.onAvatarImageReady(bitmap -> {
Log.e("AVATAR BITMAP", bitmap.toString());
remoteViews.setImageViewBitmap(R.id.avatar_view, bitmap);
appWidgetManager.partiallyUpdateAppWidget(allWidgetIds, remoteViews);
});
Log.e("AVATAR THING", "BLA");
//If user click on life and xp: open the app
Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp);
appWidgetManager.partiallyUpdateAppWidget(allWidgetIds, remoteViews);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View file

@ -43,9 +43,17 @@ public class SimpleWidget extends AppWidgetProvider {
ComponentName thisWidget = new ComponentName(context,
SimpleWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
if (Build.VERSION.SDK_INT >= 16) {
for (int widgetId : allWidgetIds) {
Bundle options = appWidgetManager.getAppWidgetOptions(widgetId);
appWidgetManager.updateAppWidget(widgetId,
getRemoteViews(context, options));
}
}
// Build the intent to call the service
Intent intent = new Intent(context.getApplicationContext(),
UpdateWidgetService.class);
AvatarStatsWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
// Update the widgets via the service
@ -58,12 +66,8 @@ public class SimpleWidget extends AppWidgetProvider {
Log.v(LOG, "onAppWidgetOptionChanged call");
Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);
int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int minHeight = options
.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
appWidgetManager.updateAppWidget(appWidgetId,
getRemoteViews(context, minWidth, minHeight));
getRemoteViews(context, options));
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId,
newOptions);
@ -74,8 +78,13 @@ public class SimpleWidget extends AppWidgetProvider {
* Determine appropriate view based on width provided.<br/>
* see http://stackoverflow.com/questions/14270138/dynamically-adjusting-widgets-content-and-layout-to-the-size-the-user-defined-t
*/
private RemoteViews getRemoteViews(Context context, int minWidth,
int minHeight) {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private RemoteViews getRemoteViews(Context context, Bundle options) {
int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
int minHeight = options
.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
// First find out rows and columns based on width provided.
int rows = getCellsForSize(minHeight);
int columns = getCellsForSize(minWidth);

View file

@ -1,118 +0,0 @@
package com.habitrpg.android.habitica.widget;
import com.habitrpg.android.habitica.APIHelper;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.callbacks.HabitRPGUserCallback;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.widget.RemoteViews;
import javax.inject.Inject;
/**
* The service that should update the simple widget
*
* @see com.habitrpg.android.habitica.widget.SimpleWidget
* Created by Mickael on 01/11/13.
*/
public class UpdateWidgetService extends Service implements HabitRPGUserCallback.OnUserReceived {
private static final String LOG = ".simplewidget.service";
@Inject
public APIHelper apiHelper;
private AppWidgetManager appWidgetManager;
public UpdateWidgetService() {
super();
((HabiticaApplication) getApplication()).getComponent().inject(this);
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
this.appWidgetManager = AppWidgetManager.getInstance(this);
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(this,
SimpleWidget.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
if (apiHelper != null) {
apiHelper.retrieveUser(true).subscribe(new HabitRPGUserCallback(this));
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.simple_widget);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
} else {
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.simple_widget);
RemoteViews textConnect = new RemoteViews(this.getPackageName(), R.layout.simple_textview);
textConnect.setTextViewText(R.id.TV_simple_textview, getString(R.string.please_connect));
remoteViews.removeAllViews(R.id.LL_header);
remoteViews.addView(R.id.LL_header, textConnect);
Intent clickIntent = new Intent(this.getApplicationContext(), SimpleWidget.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
PendingIntent updateIntent = PendingIntent.getBroadcast(this, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.BT_refresh, updateIntent);
Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_main_view, openApp);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
stopSelf();
return START_STICKY;
}
private void updateData(HabitRPGUser user, AppWidgetManager appWidgetManager) {
ComponentName thisWidget = new ComponentName(this, SimpleWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.simple_widget);
remoteViews.setTextViewText(R.id.TV_HP, "" + user.getStats().getHp().intValue() + "/" + (int) user.getStats().getMaxHealth() + " " + this.getString(R.string.HP_default));
remoteViews.setTextViewText(R.id.TV_XP, "" + user.getStats().getExp().intValue() + "/" + (int) user.getStats().getToNextLevel() + " " + this.getString(R.string.XP_default));
//remoteViews.setImageViewBitmap(R.id.IMG_ProfilePicture, dealWithUserPicture(user,this));
remoteViews.setProgressBar(R.id.V_HPBar, (int) user.getStats().getMaxHealth(), user.getStats().getHp().intValue(), false);
remoteViews.setProgressBar(R.id.V_XPBar, (int) user.getStats().getToNextLevel(), user.getStats().getExp().intValue(), false);
// If user click on refresh: refresh
Intent clickIntent = new Intent(this.getApplicationContext(), SimpleWidget.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
PendingIntent updateIntent = PendingIntent.getBroadcast(this, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.BT_refresh, updateIntent);
//If user click on life and xp: open the app
Intent openAppIntent = new Intent(this.getApplicationContext(), MainActivity.class);
PendingIntent openApp = PendingIntent.getActivity(this, 0, openAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.LL_header, openApp);
remoteViews.setOnClickPendingIntent(R.id.IMG_ProfilePicture, openApp);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onUserReceived(HabitRPGUser user) {
this.updateData(user, appWidgetManager);
}
}