端末ごとのBluetooth 仕様まとめ

各Android端末で対応しているBluetoothのバージョンとプロファイルの一覧です。
最終更新日:2011-02-17

機種

AndroidOSバージョン

Bluetoothバージョン

Bluetoothプロファイル

Nexus One

2.2

2.0+EDR

Nexus S

2.3

2.1+EDR

Xperia

2.1

2.1+EDR(Android2.1の場合)

A2DP,AVRCP,FTP(Server only),HFP,HSP,OPP

Xperia arc

2.3

2.1+EDR

A2DP,FTP

LYNX SH-10B

1.6

2.1+EDR

HSP,HFP,OPP,A2DP,AVRCP

LYNX 3D SH-03C

2.1

2.1+EDR

A2DP,AVRCP,HFP,HSP,OPP,PBAP,SPP

REGZA Phone T-01C

2.1

2.1+EDR

A2DP,AVRCP,HFP,HSP,HID,OPP,PBAP,SPP

GALAXY Tab SC-01C

2.2

3.0

HSP,HFP,HID,OPP,A2DP,AVRCP,SPP,PBAP,SAP,FTP

GALAXY S SC-02B

2.2

3.0+EDR

HSP,HFP,OPP,A2DP,AVRCP,SPP,SAP,FTP,BPP,PBAP

HTC Desire X06HT

2.2

2.1+EDR

A2DP,FTP,OPP,AVRCP,GAP,GOEP,HFP,HSP,PBAP,SPP,SDAP

HTC Desire HD 001HT

2.2

2.1+EDR

A2DP,FTP,OPP,AVRCP, GAP, GOEP, HFP, HSP, PBAP, SPP, SDAP

GALAPAGOS 003SH

2.2

2.1+EDR

HFP, HSP, DUNP, A2DP, AVRCP, OPP, PBAP

GALAPAGOS 005SH

2.2

2.1+EDR

HFP, HSP, DUNP, A2DP, AVRCP, OPP, PBAP

DELL Streak 001DL

2.2

2.0+EDR

A2DP, AVRCP, HFP, OPP, BIP, HID, HSP

004HW

2.2

2.1+EDR

Libero 003Z

2.2

2.1+EDR

A2DP, AVRCP, SPP, OPP, HFP

IS01

1.6

2.0+EDR

HSP,HFP,A2DP,AVRCP,HID,SPP,OPP,DUN

IS03

2.1

2.1+EDR

A2DP,AVRCP,HSP,HFP,OPP,PBAP,SPP

IS04

2.1

2.1+EDR

A2DP,AVRCP,HID,HFP,HSP,OBEX,OPP

IS05

2.2

2.1+EDR

HSP,HFP,A2DP,AVRCP,OPP,SPP,PBAP

IS06

2.2

2.1+EDR

A2DP,AVRCP,HFP,HSP,OPP,PBAP,SPP

/system フォルダを書き込み可能にする

Android は標準の状態で /system フォルダは読み込み専用でマウントされていて root でも書き込めないようになっています。
ということで、root 状態で書き込めるようにするための手順をメモしておきます。
PCとUSB接続ADBで端末が認識されている状態で、PCから

$ adb shell
$ su
# mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system

のように実行すると読み書き可能な状態でリマウントできます。
/dev/block/mtdblock3 の部分は引数なしの mount コマンドで自身の端末の /system マウントデバイスを確認して下さい。
Xperia であれば、下記を参考に /dev/block/mtdblock2 と指定します。

$ mount
mount
rootfs / rootfs ro 0 0
tmpfs /dev tmpfs rw,mode=755 0 0
devpts /dev/pts devpts rw,mode=600 0 0
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
tmpfs /sqlite_stmt_journals tmpfs rw,size=4096k 0 0
/dev/block/mtdblock2 /system yaffs2 ro 0 0
/dev/block/mtdblock3 /data yaffs2 rw,nosuid,nodev 0 0
/dev/block/mtdblock1 /cache yaffs2 rw,nosuid,nodev 0 0
DxDrmServerIpc /data/DxDrm/fuse fuse.DxDrmServerIpc rw,nosuid,nodev,user_id=0,gr
oup_id=0,allow_other 0 0
/dev/block//vold/179:1 /sdcard vfat rw,dirsync,nosuid,nodev,noexec,uid=1000,gid=
1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,s
hortname=mixed,utf8,errors=remount-ro 0 0

