Mastering Android Widget Development - Part4


SDK Version: 
M3

As described in the previous part, we will use a Service to update the appWidget.
So we will have the Service below, which gets the command (right now we have only the update command), ant the appwidgetId, reads the date from sharedPreferences and updates the widget.

  1. package com.helloandroid.countdownexample;
  2.  
  3. import java.util.Date;
  4.  
  5. import android.app.Service;
  6. import android.appwidget.AppWidgetManager;
  7. import android.content.Intent;
  8. import android.content.SharedPreferences;
  9. import android.os.IBinder;
  10. import android.widget.RemoteViews;
  11.  
  12. public class CountdownService extends Service {
  13.         // command strings to send to service
  14.         public static final String UPDATE = "update";
  15.  
  16.         @Override
  17.         public void onStart(Intent intent, int startId) {
  18.                 //a command, to define what to do, will be important only in the next tutorial part, now there is only update command
  19.                 String command = intent.getAction();
  20.                 int appWidgetId = intent.getExtras().getInt(
  21.                                 AppWidgetManager.EXTRA_APPWIDGET_ID);
  22.                 RemoteViews remoteView = new RemoteViews(getApplicationContext()
  23.                                 .getPackageName(), R.layout.countdownwidget);
  24.                 AppWidgetManager appWidgetManager = AppWidgetManager
  25.                                 .getInstance(getApplicationContext());
  26.  
  27.                 SharedPreferences prefs = getApplicationContext().getSharedPreferences(
  28.                                 "prefs", 0);
  29.                 long goal = prefs.getLong("goal" + appWidgetId, 0);
  30.                 //compute the time left
  31.                 long left = goal - new Date().getTime();
  32.                 int days = (int) Math.floor(left / (long) (60 * 60 * 24 * 1000));
  33.                 left = left - days * (long) (60 * 60 * 24 * 1000);
  34.                 int hours = (int) Math.floor(left / (60 * 60 * 1000));
  35.                 left = left - hours * (long) (60 * 60 * 1000);
  36.                 int mins = (int) Math.floor(left / (60 * 1000));
  37.                 left = left - mins * (long) (60 * 1000);
  38.                 int secs = (int) Math.floor(left / (1000));
  39.                 //put the text into the textView
  40.                 remoteView.setTextViewText(R.id.TextView01, days + " days\n" + hours
  41.                                 + " hours " + mins + " mins " + secs + " secs left");
  42.  
  43.                 // apply changes to widget
  44.                 appWidgetManager.updateAppWidget(appWidgetId, remoteView);
  45.                 super.onStart(intent, startId);
  46.         }
  47.  
  48.         @Override
  49.         public IBinder onBind(Intent arg0) {
  50.                 // TODO Auto-generated method stub
  51.                 return null;
  52.         }
  53. }

Services must be registered in the AndroidManifest:

  1. <service android:name=".CountdownService"></service>

The service is started automatically when you call it, but don~t forget to stop it in the AppWidgetProvider onDisable (When all widget instances are deleted):

  1. public void onDisabled(Context context) {
  2.         context.stopService(new Intent(context,CountdownService.class));
  3.         super.onDisabled(context);
  4. }

Now all we have to do is to call this Service when we want to update. The following function constructs a PendingIntent with the given parameters to do this. Insert it into the CountdownConfiguration class.

  1. public static PendingIntent makeControlPendingIntent(Context context, String command, int appWidgetId) {
  2.     Intent active = new Intent(context,CountdownService.class);
  3.     active.setAction(command);
  4.     active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
  5.     //this Uri data is to make the PendingIntent unique, so it wont be updated by FLAG_UPDATE_CURRENT
  6.     //so if there are multiple widget instances they wont override each other
  7.     Uri data = Uri.withAppendedPath(Uri.parse("countdownwidget://widget/id/#"+command+appWidgetId), String.valueOf(appWidgetId));
  8.     active.setData(data);
  9.     return(PendingIntent.getService(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT));
  10. }

