Hudsonからエミュレータを起動できない!!

10月 24th, 2009

●背景
ただいま、InstrumentationTestCaseでテストケースを書いているのですが、これをHudsonで定期実行しようとしています。

●問題
Hudsonからエミュレータを起動しようとしても、何故か起動に失敗します。

emulator: ERROR: unknown virtual device name: ‘android1.5′
emulator: could not find virtual device named ‘android1.5′

勿論、コマンドプロンプトから以下のコマンドを叩いた場合にはちゃんとエミュレータを起動できることは確認しています。

emulator @android1.5

※toolsフォルダはPathに通しています。

●原因
恐らくですが、以下のエントリと原因は同じかと思います。
androidのエミュレーターが起動しなくて大いにはまる
上記を参考にすると、WindowsのサービスであるHudsonからエミュレータを起動したため、サービスのホームディレクトリである
C:\Documents and Settings\LocalService
からしかAVDを読み込めないようです。

●対応方法
大きく二通り考えられると思います。
1.WindowsサービスのホームディレクトリにAVDを作成する
2.Hudsonを通常の管理者アカウントで起動しておく

●結果
対応の経緯は省略しますが、「1.」の方法はうまくいきませんでした。
従って、とりあえずは「2.」の方法でしのぎます。

soichiro Android, SDK1.5

モバイルネットワークを切断したい!

10月 21st, 2009

●背景
ただ今 アプリケーションのの動作検証作業を少しでも自動化しようと、
InstrumentationTestCaseでテストを書いています。

●やりたいこと
ネットワークが切断された場合を想定したテストも自動化したいので、
コード上からエミュレータのネットワークを切ります。

●やり方
Intent intent = new Intent();
intent.setAction(“android.intent.action.DATA_CONNECTION_FAILED”);
intent.putExtra( “apn”, “epc.tmobile.com”);
sendBroadcast(intent);
これだけ。
恐らくAPNさえ変えれば、実機でも有効なはず。

●補足
上記は、SDKのソースに入ってる、
MobileDataStateTracker.startMonitoring()及び
MobileDataStateTracker.MobileDataStateReceiver
の中を見ると分かります。

が、テスト終了時に、ネットワークを復帰する方法が分かりませんw

Setting→Wireless Controls→Mobile networks
→Access Point Names→T-mobile US
をクリックすれば復帰しますが、これもできれば自動化したい・・・

●謝辞
android SDKのソースコードを取得してEclipseで開発する時に参照可能な状態に設定する
上記エントリが無ければ、上記のやり方を知ることができませんでした。 ありがとうございました。

soichiro Android, SDK1.5

MixiClient公開しました。

10月 20th, 2009

こそこそと作っていたMixiClientを公開しました。

[androlib] MixiClient

MixiClientはマイミクの新着日記、コメント、コミュニティが閲覧できるmixiビューアです。
まだまだ一部の機能しかないため、バージョンは0.11としています。

骨子ができたため公開したのですが、今後はバグ対応しながら、以下の機能を追加予定です。

  1. アイコン作成
  2. コメント投稿機能
  3. notify(お知らせ)機能
  4. 日記投稿(写真有/無)機能
  5. 足跡やアルバム等の閲覧機能

バグ情報、機能要望など随時受け付けていますので、どしどしお知らせ下さい。

taga Android, MixiClient

PendingIntentに登録したIntentを更新できない

10月 9th, 2009

●問題
PendingIntentは以下のように登録しています。

Intent intent = new Intent( context, Test.class);
defineIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK);
defineIntent.putExtra( "title", event.getTitle());

PendingIntent pendingIntent =
PendingIntent.getActivity( context, 0, intent, 0);

eventを引数としてこの処理を繰り返し呼び出した場合、渡したeventによって
Testアクティビティに渡るtitle値が変わってくれないと困ります。

しかし、上記のコードでは、title値は変わりません。

●解決
APIにはちゃんと書いてあるんですが、

getActivity(Context context, int requestCode, Intent intent, int flags)

getActivityメソッドの第4引数に渡すflagsが0だからまずいんです。
こいつに、
PendingIntent.FLAG_UPDATE_CURRENT
を渡してやれば、上記intentのtitle値(extra data)をちゃんと更新してくれます。

●反省
APIをろくに読んでない
Web上のコードをピーコしすぎ

以上

soichiro Android, SDK1.5

GPSによる現在位置取得の頻度について

10月 7th, 2009

Androidの現在位置取得の頻度は、
LocationManager.requestLocationUpdates(…)
に渡す、minTime及びminDistanceで決まります。

minTimeで1時間と指定すると、基本的には1時間毎にしか現在位置を取得しないようです。
では、minDistanceを1Kmと指定すると、現在位置の取得頻度はどうなるんでしょう?

普通に考えれば、1Km移動したかどうかの判定のために、現在位置取得の頻度は多くなるはずです。

