Android Open Source - BodhiTimer Bodhi App Widget Provider






From Project

Back to project page BodhiTimer.

License

The source code is released under:

GNU General Public License

If you think the Android project BodhiTimer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
    This file is part of Bodhi Timer./*from   w  ww  .ja  v a2s  .c om*/

    Bodhi Timer 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.

    Bodhi Timer 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 Bodhi Timer.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.yuttadhammo.BodhiTimer.widget;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

import org.yuttadhammo.BodhiTimer.R;
import org.yuttadhammo.BodhiTimer.TimerActivity;
import org.yuttadhammo.BodhiTimer.TimerUtils;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.RemoteViews;
import android.content.ComponentName;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PorterDuff;

public class BodhiAppWidgetProvider extends AppWidgetProvider {

  private static SharedPreferences mSettings;

    private static int state;

  private static AppWidgetManager appWidgetManager;

  /** debug string */
  private final static String TAG = "BodhiAppWidgetProvider";

  private static Timer mTimer;

  private static boolean stopTicking;
  
  private boolean isRegistered = false;

  private int[] widgetIds;

  private Bitmap originalBitmap;

  private Context mContext;

    private HashMap<Integer,Integer> backgrounds;

  public static String ACTION_CLOCK_START = "org.yuttadhammo.BodhiTimer.ACTION_CLOCK_START";
  public static String ACTION_CLOCK_UPDATE = "org.yuttadhammo.BodhiTimer.ACTION_CLOCK_UPDATE";
  public static String ACTION_CLOCK_CANCEL = "org.yuttadhammo.BodhiTimer.ACTION_CLOCK_CANCEL";

  private static RemoteViews views;

  private static long timeStamp;

  private static int mLastTime;

  private static int themeid;
  
    public void onUpdate(Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) {
      Log.i(TAG,"onUpdate");

      if(!isRegistered) {
          context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_ON));
          context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
          isRegistered = true;
      }
      context.sendBroadcast(new Intent(ACTION_CLOCK_UPDATE));
    }
   
  @Override
  public void onEnabled(Context context) {
    super.onEnabled(context); 
      Log.i(TAG,"onEnabled");
      if(!isRegistered) {
          context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_ON));
          context.getApplicationContext().registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
          isRegistered = true;
      }      
      context.sendBroadcast(new Intent(ACTION_CLOCK_UPDATE));
  }

  @Override
  public void onDisabled(Context context) {
      Log.i(TAG,"onDisabled");
    super.onDisabled(context);
  
  
  }

    public void onDeleted(Context context, int[] appWidgetIds) {
        Log.d(TAG, "onDeleted");
        // When the user deletes the widget, delete the preference associated with it.
        final int N = appWidgetIds.length;
        for (int appWidgetId : appWidgetIds) {
            AppWidgetConfigure.deletePref(context, appWidgetId);
        }
    }
  
  @Override
  public void onReceive(Context context, Intent i) {
    super.onReceive(context, i);

    final String action = i.getAction();

        stopTicking = action.equals(TimerActivity.BROADCAST_STOP) || action.equals(Intent.ACTION_SCREEN_OFF);
    
    doUpdate(context);
        doTick();
  }
  
  private void doUpdate(Context context) {
      Log.i(TAG,"updating");

      mSettings = PreferenceManager.getDefaultSharedPreferences(context);
      mContext = context;
        if(views == null)
        views = new RemoteViews(context.getPackageName(), R.layout.appwidget);

      Intent intent = new Intent(context, TimerActivity.class);
        intent.putExtra("set", "true");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        
      if(!mSettings.getBoolean("custom_bmp", false) || mSettings.getString("bmp_url","").length() == 0) {
      Resources resources = context.getResources();
      originalBitmap = BitmapFactory.decodeResource(resources, R.drawable.leaf);
    }
    else {
      String bmpUrl = mSettings.getString("bmp_url", "");
      Uri selectedImage = Uri.parse(bmpUrl);
            InputStream imageStream = null;
      try {
        imageStream = context.getContentResolver().openInputStream(selectedImage);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      }
      originalBitmap = BitmapFactory.decodeStream(imageStream);
    }
    
    mTimer = new Timer();
      timeStamp = mSettings.getLong("TimeStamp", -1);
    mLastTime = mSettings.getInt("LastTime",0); 
    state = mSettings.getInt("State",TimerActivity.STOPPED); 

    appWidgetManager = AppWidgetManager.getInstance(context);
    ComponentName appWidgets = new ComponentName(context.getPackageName(), "org.yuttadhammo.BodhiTimer.widget.BodhiAppWidgetProvider");
    widgetIds = appWidgetManager.getAppWidgetIds(appWidgets);
    
        backgrounds = new HashMap<Integer,Integer>();
    if (widgetIds.length > 0){
            for (int widgetId : widgetIds) {

                // Get the layout for the App Widget and attach an on-click listener
                // to the button
                views.setOnClickPendingIntent(R.id.mainImage, pendingIntent);

                // set background
                themeid = mSettings.getInt("widget_theme_" + widgetId, R.drawable.widget_background_black_square);
                views.setImageViewResource(R.id.backImage, themeid);
                backgrounds.put(widgetId, themeid);
                appWidgetManager.updateAppWidget(widgetId, views);
            }
    }
  }
  
  int tick = 5;

  private Bitmap bmp;
  
    private void doTick() {
      //Log.e(TAG,"ticking");
    if (widgetIds.length == 0 || stopTicking)
      return;

    views = new RemoteViews(mContext.getPackageName(), R.layout.appwidget);

    Date now = new Date();
    Date then = new Date(timeStamp);

    int delta = (int)(then.getTime() - now.getTime());    
        
        //Log.d(TAG, "Delta: "+delta);
      
    // We still have a timer running!
    if(then.after(now) && state == TimerActivity.RUNNING){
          //Log.d(TAG, "running");
         views.setTextViewText(R.id.time, getTime(delta));
      mTimer.schedule( new TimerTask(){
              public void run() {
                if(mHandler != null){
                  mHandler.sendEmptyMessage(0);
                }
              }
            },
            TimerActivity.TIMER_TIC
      );
      }
    else if(state == TimerActivity.PAUSED){
          Log.d(TAG, "paused");

      Integer time = mSettings.getInt("CurrentTime",0);
          int rtime = Math.round(((float) time)/1000)*1000;  // round to seconds
            views.setTextViewText(R.id.time, TimerUtils.time2hms(rtime));
    }
    else {
          Log.d(TAG, "stopped");
            views.setTextViewText(R.id.time, "");
      }
      
    float p = (mLastTime != 0) ? (delta/(float)mLastTime) : 0;
    
    if(then.after(now) && state == TimerActivity.RUNNING) {
      if(bmp == null || ++tick == 10) {
        bmp = adjustOpacity(originalBitmap,(int)(255-(255*p)));
        tick = 0;
      }
    }
    else
      bmp = originalBitmap;
    
    views.setImageViewBitmap(R.id.mainImage, bmp);
    
        // Tell the widget manager
        for (int widgetId : widgetIds) {
            // set background
            if (backgrounds.containsKey(widgetId))
                themeid = backgrounds.get(widgetId);
            else
                themeid = R.drawable.widget_background_black;

            views.setImageViewResource(R.id.backImage, themeid);
            appWidgetManager.updateAppWidget(widgetId, views);
        }
    }

    
  /**
   * @param bitmap The source bitmap.
   * @param opacity a value between 0 (completely transparent) and 255 (completely
   * opaque).
   * @return The opacity-adjusted bitmap.  If the source bitmap is mutable it will be
   * adjusted and returned, otherwise a new bitmap is created.
   */
  private static Bitmap adjustOpacity(Bitmap bitmap, int opacity)
  {
      Bitmap mutableBitmap = bitmap.isMutable()
                             ? bitmap
                             : bitmap.copy(Bitmap.Config.ARGB_8888, true);
      Canvas canvas = new Canvas(mutableBitmap);
      int colour = (opacity & 0xFF) << 24;
      canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
      return mutableBitmap;
  }

  /**
     * Updates the text label with the given time
     * @param time in milliseconds
     */
  public static String getTime(int time){
        time += 999;  // round seconds upwards
    String[] str = TimerUtils.time2str(time);
    if(str.length == 3)
      return (str[0]+":"+str[1]+":"+str[2]);
    else if(str.length == 2)
      return (str[0]+":"+str[1]);
    else if(str.length == 1)
      return (str[0]);
    else
      return ("");

  }

  /** Handler for the message from the timer service */
  private Handler mHandler = new Handler() {
    
    @Override
        public void handleMessage(Message msg) {
      doTick();
    }
    };
  
}




Java Source Code List

org.yuttadhammo.BodhiTimer.ANumberPicker.java
org.yuttadhammo.BodhiTimer.NNumberPicker.java
org.yuttadhammo.BodhiTimer.TTSService.java
org.yuttadhammo.BodhiTimer.TimerActivity.java
org.yuttadhammo.BodhiTimer.TimerPrefActivity.java
org.yuttadhammo.BodhiTimer.TimerReceiver.java
org.yuttadhammo.BodhiTimer.TimerUtils.java
org.yuttadhammo.BodhiTimer.VolumePreference.java
org.yuttadhammo.BodhiTimer.Animation.BodhiLeaf.java
org.yuttadhammo.BodhiTimer.Animation.CircleAnimation.java
org.yuttadhammo.BodhiTimer.Animation.TimerAnimation.java
org.yuttadhammo.BodhiTimer.Service.AlarmTask.java
org.yuttadhammo.BodhiTimer.Service.ScheduleClient.java
org.yuttadhammo.BodhiTimer.Service.ScheduleService.java
org.yuttadhammo.BodhiTimer.widget.AppWidgetConfigure.java
org.yuttadhammo.BodhiTimer.widget.BodhiAppWidgetProvider.java