/* * Copyright (C) 2010 Nullbyte <http://nullbyte.eu> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.liato.bankdroid.appwidget; import com.liato.bankdroid.Helpers; import com.liato.bankdroid.MainActivity; import com.liato.bankdroid.R; import com.liato.bankdroid.banking.Account; import com.liato.bankdroid.banking.Bank; import com.liato.bankdroid.banking.BankFactory; import com.liato.bankdroid.banking.exceptions.BankChoiceException; import com.liato.bankdroid.banking.exceptions.BankException; import com.liato.bankdroid.banking.exceptions.LoginException; import com.liato.bankdroid.db.DBAdapter; import com.liato.bankdroid.utils.NetworkUtils; import android.app.PendingIntent; import android.app.Service; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; import android.os.IBinder; import android.preference.PreferenceManager; import android.view.View; import android.widget.RemoteViews; import java.io.IOException; import timber.log.Timber; public abstract class BankdroidWidgetProvider extends AppWidgetProvider { private final static String TAG = "BankdroidWidgetProvider"; private final static String ACTION_WIDGET_BLUR = "com.liato.bankdroid.action.WIDGET_BLUR"; private final static String ACTION_WIDGET_UNBLUR = "com.liato.bankdroid.action.WIDGET_UNBLUR"; static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Account account) { RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId, account); if (views != null) { appWidgetManager.updateAppWidget(appWidgetId, views); } } static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId); if (views != null) { appWidgetManager.updateAppWidget(appWidgetId, views); } } static void unblurAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0); Editor e = prefs.edit(); e.putBoolean("widget_unblurred_" + appWidgetId, true); e.apply(); RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId); if (views != null) { views.setViewVisibility(R.id.imgBalanceblur, View.GONE); views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.GONE); views.setViewVisibility(R.id.txtWidgetAccountbalance, View.VISIBLE); views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE); appWidgetManager.updateAppWidget(appWidgetId, views); } } static void blurAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0); Editor e = prefs.edit(); e.remove("widget_unblurred_" + appWidgetId); e.apply(); RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId); if (views != null) { views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE); views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE); views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE); views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE); appWidgetManager.updateAppWidget(appWidgetId, views); } } static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId); long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId); if (accountId == null) { Timber.w("Widget not found. ID: %s", appWidgetId); return disableAppWidget(context, appWidgetManager, appWidgetId); } Account account = BankFactory.accountFromDb(context, bankId + "_" + accountId, false); if (account == null) { Timber.w("Account not found in database"); return disableAppWidget(context, appWidgetManager, appWidgetId); } Bank bank = BankFactory.bankFromDb(account.getBankDbId(), context, false); if (bank == null) { Timber.w("Bank not found in database"); return disableAppWidget(context, appWidgetManager, appWidgetId); } account.setBank(bank); return buildAppWidget(context, appWidgetManager, appWidgetId, account); } static RemoteViews buildAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Account account) { AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId); int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout; SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0); SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context); if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) { if (providerInfo.initialLayout == R.layout.widget_large) { layoutId = R.layout.widget_large_transparent; } else { layoutId = R.layout.widget_transparent; } } Bank bank = account.getBank(); RemoteViews views = new RemoteViews(context.getPackageName(), layoutId); views.setTextViewText(R.id.txtWidgetAccountname, account.getName().toUpperCase()); views.setTextViewText(R.id.txtWidgetAccountnameBlur, account.getName().toUpperCase()); views.setTextViewText(R.id.txtWidgetAccountbalance, Helpers.formatBalance(account.getBalance(), account.getCurrency(), defprefs.getBoolean("round_widget_balance", false), bank.getDecimalFormatter(), bank.isDisabled())); views.setImageViewResource(R.id.imgWidgetIcon, bank.getImageResource()); Intent intent = new Intent(context, MainActivity.class); PendingIntent pendingIntent; //intent = new Intent(context, AccountsActivity.class); pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent); intent = new Intent(context, WidgetService.class); intent.setAction(AutoRefreshService.BROADCAST_WIDGET_REFRESH); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); intent.setData( Uri.parse("rofl://copter/" + appWidgetId + "/" + System.currentTimeMillis())); pendingIntent = PendingIntent .getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.imgWidgetIcon, pendingIntent); views.setOnClickPendingIntent(R.id.hitBox, pendingIntent); intent = new Intent(context, WidgetService.class); intent.setAction(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); intent.setData(Uri.parse( "rofl://copter/widgetunblur/" + appWidgetId + "/" + System.currentTimeMillis())); pendingIntent = PendingIntent .getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.imgBalanceblur, pendingIntent); if (defprefs.getBoolean("widget_blur_balance", false) && !prefs .getBoolean("widget_unblurred_" + appWidgetId, false)) { views.setViewVisibility(R.id.imgBalanceblur, View.VISIBLE); views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.VISIBLE); views.setViewVisibility(R.id.txtWidgetAccountbalance, View.GONE); views.setViewVisibility(R.id.txtWidgetAccountname, View.GONE); views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent); } else { views.setViewVisibility(R.id.imgBalanceblur, View.GONE); views.setViewVisibility(R.id.txtWidgetAccountnameBlur, View.GONE); views.setViewVisibility(R.id.txtWidgetAccountbalance, View.VISIBLE); views.setViewVisibility(R.id.txtWidgetAccountname, View.VISIBLE); intent = new Intent(context, MainActivity.class); intent.setAction(AutoRefreshService.ACTION_MAIN_SHOW_TRANSACTIONS); intent.setData(Uri.parse("rofl://copter/showtransactions/" + appWidgetId + "/" + System .currentTimeMillis())); intent.putExtra("bank", bank.getDbId()); intent.putExtra("account", account.getId()); pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent); views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent); } return views; } static RemoteViews disableAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { AppWidgetProviderInfo providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId); int layoutId = (providerInfo == null) ? R.layout.widget : providerInfo.initialLayout; SharedPreferences prefs = context.getSharedPreferences("widget_prefs", 0); if (prefs.getBoolean("transperant_background" + appWidgetId, false) && (providerInfo != null)) { if (providerInfo.initialLayout == R.layout.widget_large) { layoutId = R.layout.widget_large_transparent; } else { layoutId = R.layout.widget_transparent; } } RemoteViews views = new RemoteViews(context.getPackageName(), layoutId); views.setTextViewText(R.id.txtWidgetAccountname, ""); views.setTextViewText(R.id.txtWidgetAccountbalance, "ERROR"); views.setImageViewResource(R.id.imgWidgetIcon, R.drawable.icon_large); Intent intent = new Intent(context, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.txtWidgetAccountbalance, pendingIntent); views.setOnClickPendingIntent(R.id.layWidgetContainer, pendingIntent); return views; } public void onReceive(Context context, Intent intent) { // v1.5 fix that doesn't call onDelete Action final String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) { final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { this.onDeleted(context, new int[]{appWidgetId}); } } else { super.onReceive(context, intent); } if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH) || action .equals(android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE)) { AppWidgetManager appWM = AppWidgetManager.getInstance(context); int[] appWidgetIds = appWM.getAppWidgetIds(intent.getComponent()); final int N = appWidgetIds.length; for (int i = 0; i < N; i++) { int appWidgetId = appWidgetIds[i]; updateAppWidget(context, appWM, appWidgetId); } } } @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); final int N = appWidgetIds.length; for (int i = 0; i < N; i++) { WidgetConfigureActivity.delAccountId(context, appWidgetIds[i]); } } public static class WidgetService extends Service { @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); handleStart(intent, startId); } @Override public int onStartCommand(Intent intent, int flags, int startId) { handleStart(intent, startId); return START_NOT_STICKY; } public void handleStart(Intent intent, int startId) { if (intent == null) { return; } int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); Context context = getApplicationContext(); String action = intent.getAction(); if (action == null) { return; } if (action.equals(AutoRefreshService.BROADCAST_WIDGET_REFRESH)) { new WidgetUpdateTask(context, AppWidgetManager.getInstance(context), appWidgetId) .execute(); } else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_UNBLUR)) { unblurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId); Handler blurHandler = new Handler(); class BlurRunnable implements Runnable { private int mAppWidgetId; public BlurRunnable(int appWidgetId) { this.mAppWidgetId = appWidgetId; } @Override public void run() { Context context = getApplicationContext(); blurAppWidget(context, AppWidgetManager.getInstance(context), mAppWidgetId); } } SharedPreferences defprefs = PreferenceManager.getDefaultSharedPreferences(context); Integer unblurTimeout = 1000 * Integer .parseInt(defprefs.getString("widget_blur_balance_timeout", "5")); blurHandler.postDelayed(new BlurRunnable(appWidgetId), unblurTimeout); } else if (action.equals(BankdroidWidgetProvider.ACTION_WIDGET_BLUR)) { blurAppWidget(context, AppWidgetManager.getInstance(context), appWidgetId); } } @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } protected class WidgetUpdateTask extends AsyncTask<Void, Void, Void> { private Context context; private AppWidgetManager appWidgetManager; private int appWidgetId; private SharedPreferences prefs; public WidgetUpdateTask(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { this.context = context; this.appWidgetManager = appWidgetManager; this.appWidgetId = appWidgetId; this.prefs = PreferenceManager.getDefaultSharedPreferences(context); } @Override protected void onPreExecute() { super.onPreExecute(); RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId); if (views != null) { views.setViewVisibility(R.id.frmProgress, View.VISIBLE); appWidgetManager.updateAppWidget(appWidgetId, views); } } @Override protected Void doInBackground(Void... params) { String accountId = WidgetConfigureActivity.getAccountId(context, appWidgetId); if (accountId == null) { Timber.w("Widget not found %d", appWidgetId); return null; } long bankId = WidgetConfigureActivity.getBankId(context, appWidgetId); Bank bank = BankFactory.bankFromDb(bankId, context, true); if (bank == null) { return null; } try { if (!bank.isDisabled()) { bank.update(); if (prefs.getBoolean("widget_updates_transactions", false)) { bank.updateAllTransactions(); } bank.closeConnection(); DBAdapter.save(bank, context); } } catch (BankException e) { Timber.e(e, "Could not update bank %s", bank.getName()); } catch (LoginException e) { Timber.w(e, "Invalid credentials for bank %s", bank.getName()); DBAdapter.disable(bank, context); } catch (BankChoiceException e) { Timber.w(e, "BankChoiceException"); } catch (IOException e) { if (NetworkUtils.isInternetAvailable()) { Timber.e(e, "Could not update bank %s", bank.getName()); } } BankdroidWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); RemoteViews views = buildAppWidget(context, appWidgetManager, appWidgetId); if (views != null) { views.setViewVisibility(R.id.frmProgress, View.INVISIBLE); appWidgetManager.updateAppWidget(appWidgetId, views); } WidgetService.this.stopSelf(); } } } }