To update the time left every second we will use the AlarmManager class. Insert following method into the CountdownConfiguration class too. This will start and stop the updating of an AppWidget with the given appWidgetId.

  1. public static void setAlarm(Context context, int appWidgetId, int updateRate) {
  2.     PendingIntent newPending = makeControlPendingIntent(context,CountdownService.UPDATE,appWidgetId);
  3.     AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  4.     if (updateRate >= 0) {
  5.         alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), updateRate, newPending);
  6.     } else {
  7.         // on a negative updateRate stop the refreshing
  8.         alarms.cancel(newPending);
  9.     }
  10. }

Using this methods, we
- refresh the appWidget when configuration is done (in ok button onclick)

  1. PendingIntent updatepending = CountdownWidget
  2.         .makeControlPendingIntent(self,
  3.         CountdownService.UPDATE, appWidgetId);
  4. try {
  5.         updatepending.send();
  6. } catch (CanceledException e) {
  7.         e.printStackTrace();
  8. }

- start the Alarmanager in the AppWidgetProvider onUpdate method (for example at first update, or after phone reboot)
  1. public void onUpdate(Context context, AppWidgetManager appWidgetManager,
  2.                         int[] appWidgetIds) {
  3.         for (int appWidgetId : appWidgetIds) {
  4.                 setAlarm(context, appWidgetId, UPDATE_RATE);
  5.         }
  6.         super.onUpdate(context, appWidgetManager, appWidgetIds);
  7.  
  8. }

- stop the Alarmanager on the AppWidgetProvider onDelete
  1. public void onDeleted(Context context, int[] appWidgetIds) {
  2.     for (int appWidgetId : appWidgetIds) {      
  3.         setAlarm(context, appWidgetId, -1);
  4.     }
  5.     super.onDeleted(context, appWidgetIds);
  6. }

Comments

They are items of great interest and importance, thanks for the information in your blog. Hotels Santiago

your posts are very informative and i enjoy coming back your website all the time
wedding photographer florida
miami ft lauderdale ft myers dj

This is my first time i visit here. I found so many interesting stuff in your blog especially its discussion. From the tons of comments on your articles I guess I am not the only one having all the enjoyment here! keep up the good work.
internet radio dj west palm beach
dj boca raton classified ads
web designer florida

Thanks that was great. This is my favorite blog for my android.
Johney

I don't think I'll ever master the android widgets beat maker software

Thank you these are really going to help my forklift training business.

Great android app tutorial online marketing

A very good and informative article indeed . It helps me a lot to enhance my knowledge, I really like the way the writer presented his views. windows hosting

Substantially the article is really the best on this laudable topic. I concur with your conclusions and will eagerly look forward to your future updates.Just saying thank you will not just be enough for the wonderful lucidity in your writing. Bob Dickson // langenfelder alt

Good job! I have found many articles to read but you do a good thing. That is a boy. Thank you so much for sharing the delicious post. Expect your next article. John Herron // Versicherungen

These android widgets are very hard to get the hang of Beverly Hills, Bel Air, Homes

Excellent job on the android app development pool plaster repair kit

I don't know if I will ever get the hang of android widget development

This is a great post. Thanks!

Very good job on this post. I just can't believe it. rare coin values

This blog is disseminating valuable information to people who are most concerned of the following issues being targeted by this site. Many certainly will keep coming back to check out updated posts. Rich crow // Muebles Valencia

You did a really swell job on writing this here article.

computer disposal

This is a great app. How about if you make one for the iPhone instead of just the Android?

Nice stuff. I would also suggest to do a google search for someone like Ben Tresnat for some interesting stuff on the same subject. All in all, nice job =)

Amazingly insightful article. If only it was as easy to implement some of the solutions as it was to read and nod my head at each of your points :P Derek Fisher // Kreditkarte

That is genuinely helpful. I would like to ask if it would be Okay if I mentioned some of that on my own blog. Of course I would credit you and link back here also.
descalcificador de agua

Please keep on posting such quality articles as this is a rare thing to find these days. I am always searching online for articles that can help me. Looking forward to another great blog. Good luck to the author! all the best!
Free Beats

I dont think Ive seen all the angles of this subject the way youve pointed them out. Youre a true star a rock star man. Youve got so much to say and know so much about the subject that I think you should just teach a class about it Jason Schofield // Fahrzeugbeschriftung

