JSONPを使ってみた

JSONPとは、JSON with Paddingと言うことらしいですが、詳しい説明はググってください。

今回やりたいことは、別サーバにあるCSVファイルからパラメータで指定したidにマッチする値を取り出して表示する、というものです。
サーバ側のプログラムはPHPで作ってみました(経験値少ないので変なところがあるかも)。

元データになるuser.csvファイルはこんな感じです。

1,山田太郎
2,鈴木一郎
3,池田次郎

フィールドはidとnameになります。

次にサーバ側の処理です。
と、その前にPHP版のJSONライブラリと、JSONPで呼び出すためのJavaScriptライブラリを用意しておきます。

サーバ側のindex.phpはこんな感じになります。UTF-8で保存しています。

<?php
// JSON.phpを読み込む
require_once('JSON.php');

// utf-8を使えるようにするおまじない
setlocale(LC_ALL, 'ja_JP.UTF-8');

// callback関数名を取得
$cb = $_GET['callback'];
// idを取得
$id = $_GET['id'];

// CSVファイルをオープン
$fp = fopen("user.csv", "r");
$user = array('name' => '');
while (($data = fgetcsv($fp, 1000, ",")) !== FALSE) {
  // $idにマッチする値を見つけた!
  if ($id == $data[0]) {
    $user = array('id' => $data[0], 'name' => $data[1]);
    break;
  }
}
// CSVファイルをクローズ
fclose($fp);
// Services_JSONオブジェクトを作成
$json = new Services_JSON;
// レスポンスヘッダにContent-Typeを設定
header("Content-Type: text/javascript; charset=utf-8");
// JSON形式に変換して、callbackメソッドの引数として返す
echo "$cb(" . $json->encode($user) . ")";
?>

サーバ側のURLは、「http://example.com/index.php」とすると、次のようなURLをブラウザで開くことで、内容の確認が出来ます。
http://example.com/index.php?id=1&callback=hello

このレスポンスは、次のようになります。

hello({"id":"1","name":"\u5c71\u7530\u592a\u90ce"})

レスポンスの先頭の「hello」は、パラメータのcallbackで指定した文字が入ります。
例えば、http://example.com/index.php?id=1&callback=hogehogeで呼び出すと、次のようなレスポンスが返ってきます。

hogehgoe({"id":"1","name":"\u5c71\u7530\u592a\u90ce"})

という感じでブラウザで確認できたら、クライアント側のHTMLを書いてみましょう。

こんな感じです。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<span>JSONPを使うよ</span>
<script type="text/javascript" src="http://example.com/jsr_class.js"> </script>
<script type="text/javascript">
// callbackで呼び出される関数
function hello(data) {
    var resultData = '';
    resultData += '<p>こんにちは ' + data.name + ' さん</p>';
    document.getElementById('hellotarget').innerHTML = resultData;
    bObj.removeScriptTag(); 
}
var req  = 'http://example.com/index.php?id=1&callback=hello';
var bObj = new JSONscriptRequest(req); 
bObj.buildScriptTag(); 
bObj.addScriptTag();
</script>
<div id="hellotarget" style="width:180px; border:thin #666666 solid;"></div>
</body>
</html>

JSONscriptRequestの引数で、サーバ側のスクリプトを呼び出します。
このレスポンスは、callbackで指定したJavaScriptの関数に対して、引数を設定した命令文として返ってきます。
この例では"hello"という関数を指定しているので、そのままfunction hello(data)が呼び出されます。
helloの中では、受け取った連想配列のnameの値を

<div id="hellotarget">

に挿入しています。

ただ、何も考えずに作るとCSRFの餌食になってしまうので、基本的には公開しても良いデータだけを扱うようにするべきでしょう。

さて、今回こんなことを調べる気になったのは、知人からの問い合わせでした。
その経緯はここでは書けませんが、良い勉強になったことは確かです。

EclipseからAndroidのソースを見るには

Androidデバッグしていると、android.jarの中身を見たくなることがあります。

いろいろ調べてわかったことをメモに残しておきます。

Androidのソースは公開されているのですが、これを取得するには、gitを使う必要があります。
あ、これはWindowsでのやり方ですので。

準備

