ラベル android の投稿を表示しています。 すべての投稿を表示
ラベル android の投稿を表示しています。 すべての投稿を表示

2011/09/15

VMWare / Android x86 にadbで接続する

よく忘れるのでメモ。

* ゲストOS (Android)側

  - IPアドレスを調べる。
    # netcfg
    (ifconfigではない)

* ホストOS側

  - Androidデバイスに接続する。
    # adb connect [ゲストOSのIPアドレス]

  - 接続したデバイスを確認する。
    # adb devices

デフォルトのポート番号は 5555。
ポート番号を例えば 5678 に変更したいときは、次のようにする。

* ゲストOS側

  # setprop service.adb.tcp.port 5678
  # kill `pgrep adbd`

* ホストOS側

  # adb connect [ゲストOSのIPアドレス]:5678

2011/08/25

HTC Desireでb-mobile talking Fairを使う

現在 HTC Desire (X06HT, CyanogenMod 6.1.1) に b-mobile talking Fair のSIMを挿して使い始めた。

元々 b-mobile Fair を契約していたが、以下の理由により移行した。
  • 携帯電話とスマフォを2台持ち歩くのが面倒だったので、1つにまとめたかった。
  • 普段電話はそれほど使わないので、電話の基本料金も安く抑えたかった。
  • b-mobile Fair 販売開始直後に契約して3ヶ月半、そろそろ更新の時期だった。b-mobile も更新のタイミングで talking Fair の製品発表をしたのだろう。
携帯は11年以上使っていたauの最安プランSS。au の解約料金と b-mobile talking Fair の初期費用を含めて計算したところ、私の場合は13ヶ月目以降に2台持ちよりも支払いが少なくなるようだ。ちょっと長いが1台になる利便性を考えると移行して良かったと思う。

# au の"誰でも割"解約料は11年目以降に安くなる。11年に達していなければ、移行費用を回収できる期間がさらに長くなるので、契約更新月まで待ったほうがトータルで安くなりそう。
# ちなみに b-mobile は契約期間1年未満で解約料10,500円が発生。

留守電等のオプションサービスは契約していない。
Android Marketから "圏外着信お知らせツール" をインストールして試したら、問題なく動作した。これは便利。

ところでちょっとしたことだが、b-mobile Fair から talking Fair の SIM に変更したら、電波強度のところに HSDPA の "H" が表示されるようになった。Fair でも通信速度を見ると HSDPA は有効になっていたので表示が変わったというだけ。

2011/06/02

Androidでb-mobile Fair 30日間の通信量

5/1-5/31の使用量: 81MB

外出した日の使用量は2MB〜8MBの範囲。
主な用途はメール・ブラウザ・RSSリーダー。
たまにアプリをダウンロード。
5月は休日に外出することが少なかったので、平均的な月より比較的通信量が低めだったと思われる。
この調子で行くと半分以上余る。

2011/05/17

Android DNSの設定を変更する

bionic libcのソースコードとドキュメントを見て以下のことがわかった。

net.dns[n].[pid] => net.dns[n] => /etc/resolv.conf
の順番でDNSを見る。

[n] : 1-8
[pid] : プロセスID


* プロセス毎の設定

system propertyのnet.dns[n].[pid]で、プロセス毎にDNSの設定ができるようになっている。
この設定が対象のプロセスにおいて見つかった場合、nが一致するnet.dns[n] は使われない。
Androidの開発においてはよほど特殊なことをしない限り、プロセス毎の設定を利用することはないだろう。


* グローバルな設定

1. net.dns[n]にDNSのIPアドレスを設定する。
2. net.dnschange の値を現在値とは別の整数値に設定する。通常この値はインクリメントされている。

net.dnschange (ここではカウンターと呼ぶことにする)はnet.dns#が変更されたことを検知するための整数値。
前回DNS Queryを発行しようとしたときと異なる値のとき、net.dns#が再読み込みされる。
libcが覚えるカウンター値はstatic変数なので、プロセスごとにカウンターによるDNS更新の判断を行っている。
javaでの実装方法は、ConnectivityServiceが参考になる。


* 補足

