2011/12/29

Android端末のフィーチャー定義を取得する

端末のフィーチャー定義を取得する方法です。

PackageManagerクラスのgetSystemAvailableFeaturesあるいはhasSystemFeature
を利用することで調べることができます。

サンプルソースは下記。

FeatureInfo[] infos = getPackageManager().getSystemAvailableFeatures();
for (FeatureInfo info : infos) {
    android.util.Log.e("yuki" , "yuki features = "  + info);
}

フィーチャー名は PackageManager.FEATURE_* として定数定義されています。

参考:Android Developerサイト

以上です。
2011/12/28

Android3.2以降、画面回転で意図せずActivityが再起動してしまう

orientationのconfigChangedを受け取っているのに画面回転させるとActivity
が再起動されてしまう問題に悩まされたので覚書。

HoneyComb MR2(Android3.2)以降、画面回転時にSCREEN_SIZEのconfigChangeも
走るようになりました。

参考:Android Developerサイト

これにより、AndroidManifestで
 android:configChanges=orientation
としただけでは不十分となりました。

画面回転時の再起動を防ぎたい場合は
 android:configChanges=orientation|screenSize
とする必要があります。(※端末形状によってはkeyboardHiddenも必要)

実際にソースコードを組んで確認してみます。
@Override
protected void onDestroy() {
    super.onDestroy();
    int change = getChangingConfigurations();
    android.util.Log.e("yuki" , "yuki c=" + String.format("0x%08x", change));
    // CONFIG_SCREEN_SIZE 0x000004
    // CONFIG_ORIENTATION 0x0000008
}
結果は 
 yuki c=0x00000480
となります。(CONFIG_SCREEN_SIZE|CONFIG_ORIENTATION)

以上です。

2011/12/25

Android:GPSの測位が上手くいかない場合の対処法

GalaxyS や GalaxyS2でGPSの測位が上手くいかない、GPSの測位がおかしい場合の対処方法。

WiFi通信中である場合にGPSの測位がうまくいかない場合が多いです。
3Gデータ通信中だとそうでもないようです。

3Gデータ通信を常にOFFにしている(WiFiしか使用しない)ユーザにとってGPSが使えないのは非常
に不便です。
改善方法は下記です。

1. 一度データ通信(3G等)をON,WiFi通信をOFFにした状態でGPS測位させる。
2. 測位完了後にデータ通信をOFFにして、WiFi通信ONに戻す。



どうもGalaxy特有の問題だそうです。(Nexusでも発生するかは不明)
以上です。
2011/12/23

解像度別のAndroidランチャーアイコンサイズ

ランチャーアイコンを作成する際のサイズについて。

解像度によって、ランチャーアイコンのサイズは異なります。
ldpi (120 dpi) 36 x 36 px
mdpi (160 dpi) 48 x 48 px
hdpi (240 dpi) 72 x 72 px
xhdpi(320 dpi) 96 x 96 px


解像度によりサイズが変わる仕組みはこちら。


以上です。

2011/12/20

Android:プロセスが使用しているメモリ使用量のランキングを調べる方法


各プロセスが使用しているメモリ使用量のランキング上位を表示する方法です。
procrankコマンドで調べることができます。

# procrank

  PID      Vss      Rss      Pss      Uss  cmdline
  128   49064K   49064K   18013K   13896K  com.android.systemui
   74   47636K   47636K   17095K   13852K  system_server
  170   47644K   47644K   14781K    9856K  com.android.launcher
  224   45556K   45556K   14635K   10960K  android.process.acore
  157   39952K   39952K   10902K    8664K  com.android.phone
   35   39328K   39328K    8117K    4800K  zygote
  375   37096K   37096K    8011K    5620K  com.android.email

以上です。

Android:UIDを調べる方法


プロセスのUIDを調べる方法。
adb shellモードに入ってpsコマンドを発行。

# ps

下記のような結果が得られる。

USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
system    198   35    129244 33328 ffffffff 40011384 S com.android.settings
app_9     224   35    145148 45552 ffffffff 40011384 S android.process.acore
app_0     244   35    128604 33296 ffffffff 40011384 S com.android.calendar
app_15    277   35    125664 32712 ffffffff 40011384 S com.android.deskclock

今回はacoreのUIDを調べてみます。
psコマンドの結果からacoreのUSERが"app_9"であることがわかります。
続いてsuコマンドでユーザ切替。

# su app_9

続いてidコマンドを発行することでUIDがわかります。

$ id

実行結果は下記。acoreのUIDは10009のようです。

uid=10009(app_9) gid=10009(app_9)

以上です。
2011/12/16

onPause中にアプリが突然killされるケース

ActivityのonPause処理中に突然プロセスkillされることがあります。
つまりonPauseが完走しないケースが"あり得る"ということです。

プロセスをkillするのはLowMemoryKiller。
LowMemorykillerはフォアグラウンドプロセスをkillすることもありますが、ごく稀です。
killされる可能性が高くなるのはアプリがバックグラウンドにまわったpause状態の時。
Activityはforeground状態よりもpause状態の方がkillされる可能性がぐんと上がります。
通常、Activityがpause状態に遷移するのはonSavedInstance~onPauseが終わった後です。
しかし例外があります。

onSavedInstance開始~onPause終了に500msec以上かかった場合、ActivityManagerはActivity
のonPause完了を待たずにpause状態へと無理やり遷移させます。
その際下記のようなログがmainログに吐かれます。

W/ActivityManager(86): Activity pause timeout for ActivityRecord{ ... }

そのため、onPauseメソッドはActivityのpause状態で実行されることがあり、
onPauseの途中でプロセスがkillされてしまうとonPauseが完走しません。

とはいえ、バックグラウンドで10以上のアプリを起動していたりする場合に起こり得るケースで
あるため、これも稀なケースと言えます。


Androidでスクリーンセーバを試す



Androidの小ネタです。

intentにはDREAMというカテゴリがあります。
これはパソコンでいうところのスクリーンセーバに属するカテゴリです。

エミュレータでも、adbシェルで下記を実行することでスクリーンセーバ「Rocket Launcher」が起動します。

