Java tutorial
/* * Copyright 2013 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.cloud.solutions.cloudadventure; import android.app.IntentService; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import com.appspot.myapp.cloudadventure.Cloudadventure; import com.appspot.myapp.cloudadventure.model.DeviceInfo; import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.api.client.extensions.android.http.AndroidHttp; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.json.gson.GsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.cloud.solutions.cloudadventure.util.CloudEndpointUtils; import com.google.cloud.solutions.cloudadventure.util.Constants; import java.io.IOException; //import com.google.android.gcm.GCMRegistrar; /** * Receive a push message from the Cloud Messaging (GCM) service. This class should be * modified to include functionality specific to your application. This class must have a no-arg * constructor and pass the sender id to the superclass constructor. */ public class GCMIntentService extends IntentService { private final Cloudadventure endpoint; private static final String SENDER_ID = "1092332425958"; private static String userHandleString; public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; /* * NOTE on the following constants: any updates to these will also need to be mirrored in * DevicePing.java in the corresponding App Engine backend. */ public static final String GCM_PAYLOAD_PING_REASON = "GCM_PAYLOAD_PING_REASON"; public static final String GCM_PAYLOAD_MESSAGE = "GCM_PAYLOAD_MESSAGE"; public static final String GCM_PAYLOAD_FROM_USER_HANDLE = "GCM_PAYLOAD_FROM_USER_HANDLE"; public static final String GCM_PAYLOAD_TO_USER_HANDLE = "GCM_PAYLOAD_TO_USER_HANDLE"; public static final String GCM_PAYLOAD_GAME_ID = "GCM_PAYLOAD_GAME_ID"; public static final String PING_REASON_GAME_INVITE = "PING_REASON_GAME_INVITE"; public static final String PING_REASON_GAME_STARTED = "PING_REASON_GAME_STARTED"; public static final String PING_REASON_GAME_DESTROYED = "PING_REASON_GAME_DESTROYED"; public static final String PING_REASON_GAME_ENDED = "PING_REASON_GAME_ENDED"; public static final String PING_REASON_PLAYER_JOINED = "PING_REASON_PLAYER_JOINED"; public static final String PING_REASON_PLAYER_LEFT = "PING_REASON_PLAYER_LEFT"; public static final String PING_REASON_PLAYER_END_STATS = "PING_REASON_PLAYER_END_STATS"; public static final String PING_REASON_FRIEND_INVITE = "PING_REASON_FRIEND_INVITE"; public static final String PING_REASON_FRIEND_ACCEPT = "PING_REASON_FRIEND_ACCEPT"; public static final String BROADCAST_ON_MESSAGE_GAME_START = "on-message-start-event"; public static final String BROADCAST_ON_MESSAGE_GAME_DESTROY = "on-message-destroy-event"; public static final String BROADCAST_ON_MESSAGE_GAME_END = "on-message-end-event"; public static final String BROADCAST_ON_MESSAGE_PLAYER_JOIN = "on-message-join-event"; public static final String BROADCAST_ON_MESSAGE_PLAYER_LEAVE = "on-message-leave-event"; public static final String BROADCAST_ON_MESSAGE_PLAYER_END_STATS = "on-message-stats-event"; /** * Register the device for GCM. * * @param mContext the activity context * @param userHandle */ public static void register(Context mContext, String userHandle) { userHandleString = userHandle; String regId = ""; try { GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(mContext); regId = gcm.register(SENDER_ID); } catch (IOException ex) { Log.d("Debug", ex.getMessage()); } // GCMRegistrar.checkDevice(mContext); // GCMRegistrar.checkManifest(mContext); // final String regId = GCMRegistrar.getRegistrationId(mContext); // if (regId.equals("")) { // GCMRegistrar.register(mContext, SENDER_ID); // } new HandleDeviceRegistration().execute(userHandle, regId); } /** * Unregister the device from GCM. * * @param mContext the activity's context. */ public static void unRegister(Context mContext, String userHandle) { userHandleString = userHandle; try { GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(mContext); gcm.unregister(); } catch (IOException ex) { Log.d("Debug", ex.getMessage()); } } public GCMIntentService() { super("GcmIntentServie"); Cloudadventure.Builder endpointBuilder = new Cloudadventure.Builder(AndroidHttp.newCompatibleTransport(), new JacksonFactory(), new HttpRequestInitializer() { public void initialize(HttpRequest httpRequest) { } }); endpoint = CloudEndpointUtils.updateBuilder(endpointBuilder).build(); } /** * Called on registration error. This is called in the context of a Service - no dialog or UI. * * @param context the Context * @param errorId an error message */ public void onError(Context context, String errorId) { } /** * Called when a cloud message has been received. */ @Override public void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String messageType = gcm.getMessageType(intent); if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { Log.i("GCMIntentService", "Received Msg Type:" + messageType); Log.i("GCMIntentService", "Received Msg : " + extras.toString()); if (PING_REASON_FRIEND_INVITE.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for friend invite."); Intent resultIntent = new Intent(this, ProfileActivity.class); resultIntent.putExtras(intent); generateNotification(resultIntent, ProfileActivity.class); } else if (PING_REASON_FRIEND_ACCEPT.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for friend acceptance."); Intent resultIntent = new Intent(this, ProfileActivity.class); resultIntent.putExtras(intent); generateNotification(resultIntent, ProfileActivity.class); } else if (PING_REASON_GAME_INVITE.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for game invite."); Intent resultIntent = new Intent(this, GameActivity.class); resultIntent.putExtras(intent); resultIntent.putExtra(Constants.GAME_ENTRANCE_ACTION_INTENT_EXTRA_KEY, Constants.GAME_ENTRANCE_ACTION_NOTIFICATION); generateNotification(resultIntent, GameActivity.class); } else if (PING_REASON_GAME_STARTED.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for game start."); Intent messageIntent = new Intent(BROADCAST_ON_MESSAGE_GAME_START); messageIntent.putExtras(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else if (PING_REASON_GAME_DESTROYED.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for game destroy."); Intent messageIntent = new Intent(BROADCAST_ON_MESSAGE_GAME_DESTROY); messageIntent.putExtras(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else if (PING_REASON_GAME_ENDED.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for game end."); Intent messageIntent = new Intent(BROADCAST_ON_MESSAGE_GAME_END); messageIntent.putExtras(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else if (PING_REASON_PLAYER_JOINED.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for game join."); Intent messageIntent = new Intent(BROADCAST_ON_MESSAGE_PLAYER_JOIN); messageIntent.putExtras(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else if (PING_REASON_PLAYER_LEFT.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for game leave."); Intent messageIntent = new Intent(BROADCAST_ON_MESSAGE_PLAYER_LEAVE); messageIntent.putExtras(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } else if (PING_REASON_PLAYER_END_STATS.equals(intent.getStringExtra(GCM_PAYLOAD_PING_REASON))) { Log.i("GCMIntentService", "Received ping for player end stats."); Intent messageIntent = new Intent(BROADCAST_ON_MESSAGE_PLAYER_END_STATS); messageIntent.putExtras(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent); } } GcmBroadcastReceiver.completeWakefulIntent(intent); } /** * Called when a registration token has been received. * * @param context the Context */ public void onRegistered(Context context, String regId) { try { DeviceInfo deviceInfo = new DeviceInfo().setUserHandle(userHandleString).setDeviceRegistrationId(regId); endpoint.devices().insert(deviceInfo).execute(); } catch (IOException e) { e.printStackTrace(); } } /** * Called when the device has been manually unregistered. * * @param context the Context */ protected void onUnregistered(Context context, String regId) { try { endpoint.devices().remove(userHandleString).execute(); } catch (IOException e) { e.printStackTrace(); } } private static class HandleDeviceRegistration extends AsyncTask<String, Void, Void> { @Override protected Void doInBackground(String... ids) { Cloudadventure.Builder builder = new Cloudadventure.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), null); CloudEndpointUtils.updateBuilder(builder); Cloudadventure service = builder.build(); try { DeviceInfo deviceInfo = service.devices().get(ids[0]).execute(); if (deviceInfoIsEmpty(deviceInfo)) { Log.i("GCMIntentService", "Associating user " + ids[0] + " with this device for GCM registration."); deviceInfo = new DeviceInfo().setUserHandle(ids[0]).setDeviceRegistrationId(ids[1]); service.devices().insert(deviceInfo).execute(); } else if (!ids[1].equals(deviceInfo.getDeviceRegistrationId())) { Log.i("GCMIntentService", "Associating user " + ids[0] + " with this device for GCM registration."); deviceInfo = new DeviceInfo().setUserHandle(ids[0]).setDeviceRegistrationId(ids[1]); service.devices().update(deviceInfo).execute(); } else { Log.i("GCMIntentService", "User: " + ids[0] + " is already associated with this device for GCM."); } } catch (IOException e) { Log.d("GCMIntentService", "error: " + e.getMessage(), e); } return null; } } /** * Create a notification that will show up in the phone's notification bar. */ private <T> void generateNotification(Intent intent, Class<T> clazz) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(this.getString(R.string.hello_prefix) + intent.getStringExtra(GCM_PAYLOAD_TO_USER_HANDLE) + "!") .setContentText(intent.getStringExtra(GCM_PAYLOAD_MESSAGE)).setAutoCancel(true); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(clazz); stackBuilder.addNextIntent(intent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); NotificationManager mNotificationManager = (NotificationManager) this .getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(0, mBuilder.build()); } private static boolean deviceInfoIsEmpty(DeviceInfo deviceInfo) { return deviceInfo == null || (deviceInfo.containsKey("error_message") && !deviceInfo.containsKey("userHandle")); } }