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
selenium-webdriverでwebページ読み込み待ち
テストではうまく動いてたので気づくの遅れてしまった、これだとページ読み込み中にパース処理が走ってしまう
require "selenium-webdriver" require "nokogiri" driver = Selenium::WebDriver.for :chrome driver.navigate.to url doc = Nokogiri::HTML.parse(driver.page_source) doc.css('div.content').each do |n| ... end
ので、欲しい要素が表示されるまでwait
require "selenium-webdriver" require "nokogiri" driver = Selenium::WebDriver.for :chrome driver.navigate.to url wait = Selenium::WebDriver::Wait.new(:timeout => 3) # second wait.until { driver.find_element(:id => "data").displayed? } doc = Nokogiri::HTML.parse(driver.page_source) doc.css('div.content').each do |n| ... end
いけたー
参考
RubyBindings - selenium - Ruby bindings - Browser automation framework - Google Project Hosting
titanium sdk 3.3.0 + androidでgoogle mapが表示されない
titaniumでrss系のandroidアプリ作ったし、次はmap系と思い
公式ドキュメントのサンプルそのままに動かすも
http://docs.appcelerator.com/titanium/3.0/#!/guide/Google_Maps_v2_for_Android
http://docs.appcelerator.com/titanium/3.0/#!/api/Modules.Map
The Google Play services resources were not found
というエラーとともに地図が表示されない・・・
google play services sdkちゃんと入れてるのに・・・
google先生に聞いたら
[TIMOB-16510] Android: The Google Play services resources were not found - Appcelerator JIRA
titanium sdk 3.2.1以降?はバグで動かん titanium sdk 3.4.0では直ってるよ
どうりで何度やってもmap表示されないわけだ・・・
ちなみにtitanium sdkを3.2.0にしてビルドしようとするとビルドがうまくいかない・・・
titanium clsのバージョンが3.3.0だから?
ということで3.4.0が9月に出るみたいなのでそれまで待ちます
titaniumでandroidアプリ作ってみた
titaniumでandroidアプリ作ってみた
今日のアニメ(アニメニュース&アニメ番組表) - Google Play の Android アプリ
本当は、ionicでios7風のアプリ作りたかったんですが、
http://ionicframework.com
実機で動かしたらもっさりしすぎて使い物にならなかった(ボタン押してから5秒とか10秒とかのタイムラグ)のでやめてtitaniumにした
作りはすごく単純で、alloyのrssサンプルをベースに
https://github.com/appcelerator/alloy/tree/master/samples/rss
googleニュースrss使ってアニメのニュースを
しょぼいカレンダー様より番組表のデータを
データを取得する方法 - しょぼいカレンダーのヘルプ
それぞれ表示してるだけ
あと番組開始5分前に通知する機能つけた
通知機能はモジュール使った
benbahrenburg/benCoding.AlarmManager · GitHub
アイコンは、イラストレーターで絵文字フォントをでっかくしただけw
もしよかったら使ってみてください
gemfileのバージョン指定
gemfileのバージョン指定がいつも分らなくなるのでまとめ
0.2.0バージョン固定
gem "dmm-api","0.2.0"
0.2.0以降の最新バージョン
gem "dmm-api",">=0.2.0"
0.2.0以降かつ0.3未満バージョン
gem "dmm-api","~>0.2.0"
最新バージョン
gem "dmm-api"
titanium alloy アプリ名の日本語化 by android
alloy登場以前にはやったことあったけど忘れてたので
まずフォルダとファイル作成
/app /i18n /en string.xml /ja string.xml /platform /android AndroidManifest.xml
ファイルの中身はそれぞれ
/i18n/en/string.xml
<?xml version="1.0" encoding="UTF-8"?> <resources> <string name="app_name">testapp</string> </resources>
<?xml version="1.0" encoding="UTF-8"?> <resources> <string name="app_name">テストアプリ</string> </resources>
AndroidManifest.xmlは
/build/android/AndroidManifest.xmlからコピーして
android:labelを以下のように修正
android:label="@string/app_name"
iosの場合は違うみたい・・・
titaniumのアイコンとスプラッシュ画面簡単作成
titaniumに必要な画像ファイルはイラストレータで一個づつ作ってたんですけど
TiCons - Generate all icon & splash screens for your Titanium app from just 2 or 3 files!
Ticonsっていうサービス使ったら、ファイル3つ作るだけでいけた
もっとはやく知りたかった・・・