2

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?

Community
  • 1
  • 1
Mridang Agarwalla
  • 43,201
  • 71
  • 221
  • 382
  • @RomanNurik, I hope you can shed some light on this. – Mridang Agarwalla Aug 14 '13 at 12:21
  • Ah, you're probably going to want to have a completely separate receiver that lives outside the extension service. Initialization is pretty straightforward, but deregistration is a bit tricky. You may want to automatically deregister if you observe that you haven't gotten an update request in a day or two. – Roman Nurik Aug 14 '13 at 19:41
  • @RomanNurik, I think both you an CommonsWare mean the same thing i.e. that I could create a separate GCM receiver and register the intent handlers using the manifest file. This would definitely work but I don't know how I can publish an update using `publishUpdate` from an external `BroadcastReceiver` since it doesn't extend the `DashclockExtension` class. – Mridang Agarwalla Aug 15 '13 at 07:57
  • @RomanNurik, Of course, I could publish a Broadcast from my GCM receiver and handle the Broadcast in my Dashclock extension but it seems this requires the extension to be initialized e.g. this code snippet https://code.google.com/p/dashclock/issues/attachmentText?id=292&aid=2920012000&name=ARSDashClockExtension.java but it seems that after a period of time, Dashclock calls the `onDestroy` method of my extension, which unregisters the `BroadcastReceiver` and therefore I can never be sure that my embedded `BroadcastReceiver` in the `DashclockExtension` will be registered. – Mridang Agarwalla Aug 15 '13 at 08:01
  • @RomanNurik, Shouldn't the extension always be registered? Whys does Dashclock call the `onDestroy` method and not re-initialize it even though the extension is added into Dashclock? This seems to have got me stuck into some kind of a catch 22 situation. I'm guessing I've missed a very important part. Thanks for your help Roman. I appreciate it. – Mridang Agarwalla Aug 15 '13 at 08:02
  • 1
    See my answer for http://stackoverflow.com/questions/15567702 for more on this – Roman Nurik Aug 15 '13 at 21:39

1 Answers1

1

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().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491