■Google App Engine/J
・GAE/J iPhone用の実装
iPhone用のPush送信はAppleのAPNSというサービスを使います。
APNS配信にはAppleのDeveloper Centerで証明書と秘密鍵を取得する必要がありますが、こちらを参考にしてください。
http://support.titanium-mobile.jp/questions/2187
ここで注意点ですが、GAE/Jではpemファイルではなく、キーチェーンアクセスの自分の証明書から「Apple Development iOS Push Services:***」を右クリックして保存した .p12 ファイルとパスワードだけを使います。
(pemファイルの作成は不要です)
作成した .p12 ファイルを /WEB-INF/ 以下に置きます。
実装にはjavapnsを使いました。
https://code.google.com/p/javapns/
こちらのサンプルコードを参考にしました。
https://github.com/GoogleCloudPlatform/solutions-ios-push-notification-sample-backend-java
こんな感じです。
private static final String CERTTIFICATE_FILE_NAME = "/WEB-INF/apns_cert.p12";
static final String CERTIFICATE_PASSWORD = "**************";
private static byte[] certificateBytes = null;
static public void sendAPNSMessage(String msg, List devices) {
PushNotificationPayload payload = PushNotificationPayload.complex();
try {
payload.addAlert(msg);
payload.addSound("default");
} catch (JSONException e) {
e.printStackTrace();
}
List payloads = new ArrayList();
for (String device : devices) {
PayloadPerDevice payloadPerDevice = null;
try {
payloadPerDevice = new PayloadPerDevice(payload, device);
payloads.add(payloadPerDevice);
} catch (InvalidDeviceTokenFormatException e) {
log.log(Level.SEVERE, "Error", e);
}
}
PushedNotifications notifications = null;
try {
notifications = Push.payloads(getCertificateBytes(),
CERTIFICATE_PASSWORD, true, // Development:false
// Production:true
payloads);
} catch (CommunicationException e) {
log.log(Level.SEVERE, "Error", e);
} catch (KeystoreException e) {
log.log(Level.SEVERE, "Error", e);
}
if ( notifications != null ){
for (PushedNotification notification : notifications) {
String iosDeviceToken = notification.getDevice().getToken();
if (notification.isSuccessful()) {
} else {
}
}
}
}
protected static byte[] getCertificateBytes() {
if (certificateBytes == null) {
InputStream certifacteStream = this.getServletContext()
.getResourceAsStream(CERTTIFICATE_FILE_NAME);
if (certifacteStream == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
try {
int bytesRead = 0;
while ((bytesRead = certifacteStream.read(buffer, 0,
buffer.length)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
log.log(Level.SEVERE, "Error reading the certificate", e);
}
certificateBytes = outputStream.toByteArray();
}
return certificateBytes;
}
・GAE/J Android用の実装
AndroidにはGoogle Cloud Messaging(GCM)を利用します。
GAE/JでGCMを使うために、こちらを参考に gcm-server.jar と json_simple-1.1.jar をプロジェクトに含めてください。
http://intink.blogspot.jp/2012/10/google-cloud-messaging-for-android.html
一つ一つメッセージを送るのならいいのですが、多くのデバイスにまとめて送信しようとすると文字化けします。
https://groups.google.com/forum/#!msg/google-app-engine-japan/CfREYgz9NDc/wPEYvtLgiiAJ
こちらで紹介されている MySenderを利用させて頂きました。
こんな感じです。
private static final String GCM_API_KEY = "AIzaSyDJmKm3FGjMaqoesUseGme9fLVNYN-ubYE";
private static final int RETRY_COUNT = 5;
static public void sendGCMMessage(String msg, List devices) {
MySender sender = new MySender(GCM_API_KEY);
Message message = new Message.Builder().addData("message", msg).build();
try {
MulticastResult res = sender.send(message, devices, RETRY_COUNT);
List results = res.getResults();
for (Result result : results) {
if (result.getMessageId() != null) {
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// same device has more than on registration ID: update
// database
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
// application has been removed from device - unregister
// database
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
■Titanium
・Titanium iPhone用の実装
iPhone用の実装は Titanium.Network.registerForPushNotifications を使えばすごく簡単でした。
調べると方法が出てくると思うので省略します。
・Titanium Android用の実装
Android用は少々やっかいです。
専用のモジュールを利用するのが一番早いので、こちらのモジュールを利用させていただきました
http://iamyellow.net/post/40100981563/gcm-appcelerator-titanium-module
モジュールの組み込みは通常通りですが、 アプリが起動していない時用の gcm.js と、起動している時用の gcm_activity.js をResources直下に置いて、それぞれ自分のやりたいことに合わせて書き換えてください。
あと、なぜか私の環境のTitanium3.2.2だとモジュールのtimodule.xmlと、自分で作ったplatform/android/AndroidManifest.xmlがうまくマージされず権限が足りなかったので注意してください。
(その場合は手動で権限をAndroidManifest.xmlにマージしてください。${tiapp.properties['id']} は自分のアプリのパッケージ名に置き換えます)
ちなみにiPhone版は普通にPushが届くのですが、Androidの場合は30分くらい遅れることが多いです。
なんでだろう…?
0 件のコメント:
コメントを投稿