2010年11月21日日曜日

ニュースから読み解くAndroidの過去・現在・未来

第7回Android勉強会での発表資料として、以下のような資料を作ってみました。

といっても、あまり時間をかけれなかったので,リンク集のような感じになっています。

去年のXperiaタッチ&トライイベント参加者が20人強だったのに比べ、今年のIS01タッチ&トライイベントでは50人の申し込みがあるなど,やはりAndroidは盛り上がってきてるなぁという印象です。

2010年9月22日水曜日

Android用のバーコードスキャナにBitmapから解析する機能をつけた

Androidにはバーコードスキャナってゆーアプリがあります。

オープンソースなんですがGooglerが作っているようで、Android本体の標準アプリになってもおかしいくないような品質のアプリなんですが,こいつはカメラでバーコードを写して解析するような動作しかサポートしておらず,静止画として既にバーコードなどがファイルとして手元にある場合(ネットからダウンロードしたなど)の時には使えるものではありませんでした。

やりましょう!

で、先日ついったーで「IntentにBitmap込めて送ったら、結果が帰ってくるようなヤツ欲しいなー」とつぶやいてる人がいたので、作ってみました。

と言っても、一晩で作ったものなので,ちゃんと動いているか怪しいですが。いや、実際一部動いてないですが(汗)

欲しい人もたくさん居るっぽいので、とりあえず出来たもののAndroidプロジェクトをそのまま配布します。ライセンスは元のApache licenseを踏襲ということで。

Bitmapから解析する機能を付けたバーコードスキャナのプロジェクト

Bitmapから解析する機能を付けたバーコードスキャナ本体(デバッグキー版)

で、本来はAndroidマーケット上で流れているアプリに取り込まれてくれたほうが楽だと思うので,Google Code上のプロジェクトにパッチを提供しました。テスト用のActivityも付けたので,使い方知りたい方はこちらも御覧ください。

送ったパッチのissueページ

このページの☆を増やしてもらえると、本体に取り込まれるのも早くなるかも!?

たぶんどっかバグってると思うのですが、あまりマジメに直す気はないので、おかしいところを見つけた場合は教えてください。GitHubにでもブランチ作ります。

2010年9月19日日曜日

スマートフォンの超概略無責任見積りの算出方法を考えてみた

この資料は第二回札幌IT飲み会で発表した資料です。

問題点

たぶん、スマートフォン向けのアプリ(iPhone/Android/WindowsPhone問わず)をクライアントに提案したり、もっと進んで外注しようとしたことって、無いもしくは少ないと思うんですが,なんとなーくスマートフォンにはどんな機能があるのかは知っていても,どれくらい(時間と価格)で作れるものなのかが、いまいち感覚的に解らないのが原因なのかなーと、常々思っていました。

一番手っ取り早いのは、対応可能な企業から見積りを取ることなのですが、まだ企画段階なのに見積りを取ることに気が引けたり、どんなアプリにするかまだまとまってなかったりしていて、ウヤムヤになってしまうことが多いんじゃないでしょうか。

やりましょう!

そこで作ってみたのが、超概略無責任見積りです。

まーもちろん正確な見積りとは程遠いですが,プログラムのことは全然解らなくても,なーんとなくの超概算ぐらいはつかめるんじゃないでしょうか。

とはいいつつ、この見積りへ入力する条件として、画面数やボタンの数などを把握する必要があるので,紙に画面を書けるぐらいの知識(Webシステム見合いでOK)は必要となるので,実際にはWeb屋さんが使うための手法となります。

手法としては,

  • 積み上げ
  • Webシステムの見積からのコンバート

の2つを考えてみました。

詳しくはこちら。

ここで使っているシートは超概略無責任見積り計算シートにアップロードしてありますので,ご自由にお使いください。OpenOfficeで作ってますがodsなので何でも開けるはずです。ただし、見積り精度的に困ったことが起きても、知らんぷりしますが。。。詳しくはスライド確認のこと

おしえてエライ人!

で、こんなの作っちゃったら、詳しい人から「全然ちげーよバーカバーカ」って言われるのは目に見えていますw。まぁ当然全然違うと思ってるのですが,逆にスマートフォンプログラマの目線で、受注金額と単価から逆算して、単位日数の精度を向上させることができると思うのです。