# am start -a android.intent.action.MAIN -c android.intent.category.DREAM

下記のようなスクリーンセーバアプリが起動します。


以上です。

2011/12/15

ハードウェアアクセラレーションのメリットとデメリット

Android3.0より、ハードウェアアクセラレーション機能のON/OFFが指定できるようになりました。
この機能がONの場合は、Canvas、SurfaceViewやOpenGLなどの描画をGPUで実行するようになります。
ハードウェアアクセラレーション機能を使用することで描画パフォーマンスの向上が期待できます。
逆にTextViewやDrawableに対しては効果が期待できません。

下記はApplicationタグへの指定例です。
※この機能はapplicationまたはactivityタグに指定できます。

<application
    android:hardwareAccelerated="true" >

しかし、デメリットもあります。
ハードウェアアクセラレーション機能はメモリをより多く消費します。
これは、CanvasやSurfaceViewを使用している場合に限らず、TextViewやDrawableしか使用していないような
シンプルなアプリでも、機能ONであればメモリ消費量が増えてしまいます。

ハードウェアアクセラレーション機能はデフォルトでONです。
そのため、メリットとデメリット、自アプリの特徴を把握した上でハードウェアアクセラレーション機能を使用するか
しないかを考え、使用しない場合は明示的に機能OFFとする必要があります。

以上です。
2011/12/12

Androidでパケットログを取得する方法

アンドロイドの通信ログ(パケットログ)を取得する方法です。

下記のコマンドを発行するとログキャプチャ待機状態になります。

adb shell tcpdump -s 0 -v -w /data/tcp.pcap

待機状態でブラウザ等から通信を行うとパケットログが取得できます。
パケットログ取得を終了するにはCtrl+C。

取得したパケットログは上記コマンドの場合は /data/tcp.pcap に保存されます。
これをpullしてワイヤーシャークなどで実行すればパケットログ解析が可能です。



以上です。

2011/12/11

ファイルシステムの情報、空き容量を取得する方法

コード上でファイルシステムの情報や空き容量を取得するにはStatFSが使用
できます。

android.os.StatFsには下記のメソッドが用意されています。
・public StatFs (String path)
 ⇒コンストラクタ。指定したパスのファイルシステムがStartFsの対象とな
  ります。

・public int getAvailableBlocks ()
 ⇒指定したファイルシステムでアプリケーションが利用できる領域のブロ
  ックサイズを返します。

・public int getFreeBlocks ()
 ⇒指定したファイルシステムで利用できる領域のブロックサイズを返します。
  返されるブロックにはアプリケーションから利用できない領域を含みます。

・public int getBlockCount ()
 ⇒ファイルシステムの総ブロック数を返します。

・public int getBlockSize ()
 ⇒ファイルシステムのブロックサイズを返します。単位はByte。

一般アプリでファイルシステムの空き容量を調べる場合はgetAvailableBlocks
を使用します。getFreeBlocksは常用外です。

それぞれの容量を調べる場合はブロック数とブロックサイズの積を求めます。

StatFs sf = new StatFs("/mnt/sdcard/");
int kb = sf.getAvailableBlocks() * sf.getBlockSize() / 1024;
android.util.Log.e("yuki", "yuki KB=" + kb);

参考:http://developer.android.com/reference/android/os/StatFs.html#getAvailableBlocks()

以上です。

HoloテーマとDeviceDefaultテーマについて

アクティビティに指定するテーマについて。

android4.0以前はTheme.Blackが用意されていました。
Theme.Blackはデフォルトテーマとして設定され、アプリの見た目のベースとなります。
しかし、テーマは各メーカーや端末によってカスタマイズされています。
そのため、端末によっては見た目に差が出てしまうことがあります。

android4.0以降はホログラフィックテーマ用にTheme.Holoが用意されています。
このテーマはカスタマイズしてはいけないルールとなっており、端末によって見た目が
変わらないことが保証されています。

android4.0以降、メーカーや端末特有のテーマはDeviceDefaultに置き換えられています。
DeviceDefaultはGoogleから端末開発者向けに用意されたテーマです。

ホロテーマを適用したい(端末間での見た目を統一したい)場合はTheme.Holoを、
端末固有のテーマを適用したい場合はTheme.DeviceDefaultを適用します。

適用のサンプルは下記。

<style name="TestTheme"
        parent="@android:style/Theme.Holo">

以上です。
2011/12/07

アプリ起動の高速化:windowDisablePreview

スタイルの属性にwindowDisablePreviewというものがあります。

アプリを起動する際、アプリに黒系統のテーマ(Theme.Black, Theme.Holo)が適用されている場合は一瞬画面
が黒くなってからアプリが起動されます。
アプリに白系統のテーマ(Theme.Light, Theme.Holo.Light)が適用されている場合は一瞬画面が白くなってから
アプリが起動されます。

この現象は、アプリの起動パフォーマンスに問題を抱えていないアプリの場合確認が困難なぐらい一瞬です。
しかし、アプリの起動パフォーマンスに問題を抱えているアプリの場合は、ユーザがそれを認識(秒単位で)できる
ほどになります。

この画面が黒(あるいは白)くなる現象は、ユーザへのアプリ起動開始を通知する役目を担っています。
つまり、アプリの起動が非常に遅い(ランチャーアイコンをタップしても中々起動してこない)場合にユーザ
へのレスポンスタイムを縮める効果があります。

しかし、ユーザの操作なしにバックグラウンドから起動されるようなケースで、この効果を邪魔に感じる場合は
効果をOFFにすることが可能です。

下記のようにwindowDisablePreviewにtrueを設定したスタイルをactivityや
applicationに適用します。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="TestTheme"
            parent="@android:style/Theme.DeviceDefault">
        <item name="android:windowDisablePreview">true</item>
    </style>
</resources>

上記はメリットとデメリットを把握した上で使うのが重要です。
一見するとアプリのパフォーマンスが向上したように感じられますが、前述した通りレスポンスタイムは遅くなります。
windowDisablePreviewをtrueとすれば、ユーザはアプリが起動中であると認識できるタイミングは遅くなりますが、
アプリ起動中の黒(白)画面が表示されなくなるためユーザに起動中であることを気取られず高速起動したように見えます。