I'm the same way I do my best to remain neutral. It's hard if you communicate with the person the other person dislikes then you fall out of favor with them! I simple can't dislike a person just because someone else does I just can't // Tablet Android Honeycomb Terbaik Murah

This is such a great resource that you are providing and you give it away for free. I love seeing websites that understand the value of providing a quality resource for free. It's the old what goes around comes around routine. John Patrick // Elektro Rasentraktor

Thanks for the post and information! I think education is important for us so we must prepare the best education for our generation by sharing such great information with eachother! Ben Kennedy // marketing & advertising firm in Miami

This is such an informative article and very clearly written. Every single thought and idea is direct to the point. Perfectly laid out. Thank you for taking your time sharing this to you readers. Phil Hammond // wedding photographers in miami

The post was able to express what it wants to convey to the readers. It has been a very effective approach which resulted to a profitable output for all who have been fortunate enough to come across it! Simon Green // Mississauga air repair

This is such an informative article and very clearly written. Every single thought and idea is direct to the point. Perfectly laid out. Thank you for taking your time sharing this to you readers.
driving instructor in cannock

Gloriously expert position. I merely bumbled upon your post and desired to articulate that I have really relished understanding your blog articles. Cyril Brown // euromilliones

The colour schemes are lovely you have made this page very attractive. But I did not like the stuff too much you really need to improve on it. Dave Daniels // video production cardiff

Great post and now I know what to do thank you! Actually this Blog post helped me a lot. I hope you continue writing about this kind of entry.
Online-Marketing

This is a great inspiring article.I am pretty much pleased with your good work.You put really very helpful information. Keep it up. Keep blogging. Looking to reading your next post.
psicologo rivas

Happy to see your blog as it is just what I’ve looking for and excited to read all the posts. I am looking forward to another great article from you. Tom Williams // Arbeitslosenkredit

Happy to see your blog as it is just what I’ve looking for and excited to read all the posts. I am looking forward to another great article from you. Tom Williams // Arbeitslosenkredit

Please support enhance this post by adding citations to reliable sources Unsourced material may well be challenged Vince Erdrich // learn spanish in granada

Thanks for the post and information! I think education is important for us so we must prepare the best education for our generation by sharing such great information with eachother! John Walters // Spanisch lernen in Granada Spanien

Excellent post one of the few articles I’ve read today that said something unique! One new subscriber here :) Jane Smith // Alquiler coches Sevilla

A very good and informative article indeed . It helps me a lot to enhance my knowledge, I really like the way the writer presented his views. xperia play accessories

Your blog provided us with valuable information to work with. Each & every tips of your post are awesome. Thanks a lot for sharing. Keep blogging. Paul Shaun // website developer london

This article gives the light in which we can observe the reality. this is very nice one and gives in-depth information. thanks for this nice article... Mercedes-Benz Mobil Mewah Terbaik Indonesia | Mercedes-Benz Mobil Mewah Terbaik Indonesia | Meriahkan pesta ulang tahun bersama GarudaFood | Mari Berkomunitas Di Faceblog | Harga Jual Blackberry iPhone Laptop Murah | Video Music | Mp3 | Beauty and Health

That is some inspirational stuff. Never knew that opinions could be this varied. Thanks for all the enthusiasm to offer such helpful information here. Simon Paul // cirurgia plastica em BH

Thanks for posting this informative article. I haven't any word to appreciate this post.....Really i am impressed from this post....the person who create this post it was a great human..thanks for shared this with us. Jim Adams // Handy Forum

I'm the same way I do my best to remain neutral. It's hard if you communicate with the person the other person dislikes then you fall out of favor with them! I simple can't dislike a person just because someone else does I just can't. Scott Parsons // outsourcing de impressao

It is nice to find a site about my interest. My first visit to your site is been a big help. Thank you for the efforts you been putting on making your site such an interesting and informative place to browse through. I'll be visiting your site again to gather some more valuable information. You truly did a good job. Property Investment

A very informative article and lots of really honest and forthright comments made! This certainly got me thinking a lot about this issue so thanks a lot for posting! Andy Whitaker // wedding entertainment

Lots of popular smartphones use the Android operating system. As a result, consumers are clamoring for new Android apps.
best android apps

best iphone apps