Atihska
Atihska

Reputation: 5126

Updating widget using android service

I have a simple button widget that flips through a set of images. Now I want that instead of button click, the image flips after certain interval of time. For it I'll require service class. Can anyone help me with how to include that in my code. I don't have much idea about service.

Here is my code snippet: //widgetprovider.java

public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds){

        //Log.i("Tag","In onUpdate method");
        System.out.println("Tag In onUpdate method");
        RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.widget_layout);
        views.setOnClickPendingIntent(R.id.widget_button, buildButtonPendingIntent(context));
        Log.i("Tag","Context value after setOnClickPI before pushWIDGET:"+context);

        pushWidgetUpdate(context,views);
        Log.i("Tag","after pushwidget update:"+context);
    }

    public static PendingIntent buildButtonPendingIntent(Context context){

        Intent intent=new Intent();
        intent.setAction("com.example.android.intent.action.CHANGE_PICTURE");

        Log.i("Tag","intent's action:"+intent);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    public static void pushWidgetUpdate(Context context,RemoteViews views){

        System.out.println("Inside pushwidget");
        ComponentName myWidget=new ComponentName(context, MyWidgetProvider.class);
        AppWidgetManager manager=AppWidgetManager.getInstance(context);
        manager.updateAppWidget(myWidget, views);
    }

//IntentReceiver.java

public void onReceive(Context context, Intent intent) {

        // Log.i("Tag1","In onReceive:"+intent);
        System.out.println("In onReceive()");

        if (intent.getAction().equals(
                "com.example.android.intent.action.CHANGE_PICTURE")) {
            updateWidgetPictureAndButtonListener(context);
        }
    }

    private void updateWidgetPictureAndButtonListener(Context context) {

        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.widget_layout);
        views.setImageViewResource(R.id.widget_image, getImageToSet());

        System.out.println("in updateWidgetPicture method");
        // Log.i("Tag","in updaeWIdgetPicture method");
        // remember to set ur button click listeners
        views.setOnClickPendingIntent(R.id.widget_button,
                MyWidgetProvider.buildButtonPendingIntent(context));

        MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(),
                views);
    }

//edited java file

package com.example.pictureappservice;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;


// this works without service
public class MyWidgetProvider extends AppWidgetProvider {

    private static int clickCount = 0;
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds){

        Log.i("onUpdate method call","Called");
        ComponentName thisWidget=new ComponentName(context, MyWidgetProvider.class);
        int []allWidgetIds=appWidgetManager.getAppWidgetIds(thisWidget);

        //built intent to call service
        Intent intent=new Intent(context.getApplicationContext(),UpdateService.class);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,allWidgetIds);

        Log.i("LOG","before service");
        //update widget via service
        context.startService(new Intent(context,UpdateService.class));
    }

    public static class UpdateService extends Service{

        public void onStart(Intent intent, int startId){

            AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(this.getApplicationContext());
            int []allWidgetIds=intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

            ComponentName thisWidget=new ComponentName(getApplicationContext(),MyWidgetProvider.class);
            int []allWidgetIds2=appWidgetManager.getAppWidgetIds(thisWidget);

            Log.i("LOG","From Intent" + String.valueOf(allWidgetIds.length));
            Log.i("LOG","Direct" + String.valueOf(allWidgetIds2.length));

            for(int widgetId:allWidgetIds){

                //  logic 
                Log.i("LOG","intent's action"+intent.getAction());
                //if (intent.getAction().equals("com.example.android.intent.action.CHANGE_PICTURE")) {

                    RemoteViews views=new RemoteViews(this.getApplicationContext().getPackageName(),R.layout.widget_layout);    
                    views.setImageViewResource(R.id.widget_image, getImageToSet());

                    //intent
                    Intent clickIntent=new Intent(this.getApplicationContext(),MyWidgetProvider.class);
                    clickIntent.setAction("AppWidgetManager.ACTION_APPWIDGET_UPDATE");
                    //clickIntent.setAction("com.example.android.intent.action.CHANGE_PICTURE");
                    clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

                    Log.i("Tag","intent's action:"+intent);

                    PendingIntent pendingIntent=PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                    views.setOnClickPendingIntent(R.id.widget_image, pendingIntent);
                    appWidgetManager.updateAppWidget(widgetId,views);
                //}
            }
            stopSelf();
            super.onStart(intent, startId);
        }

        private int getImageToSet() {
            clickCount++;
            Log.i("Tag", "in getImageToSet()" + clickCount);

            return clickCount % 2 == 0 ? R.drawable.paypal_logo : R.drawable.paypaldonation;
        }
        @Override
        public IBinder onBind(Intent intent) {
            // We don't need to bind to this service
            return null;
        }
    }

    public static void pushWidgetUpdate(Context context,RemoteViews views){

        System.out.println("Inside pushwidget");
        ComponentName myWidget=new ComponentName(context, MyWidgetProvider.class);
        AppWidgetManager manager=AppWidgetManager.getInstance(context);
        manager.updateAppWidget(myWidget, views);
    }
}

Upvotes: 4

Views: 10434

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006614

If your "certain interval of time" is 15 minutes or longer, use android:updatePeriodMillis in your app widget metadata, which will trigger a call to your onUpdate() method in your AppWidgetProvider.

Or, use AlarmManager to trigger a PendingIntent that will invoke some code of yours that will update your app widget on some other frequency.

However, I do not recommend updating an app widget more than once per minute (longer while the device is asleep), to keep power consumption down.

Upvotes: 3

Related Questions