上記計算シートの2ページ目に、(至極簡単ですが)プログラマ向けに逆算用のシートを用意したので,自社案件に置き換えて単位日数を逆算してみてください。

もし可能なら、精度向上に向けたサンプルとして逆算した単位日数を教えてもらえると嬉しいです。一応収集用としてフォームを用意してあります。

単位日数サンプル入力フォーム

もしサンプルがある程度集まりましたら、改訂版を公開しようと思っています。

2010年8月7日土曜日

Google App Engine ja Night Sapporo (gjns)で発表しました

最近このブログは発表資料置き場になってますけど、まぁいっか。

今日はGoogle App Engine ja NightというGAE好きな人の集まりに参加してきました。東京では盛り上がってるみたいだけど,地方では大阪に続き札幌で2箇所目なんだって。札幌も盛り上がればいいねぇ。

最近AndroidばかりでGAEに触れてないのだけど,勢いで過去の発表資料+ちょびっとググって資料を作って発表してきました。

折角なのでここに貼っておきます。

ただ、参加者の多くはJava使いの方らしく、RubyやPHPをやっている人はほぼ居なかったので、ネタとしては外していたなぁと反省…

2010年6月29日火曜日

意外に知られていないANDROIDに関する7つの常識

先日札幌IT飲み会、そしてその翌日にオープンソースカンファレンス2010北海道(OSC2010Do)に参加してきました。

IT飲み会ではプレゼンタイムというのがあって、本当は2回目から参加資格があるような感じらしいのですが、初参加の当日いきなり「作ってきましたー」と手を上げて話してきました。

んで、翌日は毎年参加しているOSCがあったんですが、日本Androidの会ブースでほぼ同様のものを展示していました。

一部からこの資料公開してよーという声があったので、このブログに貼っておきます。

内容は、 非プログラマ向けにAndroidの現状というか空気感を感じてもらえるかなーと思って作ったものです。最近Androidってどう?って思ってる人は、気軽に呼んでみてください。内容もさらっとしてますし。

2010年3月26日金曜日

AndroidとGAEの同期に関する講演資料を公開します

先日第4回日本Androidの会北海道支部勉強会で講演したんですが、その時のプレゼン資料を公開します。

内容は、データってクラウドに「も」持たせた方が何かと便利だよねーって話と、じゃーライブラリ作って定型化したらみんな使いやすいかもねーって話と、具体的な使い方の話です。

次のような使い方を前提としています。

  • ユーザはAndroid端末1台と、GAE上のサービスを同期できる。(複数台と同期できる方が楽だけど、同期方法が複雑になるので断念)
  • アクセス元のAndroid端末は、電話番号やシリアルを使って自動認識させる。(これはポン付けで動く)
  • Android内のSQLiteに保存されたデータを、そのままの形でGAE上のDataStoreにも入れておき、必要であればリカバリもできる。(データ構造によりカスタマイズが必要)
  • 基本的にHTTPリクエスト(実際にはhttps)を使ってデータを送り、そのレスポンスに対してコールバックを使って制御する。
  • RESTっぽい使い方で、CRUDあたりまでは簡単に使えそう。
  • 詳しい使い方はサンプルアプリのソースを読むべし。たった300行強(SyncTestActivity)だし。

ライブラリとサンプルアプリはオープンソースとして公開しています。

SyncTester

2010年2月14日日曜日

LDD'10 WinterのLTに飛び込んできた

前日に「まだ枠が余っているから話してみたら?」と言われたので、LT開始3時間前から資料を作り、開始直前に会場入りして、LT終わったらすぐ帰ってきた(娘の迎えがあった)。

LT自体は途中で時間切れだったので残念だったけど、せっかくなので資料晒します。

「Ajaxなサイトでもスクレイピングできるのがイイ!」で締めたかったんだけど、そこまで伝えられなかったかも。

2010年2月12日金曜日

WebViewを使ったスクレイピングの使い道

Android MLで WebViewとJavaScriptを使ったスクレイピング ってゆートピックを見つけたんだけど、現在進行形で正しくこのアーキテクチャを使ってプログラムを書いているところだったので、フォロー入れます。つーか入れずに居られない。

