Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dashclock Widget extension not updating

I have a DashClockExtension that sometimes doesn't update.

It's using a LocalBroadcastReceiver to update the extension similar to http://bit.ly/1e4uMl0. The receiver is registered in the onInitialize() method:

@Override
    protected void onInitialize(boolean isReconnect) {
        super.onInitialize(isReconnect);

        LocalBroadcastManager broadcastMgr = LocalBroadcastManager.getInstance(this);
        if (mDashClockReceiver != null) {
            try {
                broadcastMgr.unregisterReceiver(mDashClockReceiver);
            } catch (Exception ignore) {}
        }
        mDashClockReceiver = new DashClockUpdateReceiver();
        broadcastMgr.registerReceiver(mDashClockReceiver, new IntentFilter(UPDATE_DASHCLOCK));
    }

That's how I send the broadcast:

public static void updateDashClock() {
    LocalBroadcastManager.getInstance(Application.getContext()).sendBroadcast(new Intent(UPDATE_DASHCLOCK));
}        

That's my BroadcastReceiver:

private class DashClockUpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        retrieveDataAndUpdateWidget();
    }
}

I noticed that while the broadcast is triggered the receiver doesn't receive the event sometimes.
I tested it by killing my app but that doesn't reproduce the issue so I'm at a loss why this would happen.

Anyone?

like image 628
Emanuel Moecklin Avatar asked Dec 11 '13 05:12

Emanuel Moecklin


2 Answers

Please take a look at how the GCM broadcast receiver is implemented in Google's GCM Client example.

It might be because your application was killed by the Android OS because it needed more memory (or for whatever reason) and then you will not receive the broadcasts in your broadcast receiver.

I hope it helps, if not, please provide us with some logs and more information.

Best of luck!

like image 101
2 revs Avatar answered Oct 19 '22 18:10

2 revs


After running extensive tests, I got some results that might be interessting to other developers too:

  • It happens indeed when the app is killed by Android (I didn't wait for Android to kill the app but killed it manually of course)
  • DashClock Widget does bind the service again after a while. My guess is that it binds the service again when it runs the scheduled ui update which is roughly once an hour (according to the DashClockExtension javadoc). I didn't confirm that guess by going through the source code though.
  • The extension will therefore update eventually but only after the regular update cycle has run which might not happen for up to an hour.

Here's my workaround:

  • DashClock Widget listens to ACTION_PACKAGE_CHANGED Intents (http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_CHANGED) to find all DashClockExtensions (service with ACTION_EXTENSION intent filter)
  • By disabling and re-enabling the DashClockExtension service when my app starts, I can "force" DashClock Widget to bind the service right away.
  • I tested this and it takes a couple of seconds after the app is killed and restarted till the DashClock widget ui updates again.

Here's how I disable, enable the service:

configureComponent("mypackagename.DashClockService", false); // disable
configureComponent("mypackagename.DashClockService", true);  // enable

private void configureComponent(Context context, String className, boolean enable) {
    PackageManager pkMgr = context.getPackageManager();
    String packageName = context.getPackageName();
    ComponentName component = new ComponentName(packageName, className);
    int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
    pkMgr.setComponentEnabledSetting(component, newState, PackageManager.DONT_KILL_APP);
}
like image 22
Emanuel Moecklin Avatar answered Oct 19 '22 18:10

Emanuel Moecklin