ですが、例えば加速度センサーなんかを使えば、携帯を机に置きっぱなしにしているかどうかが分かるため、わざわざ現在位置を取得する必要はない、という判断ができるはずです。

というわけで、実験してみました。
minTimeは0で、minDistanceに1Kmと指定し、一晩寝かせてみました。
結果、朝にはバッテリーは干上がり、目覚ましのアラームも鳴りませんでした。

以上。

soichiro Android, SDK1.5

エミュレータでの「位置情報」が2回しか更新できない!

10月 6th, 2009

表題の通りの問題ですが、長らく放置していました。
が、いい加減不便なので調べてみました。

結論から言うと、エミュレータのタイムゾーンをOSと合わせればOKみたい
参考:Can’t get multiple location updates

でも。。その理由までは分かりません。 そういうもの?

soichiro Android, SDK1.5

AcerのDonut搭載のスマートフォンが登場

9月 29th, 2009

[GIGAZINE] Androidの最新版を採用したAcerの高性能スマートフォン「A1」がついに登場へ

現在ドイツでAcerのAndroidスマートフォン「A1」の予約受付が行われているそうです。価格は389.99ユーロ(約5万1000円)とのこと。

「A1」はQualcomm 8250(768MHz)プロセッサや3.5インチのワイドVGAタッチスクリーン、オートフォーカス対応500万画素カメラ、microSDカードスロット、GPS、Bluetooth2.0、IEEE802.11 b/g対応無線LANなどを搭載しており、OSにはAndroidの最新版となるバージョン2.0「Donut」を採用。

本体サイズは115×62.5×12.5mmで重量は135グラムとなっています。

Donut搭載のスマートフォンとしては初じゃないでしょうか。

あと一点修正。Donutは「2.0」ではなく「1.6」ですね。
公式ではまだ言及されていないですが、おそらく次期バージョンの「Eclair」が「2.0」になるかと思います。

taga Android , ,

ステータスバーに通知する(NotificationとNotificationManager)

9月 27th, 2009

androidのホームの上部にあるステータスバーをドラッグすると、下のSSのように通知領域が表示されます。

notification1

 通知領域に情報を出すためには「NotificationManagerクラス」「Notificationクラス」を使います。

参考:Creating Status Bar Notifications

 この通知情報(notification)を選択すると、intentが発行され、intentに基づいた処理(アクティビティを表示させるなど)が行われます。バックグラウンドで動作しているサービスなどが、ユーザに対して情報を表示したい、選択を迫りたい場合などに使用されるのが一般的な使われ方かと思います。

《ステータスバーに情報を通知する例》

 NotificationおよびNotificationManagerの使い方は例えば以下のようになります。

  1. まずNotificationManagerの参照を取得します。
  2. NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    
  3. Notificationクラスを生成します。
  4. 			Notification notification = new Notification(
    					android.R.drawable.btn_default,
    					"通知情報が届きました",
    					System.currentTimeMillis());
    
  5. notificationが選択された場合に発行するintentをPendingIntentで包みます。
  6. Intent intent = new Intent(Intent.ACTION_VIEW);
    //intentの設定
    PendingIntent contentIntent =
    		PendingIntent.getActivity(this, 0, intent, 0);
    
  7. 通知する情報をsetLatestEventInfoメソッドにて設定します。
  8. 			notification.setLatestEventInfo(
    					getApplicationContext(),
    					"アプリ名",
    					"通知情報の説明文",
    					contentIntent);
    
  9. NotificationManagerでNotificationをnotifyします。
  10. notificationManager.notify(R.string.app_name, notification);
    

    ここまで行うと、画面上部に以下のように表示されます。
    notification2

    ドラッグして通知領域を確認すると以下のように表示されています。これを押下するとintentが発行されます。
    notification3

    《NotificationManager》

     NotificationManagerは非常に単純で、使用したいときは上記例で示したようにシステムから「getSystemServiceメソッド」を用いて取得します。メソッドも以下の3つしかありません。

    • cancel(int id)
    • 指定したIDの通知情報を削除します。ここでいうIDは、notifyメソッドをコールした際に指定したIDです。

    • cancelAll()
    • 全ての通知情報を削除します。但し、他のアプリケーションが発行した通知情報には関与できません。

    • notify(int id, Notification notification)
    • 通知情報をステータスバーに表示させます。挙動は先に示した通りです。

    《Notification》

     通知情報のコンテキストクラスです。サウンド、バイブレーション、LEDを用いてアラートする事もできます。

    バイブレーションのみ(ステータスバーに通知しない)例

    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification = new Notification();
    notification.vibrate = new long[]{0, 200, 100, 200, 100, 200};
    notificationManager.notify(R.string.app_name, notification);
    

    ・Manifestにバイブレーションのパーミッション指定をします。

    <uses-permission android:name="android.permission.VIBRATE" />
    

    ※vibrateに指定する配列は、DELAY_TIME,VIBRATE_TIME、DELAY_TIME・・・の順番です。

    また、「通知」ではなく、「実行中」として通知することも可能です。その場合は以下のようにフラグを設定します。このフラグを設定しておくと、「通知を消去」ボタンによって通知情報が消去できなくなります。

    notification.flags = Notification.FLAG_ONGOING_EVENT;
    

    一定時間経過すると自動的に通知情報が消去されるようにするには以下のフラグを使います。

    notification.flags = Notification.FLAG_AUTO_CANCEL;
    

    taga Android, SDK1.5

