2
\$\begingroup\$

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.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Well, after doing some research and testing, I think the BroadcastReceiver is the best way to create a clock, however the update each second can drain the battery, in some phones is not noticeable, but I prefered to update it each minute, I personally do not recommend using services or handler since these are killed by android in a regular basis and, if you go and release processes from the memory, the application stops working.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.