ch.fixme.status.Widget.java Source code

Java tutorial

Introduction

Here is the source code for ch.fixme.status.Widget.java

Source

/*
 * Copyright (C) 2012-2013 Aubort Jean-Baptiste (Rorist)
 * Licensed under GNU's GPL 2, see README
 */

package ch.fixme.status;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;

import org.json.JSONException;

import java.util.HashMap;

public class Widget extends AppWidgetProvider {

    static final String WIDGET_IDS = "widget_ids";
    static final String WIDGET_FORCE = "widget_force";

    public void onReceive(Context ctxt, Intent intent) {
        String action = intent.getAction();
        if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
            // Remove widget alarm
            int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
            PendingIntent pi = PendingIntent.getService(ctxt, widgetId, getIntent(ctxt, widgetId), 0);
            AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
            am.cancel(pi);

            // remove preference
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctxt);
            Editor edit = prefs.edit();
            edit.remove(Main.PREF_API_URL_WIDGET + widgetId);
            edit.remove(Main.PREF_INIT_WIDGET + widgetId);
            edit.remove(Main.PREF_LAST_WIDGET + widgetId);
            edit.remove(Main.PREF_FORCE_WIDGET + widgetId);
            edit.commit();

            // Log.i(Main.TAG, "Remove widget alarm for id=" + widgetId);
        } else if (intent.hasExtra(WIDGET_IDS) && AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
            int[] ids = intent.getExtras().getIntArray(WIDGET_IDS);
            onUpdate(ctxt, AppWidgetManager.getInstance(ctxt), ids);
        } else
            super.onReceive(ctxt, intent);
    }

    public void onUpdate(Context ctxt, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            int widgetId = appWidgetIds[i];
            Intent intent = getIntent(ctxt, widgetId);
            // Set initialize
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctxt);
            Editor edit = prefs.edit();
            edit.putBoolean(Main.PREF_INIT_WIDGET + widgetId, false);
            edit.commit();
            // Update timer
            setAlarm(ctxt, intent, widgetId);
            // Log.i(Main.TAG, "Update widget alarm for id=" + widgetId);
        }
        super.onUpdate(ctxt, appWidgetManager, appWidgetIds);
    }

    protected static Intent getIntent(Context ctxt, int widgetId) {
        Intent i = new Intent(ctxt, UpdateService.class);
        i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        return i;
    }

    protected static void setAlarm(Context ctxt, Intent i, int widgetId) {
        setAlarm(ctxt, i, widgetId, 0);
    }

    protected static void setAlarm(Context ctxt, Intent i, int widgetId, int delay) {
        // Get interval
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctxt);
        long update_interval = Long
                .parseLong(prefs.getString(Prefs.KEY_CHECK_INTERVAL, Prefs.DEFAULT_CHECK_INTERVAL)) * 60L * 1000L;
        // Set alarm
        AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
        PendingIntent pi = PendingIntent.getService(ctxt, widgetId, i, 0);
        am.cancel(pi);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + delay, update_interval, pi);
        // Log.i(Main.TAG, "start notification every " + update_interval / 1000
        // + "s");
    }

    private static class GetImage extends AsyncTask<String, Void, Bitmap> {

        private int mId;
        private Context mCtxt;
        private String mText;

        public GetImage(Context ctxt, int id, String text) {
            mCtxt = ctxt;
            mId = id;
            mText = text;
        }

        @Override
        protected Bitmap doInBackground(String... url) {
            try {
                // Log.i(Main.TAG, "Get image from url " + url[0]);
                return new Net(url[0]).getBitmap();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            AppWidgetManager manager = AppWidgetManager.getInstance(mCtxt);
            updateWidget(mCtxt, mId, manager, result, mText);
        }

    }

    protected static void updateWidget(final Context ctxt, int widgetId, AppWidgetManager manager, Bitmap bitmap,
            String text) {
        RemoteViews views = new RemoteViews(ctxt.getPackageName(), R.layout.widget);
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctxt);
        Editor edit = prefs.edit();
        if (prefs.getBoolean(Prefs.KEY_WIDGET_TRANSPARENCY, Prefs.DEFAULT_WIDGET_TRANSPARENCY)) {
            views.setInt(R.id.widget_image, "setBackgroundResource", 0);
        } else {
            views.setInt(R.id.widget_image, "setBackgroundResource", android.R.drawable.btn_default_small);
        }
        if (bitmap != null) {
            views.setImageViewBitmap(R.id.widget_image, bitmap);
            edit.putBoolean(Main.PREF_FORCE_WIDGET + widgetId, false); // Don't
            // need
            // to
            // force
        } else {
            views.setImageViewResource(R.id.widget_image, android.R.drawable.ic_popup_sync);
            edit.putBoolean(Main.PREF_FORCE_WIDGET + widgetId, true); // Something
            // went
            // wrong
        }
        if (text != null) {
            views.setTextViewText(R.id.widget_status, text);
            views.setViewVisibility(R.id.widget_status, View.VISIBLE);
        } else {
            views.setViewVisibility(R.id.widget_status, View.GONE);
        }
        Intent clickIntent = new Intent(ctxt, Main.class);
        clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
        PendingIntent pendingIntent = PendingIntent.getActivity(ctxt, widgetId, clickIntent,
                PendingIntent.FLAG_CANCEL_CURRENT);
        views.setOnClickPendingIntent(R.id.widget_image, pendingIntent);
        manager.updateAppWidget(widgetId, views);
        // Is initialized
        edit.putBoolean(Main.PREF_INIT_WIDGET + widgetId, true);
        edit.commit();
    }

    private static class GetApiTask extends AsyncTask<String, Void, String> {

        private int mId;
        private Context mCtxt;

        public GetApiTask(Context ctxt, int id) {
            mCtxt = ctxt;
            mId = id;
        }

        @Override
        protected String doInBackground(String... url) {
            try {
                return new Net(url[0]).getString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }

        @Override
        protected void onCancelled() {
            // Set alarm 5 seconds in the future
            Log.i(Main.TAG, "Set alarm in 5 seconds");
            Intent intent = getIntent(mCtxt, mId);
            setAlarm(mCtxt, intent, mId, 1000);
        }

        @Override
        protected void onPostExecute(String result) {
            try {
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mCtxt);

                HashMap<String, Object> api = new ParseGeneric(result).getData();
                boolean statusBool = (Boolean) api.get(ParseGeneric.API_STATUS);
                // Update only if different than last status and not the first
                // time
                if (prefs.getBoolean(Main.PREF_LAST_WIDGET + mId, false) == statusBool
                        && prefs.getBoolean(Main.PREF_INIT_WIDGET + mId, false)
                        && !prefs.getBoolean(Main.PREF_FORCE_WIDGET + mId, false)) {
                    // Log.i(Main.TAG, "Nothing to update");
                    return;
                }

                // Mandatory fields
                String status = ParseGeneric.API_ICON + ParseGeneric.API_ICON_CLOSED;
                if (statusBool) {
                    status = ParseGeneric.API_ICON + ParseGeneric.API_ICON_OPEN;
                }
                Editor edit = prefs.edit();
                edit.putBoolean(Main.PREF_LAST_WIDGET + mId, statusBool);
                edit.commit();

                String status_text = null;
                if (prefs.getBoolean(Prefs.KEY_WIDGET_TEXT, Prefs.DEFAULT_WIDGET_TEXT)) {
                    if (api.containsKey(ParseGeneric.API_STATUS_TXT)) {
                        status_text = (String) api.get(ParseGeneric.API_STATUS_TXT);
                    } else {
                        status_text = statusBool ? Main.OPEN : Main.CLOSED;
                    }
                }

                // Status icon or space icon
                if (api.containsKey(ParseGeneric.API_ICON + ParseGeneric.API_ICON_OPEN)
                        && api.containsKey(ParseGeneric.API_ICON + ParseGeneric.API_ICON_CLOSED)) {
                    new GetImage(mCtxt, mId, status_text).execute((String) api.get(status));
                } else {
                    new GetImage(mCtxt, mId, status_text).execute((String) api.get(ParseGeneric.API_LOGO));
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    public static class UpdateService extends IntentService {

        public UpdateService() {
            super("MyHackerspaceWidgetService");
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            final Context ctxt = UpdateService.this;
            int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctxt);
            if (prefs.contains(Main.PREF_API_URL_WIDGET + widgetId)) {
                String url = prefs.getString(Main.PREF_API_URL_WIDGET + widgetId, ParseGeneric.API_DEFAULT);
                Log.i(Main.TAG, "Update widgetid " + widgetId + " with url " + url);
                new GetApiTask(ctxt, widgetId).execute(url);
            }
            stopSelf();
        }
    }

    public static void UpdateAllWidgets(final Context ctxt) {
        AppWidgetManager man = AppWidgetManager.getInstance(ctxt);
        int[] ids = man.getAppWidgetIds(new ComponentName(ctxt, Widget.class));
        Intent ui = new Intent();
        ui.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        ui.putExtra(Widget.WIDGET_IDS, ids);
        ui.putExtra(Widget.WIDGET_FORCE, true);
        ctxt.sendBroadcast(ui);
    }

}