まず、gitをインストールします。
cygwinを使う方法もあるのですが、gitだけのために入れるのもシャクなので、msysgitを入れることにします。

http://code.google.com/p/msysgit/

ここからダウンロードします。
今回入れたのは、「Git-1.6.4-preview20090730.exe」です。
ダウンロードして、インストーラを起動して入れます。PATHに入れておくことも忘れずに。

Androidのソースを取得

ディレクトリ構成は次のようにしています。

C:\Android 
├─android-sdk-windows-1.5_r3
│  └─platforms
│      ├─android-1.1
│      └─android-1.5
│          └─sources
└─mydroid

mydroidというのは、gitで取得したリポジトリを置く場所です。
コマンドプロンプトを起動して、C:\Android\mydroidに移動します。
そして、gitコマンドでcloneを作ります。
cloneするリポジトリのパスは、「git://android.git.kernel.org/platform/frameworks/base.git」です。

C:\Android\mydroid>git clone git://android.git.kernel.org/platform/frameworks/base.git

少々時間がかかりますが、これでbaseのソースが取得できます。

ソースディレクトリにjavaのコードをコピー

C:\Android\mydroid\base\core以下のディレクトリをC:\Android\android-sdk-windows-1.5_r3\platforms\android-1.5\sourcesにコピーします。
sourcesディレクトリは新規に作成してくださいね。

Eclipseを起動

既に起動している場合には、再起動しておいた方が安心です。

起動したら、android.app.Activityを選択して、右クリック-「Open Declaration」を選択すると、Activity.javaのソースが見えるはず。
ブレークポイントも設定できるので、デバッグ時に重宝しますよ。

岡山の花火大会情報携帯対応版

http://hanabi2009.okaya.ma/

を携帯電話に対応させました。
といっても、Docomoでしか動作確認してませんが。。。

実装は、PerlのWebアプリケーションフレームワークであるCatalystを使っています。

ここまでで5日。

※:追記12:46
QRコードを作ってみました。

Lamy Pico

子供の通っている学童保育の行事があって、保護者としていろいろと裏方をしていました。
行事の一環としてバザーもやっていて、片づけとか終わった後にのぞいてみると、そこは全品50円セールの真っ最中。

まぁたいしたものは残っていないだろうと物色していたら、ボロボロの箱に見慣れた文字が。。。

「Lamy」

え?Lamy?まさか?
と思って、急いで箱を開けたら赤色のLamy Picoでした。

[rakuten:10keiya:10089606:detail]

箱はボロボロでしたが、みた感じ本体は新品同然。
しかも予備のリフィルもついていて、50円。

実はPicoの青色をすでに持っているのですが、50円ならば買わなければ、ということで急いで購入。

いい買い物をしました。
バザーも意外と良いものあるんですね。

Picoは、おもしろいギミックがあるので、ご存じない方は調べてみてください。

岡山SOHOビジネス推進協議会交流会

今日は、岡山SOHOビジネス推進協議会交流会というのに参加してきました。
義理で参加したのですが、いろいろな方の興味深いお話が聞けたり、共通のつながりがあったりと、非常に得るものの多い会でした。

これまでは、異業種交流会とかはちょっとバカにしていて、一度も参加したことは無かったのですが、やはり何事も最初から決めてかかるのは良くないと反省しました。

Android 1.5 SDK, Release3

タイミング良く、Android SDK 1.5のRelease3が出ました。

こちらからダウンロードできます。

Download Android 1.5 SDK, Release 3

早速ダウンロードして、適当な場所に展開しました。
EclipseのPreferecesからAndroid SDKのパスを1.5_r3に変更します。

これまで作ったアプリはエミュレータでだいたい動いている感じです。
まぁたいしたものは作っていないので、問題になるようなことは無いでしょうし。

Release3からは日本語IME(iWnn)がSDKに付属されるので、標準のエミュレータ上でも日本語入力をすることが出来るようになります。

ADTをGalileo(Eclipse3.5)にインストール

これまではGanymede(Eclipse3.4)でやっていたAndroid開発ですが、Galileo(Eclipse 3.5)に入れてみました。
3.4と同じURLですんなりインストールできました。

Androidはこれからという方もいるかもしれないので、Android SDKのインストールから書いてみたいと思います。

