简体   繁体   English

Android应用程序小部件更新问题

[英]Android App Widget Update Issue

Here is what I am dealing with. 这是我要处理的。

I have a widget associated to my Android App which I want to update every 10 minutes (currently using AlarmManager) only if the screen is ON. 我有一个与我的Android应用程序关联的小部件,仅当屏幕打开时,我想每10分钟更新一次(当前使用AlarmManager)。 If the screen is OFF the alarms for the pendingIntent are cancelled. 如果屏幕关闭,则取消针对pendingIntent的警报。 Once the screen comes ON again I check if the last update and current time has a difference of 10 minutes or more, if it is I send out a broadcast to update the widget. 屏幕再次打开后,我将检查上一次更新与当前时间是否相差10分钟或更长时间(如果是),我将发送广播以更新小部件。

What happens and is the problem is the alarms for the pending Intent probably are not cancelled (probably) and the widget update is executed for all the alarms for the pendingIntent that were stacked up when the screen was OFF. 发生了什么,问题是,未取消(可能)未决Intent的警报,并且当屏幕关闭时,针对所有已堆积的未决Intent的警报执行了窗口小部件更新。

Here are some code snippets. 以下是一些代码片段。

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


    }

Here is the BroadcastReceiver that receives the SCREEN_ON broadcast and sends out the request for the widget update if current time - last time widget was updated >= 10 minutes. 这是BroadcastReceiver,它接收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));

Lets say that the last update happened at 10:00 am and the screen was off for 30 minutes. 可以说最后一次更新发生在上午10:00,屏幕关闭了30分钟。 When the screen comes on, the widget gets updated for all the alarms stored for the pendingIntent at once. 当屏幕出现时,该小部件将立即更新为该pendingIntent存储的所有警报。 I want the widget update to happen only once when the screen come on again. 我希望小部件更新仅在屏幕再次出现时才发生一次。

Initially I understood that AlarmManager.ELAPSED_REALTIME triggers when the devices wakes up from being idle. 最初,我了解到AlarmManager.ELAPSED_REALTIME在设备从空闲状态唤醒时触发。

I don't know why the alarm cancel don't work. 我不知道为什么取消闹钟不起作用。 Everything else works as expected. 其他所有工作均按预期进行。

By the way I have done performance tests on the 10 minute widget update on variety of devices and it is not at all a strain on available resources. 顺便说一下,我已经在各种设备上进行的10分钟小部件更新上进行了性能测试,而这对可用资源完全没有压力。 Moreover the delivered the service does not even show up in the Battery Use monitor for Android devices. 此外,所提供的服务甚至不会显示在Android设备的“电池使用情况”监视器中。

Any help is much appreciated. 任何帮助深表感谢。

I've seen this as well. 我也看到了这一点。 Changed it to use a broadcast receiver that receives SCREEN_OFF or SCREEN_ON and stopping/starting the Alarm service manually. 将其更改为使用接收SCREEN_OFF或SCREEN_ON并手动停止/启动警报服务的广播接收器。

Not the answer you may of been wanting sorry :-) 不是您可能想要的答案的答案:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM