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 DevelopersMobile 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 は行わない方がいいですね。