2011年3月21日月曜日

Amazon S3 を Android から使ってみる

AWS SDK for Android を試してみました。

下記を参考にしました。

AWS SDK for Android の入手

このページ(AWS SDK for Android (Beta)) から aws-android-sdk-0.1.0.zip をダウンロードします。

ワークスペースに展開します。

$ 7z x aws-android-sdk-0.1.0.zip

必要な前準備

  • いつものようにプロジェクトを新規作成します。(File => New => Android Project)
  • ライブラリに aws-android-sdk-0.1.0-obfuscated.jar を追加します。(Properties => Java Build Path => Libraries => Add External JARs…) SDK を展開した場所の lib の下にあります。
  • インターネット通信を行うので、 AndroidManifest.xms の uses-resources に INTERNET を追加しておきます。

クライアントの生成

さっそく API を呼んでいきます。まずは S3 クライントを生成します。

// AccessKey と Secret Key を設定
AWSCredentials credentials = new BasicAWSCredentials("accesskey", "secretkey");
// S3 クライアントを生成
AmazonS3 s3 = new AmazonS3Client(credentials);

自分の AccessKey は アカウントのページ から確認できます。

Bucket の作成

S3 のオブジェクトはすべて Bucket に格納されます。まずはその Bucket を作ります。

// Bucket 生成
Bucket backet = s3.createBucket("takutless.testbucket");

Bucket 名に "_" を含んでいると例外が発生するので注意。(?) また S3 全体でユニークでないといけないようです。

Bucket名の決まりは クイックスタートガイド に下記のように記載されています。

Bucket names must comply with the following requirements. Bucket names:

  • Can contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)
  • Must start with a number or letter
  • Must be between 3 and 255 characters long
  • Must not be formatted as an IP address (e.g., 265.255.5.4)

オブジェクトの作成

作成した Bucket にオブジェクトを作成します。

// オブジェクトを作成
s3.putObject("takutless.testbucket", "mydir/myfile1.txt", inputStream, null);

Bucket "takutless.testbucket" に "mydir/myfile1.txt" という名前で inputStream の内容が保存されます。一緒に MetaData も指定できますが、省略(null)しました。

Management Console で確認すると Bucket が作成されて、ディレクトリ(mydir)とファイル(myfile1.txt)ができています。

オブジェクトのリスト取得

Bucket に格納されているオブジェクトのリストを取得してみます。

// Bucket に格納されているオブジェクトのリストを取得
ObjectListing objectListing = s3.listObjects("takutless.testbucket");
List<S3ObjectSummary> summaryList = objectListing.getObjectSummaries();

S3ObjectSummary にはオブジェクト名などの情報が格納されています。

ObjectListing objectListing = s3.listObjects("takutless.testbucket", "mydir/");

とすると、オブジェクト名が "mydir/" から始まるもののみ取得できます。

のはずなんですが、 listObjects() を実行すると例外が発生してしまいます。