なんのこっちゃという方は、こちらを見てください。

WebViewを使ったスクレイピング / scraping a page using the WebView in a Service

スクレイピングにあたっての問題点

まず、自分の場合は特定ページのHTMLを定点観測するためにパーサーを書く必要があったんだけど、Javaに慣れてないので以下のような問題をどう超えようか悩んでいました。

  1. PullParserなどよりXPathを使いたい(使用されるリソース量よりコーディング手間の方が優先。とりあえず形にするにはコレ重要)
  2. 対象のページで使用される文字コードがなんだか分からない場合でも、なんとかしたい。(特にHTTPヘッダーで示される文字コードと、HTMLヘッダーで示される文字コードと、実際に使われている文字コードが違うような変態ページにも対処したい)
  3. XHTMLに準拠してないページでも、なんとかしたい。準拠してなくてもXMLパーサがなんとか使える程度ならいいんだけど。
  4. 壊れているHTML(閉じ忘れ)などでも、なんとかしたい。

ぶっちゃけ、対象ページが固定されていればあまり問題にはならないのですが、今後のため汎用的に作れないかなぁと思っていました。

解決策

んで、まぁいろいろ悩んだのですが、Android向けのアプリを書いていたのでWebView(WebKitをJNI経由でコントロールするためのGUI部品)を使えば、ほぼクリア出来るということがわかりました。

思い起こせば、昔Rubyでスクレイパーを書いていたとき、もじらのHTMLパーサ使おうかなぁと悩んだことがありまして、 理由は全く同じでした。特にHTMLが壊れていても、なんとかなるのが大きい!

特に上記2・3・4なんかはJavaでやってたら死ねたと思います。(単なる知識不足ですが)

補足

一応補足しておくと、上記1ですが、結局XPathは見送りになりました。上記2・3・4のメリットとの天秤でしたが、XPathを使うためには、Javaの外部ライブラリを使うか、JavaScriptの外部ライブラリを使うか、HTML5対応ブラウザの標準関数を使う必要があり、Androidに載っているブラウザはHTML5にはまだ対応出来ていないため、どれもちょっと微妙でした。自分の場合はDOMを使ってパースすることにしました。(DOMを使う場合でも、他の手段と比べてかなりコード量は減るはずです)

2についてはWebKit側で自動的に推定してくれます。精度はレガシーなページ(EUCやShiftJISなページ)をブラウザで開いてもまぁまぁきちんと表示されることから、まぁまぁ良いぐらいでしょうか。

3についてはブラウザ内のJavaScriptを使うことで解決しています。DOMでもXPathでも使えるはずです。個人的にはJavaでパーサを書くより好きです。

4については、WebKitが対象のHTMLを取得し、レンダリングのためWebKitのHTMLパーサーに渡した時点で、文法的に明らかにおかしい(trを閉じてないのにtableを閉じたなど)は、自動的に修正してくれます。ブラウザ内のJavaScriptからアクセス可能なのは、このパース後(修正後)のHTMLなので、スクレイピングに支障をきたすほど壊れたHTMLに出会う確率はぐっと減ります。

使いどころ

ざっと思いつくのはこんな感じでしょうか。

  • レガシーなページを含む場合のスクレイピング。最近のHTMLはXHTMLに対応しているこが多いけど、昔からある個人運営のページや、携帯向けページは未だにスクレイピングしづらいものがある。
  • 上記の発展として、「(単純にタグを除くだけの全文検索タイプではなく)タグ構造を考慮に入れたサーチエンジン」のためのクローラ&パーサ。まともにHTML解析機を作ってると死ねると思うので。
  • オートパイロット。例えばヤフオクなどで、ログインしてなかったら(特定文字を検出したら)オートパイロットモードになってログインし、指定されたページに入札を行うなど。同様のことはHTTPリクエストだけでも行えるが、今何が起こっているのか見えるのでユーザは安心かと。
  • Ajax前提のサイトなど、JavaScriptが動いてくれないと必要なデータを取得できないような場合。これが今まで出来なかった! Androidエライ!!
  • HTTP的なお作法に厳しいページへのスクレイパー。Railsなどはリダイレクトを多用するけど、自分でリダイレクト対応のコードを書くのは面倒だよね。Cookieも自動的に処理してくれるから、セッション管理が楽。Basic認証とかSSLとか数え上げれば切りが無いほど、「フツウ」にHTMLに触れるのはメリット。