WiFiや3GをONにすると、net.[interface name].dns[n] が変更されて、その値の1つが net.dns[n] に設定される。

/etc/resolv.conf も見る実装がソースには残っていたが、#ifdef ANDROID_CHANGES によって除外されていた。

以下、覚書として"dns"を含むsystem propertyを挙げる。


$ adb shell getprop | grep dns
[net.change]: [net.dnschange]
[net.dns1]: [192.168.3.254]
[net.rmnet0.dns1]: [202.32.159.24]
[net.rmnet0.dns2]: [210.128.58.10]
[net.dns2]: []
[net.dnschange]: [118]
[dhcp.eth0.dns1]: [192.168.3.254]
[dhcp.eth0.dns2]: []
[dhcp.eth0.dns3]: []
[dhcp.eth0.dns4]: []
[net.eth0.dns1]: [192.168.3.254]
[net.eth0.dns2]: []
[net.dns3]: []

2011/05/16

Androidでb-mobile Fair 15日間の通信量

5/1-5/15の使用量: 28MB

連休中に出かけることが少なかったとはいえ、少なすぎる...。
目標値の3分の1以下。日中に節約しすぎた。
仕事中にメールは見ないので、休憩時間以外は3Gを切っていた。

主な用途はメール・ブラウザ・RSSリーダー。
RSSリーダーでのフィードの取得はWiFiで行っていた。
なので、通勤中のメールとブラウザの使用が主な内訳。

しかしまあ、あと105日使えるのだから、気分は良い。
4ヶ月/500MB/¥5000 という少しだけ割高なライトプランを出しても売れるのではなかろうか。

2011/05/14

AndroidのProxy設定のないアプリにProxyを越えさせる(HTTP+少しHTTPS)

DeleGateとwebnamedを使い、Proxy設定のないアプリでファイアウォールを越えてHTTP/HTTPS通信することに成功した。

こちらのブログを参考にさせてもらった。
DeleGateとwebnamedのネットワーク構成は"AndroidのProxy設定のないアプリにProxyを越えさせる(HTTPのみ)"に書いた図の、squidがDeleGateに置き換わったもの。

文末にDeleGateのinit scriptを示す。
参考元のスクリプトと主に違うところは、

- chkconfigに対応している
- DeleGateが参照するDNSサーバをwebnamedノードにしている
(192.168.3.10 がwebnamed、192.168.3.20:80 がProxy)

さて、題名に"少しHTTPS"とある理由だが、DeleGateのSSL透過プロキシ機能はman-in-the-middleな仕組みなので、サーバ証明書の検証をスキップする機能があるアプリでないと、HTTPSを使えない。

Dolphin Browserを試したところ、HTTPSでアクセスすると"アクセスしようとしているサーバ名が証明書と違うがどうするか?"という意味の警告が表示され、そのままページを開くかどうか選択できる。Gmailを開くことができた。
NewsRobはGoogle Readerから同期する際にExceptionが発生して、同期することができなかった。後日他のRSS Readerを試してみようと思う。

/etc/init.d/delegate:

#!/bin/sh
# chkconfig: 345 98 20
# description: delegate server
# processname: delegated

DAEMON=/usr/local/bin/delegated
DGROOT=/var/spool/delegate
DELEGATE_PORT=8080
PROXY_HOST=192.168.3.20
PROXY_PORT=80
DNS_SERV=192.168.3.10

test -x $DAEMON || exit 0

start_proc() {
$DAEMON DGROOT=$DGROOT -P$DELEGATE_PORT \
PROXY="$PROXY_HOST:$PROXY_PORT:*" \
PERMIT="http,https:*:*" \
REMITTABLE=http,https \
STLS=mitm \
RELAY=vhost RES_NS="$DNS_SERV,END"
}

stop_proc() {
$DAEMON DGROOT=$DGROOT -P$SRC_PORT -Fkill
}

case "$1" in
start)
start_proc
;;
stop)
stop_proc
;;
restart)
stop_proc
if [ "$?" != "0" ]; then
exit 1
fi
start_proc
;;
*)
echo "Usage: $0 start|stop|restart"
exit 1
;;
esac

2011/05/10