ランチャーアイコンから起動されるActivityには不向きと言えるでしょう。

以上です。
2011/12/06

SDカードのマウント、リマウント時にメディアストレージパスを意識する

SDカードのマウント、リマウント時に発行されるACTION_MEDIA_*系のブロードキャストインテントについて。
onReceiveで受け取る引数intentのdataにはマウントorリマウントされたストレージのパスが格納されています。
通知されるパスは下記のようなコードで確認できます。
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Uri data = intent.getData();
        String path = null;
       
        if (data != null) {
            path = data.getPath();
        }
        android.util.Log.e("test", "path=" + path);

        if ("/mnt/sdcard/xxx".equals(path)
                && Intent.ACTION_MEDIA_EJECT.equals(intent.getAction())) {
            // ...
        }
    }
};

@Override
protected void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_MEDIA_EJECT);
    filter.addDataScheme("file");
    registerReceiver(mReceiver, filter);
}
Galaxy Nexusなど、端末の内部ストレージとしてSDがマウントされているものが発売される傾向にあります。
クラウドの流行も後押しし、今後はmicroSDが搭載されない端末や内蔵ストレージ搭載の端末が増えてくるもの
と思われます。

内部ストレージ以外の他メディアがマウントされた場合もACTION_MEDIA_*系の通知がくるため、
異なるメディアストレージのパスに対して処理されるのが困るようなケースでは
Environment.getExternalStorageDirectory()等を利用してパスのチェックを行うのが良いでしょう。

2011/12/05

android4.0をダウンロードする方法(エラー対処編)

以前に書いたandroid4.0をダウンロードする方法について、
いざダウンロードを開始しても途中でダウンロードが停止してしまう現象が頻発しました。
そういう場合はsyncのジョブ数を1で実行すると解決するかもしれません。

具体的なコマンドは下記です。

1. repoコマンドのインストール
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo

2. repoコマンドのパーミッション変更
$ chmod a+x ~/bin/repo

3. repoコマンドの初期化
$ mkdir ~/android_src/
$ cd ~/android_src/
$ ~/bin/repo init -u https://android.googlesource.com/platform/manifest

4. ソースコードをダウンロード
$ ~/bin/repo sync -j1

おおよそ半日ほどでダウンロードは完了します。

以上です。
2011/12/03

onRetainNonConfigurationInstance考察

【一般的なライフサイクル(上から順に...)】
onCreate
onStart
onRestoreInstanceState
onResume
onSaveInstanceState
onPause
onStop
onRetainNonConfigurationInstance
onDestroy

【アクティビティの状態】
起動:onCreate~onResume
背面へ移動:onSaveInstanceState~onPause
停止:onStop
破棄:onDestroy

onSaveInstanceStateとonRetainNonConfigurationInstanceについて、
onRetainNonConfigurationInstanceは特別な理由がない限り画面回転用に使用します。
Activity再起動時に必要なデータはonSaveInstanceStateでBundleに格納します。

理由としてはそれぞれのAPIが呼ばれるタイミングにあります。
アプリ使用中に音声着信が割り込んだ場合を考えましょう。
音声着信割り込みで自身のActivityが背面へ移動する際にonSaveInstanceStateは呼ばれます。
つまりは、アプリの状態を保存するタイミングがあるということです。

次にonRetainNonConfigurationInstanceを考えてみましょう。
音声着信割り込みで自身のActivityが背面へ移動する際にはまだonRetainNonConfigurationInstanceは
呼ばれません。
つまり、このタイミングではアプリの状態を保存することができないということです。

注意しないといけないのは、Activityがシステムよりkillされること。
Activityが背面に回るとRUNNINGからPAUSE状態に遷移し、killされる可能性が上がります。
killされた場合はライフサイクル遷移しないためonRetainNonConfigurationInstanceは呼ばれません。

onRetainNonConfigurationInstanceについては下記のサイトが参考になります。
http://www.techdoctranslator.com/resources/articles/articles-index/faster-screen-orientation-change

2011/11/30

経過時間を求める方法

端末がブートしてからの経過時間をミリ秒単位で取得するにはSystemClock.uptimeMillis()を使用します。
コードのA地点からB地点までの経過時間を求める際などに利用できます。
sendMessageDelayed、TimerやAlermいらずなのでお手軽です。

※現在時刻はユーザが変更できるので System.currentTimeMillis()は危険です。
※SystemClock.uptimeMillis()でも危険なケースがあるのかな?(調査中)

以上です。

2011/11/26

ログにクラス名、メソッド名、行数を表示する方法

ログにクラス名、メソッド名、ファイル行数を出力する方法です。
Throwableインスタンスを生成してスタックトレースを取得します。
パフォーマンスへの影響は大きいので、常時出力はしない方がよいです。

private void methodA() {
    dbg("test");
}

private static void dbg(String msg) {
    StackTraceElement[] stack = new Throwable().getStackTrace();
    String className = stack[1].getClassName();
    String method = stack[1].getMethodName();
    int line = stack[1].getLineNumber();
    StringBuilder buf = new StringBuilder(60);
    buf.append(msg)
        .append("[")
            // sample.package.ClassName.methodName:1234
            .append(className).append(".").append(method).append(":").append(line)
        .append("]");
    android.util.Log.d("tag", buf.toString());
}

ログメソッドの呼び出し元の情報を表示します。
# スタックトレースからの取得なので、メソッドスタックを意識する必要はあります。
下記のような出力結果になります。

11-26 07:16:43.419: E/tag(649): test[yuki.test.IncludeTestActivity.methodA:2]

以上です。

Androidでパケットログを取る方法

Androidにおけるパケットログの取得にはtcpdumpコマンドが利用できます。

adb shell tcpdump -s 0 -v -w /data/tcp.pcap

コマンド発効~コマンド終了するまでパケットをキャプチャし続けます。
(終了するにはCtrl+C)

取得したログは/data/tcp.pcapに保存されていますので、pullしてWireshark
なりのパケットログ解析ツールにかければOKです。

以上です。
2011/11/25

