Dashclock Widget扩展未更新

时间:2013-12-11 05:21:40

标签: android broadcastreceiver dashclock

我有DashClockExtension有时无法更新。

它使用LocalBroadcastReceiver更新类似于http://bit.ly/1e4uMl0的扩展名。接收者使用onInitialize()方法注册:

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

这就是我发送广播的方式:

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

这是我的BroadcastReceiver:

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

我注意到,在广播被触发时,接收器有时没有收到该事件 我通过杀死我的应用程序来测试它,但这并没有重现问题,所以我不知道为什么会发生这种情况。

任何?

3 个答案:

答案 0 :(得分:2)

请在Google's GCM Client example中查看GCM广播接收器的实现方式。

可能是因为你的application was killed by the Android OS因为它需要更多内存(或出于任何原因),然后你就不会在广播接收器中收到广播。

我希望它有所帮助,如果没有,请提供一些日志和更多信息。

祝你好运!

答案 1 :(得分:1)

在进行了大量测试之后,我得到了一些可能对其他开发人员也很敏感的结果:

  • 当应用程序被Android杀死时确实发生了(我没有等到Android杀死应用程序但当然手动杀死它)
  • DashClock Widget会在一段时间后再次绑定服务。我的猜测是它在运行预定的ui更新时再次绑定服务,大约每小时一次(根据DashClockExtension javadoc)。我没有通过浏览源代码确认猜测。
  • 因此,扩展程序最终会更新,但只有在定期更新周期运行后才会更新,这可能不会发生长达一个小时。

这是我的解决方法:

  • DashClock Widget侦听ACTION_PACKAGE_CHANGED Intents(http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_CHANGED)以查找所有DashClockExtensions(带有ACTION_EXTENSION意图过滤器的服务)
  • 通过在应用启动时禁用并重新启用DashClockExtension服务,我可以“强制”DashClock Widget立即绑定服务。
  • 我对此进行了测试,应用程序被杀死并重新启动后需要几秒钟,直到DashClock小部件ui再次更新。

以下是禁用,启用服务的方法:

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

答案 2 :(得分:1)

虽然我的第一个答案有效,但它有一些不良的副作用。因此,我想出了一个没有副作用的更好的解决方案。

指示DashClockWidget使用addWatchContentUris观察某个Uri,然后在更新小部件时,只需在该Uri上调用notifyChange:

public class DashClockService extends DashClockExtension {
    private static final Uri URI_BASE = Uri.parse("content://com.myauthority");
    private static final String URI_PATH_SEGMENT = "dashclock/update";

    public static void updateWidget(Context context) {
        ContentResolver contentResolver = context.getContentResolver();
        Uri uri = Uri.withAppendedPath(URI_BASE, URI_PATH_SEGMENT);
        contentResolver.notifyChange(uri, null);
    }

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

        removeAllWatchContentUris();
        Uri uri = Uri.withAppendedPath(URI_BASE, URI_PATH_SEGMENT);
        addWatchContentUris(new String[] {uri.toString()});
    }

可以从代码中的任何位置调用updateWidget来更新小部件。最重要的是,它可以在应用程序启动时调用,例如它被Android杀死后重启(我在Application.onCreate()中调用更新)。