HTC Desire - CyanogenMod 6.1.1のバッテリー消費量(WiFi)

以下の状態において、8時間で100%=>%94 だった。
意外と減り幅が少ない印象。

- Wifi ON, 3G OFF
- K9-Mail : IMAP Idle 2アカウント, メール1件取得して6時間LED点滅
- NewsRob : 1時間毎の同期、100件くらい自動取得
- なまず速報β (速報なし)


#追記 5/11

以下の使い方で、100%=>70%

- 7.5時間WiFi、NewsRobで220件くらい自動取得、ほとんどスリープ状態
- 3時間3G、1.5時間ほどNewsRobやブラウザを使う。
- 通信量: WiFi 3.9MB、3G 4.0MB

2011/05/09

AndroidのProxy設定のないアプリにProxyを越えさせる(HTTPのみ)

ここで紹介する方法は動作はするが役立つ場面が少ない。

squid透過プロキシとProxy越えをするDNS Serverを使って、プロキシ設定のできないアプリにファイアウォールを越えさせることに成功した。

ただし、squid透過プロキシの仕組み上、HTTPSは通すことができない。squid 3.1のssl-bumpというman-in-the-middleな機能を使うとできそうだが、制約が大きそうなのでやらない。
HTTPSを通せないので、大抵HTTPSが必要なアカウント認証するWebアプリが使えないのが痛い。

これだけやってもHTTPのみ...。
はっきり言って、プロキシ設定ができるOpera Mobileだけの方が役に立つ。

以下、検証した構成。
Androidからsquidへは、iptables で80 portをsquidのホストの3128 portへリダイレクトした。

#追記 5/14
その後、squidの代わりにDeleGateを使ってHTTPSを通すことに成功した。


                       +-----------------------+
                       |  android smart phone  |
                       +-----------------------+
                          |                |
                          | DNS query      | http
                          v                v 
                    +----------+     +-------------+
                    | webnamed |     |   squid     |
                    +----------+     |(transparent)|
                          |  |       +-------------+
                DNS query |  |  http        |
                          v  +---------+    | http
                    +------------+     |    |
                    | DNS Server |     |    |
                    +------------+     v    v 
                                     +-------------+
                                     | http proxy  |
                                     |  firewall   |
                                     +-------------+
                    +--------------+   |    |
                    | resolver.cgi |<--+    | http
                    +--------------+        v
                           |         |-------------+
                 DNS query |         |   web site  |
                           v         +-------------+
                    +------------+
                    | DNS Server |
                    +------------+

2011/05/08

Androidの非公開APIを呼ぶ

リフレクションを使うと、Android SDKには公開されていないAPIを呼び出すことができる。
公開されていないAPIなので、バージョンごとの互換性が失われる可能性が高いことに注意。

以下はUSBテザリングをONにする処理。


ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);

Class c = Class.forName(cm.getClass().getName());
Field f = c.getDeclaredField("mService");
f.setAccessible(true);
Object iconn = f.get(cm);

// Method: int tether(String iface)
Method method_tether = iconn.getClass().getMethod("tether", String.class);
Object ret = method_tether.invoke(iconn, "usb0");

// Returns ConnectivityManager.TETHER_ERROR_*
int e = ((Integer) ret).intValue();

2011/05/07

Android K-9 Mail 待機時の通信量を節約する(2)

K-9 Mail通信量計測の詳細。

* 条件

- b-mobile Fair
- K-9 Mail v3.706
- Gmailの1アカウント、SSL、受信トレイが空の状態。


* 計測結果

計測値はIMAP同期が5回の同期での平均値、IMAP IDLEが1時間の間に発生した通信の平均値。
()内は128 Bytes換算のパケット数

[IMAP同期の同期毎の平均値]
- IPパケット数 = 12 (12)
- IPパケットサイズ合計 = 2.01 KBytes

[IMAP IDLEの平均値 (リフレッシュ間隔24分)]
- IPパケット数 = 5分毎に12 (12), 初回接続時に47 (62)
- IPパケットサイズ合計 = 5分毎に1.54 KBytes, 初回接続時に8.47 KBytes


* どちらが節約できるか