で、デメリット

といいつつAndroidのWebViewも万能ではない。

  • WebViewはViewクラスを継承しているので、いわゆるUIスレッドでなければ正常に動かないかも。(下記Tips参照)
  • Javaのメリットって、比較的簡単にマルチスレッドを使えるってのがあるだろうけど、上記理由によりマルチスレッドでは動かない(可能性が高い。やり方によるのかも)
  • 上記理由により、意味不明に落ちることがある。そんときのバックトレースから、Looperの仕組みなどをきちんと理解する必要があるのかもしれない。ハマると抜け出すのに苦労する。
  • リソース大食い。ServiceからWebViewを使うことにした場合、これは頻繁に虐殺されることを指す。殺されないための手当と、殺された場合にシームレスに復活するための手当を要す。これはこれで結構面倒(かつノウハウがあまりWeb上に蓄積されていない)。また、このせい(リソース食い過ぎ)で他のServiceがまともに動かない可能性も。
  • (PCを含めた)スクレイパーとしては致命的に重い。Android内に限っても、、、やっぱり重いかも。特にHT03AのCPUではそう感じる。1GHzぐらいあればあまり気にならないかも。
  • 2つのWebViewを同時に動かすと落ちる? 不安定になる?(調査中)  JNI使う場合は、行儀良くしないとアプリではなくOSが落ちます。
  • Androidに載ってるJavaScriptエンジンって、V8じゃなかったような。。。感覚的にはJavaでXMLパーサを使うより、ブラウザ内でJavaScriptを使ってパースする方が、2〜3倍遅い気がする。(あくまで感覚値)
  • UTF8でXMLやXHTMLを返すとわかっている場合は、JavaでHTTP叩いてXMLパーサを通した方がきっと早くてリソース消費も少なくてマルチスレッドで動く。なんでもばっちこいな場合のみ、WebViewが使えるのかも。特にAndroid上で動かす必要が無いならば、他の方法とよく比較検討した方がいいかも。

Tipsというかバッドノウハウ

試行錯誤から得たノウハウをちょっとだけ。(出し惜しみではなく、もうハマリポイントを忘れたため)

  • 自分の場合、Serviceクラス(の派生)からWebViewクラス(の派生)を呼んでも、正常に動きました。WebViewを使ったスクレイピングのようにレンダリングやパラメータは調整しましたけど。この状態でActivityにバインドして毎分リクエストして24時間ぐらいは平気で連続取得に耐えていますので、お作法的にはよろしく無いかもしれないけど、実際には使えると思っています。まぁ、少なくともアプリが自分のコントロール下にある(ソースをいじれる)うちは、ServiceでWebView使ってもいいかなぁとか。
  • JavaからWebView.loadUrl("javascript:ごにょごにょ;");で、今開いているページに対して追加でJavaScriptを動かせることができる。ブックマークレットみたいな感じ。ちなみに、ここで渡すJavaScriptは相当長くても動いてくれる。
  • WebKitのHTMLパーサーにかけた後の、修正済みHTMLをJavaScript経由でJavaに取り込むこともできる・・・ハズ。JavaScriptでHTMLタグのinnerHTMLを取得するなど。ハズっつーのは、実際にやってみたけど尻切れになっちゃうから。HTMLタグの子供をループしてのinnerHTML取得だと、もう少し取れるけど、完全に取れたか確認出来ないし。。。うまくいった方はやり方教えてください。
  • ってか、NDK使って、WebKitの文字コード推定&コンバートとHTMLパーサ部分だけを使うJNI作っちゃえばいいのかも。ってか、コレAndroidの標準ライブラリに入れてくれないかなぁ。

まとめ

長くなったので、まとめてみる。

  • やんちゃなページを相手にスクレイピングを仕掛けたいならWebViewに限る
  • とくにAjaxなヤツを相手にするなら現状WebView以外の選択肢は無いように思える
  • でもこいつはクセが強いぞ。心して掛かれ