EventLog. answer to life the universe etc

DDMSのEventLogから小ネタを1つ。
EventLogのフィルタ設定に"すべての答え"があります。


Google検索に実装されている計算機機能。
例えば「1*2」で検索すると「2」と計算して答えてくれます。

「人生、宇宙、すべての答え」と問いかけると、その答えをGoogleが一瞬で演算して
答えてくれるという小ネタがありますが、これがAndroidのEventLogにもこっそり実装
されているようです。

2011/11/23

Android.mk:LOCAL_MODULE_TAGSの指定


Android.mkを記載する際に指定するLOCAL_MODULE_TAGSについて。

LOCAL_MODULE_TAGSはシステム領域にアプリケーションをインストール(プリイン)
する際に必要なプロパティです。
指定できる値にはeng/user/userdebug/optional(デフォルト)があります。

ここで指定した値は、システムをビルドした際にプリインするかどうかの判断で
使用されます。

●engビルド(デバッグビルド)
特に指定は不要です。LOCAL_MODULE_TAGSの指定値に関係なく
全てインストールされます。
userビルドの時にインストール不要の場合はengを指定します。

●userビルド(商用ビルド)
明示的に値を指定する必要があります。
userまたはuserdebugの場合、プリイン対象となります。
optionalの場合はcore.mkのPRODUCT_PACKAGEにmodule名指定が必要となります。

engビルドの時は存在するのに、userビルドした際には存在しない!なんて状況が
あったりします。
動作の最終確認は、できればuserビルドでやりたいところです。
事実、userビルドかengビルドかを参照して動作(厳密な権限チェックをする/しない)
を切り替えるモジュールも存在します。

# Android3.0か4.0だかでLOCAL_MODULE_TAGSは指定必須になったような。。。
2011/11/21

AlertDialogのsetViewで出現する間隔を消す方法

AlertDialogにsetViewするとき、

setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight, int viewSpacingBottom)

ではなく、

setView(View view)

を使用した場合、コンテンツ領域とボタン領域の間に間隔が設けられてしまいます。
(図1の赤矢印部分)

これを回避するには前者のパディング指定ありのsetViewを使用します。

AlertDialog dialog = builder
    .setTitle(R.string.hoge)
    .setPositiveButton(android.R.string.ok, null)
    .create();
dialog.setView(view);

これで間隔を無くすことができます。



参考:AlertDialog.setView

以上です。
2011/11/17

Android端末のメモリ状態を取得する

Android端末のメモリ状態を取得する方法です。
# cat /proc/meminfo
MemTotal:         516316 kB
MemFree:          314328 kB
Buffers:              16 kB
Cached:            93892 kB
SwapCached:            0 kB
Active:           114636 kB
Inactive:          72664 kB
Active(anon):     103988 kB
Inactive(anon):        0 kB
Active(file):      10648 kB
Inactive(file):    72664 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         93420 kB
Mapped:            54552 kB
Slab:               4440 kB
SReclaimable:       1320 kB
SUnreclaim:         3120 kB
PageTables:         3932 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      258156 kB
Committed_AS:    1430652 kB
VmallocTotal:     450560 kB
VmallocUsed:       18524 kB
VmallocChunk:     430084 kB

/proc/meminfoで利用可能な物理メモリの容量は下記の式より求めることができます。
MemFree+Inactive

MemFree :システム全体で利用できる物理メモリの空き容量
Inactive:解放可能な物理メモリの容量

次はプロセス毎の物理メモリ使用量を調べる方法です。
# top
  PID PR CPU% S  #THR     VSS     RSS PCY UID      Name
 1337  0   4% R     1    928K    392K  fg root     top
   43  0   1% S    17  17472K    532K  fg root     /sbin/adbd

プロセス別の使用中物理メモリ容量は「RSS」の値を参考にします。


以上です。

2011/11/16

android4.0のソースをダウンロードする方法

以前android.gitがダウンしていた時に書いた、android.gitを使わずandroidソースを
ダウンロードする方法ですが、
http://yuki312.blogspot.com/2011/09/androidgitkernelorgandroid.html

4.0の環境が公開されたことに伴って、公式gitが復活したようなので、android4.0
を公式gitからダウンロードする方法を記載します。


環境は前回とかわらず
---------------------------
【環境】
Windows7 + Cygwin

Cygwinに必要なパッケージ(curlとか)は忘れました。すみません。
とりあえず 実行→パッケージが必要なら追加インストール としてください。
---------------------------
です。


【手順】
1. Cygwin起動
→Cygwin.batを実行

2. ホーム直下にbinディレクトリを作成
$ mkdir ~/bin

3. repoコマンドのインストール
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo

4. repoコマンドのパーミッション変更
$ chmod a+x ~/bin/repo

5. repoコマンドの初期化
$ mkdir ~/android_src/
$ cd ~/android_src/
$ ~/bin/repo init -u https://android.googlesource.com/platform/manifest
※1. nameとmailアドレスを尋ねられますが適当でOK
※2. 初期化に失敗した場合は手順aに
※3. SSL関係のエラーがでた場合は手順bに

6. ソースコードをダウンロード
$ ~/bin/repo sync
※ダウンロードには長時間かかります。

以上です。

---
以下はエラー発生時の対処法

(a) windowsコマンドプロンプトより
$ cd (cygwinインストールディレクトリ)/bin
$ ash.exe
$ /usr/bin/rebaseall

(b) 下記のようなエラーがでて失敗することがある
error: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL
その場合は下記を実行
$ cd /usr/ssl/certs
$ curl http://curl.haxx.se/ca/cacert.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}'
$ c_rehash

ダウンロードが途中で止まってしまう場合はandroid4.0をダウンロードする方法(エラー対処編)を試してみてください。
2011/11/12

Androidでソースコードデバッグする方法

Android開発におけるデバッグについて、Eclipse付属のデバッガを使用してソ
ースデバッグする方法。

【前準備】
・エミュレータを起動しておく
・必要な個所にブレークポイントを貼っておく