5分毎のIMAP同期とIMAP IDLEは、パケット数においてほぼ同等と見なせる。
したがって、メールが通知されるまで5分以上かかっても良い人はIMAP同期の方が節約できて、それほど待てない人はIMAP IDLEにするしかない。IDLE接続のリフレッシュ時間はデフォルトの24分が良い。


* パケット数の算出について

実測したパケット数はIPパケット数なので、モバイルデータ通信時のパケット数はもっと多くなるかもしれない。
節約するならばデータサイズだけでなく、パケット数の削減を考えなければならない。
実際は単純には計算できないと思うが、b-mobile Fairのサイトでは便宜上1パケット=128 Bytesで計算する方法を紹介している。
私はモバイルデータ通信のプロトコルについて詳しくないので、この方法にあやかってみる。

b-mobile Fairでは4ヶ月で1GBytesまでという契約だが、通信量とパケット数は関係する。
b-mobileのサポートに問い合わせて見たら、純粋な送受信したいデータの他にヘッダ、デリミタといったオーバヘッドも通信量として計算されるので、100バイトを1回送信するよりも1バイトを100回送信する方が通信量が多いということだ。


* IMAP IDLE接続のタイムアウト

IMAP IDLEの5分毎というのはサーバから送られてくるKeepAliveのパケットだと思われる。
IMAP IDLE接続のリフレッシュ間隔とは関係がない。
上記のパケット以外に、約25分間隔でFINパケットが来た。FINパケットの後、K-9 Mailは同一のIPアドレスへ再接続した。
そして特筆すべきは、たまにRSTパケットがサーバから来た。RSTパケットが来る条件は不明。
RSTは接続を強制終了する要求であり、K-9 Mailが再接続を試みたようだが、さらにRSTが返された。
RSTに続く通信は9.27 KBytes、54(69)パケットのやりとりが発生した後に別のサーバへ接続。
これらの現象はIMAP IDLE接続のタイムアウトと関係しているようだが、明確な仕様がわからなかった。

FIN、RSTはIDLE接続のリフレッシュ時間を24分(デフォルト)に設定しておくと返されない。
そのかわり、リフレッシュ間隔毎に再接続のためのやりとりが発生する。
デフォルトが24分なのはFINが返ってくる25分という時間と関係があるのかもしれない。

Android K-9 Mail 待機時の通信量を節約する(1)

私はb-mobile Fairの回線を使用し、メーラーはK-9 Mailを使っている。
待機時のメーラーの通信量が気になったので、パケット代節約の方法を探るために計測した。

ここでの計測対象はGmailに限った話しで、他のメールサーバだと結果が異なるかもしれない。

結論を言うと、
  • プッシュ接続(IMAP IDLE)より、5分より大きい間隔での定期的な同期(IMAP同期)の方が、パケット数的にはお得。
  • 節約したいならばIMAP同期で同期時間を10分以上に設定。
  • 節約したいけどプッシュ通知は必須というときは、IMAP IDLEのリフレッシュ時間を24分(デフォルト)に設定。
  • いずれにせよ、1ヶ月で5~6万パケットの大した数ではないので、倹約家以外はあまり気にする必要はなさそう。

である。

詳細は Android K-9 Mail 待機時の通信量を節約する(2) に。


補足としては、どちらの方法でも取得するフォルダの数は少ない方が通信量を節約できる。
K-9 Mailではプッシュフォルダの数だけ通信の接続数が増えるようだ。

私はK-9 Mailでプッシュフォルダを"1stクラスフォルダのみ"として、受信トレイのみを1stクラスに設定している。
基本的に受信トレイからの振り分けはPCからまとめてやっている。

逆USBテザリングでメール待ち受けができるCyanogenModパッチ(2)

環境: Ubuntu 10.10 Desktop, HTC Desire, CyanogenMod 6.1.1

前回のパッチの欠点を改善したものを作った。一応patchと、jarを固めたzipをここに置いてある。

このパッチにできることは、次のとおり。

- 一度だけAndroidとPCに設定をしておけば、USBケーブルを刺したときに通信できるようになる。
- 逆USBテザリングと通常の正方向のUSBテザリングを切り替えられる。