Android SDKのインストール

2009/07/17現在の最新環境である、1.5-r2をダウンロードします。
Download Android 1.5 SDK, Release 2
Windows/Mac OS X/Linuxがあるので、自分の環境に合わせてダウンロードしてください。
今回はWindows Vistaにいれますので、Windows版(android-sdk-windows-1.5_r2.zip)をダウンロードしました。

これを適当な場所に展開します。
私は「C:\android-sdk-windows-1.5_r2」に展開しました。

GalileoにADT(Android Development Tools) Plugin for Eclipseをインストール

Eclipse 用 ADT プラグインのインストールには、3.3と3.4のやり方が書いてありますが、3.5でも基本的には同じです。

Galileoを起動し、メニューから[Help]-[Install New Software...]を選択して、「Install」ダイアログを開きます。

「Add」ボタンで、追加するサイトを登録します。

次の値を登録します。

(Nameの値は適当)

OKボタンで、インストール可能なソフトウェアの一覧が出てくるので、すべてチェックしておきます。

そして「Next」、「Next」でライセンスを受け入れる選択をして、「Finish」でインストール開始します。
インストールが完了したら再起動するか聞いてくるので言われるままに再起動。

Android SDKの設定

Eclipseのメニューから[Windows]-[Preferences]を選択し、Android SDKのインストールパスを設定します。


お約束の「Hello」アプリを作ってみる

EclipseのPackage Explorerで右クリックメニュー[New]-[Android Project]で新規Androidプロジェクトを作成します。

適当に、次のような感じで作りました。

  • Project name:Hello
  • Build Target:Android1.5
  • Application name:Hello
  • Package name:com.example.hello
  • Create Activity:Hello

その他はデフォルトの値で。

Androidアプリをエミュレータで実行

まず最初にAndroidの仮想デバイスを作ってやります。
Eclipseのメニュー[Windows]-[Android AVD Manager]を選択して、Android Virtual Devices Managerを開きます。

「Create AVD」で新しいAVDを作成します。

  • Name:test
  • SDCard:
  • Target:Android 1.5-1.5
  • Skin:Default(HVGA)

SDCardは使わないので、今回は作成しませんが、ここにはSDCardの容量を「32M」のように設定します。
「Create AVD」ボタンで追加します。

Project Explorerから「Hello」プロジェクトを選択して右クリックし、[Run As]-[Android Application]を選択します。
AVDを聞かれたら、先ほど作成したAVDを選択します(この例だと「test」)。

エミュレータの起動にはだいぶ時間がかかるので、フリーズした!?とかあわてないように待ちましょう。

エミュレータが起動したら、実行を指定したアプリも起動します。

GDDフォンに送り込む

エミュレータで確認できたら、実機でも動作確認しましょう。
GDDフォンにはUSBケーブルが付属していますが、USBドライバはついてきません。
ドライバはAndroid SDKに含まれていますので、GDDフォンをつないだらドライバのインストール画面で、ドライバの入っているフォルダを指定します。
私の場合には、「C:\android-sdk-windows-1.5_r2\usb_driver\x86」に入っていますので、このフォルダを指定しました。

USBドライバがインストールできたら、実機に送り込んで見ましょう。
Runでいけるのですが、そのままだと先ほど設定したエミュレータで起動してしまうので、起動オプションを変更しておきます。

Eclipseメニューの[Run]-[Run Configurations...]で実行時のTarget選択方法をマニュアルに変更します。

「Target」タブの「Deployment Target Selection Mode」を「Manual」に変更します。
これで再度実行すると、実行時にどのAndroid Deviceを選択するか聞いてきますので、エミュレータではなく実機を選択します。

おまけ

データファイルなどを実機のSDカードに送り込むには、一手間必要になります。
GDDフォンをUSBで接続すると、通知(Notification)領域に「USB接続」というのがでているはずなので、これをタップし、「マウント」ボタンをタップします。
そうすると、GDDフォンのSDカードがリムーバブルディスクとしてマウントされます。

あと、EclipseのPerspectiveで「DDMS」を開いておくと便利ですよ。
こんな感じでエミュレータの画面をキャプチャすることも出来ます。