Android appwidget在运行时无法启动服务

时间:2011-03-02 09:59:06

标签: android service android-appwidget

我遇到的问题是,当我调试我的小部件时,它会改变布局,但是当我只是运行它时,它就不起作用了。根据我的调试消息,它设置setOnClickPendingIntent,但它不启动我的服务。

简而言之,我的小部件仅在调试时有效。

这是我的小部件代码:

    public class Widget extends AppWidgetProvider {

    public static String SWITCH_SCREEN1 = "1";
    public static String SWITCH_SCREEN2 = "2";

    public static final String ADD_NOTE = "addNote";
    public static final String MANAGE_REMINDERS = "manageReminders";
    public static String TAKE_PICTURE = "takePicture";


    private static int LAYOUTID = R.layout.widget_screen1;

    /**
     * This method is called when a widget is added to the home screen.
     * It sets the listeners on the items and updates the screen with info from the database
     */
    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
        setListeners(context);
        updateScreenFromDatabase(context, AppWidgetManager.getInstance(context), AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, Widget.class)));
    }


    /**
     * This method is called to update the widget. The Widget is called when the timeout set in widget.xml occurs.
     */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        updateScreenFromDatabase(context, appWidgetManager, appWidgetIds);
    }

    /**
     * This method fetches the data from the database and puts it in the 2 text elements on the screen
     * @param context
     * @param appWidgetManager
     * @param appWidgetIds
     */
    private static void updateScreenFromDatabase(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
        if(LAYOUTID == R.layout.widget_screen1){
            RemoteViews views = new RemoteViews(context.getPackageName(), LAYOUTID);
            for(int i = 0 ; i < appWidgetIds.length ; i++){
                String currentLesson = "No current lesson";
                String nextLesson = "No next lesson";
                LessonHour[] hours = Database.getInstance(context).getCurrentAndNextLessonHour();
                if(hours[0] != null){
                    currentLesson = hours[0].getStart().get(GregorianCalendar.HOUR_OF_DAY) + ":" + Utils.adjustMinutes(hours[0].getStart().get(GregorianCalendar.MINUTE)) + " " + hours[0] .getLesson().getSummary();
                }
                if(hours[1] != null){
                    nextLesson = hours[1].getStart().get(GregorianCalendar.HOUR_OF_DAY) + ":" +  Utils.adjustMinutes(hours[1].getStart().get(GregorianCalendar.MINUTE)) + " " + hours[1] .getLesson().getSummary();
                }
                views.setTextViewText(R.id.txt_widget_lesson1, currentLesson);
                views.setTextViewText(R.id.txt_widget_lesson2, nextLesson);

                appWidgetManager.updateAppWidget(new ComponentName(context, Widget.class), views);  
            }
        }

    }



    /**
     * This method is called when the screen of the widget should change.
     * The action tells the method to which screen it should change. 
     * @param context
     * @param action: the screen the method should switch to. Either WIDGET_SCREEN1 or WIDGET_SCREEN2
     */
    public static void buildUpdate(Context context, String action){
        RemoteViews views;
        if(action.equals(SWITCH_SCREEN1)){
            views =  new RemoteViews(context.getPackageName(), R.layout.widget_screen1);
            AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(context, Widget.class), views);
            LAYOUTID = R.layout.widget_screen1;
            updateScreenFromDatabase(context, AppWidgetManager.getInstance(context), AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, Widget.class)));
        }
        else if(action.equals(SWITCH_SCREEN2)){
            views =  new RemoteViews(context.getPackageName(), R.layout.widget_screen2);
            AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(context, Widget.class), views);
            LAYOUTID = R.layout.widget_screen2;
        }
        setListeners(context);
    }
    /**
     * This methods sets the onclick listeners for the elements displayed on the screen
     * @param context
     */
    private static void setListeners(Context context){
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        int[] appWidgetIds = manager.getAppWidgetIds(new ComponentName(context, Widget.class));

        for (int i = 0 ; i < appWidgetIds.length; i++){

            if(LAYOUTID == R.layout.widget_screen1){
                Log.e("khlrooster", "setting listeners on widget screen 1");
                RemoteViews views = new RemoteViews(context.getPackageName(), LAYOUTID);

                Intent intent = new Intent(context, SwitchWidgetScreenService.class);
                intent.setAction(SWITCH_SCREEN2);
                intent.setData(Uri.parse("uri::" + Math.random()));
                Log.e("khlrooster", "action of listener for screen 1: " + intent.getAction());
                PendingIntent pi = PendingIntent.getService(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
                views.setOnClickPendingIntent(R.id.imgbtn_switchDown, pi);
                views.setOnClickPendingIntent(R.id.imgbtn_widget_notification, pi);

                manager.updateAppWidget(new ComponentName(context, Widget.class), views);
                Log.e("khlrooster", "listeners set on widget screen 1");
            }

            else if(LAYOUTID == R.layout.widget_screen2){
                Log.e("khlrooster", "setting listeners on widget screen 2");
                RemoteViews views = new RemoteViews(context.getPackageName(), LAYOUTID);
                Intent intent2 = new Intent(context, SwitchWidgetScreenService.class);
                intent2.setAction(SWITCH_SCREEN1);              
                PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent2, 0);
                views.setOnClickPendingIntent(R.id.imgbtn_switchUp, pendingIntent);

                intent2 = new Intent(context, LessonDetail.class);
                intent2.setAction(ADD_NOTE);
                pendingIntent = PendingIntent.getActivity(context, 0, intent2, 0);
                views.setOnClickPendingIntent(R.id.imgbtn_notes, pendingIntent);

                intent2= new Intent(context, LessonDetail.class);
                intent2.setAction(TAKE_PICTURE);
                pendingIntent = PendingIntent.getActivity(context, 0, intent2, 0);
                views.setOnClickPendingIntent(R.id.imgbtn_photo, pendingIntent);                

                manager.updateAppWidget(new ComponentName(context, Widget.class), views);
                Log.e("khlrooster", "listeners set on widget screen 2");
            }

        }
    }


}

这是我的服务响应我的意图:

public class SwitchWidgetScreenService extends Service {

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.e("khlrooster", "Created the SwitchWidgetScreenService");
}

@Override
public void onStart(Intent intent, int startId) {
    //super.onStart(intent, startId);
    Log.e("khlrooster", "started the SwitchWidgetScreenService");
    handleEvent(intent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    handleEvent(intent);
    Log.e("khlrooster", "started the SwitchWidgetScreenService");
    return super.onStartCommand(intent, flags, startId);
}

private void handleEvent(Intent intent) {
    Log.e("khlrooster", "it works, the screen changes to: " + intent.getAction());
    if(intent.getAction().equals(Widget.SWITCH_SCREEN1)){
        Widget.buildUpdate(this, Widget.SWITCH_SCREEN1);
    }else if(intent.getAction().equals(Widget.SWITCH_SCREEN2)){
        Widget.buildUpdate(this, Widget.SWITCH_SCREEN2);
    }
}

}

1 个答案:

答案 0 :(得分:2)

我解决了我的问题,在从数据库获取数据后再次调用了setListeners。