Skip to content

Instantly share code, notes, and snippets.

@smd877
Created September 27, 2012 09:47
Show Gist options
  • Save smd877/3793180 to your computer and use it in GitHub Desktop.
Save smd877/3793180 to your computer and use it in GitHub Desktop.
GCMのClientDemoを簡略化
package com.google.android.gcm.demo.app;
import android.content.Context;
import android.content.Intent;
public final class CommonUtilities {
/** サードパーティのID登録/解除用URL */
static final String SERVER_URL = "http://localhost:8080/jsp";
/** サードパーティが取得したGoogle API project id */
static final String SENDER_ID = "1*********6";
/** GCMの通知メッセージを表示するインテントの定義名 */
static final String DISPLAY_MESSAGE_ACTION = "com.google.android.gcm.demo.app.DISPLAY_MESSAGE";
/** メッセージのExtra定義名 */
static final String EXTRA_MESSAGE = "message";
/** UIに通知するメッセージ(直訳乙) */
static void displayMessage(Context context, String message) {
Intent intent = new Intent(DISPLAY_MESSAGE_ACTION);
intent.putExtra(EXTRA_MESSAGE, message);
context.sendBroadcast(intent);
}
}
package com.google.android.gcm.demo.app;
import static com.google.android.gcm.demo.app.CommonUtilities.DISPLAY_MESSAGE_ACTION;
import static com.google.android.gcm.demo.app.CommonUtilities.EXTRA_MESSAGE;
import static com.google.android.gcm.demo.app.CommonUtilities.SENDER_ID;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.TextView;
import com.google.android.gcm.GCMRegistrar;
public class DemoActivity extends Activity {
/** 画面表示用のテキストビュー */
TextView mDisplay;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// GCM登録状態の確認
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
setContentView(R.layout.main);
mDisplay = (TextView)findViewById(R.id.display);
// ブロードキャストレシーバーの設定
registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));
// 現在のregistration_idを確認
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
// 存在しないので登録処理
GCMRegistrar.register(this, SENDER_ID);
}
else {
// 存在するので「既に登録されているよ」と表示
mDisplay.append(getString(R.string.already_registered) + "\n");
}
}
@Override
protected void onDestroy() {
// ブロードキャストレシーバーの解除
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
super.onDestroy();
}
// ブロードキャストレシーバーの登録
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 通知を受けた内容を画面のテキストビューに表示
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
mDisplay.append(newMessage + "\n");
}
};
}
package com.google.android.gcm.demo.app;
import static com.google.android.gcm.demo.app.CommonUtilities.EXTRA_MESSAGE;
import static com.google.android.gcm.demo.app.CommonUtilities.SENDER_ID;
import static com.google.android.gcm.demo.app.CommonUtilities.displayMessage;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
public class GCMIntentService extends GCMBaseIntentService {
/**
* コンストラクタ。Google API project idをスーパークラスのコンストラクタの引数に。
*/
public GCMIntentService() {
super(SENDER_ID);
}
// GCM登録する
@Override
protected void onRegistered(Context context, String registrationId) {
displayMessage(context, getString(R.string.gcm_registered));
ServerUtilities.register(context, registrationId);
}
// GCM解除する
@Override
protected void onUnregistered(Context context, String registrationId) {
displayMessage(context, getString(R.string.gcm_unregistered));
if (GCMRegistrar.isRegisteredOnServer(context)) {
ServerUtilities.unregister(context, registrationId);
}
}
// GCM通知を受けた
@Override
protected void onMessage(Context context, Intent intent) {
// メッセージ内容も出力
String message = getString(R.string.gcm_message) + intent.getExtras().getString(EXTRA_MESSAGE);
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
@Override
protected void onDeletedMessages(Context context, int total) {
String message = getString(R.string.gcm_deleted, total);
displayMessage(context, message);
// notifies user
generateNotification(context, message);
}
@Override
public void onError(Context context, String errorId) {
displayMessage(context, getString(R.string.gcm_error, errorId));
}
@Override
protected boolean onRecoverableError(Context context, String errorId) {
// log message
displayMessage(context, getString(R.string.gcm_recoverable_error, errorId));
return super.onRecoverableError(context, errorId);
}
/**
* ノーティフィケーションへの通知処理
*
* @param context
* @param message
*/
private static void generateNotification(Context context, String message) {
int icon = R.drawable.ic_stat_gcm;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, DemoActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
}
package com.google.android.gcm.demo.app;
import static com.google.android.gcm.demo.app.CommonUtilities.SERVER_URL;
import static com.google.android.gcm.demo.app.CommonUtilities.displayMessage;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import android.content.Context;
import com.google.android.gcm.GCMRegistrar;
public final class ServerUtilities {
private static final int MAX_ATTEMPTS = 5;
private static final int BACKOFF_MILLI_SECONDS = 2000;
private static final Random random = new Random();
/**
* 登録処理
*
* @param context
* @param regId
* @return
*/
static boolean register(final Context context, final String regId) {
String serverUrl = SERVER_URL + "/do.jsp";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
for (int i = 1; i <= MAX_ATTEMPTS; i++) {
try {
displayMessage(context, context.getString(R.string.server_registering, i, MAX_ATTEMPTS));
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, true);
String message = context.getString(R.string.server_registered);
CommonUtilities.displayMessage(context, message);
return true;
}
catch (IOException e) {
if (i == MAX_ATTEMPTS) {
break;
}
try {
Thread.sleep(backoff);
}
catch (InterruptedException e1) {
// Activity finished before we complete - exit.
Thread.currentThread().interrupt();
return false;
}
// increase backoff exponentially
backoff *= 2;
}
}
String message = context.getString(R.string.server_register_error, MAX_ATTEMPTS);
CommonUtilities.displayMessage(context, message);
return false;
}
/**
* 解除処理
*
* @param context
* @param regId
*/
static void unregister(final Context context, final String regId) {
String serverUrl = SERVER_URL + "/do.jsp";
Map<String, String> params = new HashMap<String, String>();
params.put("regId", regId);
try {
post(serverUrl, params);
GCMRegistrar.setRegisteredOnServer(context, false);
String message = context.getString(R.string.server_unregistered);
CommonUtilities.displayMessage(context, message);
}
catch (IOException e) {
// GCMからは解除されているが何らかの理由により解除処理をした場合の例外。
// サードパーティのサーバで例外と判断した場合にエラーを返せばここの処理が走る。
String message = context.getString(R.string.server_unregister_error, e.getMessage());
CommonUtilities.displayMessage(context, message);
}
}
/**
* POST処理
*
* @param endpoint POST address.
* @param params request parameters.
* @throws IOException propagated from POST.
*/
private static void post(String endpoint, Map<String, String> params) throws IOException {
URL url;
try {
url = new URL(endpoint);
}
catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url: " + endpoint);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
// constructs the POST body using the parameters
while (iterator.hasNext()) {
Entry<String, String> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=').append(param.getValue());
if (iterator.hasNext()) {
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString();
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection)url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// post the request
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
// handle the response
int status = conn.getResponseCode();
if (status != 200) {
throw new IOException("Post failed with error code " + status);
}
}
finally {
if (conn != null) {
conn.disconnect();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment