Archive

Archive for the ‘SDK1.5’ Category

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

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

ステータスバーに通知する(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

SDK1.5のSensorManager周りの変更点

4月 18th, 2009

 Android 1.5 Highlightsに、「SensorManager – redesigned sensor APIs」とあったのでSensorManager周りがどのように変更されているか確認してみました。

・SensorListenerがdeprecated指定
 SDK1.5に切り替えてみると、SensorListenerがdeprecatedになっていました。
javadocを参照してみるとSensorListenerのかわりにSensorEventListenerを使用するようにとのこと。

・SensorListener Class Overview

Used for receiving notifications from the SensorManager when sensor values have changed. This interface is deprecated, use SensorEventListener instead.

SensorListenerでは、センサーからの値を変更を取得するときは、onSensorChanged(int sensor, float[] values)メソッドで取得していました。

 SensorEventListenerのjavadocでは、このonSensorChangedメソッドの引数が変わっており、onSensorChanged(SensorEvent event)と、SensorEventクラスを引数としています。このSensorEventクラスはSDK.15で初めて定義されたクラスのようで、今までSensorListenerのstaticメンバで定義していたデータ値等を独立させたもののようです。

SensorEventのフィールドを見てみると以下のようになっていました。

・SensorEvent Field

public int accuracy The accuracy of this event.
public Sensor sensor The sensor that generated this event.
public long timestamp The time in nanosecond at which the event happened
public final float[] values The length and contents of the values array vary depending on which sensor type is being monitored (see also SensorEvent for a definition of the coordinate system used):

Sensor.TYPE_ORIENTATION:

All values are angles in degrees.

 onSensorChangedメソッドでSensorEvnetを受け取ることで、accuracyとtimestampが受け取れるようになっています。これでonAccuracyChangedのたびにaccuracy値を保持したり、onSensorChangedのたびにSystem.currentTimeMillis()で時間を問い合わせたりしなくてすみそうです。

 また、センサーの種類は今までSensorManagerに定義されていたのですが、新しくandroid.hardware.Sensorクラスが定義され、センサー種別の定数はSensorManagerからSensorクラスに移行されたようです。

・傾斜及び向き
 今までSensorListener.onSensorChangedメソッド内で傾きや向きを計算したりしてましたが、SensarManagerに新しく追加されたメソッドであるgetInclination(float[] I)、getOrientation(float[] R, float[] values)を利用する事で計算しなくてもよくなりそうです。ただ、これらの値の使い方は一癖ありそうなので注意した方がいいかもしれません。

・まとめ
 センサー周りに関してはSDK1.5になったことでデータと処理を分けた事と、傾斜や向きの値取得用メソッドが用意された事の2点がメインのようです。いままで計算が面倒だったのですが、これによって使いやすさは確かに向上しているのではないでしょうか。

taga Android, SDK1.5

Android 1.5 Early Look SDKを入れてみました。

4月 16th, 2009

SDK1.5をとりあえず入れてみました。ADTもarchiveでの入れなおしだったので結構面倒でした・・・

  1. http://developer.android.com/sdk/preview/にアクセスし、「android-sdk-windows-1.5_pre.zip」を選択し、ダウンロード。
  2. ダウンロードしたSDKを解凍し、toolsディレクトリにパスを通す。
  3. 同ページから「ADT-0.9_pre.zip」をダウンロード。
  4. Eclipse3.2には対応していないため、Eclipse3.2を使用している場合は3.3/3.4をインストールすること。5.現在ADTがインストールされているなら、「Help > Software Updates」からアンインストールする。
    (「Android Development Tools」と「Android Editors」をアンインストール)
  5. Help > Software Updates > Available Software > Add Site > Archive にて、ダウンロードした「ADT-0.9_pre.zip」を選択し、「Android DDMS」及び「Android Development Tools」をインストール。
  6. Eclipseを再起動。
  7. Window > Preferences > Android > SDK Locationにダウンロードし解凍したSDKのパスを指定する。

ADTのインストールが上手くいかない場合はarchiveファイルのダウンロードが正しく終わっていない場合があります。(僕の場合は発表されたばかりでアクセスが集中しているからか、2回ダウンロードに失敗しました。)

※既存のAndroidプロジェクトがあれば、以降の処理を行います。

  1. 既存のプロジェクトはビルドに失敗した状態になっている事を確認し、プロジェクトを右クリック > Properties > Android > Project TargetでSDKを選択。
  2. ビルドし直す。

ビルドし直すと、若干構成が変わっているのが分かるでしょうか?
helloworld_android1_5
「R.java」が「gen」パッケージ以下に移動しています。「Generated Java Files」とあるので、今後他の自動生成されるようなJavaファイルが出たとしてもこのgenパッケージに入ることが予想されます。

また、root直下に「default.properties」というファイルが生成されていて、中を見てみると以下のようになっています。

# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.

# Project target.
target=android-3
# apk configurations. This property allows creation of APK files with limited
# resources. For example, if your application contains many locales and
# you wish to release multiple smaller apks instead of a large one, you can
# define configuration to create apks with limited language sets.
# Format is a comma separated list of configuration names. For each
# configuration, a property will declare the resource configurations to
# include. Example:
#     apk-configurations=european,northamerica
#     apk-config-european=en,fr,it,de,es
#     apk-config-northamerica=en,es
apk-configurations=

前半の部分はバージョン管理に使用するもので、後半はどの言語に対応しているかを表すもののようです。今までアプリがどの言語に対応しているのか不明だったのですが、Android Marketなので対応言語が参照できるようになるのでしょうか。

taga Android, SDK1.5