Archive

Archive for 3月, 2009

Intent

3月 27th, 2009

 アプリを作成していくと、別画面に遷移させたいとか、他アプリのイベントを拾いたいとか、電話機能と連携したい等、外部との接点が欲しくなってきます。今回はそういった場合に使用されるIntentについて少し見ていきたいと思います。

・Intentの目的
 他のアプリやデバイス(カメラや加速度センサ等)から情報を得ようとすると、プロセスやスレッドを跨いだ処理を考慮しなくてはならず、これが非常にめんどくさいです。このやりとりを簡単に実現するために登場したのがIntentで、ブラウザ立ち上げたとか、コール中といった情報をintentで通知する、いわゆるeventのような位置付けになります。

・明示的Intent、暗黙的Intent
 Intentを作成する時には大きく分けて二通りの方法があります。一つは直接クラスを指定して呼び出す方法で、これを明示的Intentといいます。もう一つはこうして欲しいという「意図」をIntentに情報として付与し、システムに誰に処理してもらうかを決めてもらうやり方で、これを暗黙的Intentといいます。また、電話機能から「今電話かかってきたけど何かする?」という暗黙的Intentやシステムから「今起動したけど何かする?」というIntentが送付されてきます。これらのIntentを処理する際に必要になるのが次のIntent-filterです。

・Intent-filter
 外部からのIntentを処理するかどうかはAndroidManifest.xmlのIntent-filterにて宣言します。例えばhelloworldのAndroidManifest.xmlを見てみます。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jp.demo.helloworld"
      android:versionCode="1"
      android:versionName="1.0.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".helloworld"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

9~12行目に以下のようなintent-filterが設定されているのが分かります。

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

 まず、「android.intent.action.MAIN」ですが、これはactionタグの親のactivityが、このアプリケーションのエントリーポイント、開始画面として設定されていることを表します。ランチャーからアプリケーションを起動して、一番最初に表示されるわけです。ランチャーを叩くと、ACTIONが「ACTION_MAIN」であるIntentがアプリケーションに対して投げられ、それを処理できる「android.intent.action.MAIN」のintent-filterを持つactivityがintentを受理し、画面が起動するという流れになるのだと思います。
 次に「android.intent.category.LAUNCHER」ですが、categoryというのはactionを受理する際に付加的な情報を付け加えます。ここでのcategoryは「LAUNCHER」ですが、minghaiの日記さんによると、

デフォルトのIntentFilterの意味するところはランチャー向けのアプリケーションだということだ。

CATEGORYのLAUNCHERはシステムのLAUNCHERに登録できることを示す。

とのことです。

・startActivity()とstartActivityForResult()
 同一アプリにおいて、別の画面を呼び出すときは明示的Intentを作成し、startActivity()の引数として引き渡します。
 例えば以下のように書けます。

		Intent intent = new Intent(helloworld.this,XXXXX.class);
		intent.setAction(Intent.ACTION_VIEW);
		startActivity(intent);

コンストラクタで自分自身、そして呼び出し先(XXXXX.class)のクラスを指定します。ACTIONにはActivityを表示させるのでACTION_VIEWを指定しています。当然ですね。
 これで明示的なIntentの送付完了です。ただし、このstartActivity()では、遷移先のActivityから情報を引き取れません。情報を返して欲しいときはstartActivityForResult()を使うと良いでしょう。

taga Android

Activityのライフサイクル

3月 24th, 2009

・Activityのライフサイクル
今回はAndroidにおいてUIの基礎となるActivityについて見ていきます。
Android DevelopersのReferenceや、日本Androidの会の勉強会のページでまとめられているので、改めて書く必要はないかもしれませんが、一応さらっと流してみたいと思います。
まず最初に覚えておく必要があるのは、Activityのライフサイクルです。
Android Developersサイト及び日本Androidの会のどちらにも似たようなライフサイクルを表した図があります。
これを見ると、Activityが表示されるまでに、onCreate()、onStart()、onResume()の3つのメソッドが呼ばれて初めてrunning状態になることがわかります。その後、Activityの一部が見えなくなる(最前列ではなくなる)場合にはonPause()が呼ばれ、Activityの全てが隠れてしまった場合、onStop()が呼ばれます。この、最前列でなくなってしまったPause状態、Stop状態のActivityはAndroidのシステムからメモリの空き具合などによってKillされてしまう可能性があります。ただし、システムがKillする場合でも、ユーザによって明示的に終了する場合でもonDestroy()は呼ばれるので、ここで終了処理をすることは可能だと思います。

・helloworldのActivity
ここでhelloworld.javaを例として取り上げてみます。

package jp.demo.helloworld;

import android.app.Activity;
import android.os.Bundle;

public class helloworld extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