Unable to unmarshall response (Couldn't initialize a sax driver for the XMLReader)

google 先生におうかがいを立ててみると こんな解決策 が…。理由はよくわかりませんが、下記のコードを追加してこの場をしのぎます。

System.setProperty("org.xml.sax.driver", "org.xmlpull.v1.sax2.Driver");

オブジェクトの取得

オブジェクトの中身は下記にようにして取得できます。

// オブジェクトを取得
S3Object object = s3.getObject("takutless.testbucket", "mydir/myfile.txt");
// オブジェクトの中身を取得
InputStream content = object.getObjectContent();

content から read() してファイルに保存するなりできます。

今回は最も手抜きなやり方を紹介しましたが、 S3 には Bucket のアクセス件や、オブジェクトのメタデータなども細かく管理でき、 API も色々用意されています。これだけ簡単だと、もっと使ってみたくなりますね!

2011年3月12日土曜日

Facebook Android SDK を使ってみる

Facebook Android SDK とは

Android アプリから Facebook の機能(認証、Graph API、プラットフォームダイアログなど)を使うためのライブラリです。

Facebook Developers の Mobile Apps のところに説明があります。ここの情報に従って進めていきます。

Facebook Android SDK の入手

Facebook Android SDK は github で公開されています。

git でソースをダウンロードします。

$ git clone git://github.com/facebook/facebook-android-sdk.git

facebook-android-sdk というディレクトリができます。 ちなみに git を使わなくても、 github のページからダウンロード可能です。

eclipse にプロジェクトを追加

eclipse で、先ほど入手したライブラリからにプロジェクトを作ります。

  • [File] => [New] => [Android Project]
  • [Create project from existing source] にチェック
  • パスは先程入手した facebook-android-sdk の下の facebook

これで eclipse から Facebook Android SDK が使用可能になりました。

Facebook Android SDK を使ったアプリの作成

早速、 Facebook Android SDK を使ったアプリを作ってみます。

まずは新規のプロジェクトを作成します。

使用するライブラリに Facebook Android SDK を加えます。

  • プロジェクトの [Properties] を開き、左のリストから [Android] を選びます。
  • Library の [Add] ボタンを押して、 最初に作成した Facebook Android SDK のプロジェクトを指定する。

Facebook を使うからには通信を行うので、 uses-permission に INTERNET を追加します。

  • AndroidManifest.xml を開く
  • [Permissions] タブをクリック
  • [Add] ボタンをクリック
  • [Uses Permission] 選択して OK をクリック
  • 右側の [Name] ドロップダウンから [INTERNET] を選択

これで Facebook Android SDK を使ったアプリの原型ができました。

Facebook 側での準備

Facebook 側にも準備が必要です。

  • Developer App を開き、 [Set Up New App] ボタンをクリック
  • 好きなアプリケーション名を入力して、 [Create App] をクリック

名前に Facebook とかが入ってるとダメみたいなので注意

  • 左側のリストから [Mobile and Devices] をクリックし、 Key Hash を入力します。

Eclipse ではビルドするとデフォルトでデバッグ用のキーで署名されるので、ここではデバッグ用のキーから Key Hash を作ります。

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

パスワードは android です。

これで準備が整いました。

コードを追加する

ではコードを追加してみます。

Facebook Developer のサンプルコードを少し変更してビルドします。

 1:  package com.myfirstfacebookapp;
 2:  
 3:  import android.app.Activity;
 4:  import android.content.Intent;
 5:  import android.os.Bundle;
 6:  
 7:  import com.facebook.android.DialogError;
 8:  import com.facebook.android.Facebook;
 9:  import com.facebook.android.Facebook.DialogListener;
10:  import com.facebook.android.FacebookError;
11:  
12:  public class MyFirstFacebookApp extends Activity {
13:      // 引数は Facebook から取得した App ID
14:      Facebook facebook = new Facebook("135741723160602");
15:  
16:      /** Called when the activity is first created. */
17:      @Override
18:      public void onCreate(Bundle savedInstanceState) {
19:          super.onCreate(savedInstanceState);
20:          setContentView(R.layout.main);
21:  
22:          facebook.authorize(this, new DialogListener() {
23:              @Override
24:              public void onComplete(Bundle values) {}
25:  
26:              @Override
27:              public void onFacebookError(FacebookError error) {}
28:  
29:              @Override
30:              public void onError(DialogError e) {}
31:  
32:              @Override
33:              public void onCancel() {}
34:          });
35:      }
36:  
37:      @Override
38:      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
39:          super.onActivityResult(requestCode, resultCode, data);
40:  
41:          facebook.authorizeCallback(requestCode, resultCode, data);
42:      }

14 行の App ID は Developer App から確認できます。

起動したら認証を行うだけのアプリですね。

実行してみる

では実機で試してみます。

起動すると、ログイン画面が現われました。

アプリにアクセスを許可するか聞かれます。

まだ認証しかしていませんが、まずは意図通り動いているようです。 次は Graph API を使ってみたいと思います。

追記

Facebook Android SDK の認証機能は Facebook for Android (Facebook 公式の Android アプリ) の機能を使っているようです。 このアプリがサインオン状態を覚えておく事で Android でのシングルサインオンを実現しているのでしょうか。 なので、アプリを入れていないと挙動が変わります。

  • 画面が違う
  • 毎回ログインを求められる

2011年3月6日日曜日

MobileOrg for Android を使ってみる

はじめに

私は自宅では emacs の org-mode を使って個人的な Todo などを管理しています。

外に持ち出す時は、整形したテキストをメールで携帯(android)に送るという めんどくさい事をしていたのですが、最近 MobileOrg という Android アプリを見付けました。

試してみたので紹介します。

MobileOrg for Android

この MobileOrg なんですが、 org ファイルを見易く表示してくれるだけでなく、 TODO の状態を変更(TODO=>DONE など)したり、ちょっとしたメモを取ったりできます。

さらにすごい事に、最近の org-mode には、 MobileOrg と連携する機能が あり、 MobileOrg 側での変更を取り込む事ができます。

MobileOrg は マーケット から入手できます。

Dropbox を使って PC <=> Android 連携

MobileOrg は PC の org-mode と連携するために、 WebDAV と Dropbox (オンラインストレージサービス) をサポートしています。 私は手軽そうな Dropbox を使いました。

Dropbox の Android 用クライントは マーケット から入手できます。 PC用のクライアントは各種ありますが、私は ここ に書かれているもの(Linux 用)を使いました。簡単そうなので。なんでもいいと思います。

これで PC に DropBox フォルダができるので、その下に mobileorg フォルダを作りました。(これだけで Dropbox にも反映されます。不思議。)

org-mode

MobileOrg を正しく使うには、 MobileOrg をサポートしたバージョンの org-mode が必要なようです。 emacs 23.2.1 に付属のものは古かったので、最新版をゲットしました。

私の org-mode 設定は下記のとおりです。

;; org-mode
(setq load-path (cons "/usr/local/share/emacs/site-lisp/org" load-path))
(require 'org-install)
(setq org-use-fast-todo-selection t)
(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cb" 'org-iswitchb)

(setq org-directory "~/org")                            ; orgディレクトリ
(setq org-agenda-files `("~/org/main.org"))             ; orgファイル
(setq org-mobile-directory "~/Dropbox/mobileorg")       ; MobileOrg用ディレクトリ

(setq org-todo-keywords '((type "TODO(t)" "STARTED(s)" "WAITING(w)" "APPT(a)" "|" "DONE(d)" "CANCELLED(c)" "DEFERRED(f)")))
(setq org-tag-alist '(("ANY" . ?a) ("HOME" . ?h) ("WORK" . ?w) ("OUTGO" . ?o)))

さっそく org ファイルを

実験用に簡単な org ファイルを作ってみました。

# -*- org -*-
#+STARTUP: overview hidestars

* ToDo
** APPT 「江~姫たちの戦国~」見る
   SCHEDULED: <2011-03-06 日 20:00>
* Projects
** MobileOrg紹介記事を書く
   DEADLINE: <2011-03-06 日>
*** TODO DropBox アカウント入手
*** TODO 最新版 org-mode をゲット
*** TODO MobileOrg 設定
*** TODO MobileOrg 紹介記事をブログにアップする
* Reminder
** ホワイトデー
   SCHEDULED: <2011-03-14 月>

MobileOrg へ push

下記のコマンドで ~/Dropbox/mobileorg に MobileOrg 用の org ファイルが作られます。

M-x org-mobile-push

MobileOrg を設定

  1. Synchronization Mode を Dropbox に設定

    [Settings] => [Synchronization Mode] => [Dropbox]

  2. Dropbox にログイン

    [Settings] => [Configure Synchronizer Settings…] => [Login]

  3. org ファイルのパスを指定

    [Settings] => [Configure Synchronizer Settings…] => [Path] => [/mobileorg/index.org]

    index.org は org-mode が生成

  4. Sync

表示できました!

MobileOrg 側での変更を反映

MobileOrg で TODO アイテムをタップすると状態を変更できます。 いくつか DONE に変更してみます。

このままでは Dropbox に反映されないので、 Sync を行います。

さらに、 emcas で、次のコマンドを実行します。

M-x org-mobile-pull

Dropbox から変更を取ってきて org-mode の方に反映してくれます。

org-mode の活用の幅が一気にひろがりそうです。

その他

最初 main.org に下記のような行を入れていたのですが、 MobileOrg 側の TODO 状態が重複してしまいました。

#+TODO: TODO(t) STARTED(s) WAITING(w) APPT(a) | DONE(d) CANCELLED(c) DEFERRED(f)

代わりに、 .emacs に下記を加える事で解決しました。

(setq org-todo-keywords '((type "TODO(t)" "STARTED(s)" "WAITING(w)" "APPT(a)" "|" "DONE(d)" "CANCELLED(c)" "DEFERRED(f)")))

もうひとつ、

MobileOrg で Sync を行うと、表示が前回 Sync したときの状態に戻ってしまいます。(変更が戻ってしまう) org-mode で pull => push してから再度 Sync すると整合が取れた状態になります。

org-mode で pull するまでは Sync は行わない方がいいですね。