【手順】
1. [Run]→[Debug Configurations]
2. 左ペインより[Remote Java application]
3. ダブルクリックやNEWで設定を新規作成
4. ConnectタブのPortを8700に変更
5. ApplyしてDebug押下

DDMSパースペクティブ等でDevicesViewを確認し、デバッグしたいプロセスに
緑色の虫マークがついていれば成功です!
あとはアプリを動作させている際に、ブレークポイントを通過する処理に入っ
た場合、EclipseのDebugパースペクティブがアクティブになり、ソースデバッ
グが可能になります。(あとはJavaのそれと同じです)

実行時にエラーが出る場合は下記を試してみてください。

a1. DDMSパースペクティブを開くかDevicesViewを追加
a2. デバッグしたいプロセスをデバッグ対象として選択(緑の虫アイコン)

下図のようにデバッグしたいプロセスを選択して緑の虫アイコンを押下すれば
OKです。


これでもエラーが出る場合は再度デバッグ実行を試します。
[Run]→[Debug Configurations]...
※一度デバッグ実行していれば[Run]→[Run As...]にリストされているので、
そちらを実行します。

上手くいかない場合は、デバッグ実行→DevicesViewでデバッグ指定
を繰り返すとうまくいくことがあります。

以上です。

2011/11/08

chrome to phoneが使用できない間の対処法

技術情報から離れて少し休憩。

どうも先日(2011/11/08現在)からchrome to phoneで端末にデータを送信しようとすると、
「携帯端末がこのユーザーで登録されていません。」
と出て失敗する模様。

端末側でログインしようとするもどうにも失敗します。。。
私にとっては必需品となりつつある機能なので困りました。

他ユーザの方々も同じ症状に悩まされておられるようなので、
アプリかサーバどちらかに問題が発生している可能性が高いと思います。
http://www.google.com/support/forum/p/mobile/thread?tid=3bf1b6be91506e0e&hl=ja

ということで、問題が解決するまでの間は下記の方法で我慢。

QR-Code Tag Extension
https://chrome.google.com/webstore/detail/bcfddoencoiedfjgepnlhcpfikgaogdg

■QuickMark QRコードスキャナー
https://market.android.com/details?id=tw.com.quickmark&hl=ja

前者でデータをQRコード化して、後者でそれをパシャリとすればOKです。

2011/11/06

Activity間やサービス間でデータを共有する方法


複数のActivity間やサービスでデータを共有するにはIntentのExtra、preferenceやDatabase
など様々な方法がありますが、Extraでは貧弱だけれどpreferenceやDBなどを使用
するほどでもない場合には下記の方法があります。

【android.app.Application クラス】
android.app.Applicationクラスを使用すればグローバルにアプリケーションの
状態を保持することができます。
通常、ActivityはconfigChangeを契機に再起動され、メンバ変数も特別な処理を
行わない限り初期化されます。
そういったActivityのライフサイクルに左右されず、アプリケーション(プロセス)
の開始~終了までデータを保管できる場所としてApplicationクラスが使用できます。
これはアプリケーション内の各ActivityがgetApplication()を使ってアクセスできます。
Applicationクラスを使用するにはAndroidManifest.xmlに登録することで自動的に
インスタンス化されます。
→使用方法は下記が参考になります
 http://techbooster.jpn.org/andriod/application/2353/


【public static】
staticなフィールドやメソッドは複数のアクティビティやサービスからアクセス
できる方法として使用することができます。
気を付けないといけないのは、staticフィールドはActivityのライフサイクルに
左右されないということです。
ライフサイクルに伴い初期化や後処理を行う必要がある場合は別途管理する必要
があります。

Android Developerサイトにも情報が載っていますので参考にしてみてください。
http://developer.android.com/resources/faq/framework.html

以上です。

2011/11/01

端末空き容量が無い場合の試験を実施する方法


端末ROMの空き容量を0(端末ROM使用量をフル)にする方法です。
空き容量が0になるとストレージへのファイルIOやデータベースの更新操作時等、
さまざまな場面で実行時例外がスローされます。

ハイスペックな端末の場合は気にならない問題かもしれませんが、そうではな
い端末ももちろんあります。
この問題に対応する/しないを決めた上でアプリケーションを設計・実装しましょう。

まずは、端末のファイルシステムのブロックサイズを調べます。
※下記はAndroid4.0のエミュレータで検証

# df /data
-実行結果-
Filesystem             Size   Used   Free   Blksize
/data                   64M     7M    56M   4096

実行結果より、ブロックサイズは4096Byteとわかります。
実行結果の見方は下記
 - Size:ROMの総容量
 - Used:ROMの使用量
 - Free:ROMの空き容量
 - Blksize:ファイルシステムのブロックサイズ

次に、サイズ指定でファイルを生成します。
サイズは ブロックサイズ*個数 で指定します。
下記は1000ブロックのdummyファイルを作成するコマンドです。
 - bs:ブロックサイズを指定します
 - count:作成するブロック数を指定します
 - of:ファイルパスを指定します
# dd if=/dev/zero of=/data/dummy bs=4096 count=1000
-実行結果-
1000+0 records in
1000+0 records out
4096000 bytes transferred in 0.260 secs (15753846 bytes/sec)

上記をみると 4096*1000 で4096000Byte(4MB)のdummyファイルが作成されたこ
とがわかります。

dfデータでもう一度空き容量を見てみましょう。
# df /data
Filesystem             Size   Used   Free   Blksize
/data                   64M    11M    52M   4096

Freeが56M→52Mに減っていることがわかります。

※ワンポイント
一気に空き容量0となるようにdummyファイルを作成してもよいですが、
そうなると一切のファイルIOができなくなってしまいます。
試験する際は、一時的に空き容量を少し回復できるようにファイルパスを変えて
2段階でdummyファイルを作成することをお勧めします。

例)
// 空き容量回復用のファイルdummy1を作成
# dd if=/dev/zero of=/data/dummy1 bs=4096 count=1000

// 空き容量を無くす用のファイルdummy2を作成
# dd if=/dev/zero of=/data/dummy2 bs=4096 count=99999999

少しだけ空き容量を作成したい場合はdummy1を削除すればOKです。

以上です。

2011/10/30