HT-03AでのGmail設定

9月 22nd, 2009

 日本発のAndroidフォンであるHT-03Aを使い始めて早や2ヶ月が経とうとしていますが、最近ようやく気づいたメール設定について書いておこうかと思います。

 HT-03Aに初期インストールされているGmailアプリでは、必ず受信トレイを同期しなければなりません(受信トレイを同期しないという選択肢が無い)。このため、単純にフィルタリングしているだけでは受信トレイを通過するため、全てのメールが同期されてしまいます。携帯では基本的にメールを受信した時はバイブで通知するようにしているのですが、MLなどに入っているとやたらとバイブしてしまい面倒です。

 私の場合、MLなどのメールは基本PCからチェックしたいので、携帯ではデフォルトでは一部のラベルのものだけを見るようにし、見たい時だけ「メニュー」→「ラベル」から選択することでその他のメールも見られるようにしたいと思っていました。

 上記の条件を満たすには「アーカイブ」を使用する必要があるようです。フィルタリングの設定で、「操作の選択」にて「受信トレイをスキップ (アーカイブする)」を選択すると、そのメールは受信トレイには残りません。そのメールを閲覧するには該当ラベルを選択するか、「すべてのメール」を選択することで可能です。

 HT-03AのGmailアプリで閲覧したいもののみを受信トレイに残して、その他のメールはフィルタリングしてアーカイブしてしまえば、余計なメールをHT-03Aで閲覧することは無くなります。

 知っていればなんてことないのですが、僕自身、悩んだ挙句やっとのことで辿りついたのでここに記録しておきます。

taga Android

設定画面の作り方(PreferenceActivity)

9月 8th, 2009

久々にコードのお話を。

アプリによくある設定画面を作成する際に使用する「PreferenceActivity」についてです。
参考:http://developer.android.com/intl/ja/reference/android/preference/PreferenceActivity.html

preference01

preference02

preference03

上の写真は簡単なサンプルアプリを起動した画面です。
まず、プロジェクトを作成し、新規に「res/xml/pref.xml」、「res/values/arrays.xml」を作成します。
pref.xmlは設定画面の画面用、arrays.xmlは設定画面のリスト要素の値を定義しています。

res/xml/pref.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
	xmlns:android="http://schemas.android.com/apk/res/android">
	<PreferenceCategory android:title="@string/title">
		<CheckBoxPreference
			android:key="checkbox_key"
			android:title="@string/checkbox_title"
			android:summary="@string/checkbox_summary" />
		<EditTextPreference
			android:key="edittext_key"
			android:title="@string/edittext_title"
			android:summary="@string/edittext_summary"
			android:dialogTitle="@string/edittext_dialogtitle" />
		<ListPreference
			android:key="list_key"
			android:title="@string/list_title"
			android:summary="@string/list_summary"
			android:dialogTitle="@string/list_dialogtitle"
			android:entries="@array/list_entries"
			android:entryValues="@array/list_entryvalues" />
		<RingtonePreference
			android:key="ringtone_key"
			android:title="@string/ringtone_title"
			android:showDefault="true"
			android:summary="@string/ringtone_summary" />
	</PreferenceCategory>
</PreferenceScreen>

res/values/arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="list_entries">
        <item>First</item>
        <item>Second</item>
        <item>Third</item>
    </string-array>
    <string-array name="list_entryvalues">
        <item>first</item>
        <item>second</item>
        <item>third</item>
    </string-array>
</resources>

pref.xmlを取り込むActivityはPreferenceActivityを継承し、addPreferencesFromResourceメソッドを使用します。

PreferenceActivitySample.java

package jp.co.haw.example.preference;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class PreferenceActivitySample extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref);
    }
}

これで冒頭の画面が立ち上がります。

この設定画面で編集されたデータは、自動的に「SharedPreferences」として保存されます。
コードからこの値を参照したい場合は、以下のコードでSharedPreferencesインスタンスが取得できます。

PreferenceManager.getDefaultSharedPreferences(ctx);

参考:

  • Android_SDK\platforms\android-1.5\samples\ApiDemos\src\com\example\android\apis\app\PreferencesFromXml.java
  • Android_SDK\platforms\android-1.5\samples\ApiDemos\res\xml\preferences.xml

taga Android