これで晴れて快適な逆USBテザリング生活?ができるようになった。

必要な設定は
- PC
    USB RNDIS (Ubuntuだとusb0)のPC側IPアドレスを固定アドレスにする。
- Android
    システムプロパティを設定する。
    - usb.reverse.dns1 ... DNSアドレス
    - usb.reverse.gw ... PC側のusb0のアドレス
    これらのプロパティのいずれかが空のとき、通常のUSBテザリングになる。

RNDISドライバさえあれば他のOSでも動くはずだが、試していない。


以下、設定方法。

ここに記述してあることは当然上記パッチをAndroidに焼かないと動作しないので、あしからず。

AndroidをUSBで接続したときに現れるusb0インターフェースのIPアドレスを固定する。

Ubuntu Desktopに標準インストールされるNetwork Managerとethtoolではこれができなかった。なぜなら、usb0のMACアドレスは接続するたびに変化する。Network Managerが前回接続したことのあるインターフェースであると認識せず、usb0に施したはずの設定が反映されない。

ということで、Network Managerは消して、/etc/network/interfaces での運用に変更する。
# Network Managerと共存する方法があるかもしれないが、私は上手く行っていない。


# apt-get remove network-manager



これは私の環境のinterfaces。usb0 以外の設定は、環境に合わせて変更する必要がある。
usb0 のPC側アドレスは 192.168.42.100 とする。192.168.42.0/24 のうち、192.168.42.129 以外なら他のアドレスでも良い。

PC: /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto usb0
iface usb0 inet static
    address 192.168.42.100
    netmask 255.255.255.0 



Androidで次のファイルを作成する。system partitionなのでadb remountや、recovery modeで変更する。

android: /data/local.prop:

net.dns1=
usb.reverse.dns1=
usb.reverse.gw=



Androidを再起動する。
PCからadbでシステムプロパティの値を設定する。
192.168.3.254 はDNSのアドレスなので、環境に合わせて変更する。


adb shell setprop usb.reverse.dns1 192.168.3.254
adb shell setprop usb.reverse.gw 192.168.42.100



以上で設定完了。

この状態でAndroidをUSBケーブルでPCに接続し、USBテザリングを有効にしてWebブラウザ等が使用できるかを確認する。
なお、Android Marketでダウンロードできないときは、Google Talkに一度ログインするとダウンロードが開始するかもしれない。

通常の正方向のUSBテザリングに戻したいときは、usb.reverse.dns1かusb.reverse.gwを空にすれば良い。

adb shell setprop usb.reverse.gw ""



このパッチでも不便な点がある。
それは複数の異なるLAN上のPCに接続するとき、DNSとゲートウェイの設定を変更しなければならないことだ。

2011/05/06

ADWLauncherで地味にうれしいこと

アイコンをドラッグしてゴミ箱に入れるとき、1秒くらい待つと"アンインストールしますか?"と聞いてくる。
アプリケーションの管理を開かなくてもアンインストールできる。
アプリの入れ替えをちょくちょくやるのでうれしい。

2011/05/05

EclipseでF11を押すとAndroidManifest.xml.outが生成されるときの対処

EclipseでF11を押すと、xmlファイル名の後ろに.outが付いたファイル(AndroidManifest.xml.outやlayout.xml.out)が生成されてプロジェクトが実行されないときの対処。

発生条件
- EclipseにADT PluginとWTP Pluginをインストールしている
- Androidプロジェクトで作業している
- xmlファイルを開いている
- (Ctrl+)F11を押す

これはEclipse WTPの機能で、xmlファイルに対して Run As > XSL Transformation を実行したことになるため。

以下の設定を変更すればOK。

Window > Preferences > Run/Debug > Launching を開き、
"Always launch the previously launched application' in the 'Launch Operation' section."
のラジオボタンを選択する。

こちらがネタ元

逆USBテザリングの通信速度/メリット/デメリット

先に結論を言うと、WiFiと比較したときの逆USBテザリングのメリットはあまりない。

逆USBテザリングの通信速度を計測した。
接続したPCの回線はYahooBB ADSL 8M。
ping値は私のレンタルサーバ(埼玉->東京)に対して行った。

