2011-03-15 63 views
0

以下是我正在处理的内容。Android应用小部件更新问题

我有一个小部件与我的Android应用程序相关联,我想每隔10分钟更新一次(当前正在使用AlarmManager),只有在屏幕打开的情况下。如果屏幕关闭,pendingIntent的警报将被取消。一旦屏幕再次打开,我检查上次更新和当前时间是否有10分钟或更长时间的差异,如果是我发送广播更新小部件。

会发生什么,并且问题是待定Intent的警报可能未被取消(可能),并且在屏幕关闭时堆叠的pendingIntent的所有警报都会执行小部件更新。

以下是一些代码片段。

@Override 
public void onReceive(Context context, Intent intent) { 
     check_intent = intent.getAction(); 

      if(check_intent.equals("android.appwidget.action.APPWIDGET_UPDATE")){ 

       mAppPreferences = PreferenceManager.getDefaultSharedPreferences(context); 
       int saved_num_widgets = mAppPreferences.getInt(NUM_WIDGETS, 0); 
     /*Check if there is atleast one widget on homescreen*/  
       if (saved_num_widgets>0){ 
         boolean check = CheckScreenOn.check_screen_on(context); 
/*Check if Screen is ON*/ 
          if(check == true){ 
               Intent widgetUpdate = new Intent(context, MyWidget.class); 
               widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); 
               alarms = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
               newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate,0); 
               alarms.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+ PERIOD, newPending); 
               context.startService(new Intent(context, UpdateService.class)); 
          } 
          else{ 
           alarms.cancel(newPending); 
/*Screen is OFF no point updating the widget, cancel Alarms and do nothing*/ 
          } 
        } 
        else{ 
          int duration = Toast.LENGTH_LONG; 
          CharSequence text = "Please place My Widget on your home screen to keep earning money."; 
          Toast toast = Toast.makeText(context, text, duration); 
          toast.show(); 
        } 
        } 
       if(check_intent.equals("android.appwidget.action.APPWIDGET_ENABLED")){ 
        this.onEnabled(context); 
       } 
       if(check_intent.equals("android.appwidget.action.APPWIDGET_DELETED")){ 
        this.onDeleted(context); 
       } 
       if(check_intent.equals("android.appwidget.action.APPWIDGET_DISABLED")){ 
        this.onDisabled(context); 
       } 


    } 

这里是接收SCREEN_ON广播,并且如果当前时间发送出用于小窗口更新请求中的广播接收器 - 上次插件被更新> = 10分钟。

registerReceiver(new BroadcastReceiver() { 

       @Override 
       public void onReceive(Context context, Intent intent) { 
       // ... 
       long update_interval = mAppPreferences.getLong(LASTUPDATETIME, 0); 
       long curtimemillis = System.currentTimeMillis(); 
       long calculate_interval = curtimemillis - update_interval; 
       if(calculate_interval >= PERIOD){ 
        int saved_num_widgets = mAppPreferences.getInt(NUM_WIDGETS, 0); 

        if (saved_num_widgets>0){ 

           alarms.cancel(newPending); 
          Intent widgetUpdate = new Intent(context, MyWidget.class); 
          widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); 
          context.sendBroadcast(widgetUpdate); 
         } 

        } 

        } 
       }, new IntentFilter(Intent.ACTION_SCREEN_ON)); 

可以说上次更新发生在上午10点,屏幕关闭30分钟。当屏幕出现时,小部件会立即更新为pendingIntent存储的所有警报。当屏幕再次出现时,我希望小部件更新只发生一次。

最初我明白AlarmManager.ELAPSED_REALTIME会在设备从闲置状态唤醒时触发。

我不知道为什么报警取消不起作用。其他一切按预期工作。

顺便说一下,我已经在各种设备上进行了10分钟小部件更新的性能测试,并且它对可用资源没有任何负担。此外,所提供的服务甚至不会出现在Android设备的电池使用监视器中。

任何帮助,非常感谢。

+0

答案你为什么不只是跳过你的'AlarmManager'报警'_WAKEUP'部分,并用它做什么?为什么你浪费时间在毫无意义的'SCREEN_OFF'和'SCREEN_ON'检测上忙乱了,所有这些都与使用非唤醒警报的基本相同? – CommonsWare 2011-03-15 22:21:54

+0

@CommonsWare我为AlarmManager使用了非唤醒警报AlarmManager.ELAPSED_REALTIME。这是我的方法,但我发现即使使用非唤醒警报,更新也会继续触发。如果屏幕关闭时如果我停止发生更新,屏幕开启时会立即发生多个更新... – Aakash 2011-03-15 22:31:23

+1

我觉得非唤醒警报不会唤醒设备。然后可以在设备醒来时传递警报,但您只需记下上次您的工作情况并跳过多余的警报。 – CommonsWare 2011-03-15 23:04:31

回答

0

我也看过这个。将其更改为使用接收SCREEN_OFF或SCREEN_ON的广播接收器并手动停止/启动警报服务。

没有可能的一直想对不起:-)

+0

我想知道您是否取消了您的BroadcastReceiver中用于SCREEN OFF的挂起Intent的警报,或者您是否采取了其他措施来停止警报服务 – Aakash 2011-03-15 18:56:58

+0

刚刚取消了警报。如果您愿意,您也可以停止实际的服务,但这对用户没有任何影响,因为它会在您获得SCREEN_ON时重新启动 – Blundell 2011-03-16 09:34:25