参考:
Mount a filesystem read-write(ANDROID TRICKS)

SQLiteOpenHelper でテーブルカラム変更時にデータを引き継ぐ

SQLiteOpenHelper の実装サンプルです。
onUpgrade() の実装は DROP TABLE クエリを実行するのが簡単なのですが、
それだとDBバージョンアップごとにデータがリセットされてしまいます。
 
バージョンアップでカラム追加、削除を行った時も共通カラムについては引き継げるように、こちらの回答を参考に実装してみました。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
 
class DatabaseHelper extends SQLiteOpenHelper {
/**
 * DBファイル名
 */
private static final String DATABASE_NAME = “sample.db”;
/**
 * DBバージョン
 * (既存のDBとバージョン値が異なる時だけ onUpgrade()が呼ばれる)
 */
private static final int DATABASE_VERSION = 1;
/**
 * コンストラクタ
 */
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
 
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(“CREATE TABLE table1 (”
+ “name text NOT NULL, ”
+ “birthdate INTEGER NOT NULL”
+ “)”);
}
 
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 指定したテーブルのカラム構成をチェックし、
// 同名のカラムについてはアップグレード後もデータを引き継ぎます。
// 同名のカラムで型に互換性がない場合はエラーになるので注意。

// 更新対象のテーブル
final String targetTable = “table1”;
db.beginTransaction();
try {
// 元カラム一覧
final List<String> columns = getColumns(db, targetTable);
// 初期化
db.execSQL(“ALTER TABLE ” + targetTable + ” RENAME TO temp_”
+ targetTable);
onCreate(db);
// 新カラム一覧
final List<String> newColumns = getColumns(db, targetTable);
 
// 変化しないカラムのみ抽出
columns.retainAll(newColumns);
 
// 共通データを移す。(OLDにしか存在しないものは捨てられ, NEWにしか存在しないものはNULLになる)
final String cols = join(columns, “,”);
db.execSQL(String.format(
“INSERT INTO %s (%s) SELECT %s from temp_%s”, targetTable,
cols, cols, targetTable));
// 終了処理
db.execSQL(“DROP TABLE temp_” + targetTable);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
 
/**
 * 指定したテーブルのカラム名リストを取得する。
 *
 * @param db
 * @param tableName
 * @return カラム名のリスト
 */
private static List<String> getColumns(SQLiteDatabase db, String tableName) {
List<String> ar = null;
Cursor c = null;
try {
c = db.rawQuery(“SELECT * FROM ” + tableName + ” LIMIT 1″, null);
if (c != null) {
ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
}
} finally {
if (c != null)
c.close();
}
return ar;
}
 
/**
 * 文字列を任意の区切り文字で連結する。
 *
 * @param list
 * 文字列のリスト
 * @param delim
 * 区切り文字
 * @return 連結後の文字列
 */
private static String join(List<String> list, String delim) {
final StringBuilder buf = new StringBuilder();
final int num = list.size();
for (int i = 0; i < num; i++) {
if (i != 0)
buf.append(delim);
buf.append((String) list.get(i));
}
return buf.toString();
}
 
}

SQLiteOpenHelper(Android Developers)
SQLiteOpenHelper onUpgrade() Confusion Android

Android で System.exit() を使ってはいけない理由と、終了方法のまとめ

Androidではアプリを終了させる場合、System.exit(0) でもアプリを終了することができますが、この方法ではVMごと強制終了させるため、アクティビティのライフサイクルを無視することになる上メモリなどのリソース解放に失敗するおそれがあり、安全ではありません。
適切な終了方法はどれか、ということでアプリケーションを終了させる方法をまとめてみました。

■Activity#finish()
アクティビティを閉じる際の最良の終了方法です。
現在のアクティビティを閉じて前のアクティビティに戻ります。
アプリケーションの起動アクティビティで呼び出した場合はアプリケーションを終了します。
バックボタンを押した時と同じ動きで、実行すると onPause(), onDestroy()が順番に呼ばれます。
復帰時は新規生成となり onCreate(), onStart(), onResume() の順でイベントが発生します。
 
