使用Android服务更新小部件

4
我有一个简单的按钮部件,可以翻转一组图像。现在我想要在一定时间间隔后自动翻转图片,而不是通过按钮点击。为此,我需要使用服务类。有谁能帮我解决如何将它包含在我的代码中的问题。我对服务不太了解。
以下是我的代码片段: //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);
    }

//编辑后的Java文件

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);
    }
}
1个回答

3
如果您的“一定时间间隔”为15分钟或更长时间,请在您的应用程序小部件元数据中使用android:updatePeriodMillis,这将触发对您的AppWidgetProvider中的onUpdate()方法的调用。
或者,使用AlarmManager来触发一个PendingIntent,该PendingIntent将调用您的某些代码,以便在其他频率上更新您的应用程序小部件。
但是,我不建议每分钟更新一次应用程序小部件(在设备睡眠时更新时间更长),以保持功耗低。

我添加并修改了代码以添加服务类。请查看我的编辑后的代码。我遇到了错误“很抱歉,服务已停止”。 - Atihska
@Atihska:检查LogCat并查看与您的错误相关联的堆栈跟踪。 - CommonsWare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接