Android appwidget 在运行时不启动服务

标签 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");
            }

        }
    }


}

这是我的服务响应我的 Intent :

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);
    }
}

最佳答案

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

关于Android appwidget 在运行时不启动服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5165841/

相关文章:

android - 如何在 AppWidget 中重置 RemoteView 的 ColorFilter

java - 查看 SharedPreference 变量是否为空

android - 什么是粘性广播?

android - adb连接错误:An existing connection was forcibly closed by the remote host

在我重新激活 WiFi/移动网络之前,服务中的 Android 位置监听器无法工作

android - 如果 UI 现在可见,服务如何确定

ios - 今天扩展在 iOS 14 测试版中不起作用

android - 应用小部件 : instance don't be shown after config activity is finished on some devices

Android:如何停止在 ImageView 上应用的无限动画?

.net - 如何在 WCF 服务和客户端之间共享对象?