titanium alloy android push通知 by ruby
前準備
Google Developers Consoleから
新しいプロジェクトを作成し、プロジェクトナンバーを控える
Project Number: 333333334444444 # GCM sender ID
APIs & auth > APIsからGoogle Cloud Messaging for AndroidをOFF→ONに
APIs & auth > CredentialsからPublic API access→Create new keyと進みServer keyを作成
AIzaSyCZzdkY35DyGGDzdw7WFz0F1pxxvk_M # API KEY
サーバー(heroku+mongolab)
android端末から得られるdeviceTokenが通知に必要なのでmongodbに保存&通知処理
require "mongoid" require "sinatra" require "gcm" if development? require 'sinatra/reloader' end Mongoid.load!("mongoid.yml", :development) class Registration include Mongoid::Document field :cd, type: String end post "/gcm" do Registration.find_or_create_by(cd: params[:id]) end get "/" do erb :index end post "/registration" do gcm = GCM.new("<API KEY>") registration_ids= Registration.all.pluck(:cd) options = {data: {title: params["title"],message: params["message"]}} @res = gcm.send(registration_ids, options) erb :gcm end
titanium
githubからモジュール取得して配置
iamyellow/gcm.js · GitHub
/modules /android /net.iamyellow.gcmjs
tiapp.xml
<property name="GCM_sender_id" type="string"><GCM sender ID></property> <modules> <module platform="android" version="0.2">net.iamyellow.gcmjs</module> </modules>
index.js
var gcm = require('net.iamyellow.gcmjs') var pendingData = gcm.data; if (pendingData && pendingData !== null) { // if we're here is because user has clicked on the notification // and we set extras for the intent // and the app WAS NOT running // (don't worry, we'll see more of this later) Ti.API.info('******* data (started) ' + JSON.stringify(pendingData)); } gcm.registerForPushNotifications({ success: function (ev) { // on successful registration Ti.API.info('******* success, ' + ev.deviceToken); }, error: function (ev) { // when an error occurs Ti.API.info('******* error, ' + ev.error); }, callback: function () { // when a gcm notification is received WHEN the app IS IN FOREGROUND alert('hellow yellow!'); }, unregister: function (ev) { // on unregister Ti.API.info('******* unregister, ' + ev.deviceToken); }, data: function (data) { // if we're here is because user has clicked on the notification // and we set extras in the intent // and the app WAS RUNNING (=> RESUMED) // (again don't worry, we'll see more of this later) Ti.API.info('******* data (resumed) ' + JSON.stringify(data)); } });
app/assets/android/gcm.js
/*global Ti: true, require: true */ (function (service) { var serviceIntent = service.getIntent(), title = serviceIntent.hasExtra('title') ? serviceIntent.getStringExtra('title') : '', statusBarMessage = serviceIntent.hasExtra('message') ? serviceIntent.getStringExtra('message') : '', message = serviceIntent.hasExtra('message') ? serviceIntent.getStringExtra('message') : '', notificationId = (function () { // android notifications ids are int32 // java int32 max value is 2.147.483.647, so we cannot use javascript millis timpestamp // let's make a valid timed based id: // - we're going to use hhmmssDYLX where (DYL=DaysYearLeft, and X=0-9 rounded millis) // - hh always from 00 to 11 // - DYL * 2 when hour is pm // - after all, its max value is 1.159.597.289 var str = '', now = new Date(); var hours = now.getHours(), minutes = now.getMinutes(), seconds = now.getSeconds(); str += (hours > 11 ? hours - 12 : hours) + ''; str += minutes + ''; str += seconds + ''; var start = new Date(now.getFullYear(), 0, 0), diff = now - start, oneDay = 1000 * 60 * 60 * 24, day = Math.floor(diff / oneDay); // day has remaining days til end of the year str += day * (hours > 11 ? 2 : 1); var ml = (now.getMilliseconds() / 100) | 0; str += ml; return str | 0; })(); // create launcher intent var ntfId = Ti.App.Properties.getInt('ntfId', 0), launcherIntent = Ti.Android.createIntent({ className: 'net.iamyellow.gcmjs.GcmjsActivity', action: 'action' + ntfId, // we need an action identifier to be able to track click on notifications packageName: Ti.App.id, flags: Ti.Android.FLAG_ACTIVITY_NEW_TASK | Ti.Android.FLAG_ACTIVITY_SINGLE_TOP }); launcherIntent.addCategory(Ti.Android.CATEGORY_LAUNCHER); launcherIntent.putExtra("ntfId", ntfId); // increase notification id ntfId += 1; Ti.App.Properties.setInt('ntfId', ntfId); // create notification var pintent = Ti.Android.createPendingIntent({ intent: launcherIntent }), notification = Ti.Android.createNotification({ contentIntent: pintent, contentTitle: title, contentText: message, tickerText: statusBarMessage, icon: Ti.App.Android.R.drawable.appicon, flags: Ti.Android.FLAG_AUTO_CANCEL | Ti.Android.FLAG_SHOW_LIGHTS }); Ti.Android.NotificationManager.notify(notificationId, notification); service.stop(); })(Ti.Android.currentService);
app/assets/android/gcm_activity.js
/*global Ti: true, require: true */ (function (activity, gcm) { var intent = activity.intent; // HERE we catch the intent extras of our notifications if (intent.hasExtra('ntfId')) { // and then we'll use 'data' property to pass info to the app (see pendingData lines of the 1st snippet) gcm.data = { ntfId: intent.getIntExtra('ntfId', 0) }; } // 'isLauncherActivity' is a module property which tell us if the app is not running if (gcm.isLauncherActivity) { // if the app is not running, we need to start our app launcher activity // (launcher activity shows the splash screen and setup your app environment, so we need this) var mainActivityIntent = Ti.Android.createIntent({ // 'mainActivityClassName' is another module property with name of our app launcher activity className: gcm.mainActivityClassName, packageName: Ti.App.id, flags : Ti.Android.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Ti.Android.FLAG_ACTIVITY_SINGLE_TOP }); mainActivityIntent.addCategory(Ti.Android.CATEGORY_LAUNCHER); activity.startActivity(mainActivityIntent); } else { // if the app is running (is being resumed), just finish this activity! activity.finish(); } })(Ti.Android.currentActivity, require('net.iamyellow.gcmjs'));
titaniumはこのドキュメントのコピペでいけた
GCM push notifications for Titanium (made easy) - i am yellow
参考
Getting Started | Android Developers
GCM push notifications for Titanium (made easy) - i am yellow
http://freestyle.nvo.jp/archives/1218
spacialdb/gcm · GitHub