■Activity#moveTaskToBack (boolean nonRoot)
アプリケーション全体を終了する際の推奨される終了方法です。
アプリケーションを中断状態にします。
引数に false を指定した場合、アプリケーションの開始アクティビティ以外の呼び出しでは何もしなくなるため、通常は引数にtrueを指定して呼び出します。
ホームボタンを押した時の動作と同じ動きで、実行するとonPause()イベントが発生します。
次の再開までバックグラウンドで待機状態になり、メモリ不足になった時はOSにより自動でonDestroy()イベントが発生してアプリケーションの全てのタスクが終了します。
onDestroy()が呼ばれる前に復帰した時は最後のアクティビティから再開し、onRestart(), onStart(), onResume() の順でイベントが発生します。
 
例:

this.moveTaskToBack(true);

ドキュメントより引用:

public boolean moveTaskToBack (boolean nonRoot)
 
Since: API Level 1
Move the task containing this activity to the back of the activity stack.
The activity’s order within the task is unchanged.
If the task was moved (or it was already at the back) true is returned, else false.
 
訳:このアクティビティを含むタスク全体のアクティビティスタックの順番を後ろに移動させます。
タスク内のアクティビティの順番は変更されません。
 
パラメータ
nonRoot If false then this only works if the activity is the root of a task; if true it will work for any activity in a task.
  訳:falseの場合は現在のアクティビティがタスクのルートアクティビティ(アプリケーションの開始アクティビティ)の時だけ動作します。
     trueの場合はタスク内のどのアクティビティであっても動作します。

 
■android.os.Process.killProcess(int pid)
Process.myPid ()を引数に与えると現在のプロセスを強制終了します。
アクティビティが実行中のプロセスを対象に呼び出すと、finish()と同じくそのアクティビティを終了します。
ただし、onDestroy()などActivityのライフサイクルを全て無視して強制終了するため、通常は Activity.finish() が推奨されます。
例:

android.os.Process.killProcess(Process.myPid());

ドキュメントより引用:

public static final void killProcess (int pid)
 
Since: API Level 1
Kill the process with the given PID.
Note that, though this API allows us to request to kill any process based on its PID,
the kernel will still impose standard restrictions on which PIDs you are actually able to kill.
Typically this means only the process running the caller’s packages/application and any additional
processes created by that app; packages sharing a common UID will also be able to kill each other’s processes.
訳:指定したIDのプロセスを終了します。
このAPIでは指定のPIDに基づいてどんなプロセスでも終了することが許されていますが、
実際終了できるかどうかはカーネルの標準的な制限で決まる点に注意してください。
つまり、典型的には呼び出し元のパッケージやアプリケーションが実行しているプロセスと、そのアプリが作成した追加のプロセスに限られるという意味です。
UIDを共有しているパッケージもまたお互いのプロセスを終了させる事ができます。

 
■System.exit(int)
System.exit(RESULT_OK)のように実行することで実行中のプロセスを強制終了します。
android.os.Process.killProcess(Process.myPid()) と同じような動きになりますが、
安全ではないので使うべきではありません。
ドキュメントには、

public static void exit (int code)
 
Since: API Level 1
Causes the virtual machine to stop running and the program to exit.
If runFinalizersOnExit(boolean) has been previously invoked with a true argument, then all objects will be properly garbage-collected and finalized first.
訳:バーチャルマシンの実行を停止し、プログラムを終了させます。
runFinalizersOnExit(boolean) を事前に引数にtrueを指定して呼び出してれば、全てのオブジェクトは最初に適切にガベージコレクトされてファイナライズされます。

のように一見、runFinalizersOnExit(true)を設定しておけば問題ないかのように書かれていますが、
実際にはrunFinalizersOnExit(boolean)の説明に

This method is deprecated. this method is unsafe.

と、どちらにしても安全ではない事が明確に書かれているためです。
 
通常は finish() または moveTaskToBack(true)を使い、どうしてもプロセスを強制終了したい場合は、Process.killProcess(Process.myPid ()) を使いましょう。
 
■おまけ…
アプリ内の全てのタスク(アクティビティ,プロセス)を一度に即終了したい場合, moveTaskToBack(true) を使う以外の方法として次のようなものがあります。
 
