Search code examples
javaandroidbroadcastreceiverandroid-broadcastdashclock

How can I maintain a persistent BroadcastReceiver in a Dashclock extension?


Here's the scaffolding code of my Dashclock extention. It receives messages from GCM and displays the information.

public class ComputerWidget extends DashClockExtension {

    private MessageReceiver objMessageReceiver;
    private class MessageReceiver extends BroadcastReceiver {    
        @Override
        public void onReceive(Context ctxContext, Intent ittIntent) {    
            GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(ctxContext);
            String strType = gcm.getMessageType(ittIntent);    
            if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(strType)) {    
                showInformation(ittIntent.getExtras());    
            }    
        }    
    }

    @Override
    protected void onInitialize(boolean booReconnect) {    
        super.onInitialize(booReconnect);    
        if (objMessageReceiver != null) {    
            try {    
                unregisterReceiver(objMessageReceiver);    
            } catch (Exception e) {
                e.printStackTrace();
            }    
        }

        IntentFilter intentFilter = new IntentFilter("com.google.android.c2dm.intent.RECEIVE");
        intentFilter.addCategory("com.something.something");    
        objMessageReceiver = new MessageReceiver();
        registerReceiver(objMessageReceiver, intentFilter);
    }

    public void onCreate() {    
        super.onCreate();    
    }

    protected void showInformation(Bundle bndBundle) {    
        final ExtensionData edtInformation = new ExtensionData();
        setUpdateWhenScreenOn(true);    
        try {    
            if (bndBundle.getString("event").equalsIgnoreCase("logon")) {    
                edtInformation.visible(true);
                    edtInformation.expandedTitle(bndBundle.getString("machine"));
                edtInformation.expandedBody(getString(R.string.logon, bndBundle.getString("username")));
                    }    
        } catch (Exception e) {
            edtInformation.visible(false);
        }    
        edtInformation.icon(R.drawable.ic_dashclock);
        publishUpdate(edtInformation);
    }

    public void onDestroy() {    
        super.onDestroy();    
        if (objMessageReceiver != null) {    
            try {    
                unregisterReceiver(objMessageReceiver);    
            } catch (Exception e) {
                e.printStackTrace();
            }    
        }    
    }

    @Override
    protected void onUpdateData(int arg0) {    
        setUpdateWhenScreenOn(true);
        System.out.println("Update");    
    }

}

As you can see, I'm registering my GCM BroadcastReceiver when my extension is initialized and I'm unregistering it when the extension is destroyed.

This piece of code works just fine as long as the receiver is initialized but Dashclock, after a period of inactivity, destroys the extension and therefore I can't receive any GCM messages.

How can I keep the BroadcastReceiver alive so that I can receive GCM messages? Is there a way to accomplish this programatically and not through the manifest file?

I came to this solution after my last question regarding BroadcastRecieversHow do I publish an update to Dashclock when my application receives an Intent?


Solution

  • How can I keep the BroadcastReceiver alive so that I can receive GCM messages?

    Register it in the manifest, the way the GCM samples show you.

    Is there a way to accomplish this programatically and not through the manifest file?

    No, but you can enable and disable the manifest-registered receiver via PackageManager and setComponentEnabledSetting().