Android için Phonegap ile Urban Airship Entegrasyonu
Herkese selamlar,
---
UPDATE 01/12/2011 :
I added sample project to my github acc.
Örnek projeyi github hesabıma ekledim.
http://developerarea.blogspot.com/2011/12/sample-c2dm-project-on-github.html
---
Uzun süredir cep telefonu üzerinden whatsapp, facebook messenger vb. programlar gibi mesajlaşmaya olanak sağlayan bir program üzerinde çalışıyordum. Haliyle webçi bir insan olduğumdan kodlamaları sencha touch, phonegap ve Push Notification ile C2DN notification'ı içinde barındıran Urban Airship library'sini kullanrak yaptım. Bu yazıyı da yazmamın sebebi, internet üzerinde buna benzer bir anlatım olmamasından dolayı (daha doğrusu hep yarım yamalak :D) memlekete bir faydamız dokunsun istedim. :D Tahminen uzun bir süre aynı projeye bakmayacağımdan unuturum. böylelikle gerektiğinde tekrar buradan incelerim :D
Öncelikle Phonegap ve Urban Airship'i kısaca anlatıyım. Phonegap; android, iphone, blackberry gibi mobil işletim sistemlerinde html tabanlı yaptığınız programlarını çalıştırmanıza olanak sağlayan bir library. Kendisinin ayrıca javascript library'si ile telefon üzerinde titreşim yollamaktan tutun, telefon defterine ulaşma, mesaj atma vb. birçok özelliği bulunmakta.
Urban Airship ise iphone ile hayatımıza giren push notification olayını en kolay çözmeye yarayan, ayrıca google'ın misilleme gibi çıkarttığı C2DN notification'ı da destekleyen bir library. İyi tarafı 200000 mesaja kadar bedava sağlıyor olması. Kötü tarafı ise 200000 mesaja kadar bedava sağlıyor olması :D
Şimdi kısaca bunları anlattıktan sonra entegrasyonu nasıl yapacağımızı anlatmaya başliyim. Şimdilik android için tamamladım. Iphone için de çalışıyorum üzerinde. Biterse onunda kısaca bir yazısını yazarım.
Öncelikle gerekenler;
1. Android 2.2 veya üstü bir telefon ve/veya tablet (Simulator'da deneyemezsiniz maalesef)
2. Urban Airship kullanıcısı olmak. (200000 mesaja kadar bedava)
3. Android için C2DN kaydı yaptırmak.
4. Kodlama tarafı için Eclipse Platformu
5. Ve biraz sabır :D
Şimdi başlayalım çalışmaya.
* ilk önce c2dm auth token'ımızı c2dn'e kayıt olduktan ve bize kısmi onay maili geldikten sonra alıyoruz. Bunun için kod yazmak gerekiyor olsa da ben hazırladım gerekli yerleri doldurun kullanın.
Tabii şunu unutmadan söyliyim. Bu kodu kullanabilmeniz için Access-Control-Allow-origin özelliğini browser'ınız için açmanız lazım. Çünkü google'a başka türlü bağlanamayız. Eğer uğraşamam ben diyorsanız internette nasıl alabileceğinize dair yazılar bulunmakta.
* Kodu aldıktan sonra urban airship sayfasından kayıt oluyoruz veya login oluyoruz. Sonrasında application add sayfası çıkacak. Orayı gerekli bilgilerle dolduruyoruz. (aşağıya ss koydum.)
* Programınızı ekledikten sonra size development app key ve development secret key olmak üzere 2 adet key verecek. Bunları not alıyoruz bi yere. (Yada sonradan tekrar girer siteden kopyalarsınız farketmez :D)
NOT : Programınızı tamamen bitirdikten sonra application mode'u production'a çevirip production Key'lerinizi girmeniz gerekecek. Yoksa düzgün çalışmaz.
* Eclipse'te android projesi yaratıyoruz. (Android proje nasıl yaratılır, phonegap nasıl kullanılır için; http://phonegap.com/start#android)
* Gerekli bilgileri giriyoruz. Ayrıca Urban airship'te girdiğiniz android package ismini buraya giriyorsunuz. Farklı girmemelisiniz.
* Sonrasında bütün dosyalar otomatik yaratıldıktan sonra /Assets/ Klasörünün içinde "airshipconfig.properties" dosyasını yaratıyorsunuz ve içine;
---------
# Development key girin
developmentAppKey = AAAAAAAAA
# development secret key girin
developmentAppSecret = BBBBBBBBB
# production key (ilk asamada gerekmiyor ama sallama birsey girin :))
productionAppKey = CCCCCCCCC
productionAppSecret = DDDDDDDDD
# Notification metodlari bunlar : "helium", "c2dm" or "hybrid"
# Bedava oldugu icin c2dm kullaniyoruz :)
# c2dm için kayıt oldugunuz maili yazin
# productiona gectiginiz vakit bunu true yapin
kodlarını girin ve içlerini gerekli bilgilerle doldurun.
* Projenize Urban airship sitesinden yüklediğiniz jar dosyasını reference olarak ekleyin.
* Androidmanifest.xml dosyasını aşağıdaki şekilde değiştiriyoruz.
* Bunlar yapıldıktan sonra artık java'da kod yazmaya başlayabiliriz :D
* Plugin'imiz icin class'ımızı yazıyoruz. Class'imizin ismini "PushNotificationPlugin" olarak yazıyoruz. Sonrasında aşağıdaki kodları ekliyoruz.
-------------
package com.programismi.plugins;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.programismi.ua.IntentReceiver;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import com.phonegap.api.PluginResult.Status;
public class PushNotificationPlugin extends Plugin {
final static String TAG = PushNotificationPlugin.class.getSimpleName();
static PushNotificationPlugin instance = null;
public static final String ACTION = "registerCallback";
public PushNotificationPlugin() {
public static PushNotificationPlugin getInstance() {
public void sendResultBack(String msg, String payload) {
JSONObject data = new JSONObject();
data.put("payload", payload);
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
String js = String.format("window.plugins.pushNotification.notificationCallback('%s');", data.toString());
public void sendApid(String apid){
String js = String.format("window.plugins.pushNotification.getApid('%s');", apid);
public PluginResult execute(String action, JSONArray data,
PluginResult result = null;
if (ACTION.equals(action)) {
result = new PluginResult(Status.NO_RESULT);
result.setKeepCallback(false);
Log.d(TAG, "Invalid action: " + action + " passed");
result = new PluginResult(Status.INVALID_ACTION);
* Sonrasında MainApplication Class'ına gelip burada plugin'imizi tanımlıyoruz.
import org.json.JSONArray;
import com. programismi.ua.IntentReceiver;
import android.app.Application;
import android.content.Context;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
import com.phonegap.api.PluginResult.Status;
import com.urbanairship.UAirship;
import com.urbanairship.push.PushManager;
import com.urbanairship.push.PushPreferences;
public class programismiApplication extends Application {
final static String TAG = programismiApplication.class.getSimpleName();
private static programismiApplication instance;
public static Plugin gwebView;
public static String lPushId;
public programismiApplication () {
public static Context getContext() {
PushManager.enablePush();
PushManager.shared().setIntentReceiver(IntentReceiver.class);
PushPreferences prefs = PushManager.shared().getPreferences();
prefs.setSoundEnabled(true);
prefs.setVibrateEnabled(true);
// apid is a unique identifier for a particular device
String pushId = prefs.getPushId();
Log.i(TAG, "My Application onCreate - App APID: " + pushId);
String js = String.format("window.plugins.pushNotification.getApid('%s');", lPushId);
Sonrasında ise MainActivity dosyamızın üzerinde aşağıdaki gibi değişiklikler yapacağız;
import android.os.Bundle;
import com.phonegap.DroidGap;
import com.urbanairship.UAirship;
public class programismiActivity extends DroidGap {
private static programismiActivity instance = null;
private sendJavascript mc;
public programismiActivity () {
public static programismiActivity getInstance() {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mc = new sendJavascript(this, appView);
appView.addJavascriptInterface(mc, "MyCls");
super.loadUrl("file:///android_asset/www/index.html");
super.addService("PushNotificationPlugin", "com.programismi.plugins.PushNotificationPlugin");
UAirship.shared().getAnalytics().activityStarted(this);
UAirship.shared().getAnalytics().activityStopped(this);
Bunlardan sonra arkaplanda veri iletişimini sağlayacak "IntentReceiver" dosyamızı yaratıyoruz.
package com.programismi.ua;
import com.programismi.programismiActivity;
import com.programismi.programismiApplication;
import com.programismi.plugins.PushNotificationPlugin;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.phonegap.api.Plugin;
import com.urbanairship.UAirship;
import com.urbanairship.push.PushManager;
public class IntentReceiver extends BroadcastReceiver {
private static final String TAG = IntentReceiver.class.getSimpleName();
private PushNotificationPlugin plugin;
public static String intApid;
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Received intent: " + intent.toString());
String action = intent.getAction();
if (action.equals(PushManager.ACTION_PUSH_RECEIVED)) {
int id = intent.getIntExtra(PushManager.EXTRA_NOTIFICATION_ID, 0);
Log.i(TAG, "Received push notification. Alert: " + intent.getStringExtra(PushManager.EXTRA_ALERT)
+ ". Payload: " + intent.getStringExtra(PushManager.EXTRA_STRING_EXTRA) + ". NotificationID="+id);
String alert = intent.getStringExtra(PushManager.EXTRA_ALERT);
String extra = intent.getStringExtra(PushManager.EXTRA_STRING_EXTRA);
plugin = PushNotificationPlugin.getInstance();
plugin.sendResultBack(alert, extra);
} else if (action.equals(PushManager.ACTION_NOTIFICATION_OPENED)) {
Log.i(TAG, "User clicked notification. Message: " + intent.getStringExtra(PushManager.EXTRA_ALERT)
+ ". Payload: " + intent.getStringExtra(PushManager.EXTRA_STRING_EXTRA));
Intent launch = new Intent(Intent.ACTION_MAIN);
launch.setClass(UAirship.shared().getApplicationContext(), programismiActivity.class);
launch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
UAirship.shared().getApplicationContext().startActivity(launch);
} else if (action.equals(PushManager.ACTION_REGISTRATION_FINISHED)) {
Log.i(TAG, "Registration complete. APID:" + intent.getStringExtra(PushManager.EXTRA_APID)
+ ". Valid: " + intent.getBooleanExtra(PushManager.EXTRA_REGISTRATION_VALID, false));
intApid = intent.getStringExtra(PushManager.EXTRA_APID);
Log.i(TAG, "Sending Apid to JS.");
Bundan sonra ise C2DM'den alacağımız APID'yi javascript ile client tarafına yollamamız için "sendJavascript" adında Class yazmamız kalıyor.
import com.phonegap.DroidGap;
import com.urbanairship.push.PushManager;
import com.urbanairship.push.PushPreferences;
import android.webkit.WebView;
public class sendJavascript {
private WebView mAppView;
public sendJavascript(DroidGap gap, WebView view)
PushPreferences prefs = PushManager.shared().getPreferences();
return prefs.getPushId();
Hepsi bittikten sonra ise son olarak /assets/www/ klasörüne (başka bir klasörde yaratmayın!) pushnotification.js dosyasını yaratıp javascript pluginimizi yazıp olayı tamamlıyoruz.
function PushNotification() {
PushNotification.prototype.registerCallback = function(successCallback, failureCallback) {
successCallback, // called when signature capture is successful
failureCallback, // called when signature capture encounters an error
'PushNotificationPlugin', // Tell PhoneGap that we want to run "PushNotificationPlugin"
'registerCallback', // Tell the plugin the action we want to perform
[]); // List of arguments to the plugin
PushNotification.prototype.notificationCallback = function (json) {
var data = Ext.util.JSON.decode(json);
PhoneGap.addConstructor(function() {
if (typeof navigator.pushNotification == "undefined")
navigator.pushNotification = new PushNotification();
PushNotification.prototype.sendApid = function (apid) {
Hepsi bu :D Biraz zahmetli uğraştırıcı bir iş. Ama bazen kaliteli birşey yapmak için uğraşmak gerekiyor.
Bunları yazarken okuduğum linkler;
http://minimoesfuerzo.org/2011/06/6/urban-airship-10-integration-android-phonegap-app/
http://blog.jamesbaca.net/?p=235&cpage=1
Bulduğum bütün linklerde problem; hiçbirinde APID'yi almamasıydı. Haliyle de program saçma oluyordu. Benim yaptığım şekilde ise javascript tarafından apid'yi alabiliyoruz.
//////////////////////////////////////////// blog.ilkerguller.com by Ilker Guller