・AndroidManifest.xml で <activity android:noHistory=”true”> オプションを指定して finish() する。
 noHistory=”true”を指定しておくとアクティビティのスタックがなくなる事を利用する方法です。
 
参考:
Activity(developer.android.com)
 アクティビティのライフサイクルについてなど。
アクティビティとタスクデザイン (ソフトウェア技術ドキュメントを勝手に翻訳)
Application Fundamentals(developer.android.com)
android close application
 Androidの強制終了の仕方についての議論。

Android – HttpClient のクッキー管理機能をカスタマイズする

HttpClient のクッキー処理の仕様をブラウザに合わせたい、RFC準拠にしたい、自分で管理したい、という時はクッキーポリシーの設定で動作を変更することができます。
方法1: 標準で提供されているクッキーポリシーを選んで設定する
例:

DefaultHttpClient client = new DefaultHttpClient(params);
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.NETSCAPE); // SetCookieの扱いをNetscapeの仕様に変更

 
設定可能な値:
– CookiePolicy.BEST_MATCH … デフォルトのベストマッチポリシー
– CookiePolicy.RFC_2109 … RFC2109に準拠(時代遅れの厳密なポリシー)
– CookiePolicy.RFC_2965 … RFC2965に準拠(標準的で厳密なポリシー)
– CookiePolicy.NETSCAPE … ネットスケープのドラフトに準拠
– CookiePolicy.BROWSER_COMPATIBILITY … (おかしな)一般的なブラウザと互換性がある動作にする。
 
方法2:カスタムポリシーを使う
例:

DefaultHttpClient client = new DefaultHttpClient(params);
// カスタムクッキーポリシーを定義する
CookieSpecFactory csf = new CookieSpecFactory() {
 
@Override
public CookieSpec newInstance(HttpParams params) {
return new BrowserCompatSpec(){
@Override
public void validate(Cookie cookie, CookieOrigin origin)
throws MalformedCookieException {
// ここで判定してクッキー導入処理を行う。
// super.validate(cookie, origin);
}
};
}
};
client.getCookieSpecs().register(“myspec”, csf); // カスタムポリシーに結びつけるキーワードを登録して・・
client.getParams().setParameter(
ClientPNames.COOKIE_POLICY, “myspec”); // そのキーワードでポリシーを設定!

 
カスタムポリシーを定義する場合は標準で提供されているポリシーのソースが参考になります。
 
– RFC_2109 … RFC2109Spec.java
– RFC_2965 … RFC2965Spec.java
– NETSCAPE .. NetscapeDraftSpec.java
– BROWSER_COMPATIBLE .. CookieSpecBase.java
 
その他クッキー関係の設定方法は公式ドキュメントに詳しく書かれています。
 
参考:
HttpClientでのCookieの扱い(HttpClient3.0-rc3)
HttpComponentsライブラリ公式ドキュメント(hc.apache.org)
RFC2109(日本語訳)
RFC2965(日本語訳)
HttpComponentsのcookieパッケージソース(svn.apache.org)

Windows 用 Android ドライバのまとめ

Windows で Android SDK (adbなど)を使うための各種Android端末用 android_winusb.inf 設定一覧です。
SDKを展開したフォルダにあるusb_driver/android_winsub.inf に記述されている[Google.NTamd64]と[Google.NTx86]の両方に同じ設定を付け足してください。
 
設定適用済みandroid_winusb.inf

; HTC Dream
%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C01
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01
%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF
; HTC Magic
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01
;
;Moto Sholes
%SingleAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB
%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01
;
;Google NexusOne
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01
 
; Xperia X10
%SingleAdbInterface% = USB_Install, USB\VID_0FCE&PID_D12E
%CompositeAdbInterface% = USB_Install, USB\VID_0FCE&PID_D12E&MI_01
 
; HTC Desire
%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C87
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C87&MI_01
 
; HTC DesireHD
%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0CA2
%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0CA2&MI_01
 
; Samsung galaxy (galaxy S, galaxy Tab)(*)
%CompositeAdbInterface% = USB_Install, USB\VID_04E8&PID_6640&MI_00
%SingleBootLoaderInterface% = USB_Install, USB\VID_04E8&PID_6640&MI_04
 
; SHARP IS01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9337&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9336&MI_05
 
