Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Google Cloud Messaging (GCM)
From b7d55aea43a63c04c3558aabeda08ee4e4e89780 Mon Sep 17 00:00:00 2001
From: Jordi Coscolla <jordi@coscolla.net>
Date: Mon, 3 Feb 2014 08:24:37 +0100
Subject: ADD GCM to android
---
ig/android/ig/build.gradle | 4 +-
ig/android/ig/src/main/AndroidManifest.xml | 23 ++++++
.../java/net/coscolla/ig/GcmBroadcastReceiver.java | 24 ++++++
.../java/net/coscolla/ig/GcmIntentService.java | 87 ++++++++++++++++++++++
.../main/java/net/coscolla/ig/MainActivity.java | 47 +++++++++++-
.../ig/src/main/java/net/coscolla/ig/gcm/GCM.java | 76 +++++++++++++++++++
.../ig/src/main/res/layout/fragment_main.xml | 12 ++-
7 files changed, 267 insertions(+), 6 deletions(-)
create mode 100644 ig/android/ig/src/main/java/net/coscolla/ig/GcmBroadcastReceiver.java
create mode 100644 ig/android/ig/src/main/java/net/coscolla/ig/GcmIntentService.java
create mode 100644 ig/android/ig/src/main/java/net/coscolla/ig/gcm/GCM.java
diff --git a/ig/android/ig/build.gradle b/ig/android/ig/build.gradle
index 626ae05..5917dab 100644
--- a/ig/android/ig/build.gradle
+++ b/ig/android/ig/build.gradle
@@ -5,7 +5,7 @@ android {
buildToolsVersion "19.0.0"
defaultConfig {
- minSdkVersion 7
+ minSdkVersion 8
targetSdkVersion 19
versionCode 1
versionName "1.0"
@@ -20,4 +20,6 @@ android {
dependencies {
compile 'com.android.support:appcompat-v7:+'
+ compile 'com.android.support:support-v4:19.0.+'
+ compile 'com.google.android.gms:play-services:4.1.+'
}
diff --git a/ig/android/ig/src/main/AndroidManifest.xml b/ig/android/ig/src/main/AndroidManifest.xml
index 32b5afc..37cffb5 100644
--- a/ig/android/ig/src/main/AndroidManifest.xml
+++ b/ig/android/ig/src/main/AndroidManifest.xml
@@ -2,6 +2,18 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.coscolla.ig" >
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19"/>
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
+
+ <permission android:name="net.coscolla.ig.permission.C2D_MESSAGE"
+ android:protectionLevel="signature" />
+ <uses-permission android:name="net.coscolla.ig.permission.C2D_MESSAGE" />
+
+
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
@@ -16,6 +28,17 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
+ <receiver
+ android:name=".GcmBroadcastReceiver"
+ android:permission="com.google.android.c2dm.permission.SEND" >
+ <intent-filter>
+ <action android:name="com.google.android.c2dm.intent.RECEIVE" />
+ <category android:name="net.coscolla.ig" />
+ </intent-filter>
+ </receiver>
+ <service android:name=".GcmIntentService" />
</application>
</manifest>
+
diff --git a/ig/android/ig/src/main/java/net/coscolla/ig/GcmBroadcastReceiver.java b/ig/android/ig/src/main/java/net/coscolla/ig/GcmBroadcastReceiver.java
new file mode 100644
index 0000000..e4dc07b
--- /dev/null
+++ b/ig/android/ig/src/main/java/net/coscolla/ig/GcmBroadcastReceiver.java
@@ -0,0 +1,24 @@
+package net.coscolla.ig;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v4.content.WakefulBroadcastReceiver;
+
+import static android.support.v4.content.WakefulBroadcastReceiver.startWakefulService;
+
+public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
+ public GcmBroadcastReceiver() {
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ ComponentName comp = new ComponentName(context.getPackageName(),
+ GcmIntentService.class.getName());
+
+ startWakefulService(context, (intent.setComponent(comp)));
+ setResultCode(Activity.RESULT_OK);}
+ }
diff --git a/ig/android/ig/src/main/java/net/coscolla/ig/GcmIntentService.java b/ig/android/ig/src/main/java/net/coscolla/ig/GcmIntentService.java
new file mode 100644
index 0000000..1e23422
--- /dev/null
+++ b/ig/android/ig/src/main/java/net/coscolla/ig/GcmIntentService.java
@@ -0,0 +1,87 @@
+package net.coscolla.ig;
+
+import android.app.IntentService;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.NotificationCompat;
+import android.util.Log;
+
+import com.google.android.gms.gcm.GoogleCloudMessaging;
+
+/**
+ * Created by jordicoscolla on 03/02/14.
+ */
+
+public class GcmIntentService extends IntentService
+{
+
+ public static final int NOTIFICATION_ID = 1;
+ private NotificationManager mNotificationManager;
+ NotificationCompat.Builder builder;
+
+ public GcmIntentService()
+ {
+ super("GCM_INTENT_SERVICE");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ Bundle extras = intent.getExtras();
+ GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
+
+ String messageType = gcm.getMessageType(intent);
+
+ if (!extras.isEmpty()) {
+ /*
+ * Filter messages based on message type. Since it is likely that GCM
+ * will be extended in the future with new message types, just ignore
+ * any message types you're not interested in, or that you don't
+ * recognize.
+ */
+ if (GoogleCloudMessaging.
+ MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
+ sendNotification("Send error: " + extras.toString());
+ } else if (GoogleCloudMessaging.
+ MESSAGE_TYPE_DELETED.equals(messageType)) {
+ sendNotification("Deleted messages on server: " +
+ extras.toString());
+ // If it's a regular GCM message, do some work.
+ } else if (GoogleCloudMessaging.
+ MESSAGE_TYPE_MESSAGE.equals(messageType)) {
+
+ // Post notification of received message.
+ sendNotification("Received: " + extras.toString());
+ }
+ }
+ // Release the wake lock provided by the WakefulBroadcastReceiver.
+ GcmBroadcastReceiver.completeWakefulIntent(intent);
+ }
+
+ // Put the message into a notification and post it.
+ // This is just one simple example of what you might choose to do with
+ // a GCM message.
+ private void sendNotification(String msg) {
+ mNotificationManager = (NotificationManager)
+ this.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ Intent intent = new Intent(this, MainActivity.class);
+ intent.setAction("IG_NOTIFICATION");
+ intent.putExtra("message", msg);
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
+ intent, 0);
+
+ NotificationCompat.Builder mBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_launcher)
+ .setContentTitle("GCM Notification")
+ .setStyle(new NotificationCompat.BigTextStyle()
+ .bigText(msg))
+ .setContentText(msg);
+
+ mBuilder.setContentIntent(contentIntent);
+ mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
+ }
+}
diff --git a/ig/android/ig/src/main/java/net/coscolla/ig/MainActivity.java b/ig/android/ig/src/main/java/net/coscolla/ig/MainActivity.java
index b08cbae..2bbe348 100644
--- a/ig/android/ig/src/main/java/net/coscolla/ig/MainActivity.java
+++ b/ig/android/ig/src/main/java/net/coscolla/ig/MainActivity.java
@@ -1,30 +1,62 @@
package net.coscolla.ig;
+import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
+import android.widget.TextView;
+
+import net.coscolla.ig.gcm.GCM;
public class MainActivity extends ActionBarActivity {
+ private static final String GCM_PROJECT_ID = "250453093540";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ PlaceholderFragment fragment = (PlaceholderFragment) getSupportFragmentManager().
+ findFragmentByTag("fragment");
+
if (savedInstanceState == null) {
+ fragment = new PlaceholderFragment();
getSupportFragmentManager().beginTransaction()
- .add(R.id.container, new PlaceholderFragment())
+ .add(R.id.container, fragment, "fragment")
.commit();
}
+
+ String message = getIntent().getStringExtra("message");
+ if(message != null){
+ if(fragment != null)
+ fragment.setText(message);
+ }
+
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... voids) {
+ String regId = GCM.register(MainActivity.this, GCM_PROJECT_ID);
+ Log.d("REGISTER", regId);
+ return null;
+ }
+ };
+ task.execute();
+ }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
@@ -51,6 +83,9 @@ public class MainActivity extends ActionBarActivity {
*/
public static class PlaceholderFragment extends Fragment {
+ private TextView text;
+ private String prev_text;
+
public PlaceholderFragment() {
}
@@ -58,8 +93,18 @@ public class MainActivity extends ActionBarActivity {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
+ text = (TextView) rootView.findViewById(R.id.text);
+ if(prev_text != null)
+ text.setText(prev_text);
return rootView;
}
+
+ public void setText(String message)
+ {
+ if(this.text != null)
+ this.text.setText(message);
+ prev_text = message;
+ }
}
}
diff --git a/ig/android/ig/src/main/java/net/coscolla/ig/gcm/GCM.java b/ig/android/ig/src/main/java/net/coscolla/ig/gcm/GCM.java
new file mode 100644
index 0000000..1ff39fa
--- /dev/null
+++ b/ig/android/ig/src/main/java/net/coscolla/ig/gcm/GCM.java
@@ -0,0 +1,76 @@
+package net.coscolla.ig.gcm;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import com.google.android.gms.gcm.GoogleCloudMessaging;
+
+import java.io.IOException;
+
+
+/**
+ * Created by jordicoscolla on 03/02/14.
+ */
+public class GCM {
+
+ private static final String LOGTAG = "GCM";
+ public static final String EXTRA_MESSAGE = "message";
+ public static final String PROPERTY_REG_ID = "registration_id";
+ private static final String PROPERTY_APP_VERSION = "appVersion";
+ private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
+
+ public static String register(Context ctx, String SENDER_ID)
+ {
+ GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(ctx);
+ String cacheRegId = getRegistrationId(ctx);
+ if( cacheRegId.equals(""))
+ {
+ try {
+ String id = gcm.register(SENDER_ID);
+ getGCMPreferences(ctx).edit().putString(PROPERTY_REG_ID, id).commit();
+ return id;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return "";
+ }
+
+ private static String getRegistrationId(Context context) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+
+ String registrationId = prefs.getString(PROPERTY_REG_ID, "");
+ if (registrationId == null || registrationId.length() == 0) {
+ Log.i(LOGTAG, "Registration not found.");
+ return "";
+ }
+
+ int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
+ int currentVersion = getAppVersion(context);
+ if (registeredVersion != currentVersion) {
+ Log.i(LOGTAG, "App version changed.");
+ return "";
+ }
+ return registrationId;
+ }
+
+ private static SharedPreferences getGCMPreferences(Context context) {
+ return context.getSharedPreferences("GCM", Context.MODE_PRIVATE);
+ }
+
+ private static int getAppVersion(Context context) {
+ try {
+ PackageInfo packageInfo = context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), 0);
+ return packageInfo.versionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new RuntimeException("Could not get package name: " + e);
+ }
+ }
+
+
+
+}
diff --git a/ig/android/ig/src/main/res/layout/fragment_main.xml b/ig/android/ig/src/main/res/layout/fragment_main.xml
index da7bbec..914d668 100644
--- a/ig/android/ig/src/main/res/layout/fragment_main.xml
+++ b/ig/android/ig/src/main/res/layout/fragment_main.xml
@@ -8,9 +8,13 @@
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="net.coscolla.ig.MainActivity$PlaceholderFragment">
- <TextView
- android:text="@string/hello_world"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <TextView
+ android:id="@+id/text"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+ </ScrollView>
</RelativeLayout>
--
1.8.3.4 (Apple Git-47)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.