2012/10/27

ClipboardManager で NoClassDefFoundError

Java のパッケージは便利なのですが、同じ名前でパッケージが違うと時々混乱します。
Android の ClipboardManager もそんなクラスの一つです。

テキストを Clipboard にコピーする方法として、以下の様なコードがよく提示されています。
あえて import 文を見せているところが重要。
import android.content.ClipboardManager;

// 省略

private void copyToClipboard(String text) {
    ClipboardManager clipboardManager =
            (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    clipboardManager.setText(text);
}


これ、最近のADTでは、"Class requires API level 11 (current min is 7)" というように怒られます。


このエラー、「API11 未満ではこのクラスは提供されていないよ。」という意味ですから、この時点で何かおかしいとは思うわけですが、とりあえず、@TargetApi(11) をつけて問題を回避してみます。
import android.content.ClipboardManager;

// 省略

@TargetApi(11)
private void copyToClipboard(String text) {
    ClipboardManager clipboardManager =
            (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    clipboardManager.setText(text);
}

これを、API11 未満の端末で動作させると、NoClassDefFoundError が発生します。
E/AndroidRuntime(221): java.lang.NoClassDefFoundError: android.content.ClipboardManager

先ほど Eclipse で警告が出ていたように、Class が存在していないようです。
2012/10/26

adb を使わないで fastbootモードにする @ Nexus7

先日、穀風: Nexus7 を工場出荷状態に初期化してみた で fastbootモードにする手順として、以下のように書きました。
fastboot Nexus7 をUSBで接続して、Cygwin から以下のコマンドを実行。
$ adb.exe reboot bootloader

しかし、改めて Building for devices | Android Open Source を読んでいたら、以下のような記述を発見。
During a cold boot, the following key combinations can be used to boot into fastboot mode


(adb を使わなくても、)電源ON してからロゴが表示されている間に音量ダウンキーを押せばオッケーとのことです。

実際やってみると、電源キーから手を離してしまうとダメでした。
「電源を押したまま、ロゴが表示されたタイミングで音量ダウンキーを押す」とうまくいきます。
ネット検索してみると、多くの方が、「音量ダウンキーを押したまま、電源キー長押し」と書いています。
確かに、そちらの方が確実ですね。
2012/10/23

Nexus7 用に Android をビルドしてみた (3)

穀風: Nexus7 用に Android をビルドしてみた (2) でソースコードの取得が完了したので、次は Building the System | Android Open Sourceを参考に、実際のビルドに移ります。
ターゲットはBuilding for devices | Android Open Sourceに載っていました。
$ source build/envsetup.sh
$ lunch full_grouper-userdebug
$ make -j4

気長に待つこと数時間。
コンパイルが終了しました。

あとは実機に焼くだけです。
Nexus7 を接続し、まずは fastbootモード立ち上げます。
$ adb reboot bootloader

私の Nexus7 は既にアンロック済みなので、このまま続行しますが、まだの場合は以下のコマンドでブートローダーをアンロックします。
$ fastboot oem unlock

出力先のディレクトリに移動し、書き込みコマンドを実行します。
$ cd out/target/product/grouper
$ fastboot -w flashall

書き込みが終了すると、自動的にリブートがかかり、あのお馴染みの起動画面が立ち上がります。
エミュレータを良く使ってる人は見飽きているはずのこれです。


数秒待つと、Android のホーム画面に。
当然ですが、Gmail も Google Play もないプレーンな Androidです。

なんか、役に立たない子になっちゃったなぁ(笑)
まぁ、ちょっと遊んだら工場出荷時に戻してやろうと思います。


2012/10/22

Nexus7 用に Android をビルドしてみた (2)

穀風: Nexus7 用に Android をビルドしてみた (1) で環境構築が済んだので、次は Downloading the Source Tree | Android Open Sourceを参考にソースコードを取ってきます。

ダウンロード先は任意に決められますが、今回は ~/android_src というディレクトリにソースコードをダウンロードすることにしました。

また、Building for devices | Android Open Sourceによると、Nexus7 用のブランチは 「android-4.1.1_r4 or master」 と書かれています。
ただ、先日のアップデートで Nexus7 は Android 4.1.2 になってしまいました。
後ほど書きますが、ビルドに必要なバイナリも 4.1.2 用しか提供されていません。
とりあえず、今回は android-4.1.2_r1 を取ってくることにしました。(Nexus7 のデバイスネームは grouper って言うらしい)
2013/2/5 追記
現在の最新ブランチ(タグ)は android-4.2.1_r1.2 です。
Nexus 系はどんどん新しいバージョンが出るので、どのブランチを取って来るべきか悩みます。
基本的には提供されているバイナリ(下記)を見て決定すればよいでしょう。
指定できるブランチ(タグ)名は https://android.googlesource.com/platform/manifest にブラウザなどでアクセスするとわかります
$ mkdir ~/android_src
$ cd ~/android_src
$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.1.2_r1
$ repo sync

結構長い時間がかかりますが、ソースコードの取得が終了するまで気長に待ちます。

その間に、Nexus7 の動作に必要なバイナリを取得しておきます。
Building for devices | Android Open Source によると、ICS 以降、オープンソースに出来ないハードウェアドライバのバイナリが必要であるとのこと。
それらを、Google's Nexus driver page からダウンロードしておく必要があるそうです。

ちなみに、2012/12/22 現在のスクリーンショットは以下です。
既に 4.1.2 のものしか提供されていませんので、これらをダウンロードしてきます。

ダウンロードしたファイルをソースツリーのルートに置きます。
今回は ~/android_src です。
tar ball を展開すると、シェルスクリプトが作成されますので、それらを実行します。
$ ls *.tgz
broadcom-grouper-jzo54k-26240daf.tgz    nvidia-grouper-jzo54k-56de148f.tgz
elan-grouper-jzo54k-c889b8f4.tgz        nxp-grouper-jzo54k-4bfb1fb6.tgz
invensense-grouper-jzo54k-aae1cd0c.tgz  widevine-grouper-jzo54k-aca0e725.tgz
$ for i in *.tgz
> do
> tar zxf $i
> done
$ for i in *.sh
> do 
> ./${i}
> done

この時、各スクリプトを実行すると、ライセンスに同意するよう求められます。

同意するには、Y や Yes ではなく、I ACCEPT と書かなければいけません。

全てうまく行くと、vendor というディレクトリに必要なファイルが展開されます。

過去のビルドがあって、バイナリを新規に追加した場合は、以下のコマンドを実行して残骸を消しておく必要があるようです。
$ make clobber

うまく行ったら、もとのファイルは削除してしまってかまいません。
rm *.tgz *.sh

穀風: Nexus7 用に Android をビルドしてみた (3)

Nexus7 用に Android をビルドしてみた (1)

@ Ubuntu 12.04 LTS

Nexus7 を手に入れたので、自分でビルドしていろいろいじってみようかと思います。
とりあえずは、AOSPから取ってきたソースコードをビルドして焼いてみるところまで。

以下を参考に環境を構築します。
Initializing a Build Environment | Android Open Source

基本的には書いてある通りなのですが、現在は sun JDK 6 の入手先が変わっているので要注意。
以下のサイトを参考にさせていただきました。
Installing Java6 JDK on Ubuntu 12.04 | digital nomad
$ mkdir ~/src
$ cd ~/src
$ git clone https://github.com/flexiondotorg/oab-java6.git
$ cd ~/src/oab-java6
$ sudo ./oab-java.sh
$ sudo apt-get install sun-java6-plugin sun-java6-jre sun-java6-bin sun-java6-jdk

update-java-alternatives を使用して実行環境を java-6-sun にしておきます。
参考: まさおのブログ (表): Ubuntu 複数インストールされている java を切り替え
$ update-java-alternatives -l
java-1.6.0-openjdk-amd64 1061 /usr/lib/jvm/java-1.6.0-openjdk-amd64
java-1.7.0-openjdk-amd64 1051 /usr/lib/jvm/java-1.7.0-openjdk-amd64
java-6-sun 63 /usr/lib/jvm/java-6-sun
$ sudo update-java-alternatives -s java-6-sun

必要なパッケージインストール
$ sudo apt-get install git-core gnupg flex bison gperf build-essential \
  zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
  libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
  libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386
$ sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

/etc/udev/rules.d/51-android.rules に以下の行を加える(ファイルがない場合は作成する)
# adb protocol on grouper (Nexus 7)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e42", MODE="0666"
# fastboot protocol on grouper (Nexus 7)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e40", MODE="0666"

CCACHE と repo もインストールしておく
$ sudo apt-get install ccache
$ mkdir ~/bin
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

~/.bashrc に以下を加える
export USE_CCACHE=1
PATH=~/bin:$PATH

変更を反映させて環境構築完了。
$ source ~/.bashrc

穀風: Nexus7 用に Android をビルドしてみた (2)