I just finished a widget clock that displays the actual seconds and changes an ImageView
each 15 minutes. I have used a BroadcastReceiver
with AlarmManager;
. I also have setup a click on an ImageView
to change it for another image and play a sound, and this image is back to an original one after 5 seconds. I'm using a ClickPendingIntent
to handle this and everything works fine, however my widget appears using 2% of the battery, which I think is too much for only displaying the actual time.
Please let me know if this is normal or there is something that I can do to avoid use unnecessary battery.
AppWidgetProvider:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
//super.onUpdate(context, appWidgetManager, appWidgetIds);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
pushWidgetUpdate(context, remoteViews);
}
@SuppressWarnings("deprecation")
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
//super.onEnabled(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
remoteViews.setOnClickPendingIntent(R.id.imageView1, buildButtonPendingIntent(context));
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis() + 1000, 1000, test(context));
pushWidgetUpdate(context, remoteViews);
}
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
//super.onDisabled(context);
Intent intent = new Intent(context, MyWidgetProvider.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
public static PendingIntent buildButtonPendingIntent(Context context){
Intent intent = new Intent();
intent.setAction("custom.intent.action.CHANGE_PICTURE");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static PendingIntent test(Context context){
Intent intent = new Intent();
intent.setAction("custom.intent.action.HELLO");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews){
ComponentName myWidget = new ComponentName(context, MyWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
BroadcastReceiver:
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("custom.intent.action.CHANGE_PICTURE")){
updateWidgetPictureAndButtonListener(context, true);
} else if(intent.getAction().equals("custom.intent.action.HELLO")){
updateWidgetPictureAndButtonListener(context, false);
}
}
private void updateWidgetPictureAndButtonListener(Context context, boolean updateOnlyPicture){
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
java.text.DateFormat dateFormat = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault());
if(updateOnlyPicture == true){
remoteViews.setImageViewResource(R.id.imageView1, getImageToSet());
MediaPlayer mPlayer = MediaPlayer.create(context, R.raw.alert);
mPlayer.start();
} else if(updateOnlyPicture == false){
remoteViews.setTextViewText(R.id.textView1, dateFormat.format(new Date()));
@SuppressWarnings("deprecation")
int min = dateFormat.getCalendar().getTime().getMinutes();
@SuppressWarnings("deprecation")
int sec = dateFormat.getCalendar().getTime().getSeconds();
//Refresh image to a normal state after being clicked
if(isImageclicked == true){
if(sec == actualSeconds + 5){
remoteViews.setImageViewResource(R.id.imageView1, R.drawable.center);
actualSeconds = 0;
isImageclicked = false;
}
}
if(min == 00){
remoteViews.setImageViewResource(R.id.imageView1, R.drawable.center);
}
else if(min == 15){
remoteViews.setImageViewResource(R.id.imageView1, R.drawable.left);
}
else if(min == 30){
remoteViews.setImageViewResource(R.id.imageView1, R.drawable.right);
}
else if(min == 45){
remoteViews.setImageViewResource(R.id.imageView1, R.drawable.down);
}
}
remoteViews.setOnClickPendingIntent(R.id.imageView1, MyWidgetProvider.buildButtonPendingIntent(context));
MyWidgetProvider.pushWidgetUpdate(context, remoteViews);
}
@SuppressWarnings("deprecation")
private int getImageToSet(){
java.text.DateFormat dateFormat = SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault());
clickCount++;
isImageclicked = true;
actualSeconds = dateFormat.getCalendar().getTime().getSeconds();
return R.drawable.alert;
}
Do you think 2% - 3% is "good" for a clock widget? If not, what would you recommend to make it use less battery? It does consume any battery for at least a day, but then it appears in the battery analyzer app with 2% and then increases in 1% slowly, but it does it. I was using a service which seems to use less battery, but when a user clears the processes in memory, it stops working.