* HTC Desire

SpeedTest.Net
Download 5.19 Mbps, Upload 0.77 Mbps
ping 28ms

* PC - Ubuntu 10.10 Desktop x86_64

速度.jpスピードテスト
Download 5.13 Mbps, Upload 0.80 Mbps
ping 26ms


ということで、この環境だとほぼUSBホストOSと同等の速度が出ることがわかった。

逆USBテザリングのメリットは、

- 充電速度がWiFi接続中よりも速い
- WiFiステーションがなくても接続できる

だと思う。
WiFi接続しながら充電していると充電完了までの時間が長くなる。逆USBテザリングの場合は通信のための消費電力がかなり小さいものと思われるため、WiFi OFF時の充電速度とほぼ変わらない。
WiFiステーションはいまどきどこでもありそうなので、あまりアドバンテージにはならないかもしれないが、セキュリティ上の理由でWiFiステーションを使いたくないときに、モバイルデータ通信の代替にはなる。

ちなみに私が逆USBテザリングを選択する理由は"趣味"だ。


反対にデメリットは多い。

- PCが必要
- PCでの設定が必要 (Linuxではできたが、Windowsは知らない)
- USBケーブルが必要
- rootedが必要
- USBテザリングをサポートしているAndroidが必要
- メール待ち受けやAndroid Marketを使用するにはAndroidのベースモジュールの変更が必要
- USBでの接続時間が長いとバッテリーの劣化が進むかも

Linux、rooted、テザリングをサポートしているROMが必要という時点で、逆USBテザリングは相当しきいが高い。
VMWare等でLinuxを動かせばWindowsでもできないことはないが...

テザリングは、最近ではドコモのOptimus PADやKDDIのHTC Evoが標準でサポートしている。今後標準サポートする機種は増えてくるのではないかと思う。

逆USBテザリングでメール待ち受けができるCyanogenModパッチ(1)

Androidの逆USBテザリング時に通信しないアプリが存在する理由で述べた問題を解決すべく、Androidのベースモジュールに手を入れた。

やったことは、アプリに対してUSBテザリングのON/OFFをWiFiの接続状態に見せかけるようにした。
ConnectivityManager を通じてネットワークの状態を確認しているアプリは、USBテザリングがONになったときWiFiが接続したものと認識するようになる。
また、USBテザリングがON(OFF)になったときにWiFiが接続(切断)したという通知がアプリに伝わるようになる。

すなわち、メーラーの自動受信やAndroid MarketのOATのような待機系の機能が逆USBテザリング時に使えるようになる。


試したアプリの動作は次のとおり。

* K-9 Mail

IMAP IDLE接続でUSBテザリングON/NAT設定すると、"同期停止"の表示がなくなり、メールを自動的に受信した。
USBテザリングをOFFにすると、再び"同期停止"の表示になった。

* Android Market

アプリからのダウンロード、PCサイトからのOTAインストール(USBにつながっているからOn The Airじゃないけど)はできた。
しかしたまにダウンロードが開始しないことがある。そのようなときはダウンロード履歴を何回か開いてみると開始する。Google Talkにログインするとダウンロードが開始した。通常のWiFi接続のときも同様の現象を見たことがあるので、これが今回の変更による問題なのかどうかはわからない。

* NewsRob

WiFi Onlyの定期的な同期を設定。USBテザリングON/NAT設定すると、設定された同期間隔でフィードを取得した。

* なまず速報

USBテザリングON/NAT設定した後すぐに接続した。
USBテザリングをOFFにするとしばらく通知領域にアイコンが残り、"診断情報"のサーバ接続が"はい"のままだった。
これはアプリの性質上、できる限り切断時間を短くするよう、繰り返しリトライを行っているものと推測される。


変更内容は以下のとおり。ものすごくwork aroundなやり方。

* android.net.ConnectivityManager
  • getActiveNetworkInfo() ... テザリングON時に"WiFiで接続した"という情報を返す。
  • getAllNetworkInfo() ... WiFiのNetworkInfoについて、テザリングが有効であれば"WiFiで接続した"という情報に置き換える。
  • getNetworkInfo(type) ... getAllNetworkInfo()と同様。