レイアウトファイルにおけるincludeタグの動作を検証

上手くレイアウトを分割・コンポーネント化することで、レイアウトファイル
の可読性や再利用性を向上させることができます。

端的に言えば、includeタグで別レイアウトファイルを指定すると、
指定したレイアウトファイルの内容で置換されるようになります。

includeタグにはandroid:idを指定することができますので、それ自体にリソ
ースIDを指定することができます。
下記の例をみてます。

layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <include android:id="@+id/includer" layout="@layout/include" />
</LinearLayout>


layout/include.xml
<?xml version="1.0" encoding="utf-8" ?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:text="@string/hello"/>
</FrameLayout>

ポイントはmain.xmlのinclude要素にリソースID(includer)が指定されていること。
上記の内容で、setContentView(main.xml)とした場合のレイアウト階層をみる
と、include先(include.xml)のFrameLayoutのリソースIDに"includer"が割り
当てられます。


では、include.xmlにあるFrameLayoutが既にリソースID割り当て済みだとした
らどちらが優先されるのでしょうか?下記の内容で検証してみます。

layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <include android:id="@+id/includer" layout="@layout/include" />
</LinearLayout>


layout/include.xml
<?xml version="1.0" encoding="utf-8" ?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/includee"
    >
    <TextView 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:text="@string/hello"/>
</FrameLayout>

ポイントはmainのinclude要素にリソースID"includer"が、include.xmlの
FrameLayout要素にリソースID"includee"が指定されていること。
先の内容では、include要素のリソースIDがinclude先(include.xml)の
FrameLayoutのリソースIDに割り当てられましたが、今回はFrameLayoutに
はすでにリソースID"includee"が割り当てられています。
includerとincludeeどちらが優先されるのでしょうか?

結果は
    includer > includee
となりました。
両方定義されている場合はincluderが優先。
includeeのみ定義されている場合はincludeeとなります。

以上です。

2011/10/29

Androidエミュレータを再起動する方法

下記のコマンドを実行するとエミュレータの再起動ができる。
(正しい方法かどうかは未確認)

adb shell kill -9 zygoteのpid

Androidの基幹プロセスに含まれるzygoteのPIDは下記で確認できる。

adb shell ps

... 略 ...
root      35    1     114620 39328 ffffffff 40010794 S zygote
... 略 ...

左から、
USER/PID/PPID/VSIZE/RSS/WCHAN/PC/NAME
上記の例ではzygoteのPIDは35となる。
この場合

adb shell kill -9 35

とすればエミュレータは再起動する。

apkからマニフェストの内容を読み取る方法

apkはaaptツールを使用することで、マニフェストの大まかな内容を知ることができる。
aaptの実行ファイルはSDKのplatform-toolsに含まれている。

) 実行方法
aapt dump xmltree hoge.apk AndroidManifest.xml > foo.txt

上記でhoge.apkのマニフェスト内容がfoo.txtに出力される。

不具合を解析する際に「apkのみでソースコードがない」といった場合に、
期待するパーミッションが宣言されているか、intent-filterの値はどうか等の確認できる。
2011/10/24

マーケットアプリで「読み込んでいます...」から進まない場合の対処方法

技術ネタ以外から少々...

3か月ほど前にAndroidマーケットアプリがリニューアルされましたが、
「読み込んでいます...」から全く進まなくなる場合があります。

下記を試したところ現象が解消することがあったのでメモ。

・タスクマネージャからマーケットアプリプロセスを終了する
・端末再起動

プロセスを終了させる方法が良いと思います。
それでもダメなら再起動で。

2011/10/22

Android4.0向けのADTをインストールする


SDK-r14が公開されました。
http://developer.android.com/intl/ja/sdk/index.html

SDK-r14をインストールした場合はEclipseでAndroidを開発するためのプラグイン
ADTも更新する必要があります。
更新方法は下記になります。
※日本語化されていないEclipseでの手順です。
日本語化パッチを適用している方は読み替えてください。
※EclipseのバージョンはHelios

1. メインメニューより[Help]>[Install New Software...]
2. work withに下記のURLを指定
https://dl-ssl.google.com/android/eclipse/
3. 入力したらインストールパッケージがリストに表示される
Developer Tools
にチェック
4. あとは[Next>]で進めてインストール完了

手順2を入力してもリストが更新されない場合は下記のURLで試してみる。
http://dl-ssl.google.com/android/eclipse/

以上です。

Activityのライフサイクルが保証されないケース


以前紹介したLowMemoryKiller関係で1つ。
→以前の記事

バックグラウンドにあるアプリはkillされやすいことを調査しましたが、
注意しないといけないのはLowMemoryでkillされた場合はActivityのライフサイクルが
保証されないということです。

フォアグラウンドでもkillされる可能性はありますが、バックグラウンドの場合はその
可能性がぐんとあがります。
※FOREGROUND = 空きメモリ約8MB以下でkill / HIDDEN = 空きメモリ約29MB以下でkill

空きメモリが20MBの状態でアプリ起動された場合、フォアグラウンド中はいつも通りに
操作できますが、他アプリ割り込みなどによりバックグラウンドに回った途端にこのア
プリはLowMemoryKillerのkill対象になってしまいます。
つまりはLowMemoryでkillされるため、onStop~onDestoryが呼ばれない可能性があるとい
うことです。

最近はハイスペック端末も増えて、一般には気にすることではないかもしれませんが、
・メモリ上ではなくデータベースなど永続的なストレージでフラグON/OFFを管理している
・フラグのON/OFFがActivityのライフサイクルに依存している
上記のようなアプリは期待しない状態に陥る可能性があります。

アプリが起動しなくなるような状態を避けるためにも、ライフサイクルがすべて正しく
コールされることは必ずしも保証されないことを覚えておいた方がよいでしょう。

onSavedInstanceはonStopの前に呼ばれます。これをうまく使えばkillされる直前のデータ
をうまく退避させることも可能です。

2011/10/10

最新のツイートを取得する方法



指定ユーザの最新ツイートを取得する方法を調査しました。

まず、最新のツイートを指すURIは下記となります。
http://api.twitter.com/1/statuses/user_timeline/<ユーザ名>.<形式>?count=1

<ユーザ名>・・・取得したユーザ名(ユーザID)
<形式>・・・JSON形式の場合は.json、xml形式の場合は.xml等
※count=1は一件取得する場合のクエリ。

例)Yuki_312の最新ツイートを1件JSON形式で取得した場合
http://api.twitter.com/1/statuses/user_timeline/Yuki_312.json?count=1

上記URIから、HttpURLConnectionなどを使用してツイートを取得する。
※HttpURLConnectionを使用したHTTP通信の方法は割愛

最新のツイートをbyte配列で取得した場合、下記でJSONArray型に変換すると
便利。
JSONArray json = new JSONArray(
        new String(/*最新のツイート*/recentTweet(), "UTF-8"));


JSONArray型に変換できればあとは順々にデータを取得すればOKです。
ツイート日付の取得はちょっとコツが必要。
int len = json.length();
for (int i = 0; i < len; i++) {    
    JSONObject tweet = json.getJSONObject(i);    
    String text = tweet.getString("text");    
    
    // ツイート日付の取得    
    SimpleDateFormat df = new SimpleDateFormat("EEE MMM d HH:mm:ss Z yyyy", Locale.ENGLISH);    
    df.setTimeZone(TimeZone.getTimeZone("GMT"));    
    Date created_at_en = df.parse(tweet.getString("created_at"));    
    String created_at_ja = DateFormat.getDateInstance(DateFormat.FULL, Locale.JAPAN)    
            .format(created_at_en);    
    
    JSONObject user = tweet.getJSONObject("user");    
    String screen_name = user.getString("screen_name");    
}


2011/10/08

Android:adb logcat


端末のログ情報を取得できるlogcatツールについてのTipsです。

・ログに出力時間を含める
adb logcat -v time

・ログにスレッドIDも出力
adb logcat -v long

・ファイルに出力
adb logcat > log.txt

・radioログを取得
adb logcat -b radio

・ログレベルによるフィルタ(例はInfo以上のみ出力)
adb logcat *:I

・指定タグへのログレベルフィルタ(例はタグTestに対するフィルタ, 他タグは全出力)
adb logcat Test:I

・指定タグのみ出力する場合(Sはサイレント指定)
adb logcat Test:V *:S

・USBを抜いた後もログを取り続ける場合
adb logcat > log.txt &

最後の方法はUSB未挿入状態でのみ不具合が発生する場合に便利です。

2011/10/03

LowMemoryKillerによりkillされる閾値について


アプリがLowMemoryKillerによってkillされる閾値について調査しました。

LowMemoryKillerは端末上メモリの空き容量が少なくなると、容量確保のため、
決まったルールに従ってアプリをkill(強制終了)する機構です。

LowMemoryでkillされる閾値(メモリの空き容量)は固定ではなくアプリの状態で
上下します。
閾値は下記より求めることができます。

(1)閾値の算出
Androidのプロパティには下記が定義されている。
(実際にはinit.rcで設定される)
[ro.FOREGROUND_APP_ADJ]: [0]
[ro.VISIBLE_APP_ADJ]: [1]
[ro.HOME_APP_ADJ]: [6]
[ro.HIDDEN_APP_MIN_ADJ]: [7]
[ro.EMPTY_APP_ADJ]: [15]

[ro.FOREGROUND_APP_MEM]: [2048]
[ro.VISIBLE_APP_MEM]: [3072]
[ro.HOME_APP_MEM]: [6144]
[ro.HIDDEN_APP_MEM]: [7168]
[ro.EMPTY_APP_MEM]: [8192]

[XXXX_XXX_ADJ]は「システム内で生かすべき優先順位」です。
より値が小さいほどシステムからkillされづらくなります。
つまりは、値が大きければ閾値がよりシビアであり、値が小さければその逆と
なります。

XXXX_XXXにあたる部分はそのアプリの状態を表します。
状態の詳細は下記のコードコメントから予想できると思います。
// This is the process running the current foreground app.  We'd really
// rather not kill it! Value set in system/rootdir/init.rc on startup.
final int FOREGROUND_APP_ADJ;


// This is a process only hosting activities that are visible to the
// user, so we'd prefer they don't disappear. Value set in
// system/rootdir/init.rc on startup.
final int VISIBLE_APP_ADJ;

// This is a process holding the home application -- we want to try
// avoiding killing it, even if it would normally be in the background,
// because the user interacts with it so much.
final int HOME_APP_ADJ;

// This is a process only hosting activities that are not visible,
// so it can be killed without any disruption. Value set in
// system/rootdir/init.rc on startup.
final int HIDDEN_APP_MAX_ADJ;
static int HIDDEN_APP_MIN_ADJ;

// This is a process without anything currently running in it.  Definitely
// the first to go! Value set in system/rootdir/init.rc on startup.
// This value is initalized in the constructor, careful when refering to
// this static variable externally.
static int EMPTY_APP_ADJ;


ここでもう一度プロパティを見てみると、アプリのどの状態がkillされづらい
(値が小さい)かがわかります。
フォアグラウンドであればよりkillされづらく、背面にいればkillされやすい
ようです。
また、HOMEアプリが特別扱いされているのもわかります。


次に、killされる閾値について見ていきます。
[XXXX_XXX_MEM]はアプリ動作に最低限必要な空きページ数です。
この値を下回るとアプリはkillされることになります。

この値はページ数であり、最低限必要な空きメモリ量ではないことに注意してください。
LowMemoryでkillされる閾値(空きメモリ量)は下記で求めることができます。
ページ数([XXXX_XXX_MEM]) × ブロックサイズ(1ページあたりのサイズ)

ブロックサイズは各端末により異なります。
下記のシェルコマンドで端末のブロックサイズを求めることができます。
# df /system

実行結果)
Filesystem             Size   Used   Free   Blksize(ブロックサイズ)
/system                 86M    86M     0K   4096

例えば、[ro.FOREGROUND_APP_MEM]: [2048]でブロックサイズが4096の場合、
2048(ページ数)×4096(ブロックサイズ)=8388608Byte
となり、killされる閾値は約8MBということになります。