helloworldクラスはActivityクラスを継承して、onCreateメソッドをOverrideしています。
onCreateメソッドの中ではsetContentView()によってレイアウトを設定しています。
例えば、setContentView()を呼び出すのをonCreate()ではなくonStart()やonResume()にしても、画面に表示される前に呼び出されるメソッドなので、同じように表示されるはずです。
例えばonResume()に書いてみます。

package jp.demo.helloworld;

import android.app.Activity;
import android.os.Bundle;

public class helloworld extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onResume(){
        super.onResume();
        setContentView(R.layout.main);
    }
}

このように書き換え、実行してみても、エミュレータ上には前と同じように、下記のように表示されるかと思います。
helloworld

 Activityがいきなりkillされるというのが中々取っ付きにくい部分かもしれませんが、ライフサイクルのどの部分でkillされる可能性があるかを確認すれば、そこまで複雑ではないことが分かります。
 まずはライフサイクルとにらめっこ、ですね。

taga Android

Androidプロジェクトのディレクトリ構成

3月 23rd, 2009

今回は環境構築編で作成したhelloworldプロジェクトのディレクトリ構成について言及していきます。

まず、eclipseのパッケージエクスプローラでhelloworldプロジェクトを展開してみると以下のようになります。

package

では、このディレクトリ構成をざっと見ていきます。

srcディレクトリ
 srcディレクトリはそのままですね。javaファイルが格納されます。
今回で言えば、helloworld.java及びR.javaがあります。

  • jp.demo.helloworld.helloworld.java
  •  helloworldのメインクラスです。
    helloworldクラスはActivityクラスを継承していますが、
    このActivityクラスについては次回詳しく見ていきます。

    package jp.demo.helloworld;
    
    import android.app.Activity;
    import android.os.Bundle;
    
    public class helloworld extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    }
    

    Activityの起動時に呼ばれるonCreate()メソッドで、Rクラスを介して
    main.xmlのレイアウト情報を元に画面を設定しています。

  • jp.demo.helloworld.R.java
  •  リソースファイルにindexを付加しているクラスです。
    これはコンパイラによって自動生成・自動更新されるファイルなので、
    手動で変更してはいけません。

    /* AUTO-GENERATED FILE.  DO NOT MODIFY.
     *
     * This class was automatically generated by the
     * aapt tool from the resource data it found.  It
     * should not be modified by hand.
     */
    
    package jp.demo.helloworld;
    
    public final class R {
        public static final class attr {
        }
        public static final class drawable {
            public static final int icon=0x7f020000;
        }
        public static final class layout {
            public static final int main=0x7f030000;
        }
        public static final class string {
            public static final int app_name=0x7f040001;
            public static final int hello=0x7f040000;
        }
    }
    

    上記ソースコードを見てもらうとデフォルトではdrawable/icon.png、layout/main.xml、string.xmlにindexが張られていることが分かるかと思います。

assetsディレクトリ
 このassetsディレクトリには動画などのストリームで扱うようなファイルを配置します。
詳しいことはよくわからないのですが、assetsディレクトリとresディレクトリについては、
以下のページにて詳しく書かれています。
恐らくresディレクトリで扱えないようなファイルを扱う場合はassetsディレクトリ配下に置くのだと思います。
http://developer.android.com/guide/topics/resources/index.html

resディレクトリ
 リソースファイルを管理するディレクトリです。
新しいリソースを追加する場合はリソースを追加した後にプロジェクトを再読み込みすればR.javaが更新されます。

  • res/drawable
  •  イメージリソースを配置するディレクトリです。推奨フォーマットはpngです。
    アプリのアイコンとなるicon.pngが配置されています。

  • res/layout
  •  画面のレイアウトを定義するためのxmlファイルを配置するディレクトリです。
    ここにはmain.xmlが配置されており、中身は以下のようになっています。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello"
        />
    </LinearLayout>
    

    LinerLayoutはhtmlでいうdivタグやpタグのようなもので、レイアウト制御するようなクラスです。TextViewはテキスト表示用のクラスで、android:text属性で、”@string/hello”を指定していますが、これはstring.xmlのhelloという変数のことです。

  • res/values
  •  文字列定義を行うためのxmlファイルを配置するディレクトリです。
    ここにはstring.xmlが配置されており、中身は以下のようになっています。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="hello">Hello World, helloworld</string>
        <string name="app_name">helloworld</string>
    </resources>
    

    layout.xmlから参照されているhelloは「Hello World, helloworld」という文字列になっていることが分かると思います。

AndroidManifest.xml
 アプリケーションの概略を記述するファイルです。
Androidでは、外部リソース(電話帳やインターネットなど)を仕様するとき、
パーミッションを指定しなければなりませんが、
そういった情報もこのファイルに記述されます。
その他メインアクティビティやintent-filter等も記述可能です。