* com.android.server.connectivity.Tethering
  • TetheredState.enter() ... USBテザリングがONになった直後、"WiFiで接続した"というIntentをbroadcastする。
  • TetheredState.exit() ... USBテザリングがOFFになった直後、"WiFiが切断した"というIntentをbroadcastする。


ビルドした/system/framework配下のファイルとソースコードのパッチを一応ここにおいた。
zipはHTC Desire、CyanogenMod 6.1.1限定なので需要ないと思うが。

最後に問題点を挙げる。

- WiFiとテザリングの同時使用は考えていないので、USBテザリング中にWiFiをONにするとおかしな挙動をするかもしれない。

- 本来の正方向のUSBテザリングを3G回線でするとき、アプリがWiFiだと認識してWiFi向けの機能を実行してしまう。アクティブな接続の種類をアプリに返すとき、3Gより優先してなりすましWiFiの情報を返してしまうため。

- USBテザリングをONにした後、それほど間を空けずホストOS側でrusbtether-natを実行しないと、アプリが通信できないものと判断してしまうかもしれない。

- jarを焼いて直後のOS起動後、USBテザリングをOFFにするとUSBデバッグができない状態となり、USBテザリングをON/OFF繰り替えしても復帰できなくなってしまった。再起動したら直った。その後この現象は発生していない。

2011/05/04

CyanogenMod 6 froyo-stable をソースコードからビルドする

環境: Ubuntu 10.10 Desktop x86_64

CyanogenMod 6.1.1の/system/framework/framework.jar, services.jar を入れ替えるために、ソースコードからビルドした。
/syste/framework/配下のファイルの入れ替え以外は試していない。

CyanogenMod Wikiにプラットフォームごとのビルド方法が説明されている。有難い。
UbuntuとOS Xでの方法が書いてあるが、両方見た方がいいかも。


$ repo init -u repo init -u git://github.com/CyanogenMod/android.git -b froyo-stable
$ repo sync


を実行すると


error: revision master in CyanogenMod/android_device_advent_vega not found


というエラーが発生した。
.repo/manifest.xml からandroid_device_advent_vegaをコメントアウトして、再び repo sync。
これが完了したらビルドの設定。

WikiでのUbuntu上でのビルド方法には brunch bravo を実行するように書いてあったものの、このバージョンのenvsetup.shにはbrunchがないようだ。
OS X上でのビルド方法にはlaunchを実行するように書いてある。

続いてmake。frameworks/base と frameworks/base/services/java だけ部分的にmakeしたいが、モジュール間の依存関係を調べるのも面倒なのでフルビルド。

次のエラーが発生した。


(unknown): error 17: Field org.apache.http.protocol.HTTP.EXPECT_CONTINUE has changed value from "100-Continue" to "100-continue"


このスレッドを見ると、CyanogenMode 6.1.1リリースのすぐ後に修正された問題のようだ。


external/apache-http/src/org/apache/http/protocol/HTTP.java:    public static final String EXPECT_CONTINUE = "100-continue";


の 100-continue を 100-Continue に変更。

続いて次のエラーが発生した。


make: *** No rule to make target `vendor/cyanogen/proprietary/RomManager.apk', needed by `out/target/product/bravo/system/app/RomManager.apk'.  Stop.


WikiにROM Managerをダウンロードするように書いてあったが、やらなかったので出た。
ビルド中にcurlで外から取得するようになっていて、取得先のURLが見つかっていない。
CyanogenModの.zipから取り出して配置して、再びmake。

以上でmakeが完了した。
フルビルドした後はビルドしたいモジュールのディレクトリに移動して、mmコマンドを実行。

実はCyanogenModのビルドに先立って、手元にandroid git repositoryから取得したソースがあったので、それを使おうとした。
CyanogenModのframework.jarのclasses.dexをsmaliで逆コンパイルし、一部のクラスだけ置き換えたのだが、問題があった。
gitのタグandroid-2.2.1_r1とCyanogenMod 6.1.1では、android.internal.RのリソースIDが変わっていて、適切なリソースを取得できなかった。