下記まとめとなります。
※Blksizeやページ数を上記とした場合

アプリの状態 = 閾値
FOREGROUND = 約8MB
VISIBLE = 約12MB
HOME = 約25MB
HIDDEN = 約29MB
EMPTY = 約33MB

HOMEアプリは空きメモリ容量約25MBを下回るとkillされるのに対して、
FOREGROUNDなアプリは空きメモリ容量約8MBを下回らないとkillされない。

以上です。

2011/10/02

PreferenceListで選択されたPreferenceを判別する方法


アプリ設定の読込みや保存に利用できるPreference。
Preferenceの編集にはPreferenceActivityを利用することができます。

今回はPreferenceActivityを使用する前提で、ユーザが選択したPreferenceを
判定する方法です。

1. Preference選択時のコールバックを拾う
PreferenceActivityの下記メソッドをオーバーライドする
android.preference.PreferenceActivity.onPreferenceTreeClick(PreferenceScreen, Preference)

2. 選択したPreferenceを判別する
ユーザが選択したPreferenceの判別には下記のメソッドが使用できる
android.preference.Preference.getKey()

getKey()で返ってくる値は、Preferenceのリソース(下記メソッドで指定するxml)
で指定するandroid:keyの値となる。
android.preference.PreferenceActivity.addPreferencesFromResource(int)

一連のソースは下記

・Preference(config.xml)
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
	xmlns:android="http://schemas.android.com/apk/res/android">
	<PreferenceCategory
		<EditTextPreference 
			android:key="follow_user"
			...
	</PreferenceCategory>
</PreferenceScreen>

・Preference設定画面
public class TwitterWidgetConfigure extends PreferenceActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.config);
	}

	@Override
	public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
			Preference preference) {
		// key"follow_user"が返される
		android.util.Log.e("yuki", "yuki key=" + preference.getKey());
		return true;
	}

以上です。
2011/10/01

Android.gitからダウンロードしたソースをEclipseで紐付けする方法



前回ダウンロードしたAndroidのソースコードをEclipseに取り込むことで、
framework層以下のソースコードを[呼出し階層を開く]や、宣言へのジャンプ
機能で開けるようにできます。

方法は下記。
※xcopyコマンド(windows)で実現しようとしましたが、上手くいかなかったの
で、cpコマンド(cygwin)でやりました。

export PATH_GIT_BASE=~/android_src/frameworks/base
export PATH_JAR_BASE=~/jar

cp -R $PATH_GIT_BASE/core/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/core/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/graphics/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/keystore/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/location/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/media/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/opengl/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/sax/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/telephony/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/vpn/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/wifi/java $PATH_JAR_BASE
cp -R $PATH_GIT_BASE/services/java $PATH_JAR_BASE


・PATH_GIT_BASEはandroid.gitからダウンロードしたソースフォルダのルートデ
ィレクトリ。
・PATH_JAR_BASEはコピー先のディレクトリ。

Eclipseに取り込む前に下記フォルダ(sources)を作成します。
%ANDROID_SDK_ROOT%\platforms\android-XX\sources
※android-XXはAndroid API Levelなので、Eclipseで作成しているプロジェクト
が参照するAPI Levelを指定

PATH_JAR_BASEにコピーしたファイルのjavaディレクトリ下を、作成したsources
フォルダに移動します。

ここまでで、sourcesディレクトリの階層は下記のようになっているはずです。
sources
 |+android
 |+com
 |+javax
 |Android.mk ...などなど

上記の状態でEclipseを起動すると、Activity.classファイルなどを開く際に
コピーしたjavaファイルがアタッチされて参照できるようになっているはずです。

足りないファイルがある場合は同じ要領でsources下にソースコードを持って
くればOKです。

以上です。

2011/09/30

android.git.kernel.org以外からAndroidソースコードをダウンロードする方法



2011/09/30現在、Kernel.orgから発表されたサーバへの不正侵入があって以来、
android.git.kernel.orgが休業状態となりソースがダウンロードできない。

Linuxのソースコード管理サイトに不正侵入



ということで、codeauroraの非公式ミラーサイトからソースをダウンロード
しようと思います。
コツとしてはandroid.git.kernel.orgにアクセスしないようにすることです。
正式な方法は検索すれば見つかると思うので割愛。
ミラーの正当性は保証しません。
(追記)2011年12月、android gitサーバが復活したことに伴い正式なダウンロード方法を記載
⇒正式なgitからのダウンロードはこちら


【環境】
Windows7 + Cygwin

Cygwinに必要なパッケージ(curlとか)は忘れました。すみません。
とりあえず 実行→パッケージが必要なら追加インストール としてください。


【手順】

1. Cygwin起動
→Cygwin.batを実行

2. ホーム直下にbinディレクトリを作成
$ mkdir ~/bin

3. repoコマンドのインストール
$ curl http://git-repo.googlecode.com/files/repo-1.12 > ~/bin/repo

4. repoコマンドのパーミッション変更
$ chmod a+x ~/bin/repo

5. repoコマンドの初期化
$ mkdir ~/android_src/
$ cd ~/android_src/
$ ~/bin/repo init -u git://codeaurora.org/platform/manifest.git
※1. nameとmailアドレスを尋ねられますが適当でOK
※2. 初期化に失敗した場合は手順aに
※3. SSL関係のエラーがでた場合は手順bに

6. .repo/manifests/default.xmlの編集
→~/android_src/.repo/manifests/default.xmlを修正
先頭付近の
fetch="git://android.git.kernel.org/"

fetch="git://codeaurora.org/"
に変更

7. ソースコードをダウンロード
$ ~/bin/repo sync
※ダウンロードには長時間かかります。

以上です。

---
以下はエラー発生時の対処法

(a) windowsコマンドプロンプトより
$ cd (cygwinインストールディレクトリ)/bin
$ ash.exe
$ /usr/bin/rebaseall

(b) 下記のようなエラーがでて失敗することがある
error: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL
その場合は下記を実行
$ cd /usr/ssl/certs
$ curl http://curl.haxx.se/ca/cacert.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}'
$ c_rehash