中身は以下のようになっています。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="jp.demo.helloworld"
      android:versionCode="1"
      android:versionName="1.0.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".helloworld"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

“@drawable/icon”(drawable/icon.png)や”@string/app_name”(string.xmlのapp_name変数)が指定されています。

 これらのファイルのつながりを元に起動時の動きを確認すると、次のようになります。
 helloworldを立ち上げると、onCreate()メソッドにてlayout/main.xmlに基づいて画面が設定され、このときmain.xml内のTextViewのtextでstring.xmlのhello変数が指定されているために画面に「Hello World, helloworld」と表示される。
 これで大まかな全体像が掴めたかと思います。

taga Android

環境構築

3月 17th, 2009

androidの開発のための環境を構築します。
ここではWindows XPを想定しています。

1.SDKのダウンロード

まず、下記URL(Android Developersサイト)にアクセスします。
http://developer.android.com/

android-developers220404
SDKタグをクリックします。
android-11-sdk-release-1-11_r1-android-developers220417
WindowsのPakageの列のリンク「android-sdk-windows-xxxxxx.zip」(xxxxxの部分はバージョンなので変わります)をクリックします。
download-the-android-sdk-android-developers220443
ライセンス画面にうつるので、
「I agree to the terms of the Android SDK License Agreement.」のチェックボックスをチェックして
「Download」ボタンを押下するとSDKのダウンロードが始まります。
ダウンロードが完了するとSDKの取得は完了です。

2.解凍と配置

ダウンロードしたzipファイルを解凍し、任意のパス(私はC:app配下にしました)に配置します。
このとき、解凍したフォルダ名は長いですが、androidのSDKはかなりの頻度で更新されていますので、
どのフォルダがどのSDKかわかるようにフォルダ名をそのままにしておくことをお勧めします。

3.Path設定

環境変数の「Path」に先ほど配置したandroidフォルダのtoolsフォルダまでのパスを追加して下さい。
例:「C:android-sdk-windows-xxxxxtools」

パスが通っているかどうかをコマンドプロンプトからエミュレータを立ち上げて試してみます。
cmd
コマンドプロンプトを立ち上げ、「emulator」と入力し、エンターを押下してみてください。
emulator
パスが通っていればandroidエミュレータが立ち上がるはずです。
(起動まで10秒前後かかります)

4.Eclipseプラグイン「Android Developer Tools」のインストール

ここではEclipseをすでにインストールされている前提で説明します。
前提とするバージョンは3.4(ganymede)です。
(もしEclipseをインストールしていなければ、eclipse.orgからダウンロードし、インストールしてください。)

  1. Eclipseを起動し、「Help」→「Software Updates….」を選択。
  2. 「Available Software」タブを選択。
  3. 「Add Site…」ボタンを押下。
  4. Locationのテキストボックスに以下のURLを入力。

    https://dl-ssl.google.com/android/eclipse/

    もしhttpsスキーマのURLで上手くいかないようであれば、
    以下のようなhttpスキーマに切り替えること。

    http://dl-ssl.google.com/android/eclipse/

    OKボタンを押下。

  5. 追加したサイト配下を見ると「Developer Tools」があるので、これにチェックを入れ、「Install…」ボタンを押下する。
  6. 「Android Developer Tools」と 「Android Editors」がチェックされていることを確認して、「Next」ボタンを押下する。
  7. チェックボタンをチェックし、「Finish」ボタンを押下する。
  8. Eclipseを再起動する。

5.Hello World

最後にHello Worldを作成して、ADTとSDKの連携がうまくいっているか確認します。

  1. 「File」→「New」→「Project…」を選択。
  2. 「Android/Android Project」を選択。
  3. 以下のように入力し、「Finish」ボタンを押下。android-project
  4. 「Package Explorer」から「helloworld」を右クリックし、「Run As」→「Android Application」を選択。
    eclipse
  5. 下記のように「HelloWorld, helloworld」と表示されていることを確認。
    ただしこの時、エミュレータのロードにかなり時間がかかります。
    また、起動し終わってもロックされているために下記のような表示にならない場合は、
    MENUを押してロックを解除してください。
    helloworld

以上で環境構築は終了です。

taga Android, 環境

Androidアプリ開発Blog始めました。

3月 10th, 2009

みなさま、はじめまして。

(株)ハウインターナショナルでは、Android携帯で利用可能なAndroidアプリの研究開発を始めました。

その開発の一環として、Androidアプリに開発ノウハウや失敗談などをBlog上で公開していきたいと思います。

まだまだAndroidアプリの開発には不慣れ部分が多いため、拙い内容が多いかもしれませんが、コツコツ続けて行きたいと思います。

また、突っ込みなど大歓迎ですので、ドシドシコメントお待ちしてます。

taga Misc.