Android Platformでの一部のプロジェクトのみmakeする

例えば frameworks/base をmakeしたいとき。
mmmをAndroid.mk のあるディレクトリを渡して実行する。

$ . build/envsetup.sh
$ mmm frameworks/base


mmmは再帰的にディレクトリを見るわけではないので、
frameworks/base 配下のプロジェクトに対しても個別にmmmを実行する。

Ubuntu 10.10 x86_64 でAndroidをビルドする

環境: Ubuntu 10.10 Desktop x86_64

libstdc++.so がないと言われる

embeddedさんのブログを参考にして、

$ sudo apt-get install gcc-multilib g++-multilib ia32-libs lib32z1-dev lib32ncurses5-dev

を実行したらビルドできた。
たぶん
g++-4.4-multilib: /usr/lib/gcc/x86_64-linux-gnu/4.4/32/libstdc++.so
が必要だったのだと思う。

2011/05/03

Androidの逆USBテザリング時に通信しないアプリが存在する理由

正確にはWiFi/3GがOFF、USBテザリングONのときに通信しないアプリが存在する理由。

私が使用している K-9 Mail、NewsRob、ついっぷるは逆USBテザリング時に自動同期しない。Android Marketでアプリをダウンロードできない。
その理由について考えた。

Android SDKのConnectivityManagerから、ネットワーク接続の状態を取得できる。
ConnectivityManagerが認識する接続の種類を挙げる。

TYPE_MOBILE
TYPE_WIFI
TYPE_WIMAX
TYPE_BLUETOOTH (非公開, 2.3.3から)
TYPE_DUMMY (非公開,2.3.3から)
TYPE_ETHERNET (非公開,2.3.3から)
(Sub Type) TYPE_MOBILE_DUN
(Sub Type) TYPE_MOBILE_HIPRI
(Sub Type) TYPE_MOBILE_MMS
(Sub Type) TYPE_MOBILE_SUPL

この中にUSBテザリングはない。
AndroidのUSBテザリングはUSB => WiFi/3G の方向での通信だけを想定していると思われるため、テザリング中であるか否かはAndroid端末内からの通信ができるかどうかと関係ない、ということなのだろう。

2.3.3で追加されているTYPE_BLUETOOTH, TYPE_DUMMY, TYPE_ETHERNETは@hideが記述されていて、Android SDKには非公開となっている。コミットログには

  Add some network types that OEM's are asking for.
  Adding them hidden so that if OEM's are rolling their
  own at least they can use the same values.
  Will mark them unhidden in a future sdk release.

と記述されていたので、企業からリクエストがあって追加した将来の互換性を保つための値で、わからないがTYPE_ETHERNETはEthernetインターフェースを装備したデバイスに使うのだと思う。Androidが動くNet Bookとか?

定期的にデータを取得するようなアプリは、ConnectivityManagerから接続状態を見て、未接続状態のときはデータを取得しない処理が実装されていることが多いと思われる。それが、アプリのお作法として適切だ。
したがって、WiFi/Mobile Data Connection/WiMAXが全て未接続であれば、USBテザリングのON/OFFには関係なく未接続状態だと判断されるだろう。
オープンソースであるK-9 Mailのソースを確認したらメールを同期する条件として、少なくとも全ての接続タイプのうち1つでもState.CONNECTEDであることが含まれていた。

なお、ConnectivityManagerでチェックせずに通信を開始するような機能は使用できる。
ついっぷるでは、「ネットワークに接続されていません」とメッセージは出ていても、手動で更新ができる。


#追記 5/5
ConnectivityManagerで接続状態を確認していることだけが理由ではなかった。
K-9 Mailはメール送受信用のサービスが常時動作しているが、常に走っているわけではなくネットワークが切断状態のときはサスペンドするようになっている。再び起動するのは ConnectivityManager.CONNECTIVITY_ACTION の Intent が通知されたときだ。
電力消費を抑えるための工夫だろうと思う。実験したところ、Android Marketについても同様のことが言える。

逆USBテザリングでメール待ち受けができるCyanogenModパッチを作って検証したら上手く動いた。