; SHARP JN-DK01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9353&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9352&MI_05
%SingleBootLoaderInterface% = USB_Install, USB\VID_04DD&PID_9373
 
; SHARP SH-10B(LYNX)(*)
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9334&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9333&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9332&MI_05
 
; SHARP SH-03C(LYNX 3D)(*)
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9393&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9392&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_9391&MI_05
 
; SHARP IS03
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_939C&MI_05
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_939A&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_939B&MI_01
 
; SHARP 003SH(Galapagos)
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_93B5&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_93B4&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_04DD&PID_93B3&MI_05
 
; Toshiba T-01C(REGZA)
; http://www.fmworld.net/product/phone/sp/android/develop/t-01c_usb/download.html
%CompositeAdbInterface% = USB_Install, USB\VID_0930&PID_0D85&MI_01

(*)galaxy, SH-10B等についてはandroid_winusb.infへの記述だけではPCで認識できません。下記サイトからそれぞれの専用ドライバをインストールし、端末設定の「アプリケーション→開発」からUSBデバッグを有効にすることでadbなどから認識されるようになります。
 
– galaxy S, galaxy Tab
(Samsung Kies Installer に同梱)
http://jp.samsungmobile.com/pc/lineup/SC-02Bdownload.html
 
– SH-10B(LYNX)
https://sh-dev.sharp.co.jp/android/modules/driver/#sh_10b
 
– SH-03B(LYNX 3D)
https://sh-dev.sharp.co.jp/android/modules/driver/#sh_03c
 
参考:
ADB + Samsung Galaxy(stack overflow)
 
Samsung Galaxy S (Vibrant) not debugging(App Inventor Coffee Shop)
SH Developers Square(sharp) – シャープ製Android携帯のADBドライバ配布サイト。
 対応端末: SH-03C, IS03, SH-10B(LYNX), IS01

Android1.6でLinearLayoutを子要素なしで表示するとRuntimeExceptionになる

Xperia(2.1)で検証していて、別のXperia(1.6)で動かしたところこんなエラーが発生。

E/AndroidRuntime(10100): Uncaught handler: thread main exiting due to uncaught exception<br />
E/AndroidRuntime(10100): java.lang.RuntimeException: mBaselineAlignedChildIndex of LinearLayout set to an index that is out of bounds.<br />
E/AndroidRuntime(10100): 	at android.widget.LinearLayout.getBaseline(LinearLayout.java:151)<br />
E/AndroidRuntime(10100): 	at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:644)<br />
E/AndroidRuntime(10100): 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:280)<br />
E/AndroidRuntime(10100): 	at android.view.View.measure(View.java:7755)<br />
E/AndroidRuntime(10100): 	at android.widget.ScrollView.measureChildWithMargins(ScrollView.java:892)<br />
E/AndroidRuntime(10100): 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)<br />
E/AndroidRuntime(10100): 	at android.widget.ScrollView.onMeasure(ScrollView.java:276)<br />
E/AndroidRuntime(10100): 	at android.view.View.measure(View.java:7755)<br />
E/AndroidRuntime(10100): 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:2989)<br />
E/AndroidRuntime(10100): 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)<br />
E/AndroidRuntime(10100): 	at android.view.View.measure(View.java:7755)<br />
E/AndroidRuntime(10100): 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:2989)<br />
E/AndroidRuntime(10100): 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)<br />
E/AndroidRuntime(10100): 	at android.view.View.measure(View.java:7755)<br />
E/AndroidRuntime(10100): 	at android.widget.LinearLayout.measureVertical(LinearLayout.java:464)<br />
E/AndroidRuntime(10100): 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:278)<br />
E/AndroidRuntime(10100): 	at android.view.View.measure(View.java:7755)<br />
E/AndroidRuntime(10100): 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:2989)<br />
E/AndroidRuntime(10100): 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:245)<br />
E/AndroidRuntime(10100): 	at android.view.View.measure(View.java:7755)<br />
E/AndroidRuntime(10100): 	at android.view.ViewRoot.performTraversals(ViewRoot.java:748)<br />
E/AndroidRuntime(10100): 	at android.view.ViewRoot.handleMessage(ViewRoot.java:1614)<br />
E/AndroidRuntime(10100): 	at android.os.Handler.dispatchMessage(Handler.java:99)<br />
E/AndroidRuntime(10100): 	at android.os.Looper.loop(Looper.java:123)<br />
E/AndroidRuntime(10100): 	at android.app.ActivityThread.main(ActivityThread.java:4203)<br />
E/AndroidRuntime(10100): 	at java.lang.reflect.Method.invokeNative(Native Method)<br />
E/AndroidRuntime(10100): 	at java.lang.reflect.Method.invoke(Method.java:521)<br />
E/AndroidRuntime(10100): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)<br />
E/AndroidRuntime(10100): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)<br />
E/AndroidRuntime(10100): 	at dalvik.system.NativeStart.main(Native Method)<br />

