Mimic GCM messages for faster development

Tsuharesu
2 min readJan 17, 2017

--

My good friend Aleksey told me about this way of working called “Pain Driven Development” and I loved the name hahaha. At times something is so laborious to do that you search for ways to speed up your day or you suffocate in boredom. One of the latest for me was waiting for GCM to deliver messages to a device. I had to fix something related to notification and… well, notifications just wouldn’t appear!

My first alternative was to find a way to send notifications directly to the device, getting rid of the whole backend part. It worked... kind of. Google sends the message when it “wants” to. Not fast enough for me. I had to send using Postman, wait for X minutes and then I got a notification. Then my code needed to change and I had to do this cycle again. Argh! I am addicted to automation and fast iterations, I could not wait all this time. It had to be a better way. Well, there is, fret not my friend!

I found the solution on Google+ (only developers use it, right?): send an Intent to your Broadcast Receiver with the message that GCM would send. Now I got rid of my backend, GCM and network altogether! Here is the post. I copied the steps here and added some other infos to them.

Step 1: In your AndroidManifest.xml locate your GCM Broadcast Receiver. My package name is com.tsuharesu.chat and my class is located at com.tsuharesu.chat.gcm.GCMBroadcastReceiver.

<receiver
android:name=”com.tsuharesu.chat.gcm.GCMBroadcastReceiver”
android:permission=”com.google.android.c2dm.permission.SEND” >
<intent-filter>
<action android:name=”com.google.android.c2dm.intent.RECEIVE”/>
<action android:name=”com.google.android.c2dm.intent.REGISTRATION”/>
<category android:name=”com.tsuharesu.chat”/>
</intent-filter>
</receiver>

Step 2–1: Temporarily remove the following attribute from its declaration:

android:permission=”com.google.android.c2dm.permission.SEND”

Step 2–2: Or, you can make your receiver change based on your build.gradle:

<receiver
android:name=”com.tsuharesu.chat.gcm.GCMBroadcastReceiver”
android:permission=”${gcmPermissionRequired}” >
<intent-filter>
<action android:name=”com.google.android.c2dm.intent.RECEIVE”/>
<action android:name=”com.google.android.c2dm.intent.REGISTRATION”/>
<category android:name=”com.tsuharesu.chat”/>
</intent-filter>
</receiver>

And add this to your build.gradle:

buildTypes {
debug {
manifestPlaceholders = [gcmPermissionRequired: “”] // “” => let the GCM BroadcastReceiver accept Intents from ‘adb shell am broadcast’
}
release {
manifestPlaceholders = [gcmPermissionRequired: “com.google.android.c2dm.permission.SEND”]
}
}

Step 3: Build and run you app ;)

Step 4: Open a terminal where you can access ADB.

Step 5: Enter your device shell.

adb shell

Step 6: Fire an intent (replace your package and receiver location) and hit enter:

am broadcast -a com.google.android.c2dm.intent.RECEIVE -n com.tsuharesu.chat/com.tsuharesu.chat.gcm.GCMBroadcastReceiver —-es ‘data.alert’ ‘foo’

If you did everything correctly you should get some output like:

Broadcasting: Intent { act=com.google.android.c2dm.intent.RECEIVE cmp=com.tsuharesu.chat/gcm.GCMBroadcastReceiver (has extras) }
Broadcast completed: result=0

Also, if you need to send a JSON (default these days) it’s appropriate to use single quotes ‘ ’ enclosing the data part in the intent. This free you from escaping characters that JSON uses, double quotes “ ” being the most common. Example:

am broadcast -a com.google.android.c2dm.intent.RECEIVE -n com.tsuharesu.chat/com.tsuharesu.chat.gcm.GCMBroadcastReceiver —-es ‘notifications’ ‘[{“user_id”:438,”text”:”hey man”}, {“user_id”:438,”text”:”listen to this music!”}]’

Step 7: After you finished, undo Step 2–1 if needed.

--

--