どうも1.6の不具合らしく、LinearLayout, TableLayout あたりをaddView()なしで表示しようとするとこういうエラーになるようで…。
何も表示しないビュー(テキストなしのTextView)を該当のレイアウトにはめ込んだら問題なく動くようになりました。

参考:

Issue 3484 – Creating LinearLayout without child views programatically fails.(Android Issues)

apk パッケージの AndroidManifest.xml を解析するには

.apk ファイルに含まれる AndroidManifest.xml はバイナリ形式になっているため、そのままでは設定を読むことが出来ません。
 
元のXMLに戻すのではなく、XMLの情報を読みたいだけであれば、Android SDKに付属している aapt (Android Asset Packaging Tool)というツールを使うことで可能です。
 

aapt l -a <apkファイル>

aaptプログラムはapk作成のためのツールです。
それぞれのバージョン毎に独立した実行ファイルになっていて、platforms 以下それぞれのSDKバージョンのフォルダ以下に存在しています。
(追記)以前は platforms以下に分かれて配置されていましたが、現在は platform-tools フォルダに統合されました。

android-sdk/platform-tools/aapt

実行すると以下のようなダンプが出力されます。
AndroidManifest.xml について書かれているのは “Android Manifest:”以下ですね。

res/drawable/icon.png
res/layout/items.xml
res/layout/main.xml
AndroidManifest.xml
resources.arsc
classes.dex
META-INF/MANIFEST.MF
META-INF/CERT.SF
META-INF/CERT.RSA
 
Resource table:
Package Groups (1)
Package Group 0 id=127 packageCount=1 name=com.example.foo
~中略~
Android manifest:
N: android=http://schemas.android.com/apk/res/android
  E: manifest (line=2)
    A: android:versionCode(0x0101021b)=(type 0x10)0x3
    A: android:versionName(0x0101021c)=”1.2″ (Raw: “1.2”)
    A: package=”com.example.foo” (Raw: “com.example.foo”)
    E: application (line=6)
      A: android:label(0x01010001)=@0x7f040000
      A: android:icon(0x01010002)=@0x7f020000
      E: activity (line=7)
        A: android:label(0x01010001)=@0x7f040000
        A: android:name(0x01010003)=”.Foo” (Raw: “.Foo”)
        E: intent-filter (line=9)
          E: action (line=10)
            A: android:name(0x01010003)=”android.intent.action.MAIN” (Raw: “android.intent.action.MAIN”)
          E: category (line=11)
            A: android:name(0x01010003)=”android.intent.category.LAUNCHER” (Raw: “android.intent.category.LAUNCHER”)
    E: uses-sdk (line=16)
      A: android:minSdkVersion(0x0101020c)=(type 0x10)0x3

インテントごとの実行権限など一通りの設定を参照することが出来ます。
その他にもリソースID情報などもapkに関係する様々な情報を得られます。
 
参考:
How to parse the AndroidManifest.xml file inside an .apk package(stackoverflow)
エンコードされたAndroidManifest.xmlをデコードする

HTC Desire で急に通知バイブが鳴動しなくなる問題の対策

HTC Desire, Droid Incredible などで gmail の通知などでバイブが鳴らなくなる不具合があるようです。
調べてみたところSound Managerというアプリでバイブレーション設定することで解決するとのこと。
バイブが鳴るようになったら Sound Manager はアンインストールしてもOKです。
 
ダウンロード用QRコード(クリックでAndroid Merketへジャンプします)
画像
参考:
No notification vibration(Android Forum)