2011年7月31日日曜日

EclipseのResource is out of sync with the file system対応

特別な話では無いのですが、設定方法を忘れてしまってあたふたしたので備忘録として記載。

ライブラリソース内デバッグとかを行う際、Resource is out of sync with the file systemのエラーがEclipseから出てしまい、その対処方法です。

[Windows]->[Preferences]で設定ダイアログを表示します。



この画面通り、チェックを付与すればOKですね。

※Eclipse 3.5系が中心で作業しているので、以降は違う箇所とかに変更されているかもしれません。(^^;

2011年5月24日火曜日

Android JNIライブラリの利用<その1>

Android JNIライブラリの作成で開発したライブラリプロジェクトを、そのままEclipseから利用する方法です。
<その1>ではJNIを対象としていますが、利用方法はJavaプロジェクトも全く同一です。<その2>はJNI専用になります。

<Android JNIライブラリ利用側>
  • ライブラリプロジェクトが完成したら、今度は利用するプロジェクト側を用意します。これは例ですが、特別なことはしていません。

  • プロジェクトプロパティの[Android]にあるLibraryの[Add...]ボタンでAndroidライブラリを選択します。ライブラリ登録したプロジェクトが選択できるようになります。設定完了した[Android]タブ

  • 同じくプロジェクトプロパティの[Java Build Path]のProjectsタブにある[Add...]ボタンを押下します。すると、Workspaceにある自分を除く全てのプロジェクトが選択できますが、JNIライブラリを選択します。この例では2つしか無いのでJNIライブラリだけ選択候補になっているように見えますが、間違えないでください。

  • Librariesタブに移動し[Add Class Folder...]ボタンを押下します。ここで、ライブラリ側のJavaソースがあるsrcフォルダを選択します。

  • Order and Exportタブに移動し先程追加したソースのクラスフォルダにチェックを入れます。一応これで準備完了です。後は好きにライブラリを利用したプログラムを開発すれば良いです。

  • ちなみに、Project Explorerで確認するとライブラリが追加されていることが分かると思います。ついでですが、説明しませんでしたがプロジェクトプロパティの[Java Build Path]にあるSourceタブは完了すると勝手にソースが追加されます。これを削除するとライブラリをコンパイルしませんので注意してください。

設定のみなので簡単でしたよね。後はJava実装を行なって実行すれば良いです。
ただ、初心者はJNIライブラリは利用側を実装するまでビルドしないことをお勧めします。というのも、ビルド結果がライブラリフォルダ内で行われてしまい、ライブラリ利用側のbinにコピーされない現象が発生しました。私が行なった対処方法は、binフォルダやgen、Libs、obj配下のディレクトリやファイルを削除することで対応できたように記憶しています。

上記のJNIライブラリ利用は、ライブラリ開発者とアプリ開発者が同一の場合に利用できます。しかしながら、他人にバイナリを配布する際はどうするのか?
これを<その2>に記載したいと思います。

2011年5月17日火曜日

Android JNI で C++ を利用する<その2>

単純なC++の場合には問題無いのだけれど、JNIフォルダの中に複数のフォルダを配置した階層構造とした場合に少々嵌ったので備忘録として記録。

この図のようなJNIディレクトリ構造を持つJNIを開発すると仮定する。
CソースとCPPソースが混在したとしても、Application.mkはJNI直下で無ければならない点に注意。次に、JNI直下では各ディレクトリ毎にAndroid.mkを配置するようにした場合(JNI直下でも良いがその場合には全て指定)には、次の一行をAndroid.mkに記述しておく。
include $(call all-subdir-makefiles)
これに気がつくまでに、時間がかなり掛かってしまったので注意してください。

2011年5月16日月曜日

Android JNIライブラリの作成

Androidの開発を行なっていく上で、避けて通れないのがライブラリ化でしょう。開発していく中で再利用ソースが増えてくるので、他プロジェクトでも利用したいって気持ちが増えます。
かといって共用部分をコピー&ペーストする方法もありますが効率的ではありませんし、なによりプロっぽくありません。ご存知だとは思いますが、アマチュアとプロフェッショナルの決定的な違いは仕事でお金を貰えるか否かになります。作業の効率化もそうですが、メンテナンスも常に意識し他者に継承出来ることが重要視されます。

#企業では同じ仕事を延々に同一担当者が行うことは出来ませんし。
#簡単なメンテナンスとかは、徐々に後輩に移行させる会社を想定しています。

御託はこの辺で終わりにして、本題のJNIライブラリ作成です。
実はAndroidのJavaライブラリ作成方法と全く同じで作成出来ましたってことで終わりにしても良いのですが、それだとやや酷いので、私の作業過程とちょっとしたトラブルの備忘録って趣旨で記載します。

この記事ではAndroid JNIをEclipse CDTの設定方法等は説明しません。それは、以前の記事であるAndroid JNI を Eclipse CDT でプロジェクト統合する<ubuntu 10.10編 その2>を見てください。


<Android JNIライブラリ作成>
  • Androidプロジェクトを生成します。この図のように、ライブラリ専用プロジェクトにActivityが不要な場合にはチェックを外しておきます。
    ☆上図では誤ってパッケージ名をタイプミスしたため、実行エラーとなってちょっと焦りました。こういった配慮も必要ですね。

  • 不要なファイルを削除します。リソースファイルは自動的に作成されますが、特に必要無いので削除しています。

  • Android Manifestの修正を行ないます。
    図の通り、Define an・・・の箇所のチェックを外すことでアプリケーションタグが削除されます。ライブラリは外部から直接起動されない(組み込まれる)ので、必要がある場合には組み込み先側での指定になります。

  • クラスファイルの作成を行ないます。ここでは、JNIの呼出元となるJavaクラスとしてsamplelibクラスを生成しています。内容は以下の通りとしました。
    package jp.co.anaheim_eng.teslib;

    public class samplelib {

    static {
    // ライブラリロード
    System.loadLibrary("testjni");
    }

    // JNIのネイティブメソッド
    public native String GetStringJNI();

    /**
    * デフォルトコンストラクタ
    */
    public samplelib() {
    }

    /**
    * 単なる文字列をJNI経由で返却するファンクション
    * @return
    */
    public String getString() {
    return GetStringJNI();
    }
    }
    この辺りで、前述リンク先の<AndroidプロジェクトのC/C++プロジェクト化>を終了しているものとします。

  • プロジェクトプロパティの[Android]にある[Is Library]をチェックを入れます。

  • JNI側のプログラムは以下の通りとしました。
    ヘッダーファイル[jp_co_anaheim_eng_testlib_samplelib.h]
    #include <jni.h>
    #ifndef _Included_jp_co_anaheim_eng_testlib_samplelib
    #define _Included_jp_co_anaheim_eng_testlib_samplelib

    /*
    * DEBUG パラメタ 0: Releaseビルド, 1: Debugビルド
    */
    #define DEBUG 1

    #ifdef __cplusplus
    extern "C" {
    #endif

    /*
    * Class: Java_jp_co_anaheim_1eng_testlib_samplelib
    * Method: GetString
    * Signature: ([II)Ljava/lang/String;
    */
    JNIEXPORT jstring JNICALL Java_jp_co_anaheim_1eng_teslib_samplelib_GetStringJNI
    (JNIEnv *, jobject);

    #ifdef __cplusplus
    }
    #endif

    #endif
    cppファイル[TestJni.cpp]
    #include <string.h>
    #include "jp_co_anaheim_eng_testlib_samplelib.h"
    #include <android/log.h>

    #include <iostream>
    #include <string>

    #if DEBUG
    # define DebugLogInfo(...) ((void)__android_log_print(ANDROID_LOG_INFO, "TestJni LIB", __VA_ARGS__))
    #else
    # define DebugLogInfo(...) do{}while(0)
    #endif

    JNIEXPORT jstring JNICALL Java_jp_co_anaheim_1eng_teslib_samplelib_GetStringJNI
    (JNIEnv *env, jobject thiz)
    {
    std::string strRtn = "Hello JNI Library";
    return env->NewStringUTF(strRtn.c_str());
    }
    [Android.mk]
    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE := testjni
    LOCAL_SRC_FILES := TestJni.cpp
    LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
    LOCAL_LDLIBS := -llog

    include $(BUILD_SHARED_LIBRARY)
    [Application.mk]
    APP_STL := stlport_static
    これでJNIライブラリの準備は完了となります。次からはJNIライブラリをどのように利用するかについて記述します。

2011年5月4日水曜日

Android JNI でのファイルの取扱と脆弱性

日本Androidの会 セキュリティ部で私が投稿した内容を纏めます。(^^;

事の発端はSkypeの脆弱性が指摘された件は、SQLiteのパーミッションに問題があったことから始まっています。
#パーミッションが開放されたとしても暗号化されていればまだ良かったのですがね。

「kaito」さんも指摘されていますように、一般的なAndroid APIを利用してファイルを作成する場合には、other権限で読み書きできるパーミッションが付与されることは無いからです。

「kaito」さんの解析成果によりSkype同梱されている「libpcmhost.so」が問題であるとの推測されましたので、JNI側でファイルを作成するとどうなるかを調査しました。

JNI側で一般的な入出力関数である「fopen」「open」の2つを調査しました。ファイルの中身は問題ではありませんので、単なるファイルをopenしcloseすることでファイルを生成させるというものです。ソースサンプルは以下の通り。

#include <stdio.h>
#include <fcntl.h>
#include <jni.h>
#include <android/log.h>

#define DEBUG 1
#if DEBUG
# define DebugLogInfo(...) ((void)__android_log_print(ANDROID_LOG_INFO, "TestOpen", __VA_ARGS__))
#else
# define DebugLogInfo(...) do{}while(0)
#endif

JNIEXPORT jint JNICALL Java_jp_co_anaheim_1eng_MainActivity_testOpen (JNIEnv *env, jobject thiz)
{
//fopen関数は最も一般的
FILE *fp;
fp = fopen( "/data/data/jp.co.anaheim_eng/testfile0.txt", "w+" );
if( fp == NULL ) {
DebugLogInfo("File cannot open error.");
return 1;
}
fclose(fp);

//open関数でパーミッションを指定しない状態で実行
int fd;
fd = open("/data/data/jp.co.anaheim_eng/testfile1.txt", O_CREAT | O_RDWR);
if (fd == -1) {
DebugLogInfo("testfile1.txt File cannot open error.");
return 1;
}
close(fd);

//ここは敢えてパーミッションを666に設定している
fd = open("/data/data/jp.co.anaheim_eng/testfile2.txt", O_CREAT | O_RDWR, 0666);
if (fd == -1) {
DebugLogInfo("testfile2.txt File cannot open error.");
return 1;
}
close(fd);

return 0;
}

このソースをJavaから呼び出して見た結果は以下の通り。

エミュレータはこの結果になるが、ひょっとすれば実機なら変わるかも?ってことでAndroid 2.3.3搭載している開発標準端末であるNexus Sで実行してみた。結果は以下の通り。
#ちなみに私のNexus Sはroot化していませんので。


Skypeの脆弱性はパーミッションを意識しない状態というか、AndroidのNativeで作成されるパーミッションを調査しなかっただけなのだろう。解決方法は?というと、open関数であれば適切なパーミッションを付与させれば良い。その他の場合には自分でパーミッションを設定させる命令を追加すれば良いだけ。

#include <sys/stat.h>

//パーミッションとして660に設定した
if (chmod("/data/data/jp.co.anaheim_eng/testfile0.txt", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) != 0) {
DebugLogInfo("File cannot change chmod.");
return 1;
}

この処理を追加して実行した結果が以下の通りとなる。


<雑感>
Android NativeであるNDKを利用してファイル操作を行った場合には特にパーミッションを注意しなければならいと思う。因みにUbuntu上でfopenを利用した場合のパーミッションは644になっているので、666のAndroidはややどうかなぁって気はする。
デフォルトパーミッションはJavaと同様に660にして欲しい気もするのだが、最低でも664 or 644になっていることを望みます。

root化された端末では、パーミッションによるセキュリティ担保が出来るということは期待しない方が良いから暗号化等の配慮が必要にはなる。であるとするとJNIで666となるパーミッションの標準もこのままでも良いのかも?って気がしないでもないなぁ。(^^;

2011年3月17日木曜日

Ubuntu 10.10 に Nexus S と XOOM を接続する

東北関東大震災(東北地方太平洋沖地震)で被害にあわれた皆様方に心よりお見舞いを申し上げるとともに犠牲になられた方々、遺族の皆様にはお悔やみを申し上げます。

私も東京にいますので、地震発生直後はいつもの地震だなって思っていましたが次第に大きくなり本棚等が倒れそうになり必死で抑えるのが精一杯でした。最初はTwitterで地震コメントを呟いたのですが、途中からは本棚を抑えながらも大量の地震コメントが流れてきました。
この時こそネットワークで繋がっているっていいなぁって思った改めて実感しました。

まだまだ被害の全容や刻々と変化する情勢に予断を許せる状況ではありませんが、災害に悲観しているだけでは復興の役にも立たないのでポジティブに仕事をすることで、僅かながら社会貢献することにしたいと思っています。


<Ubuntu 10.10 on VMWare Workstation>
私の環境はUbuntu 10.10をWindows 7 Pro 64bitのVMWare Workstationで稼働させています。この環境にNexux Sを接続します。とはいえ、普通に接続すれば問題ないのですが、物忘れが多い私の備忘録として記載します。

1)環境の準備
  • Ubuntu 10.10
  • Nexus S

 これだけなんですが、VMWare WorkstationはWindows 7 64bitで稼働させています。VMWare Playerでも同様に稼働できると思います。Nexus Sを例にしていますが、取り敢えずAndroid端末ならなんでも良いです。
 Android端末はUSBデバッグをONにしておきましょう。(笑

2)情報収集
  • Ubuntu 10.10上のAndroid端末情報を取得する。
    $ sudo lsusb
    Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 001 Device 004: ID 18d1:4e22 Google Inc.
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    この結果からIDの隣である18d1がUSB Vendor IDになります。隣にある4e22は何だ?ってことになると思います。分かり難いですよね。詳しく見るには以下のコマンドを入力すると分かります。
    $ sudo udevadm info --query=all --name=/dev/bus/usb/001/004
    P: /devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
    N: bus/usb/001/004
    S: char/189:3
    E: UDEV_LOG=3
    E: DEVPATH=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
    E: SUBSYSTEM=usb
    E: DEVNAME=bus/usb/001/004
    E: ID_VENDOR=Samsung
    E: ID_VENDOR_ENC=Samsung
    E: ID_VENDOR_ID=18d1
    E: ID_MODEL=Nexus_S
    E: ID_MODEL_ENC=Nexus\x20S
    E: ID_MODEL_ID=4e22
    E: ID_REVISION=0227
    E: ID_SERIAL=Samsung_Nexus_S_xxxxxxxxxxxxxxxx
    E: ID_SERIAL_SHORT=xxxxxxxxxxxxxxxx
    E: ID_BUS=usb
    E: ID_USB_INTERFACES=:080650:ff4201:
    E: ID_MEDIA_PLAYER=google_nexus-s
    E: MAJOR=189
    E: MINOR=3
    E: DEVTYPE=usb_device
    E: DRIVER=usb
    E: PRODUCT=18d1/4e22/227
    E: TYPE=0/0/0
    E: BUSNUM=001
    E: DEVNUM=004
    E: DEVLINKS=/dev/char/189:3
    ID_MODELにNexus Sを記載されていますし、ID_VENDOR_IDには先の値が入っています。(x16桁は端末シリアル番号です。)

3)udevのルール編集と
  • 51-android.rulesを新規で作成します。
    $ sudo vi /etc/udev/rules.d/51-android.rules
    SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", OWNER="ユーザ名", GROUP="ユーザ名"
    上記の"18d1"がID_VENDOR_IDになります。Android機器が異なる場合にはベンダ毎に変わります。Nexusシリーズの場合、Googleが製造していないのでNexus Sの場合にはサムソンになるのですが、サムソンは"04e8"なので別IDを利用していることになります。

  • udevの再起動
    $ sudo restart udev
    これで設定自体は完了しています。

  • adbの再起動
    ここで、一旦Android端末をUSBから接続を外し、再度接続し直します。
    $ adb kill-server
    $ adb start-server
    $ adb devices
    List of devices attached
    emulator-5554 device
    端末シリアル番号 device
    これで完了です。



<追記>
2月下旬に発注していたMotorola XOOMが2011/3/15に到着しました。レポートは後日としますが、Windows 7 64bit上でVMWare Workstationで稼働していますUbuntu 10.10でNexus S同様に接続しました。
上記ど同様にlsusbコマンドで調査し下記設定で問題なく動作しています。
$ sudo vi /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="22b8", OWNER="ユーザ名", GROUP="ユーザ名"
Eclipse上のDDMSから画面キャプチャも問題なく出来るのですが、速度が遅いので
$ adb shell screencap -p /mnt/sdcard/capture.jpg
$ adb pull /mnt/sdcard/capture.jpg
で行う方がかなり速く取得できました。コマンド操作が面倒な方は通常通りで良いですが。(笑)

2011年3月10日木曜日

Android JNI で C++ を利用する

Android JNIでって話だとC言語サンプルはNDKにも付いてくるのだけど、C++となると情報が結構少ないので、備忘録として記載。

基本的に拡張子をcppにすることでコンパイルすることは出来ます。私のC++での開発経験はVisual C++(今はVisual Studioですよね)ではほとんど無い経験がありません。Borland Delphiを1.0から開発していたことが長かったので、C++はBorland C++ Builderだったのです。
#昨年はC++ Builderの講師の仕事もしていましたので・・・

何故こんな話をしているかというと、C++でclass定義というと「.h」にはクラス定義のみで、コンストラクタやデストラクタ、各メソッドは「.cpp」ファイルに記述していました。
#というか、勝手にテンプレートでそのように作られるんですね。

兎も角、「.h」「.cpp」のソースファイルを用意します。コンパイルするためには「Android.mk」を作成します。およそ以下のような感じになります。
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := 「JNIライブラリ名」
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
include $(BUILD_SHARED_LIBRARY)

ヘッダーファイルが無い場合には良いのですが、定義する場合には「LOCAL_C_INCLUDES」を記述しなければなりません。
Android.mkファイルの各パラメタの詳細については、Android NDKでJNIを使用してアプリを高速化するには3/3を参照してください。

とまぁ、これで普通は終わりなのですが、Android NDK r4以降でC++特有のSTL(標準テンプレートライブラリ)が利用できるようになりました。とは言っても、βとのことなのですが。STLが利用できるようになると、なにかと便利になるのでこれを利用しないでC++を利用する価値はありません。
手元にNDK r4が無いので分かりませんがr5以降(r5bも含む)には2つのSTLが同梱されています。ひとつはGNU libstdc++ STLとSTLportです。どちらが良いかは各自の判断に任せるとして、利用方法は以下の通り。
「Application.mk」を作成します。
APP_STL := stlport_static
#APP_STL := gnustl_static

2行目をコメント化(#の付いた行)しているので、この場合にはSTLportを静的ライブラリ組み込みしてコンパイルします。たったこの一行で終わりです。
サイト検索すると、過去のNDKではSTLportを実行するためにソースをダウンロードしてコンパイルしてって作業が必要だったそうなのですが、現在はこんなに簡単になっています。

コンパイルは良いけど、ソースを記述する際にSTLportのインクルードヘッダーファイルは何処にあるのかって話になる。場所は「android-ndk-r5b/sources/cxx-stl/stlport/stlport」がヘッダーになります。
Eclipseでコーディングする際には、プロジェクトプロパティの「C/C++ General」->「Path and Symbols」->「Includes」のC++に追加することになります。

因みにgnu libstdc++を利用する際は「android-ndk-r5b/sources/cxx-stl/gnu-libstdc++/include」ですね。

2011年3月8日火曜日

Motorola XOOM <途中経過>

Amazon.comのシステムを利用しているMotorola STOREですが、Standard Shippingを選択すると随分待たされてしまいました。

日本時間の2月26日午前中に予約を入れ、その時点での配達完了日程は3/3~3/8に。まぁStandard Shippingだとそんなものかなぁと思っていました。すると、夕刻には既に配達へのステータス変更になったので予定より早く到着するものと期待。

結果的にトラッキング番号は発行されましたが、到着前日で本日(3/8)に転送業者に到着しました。転送業者の検品でも問題がありませんでしたので無事、米国内は輸送されました。(笑)

日本に到着する予定はまだ不明ですが、来週末までには手元に届くものと思っています。


余談ですが、以下の取引経験からMotorola STOREも同じかなと推測したことが、思わぬ不安を招いたことになりました。

<私のAmazon.com取引経験>
Amazon.comでDVDとかを発注した場合ですが、2008年ぐらいまではStandardShippingを選択していても、予定(およそ2週間後~1ヶ月)よりも圧倒的に早く到着していました。
特に、在庫があれば発注からおよそ10日程度で手元に届いていたし、Standard Shippingでもトラッキングナンバーが発行されていました。
2010年ぐらいからAmazon.comの輸送が変更となり、国際輸送でのStandard Shippingではトラッキングナンバーは発行されなくなりました。
もちろん、輸送費用が高いオプションを選択すればこの限りではありません。

輸送日程も2010年からは10日程度から20日程度まで延びるので、確かに高価な輸送方法との差別化には成功しているようなのです。

2006年から利用していた私としては、うーん?って感じなのですが、Motorola STOREでも有効であることを今回体験しましたので、Amazon.comを利用したショップサイトでもStandard Shipping選択は到着日程が1ヶ月程度の余裕がある場合に限らないと、精神衛生上あまりよろしくないなぁと。

とはいえ、楽しい個人輸入ライフは辞められそうにありませんね。

2011年2月28日月曜日

Motorola XOOMを発注

TwitterのTLで@l_b__さんがMotorola XOOMを発注したとの内容を見て、思わず私もポチってしまいました。(笑)

Motorola STOREから発注を行いました。Android 3.0 (Honeycomb)搭載のXOOMですが、Bestbuyでは店頭のみの販売で2/24から開始しています。そもそも、Verizon Wirelessの端末は基本的にSIM形式では無くauと似た周波数ですがauとは若干異なるため、日本に輸入してもそのままでは利用することは出来ません。

#米国の通信業者では、AT&TまたはT-MobileならSIMをdocomo製・SBM製にすると動作する可能性があります。

今日の発表でauがMotorola XOOM WiFi版を販売することになったので、一般の人はこれを待って購入するのがベストというかこれしかありません。私の場合には、開発用テスト機と展示会デモ機としての役目もあり、どうしても機種を数多く購入するために○年縛りになることは避ける必要があるので海外端末に流れる傾向があります。

前置きは置いておいて、Motorola STOREですがAmazon.comが運営する販売サイトに載った独自サイトとして営業していました。この便利な点は、Amazon.comのアカウントがあれば同じまま利用できる点。配送も恐らくはAmazon.comを利用しているものと思われます。

発注を行うと、hostedbyamazon.comドメイン(amazon.comが取得したドメイン)から送信されるので、安心感もあります。ただ、海外から個人輸入する場合に関税が必要なものはAmazon.comは直接発送を行いません。
私の場合には、スピアネットさんを利用して転送していますが、オレゴン州にある転送サービスを利用すると州税が$0なので少しでも安価にすることが出来ます。今回、私の支払ったCA州税は$81.9です。
#オレゴン州はカリフォルニア州より北なので、輸送時間がやや長いです。金より時間を選択しています。(笑)

今回購入したのは、XOOM本体とPortfolio Case for MOTOROLA XOOMです。



ところで、関税が不要なものとしては、CD,DVD,Blu-rayなどのコンテンツ、光学機器、化粧品などです。詳しくはジェトロのサイトでって今探すと今年の1月で個人輸入のコンテンツが閉鎖していました。orz
個人輸入の場合には一般的に10万以下の少額輸入貨物になるので、税関サイトの少額輸入貨物の簡易税率が参考になります。

私はAmazon.comでBlu-ray版のエヴァンゲリヲン新劇場版 序1.11を購入しました。(笑) なにせ、価格は$15.49(私が購入した価格は$18.99でした)です。2.22が$22.99ですね。Blu-rayはアメリカと日本は同じリージョンコードなので便利です。
#2.22は日本で購入しました。なにせ早く手に入れたかったので。(汗

衣類とかでは、革製だと関税が掛かりますがそれ以外だと概ね関税は掛からないので輸出してくれるところが多いです。靴も関税が掛かるので基本的にはショップから日本へ直送することは無理です。
例えば、米国から日本へ製品を輸出する場合には、税関手続きが必要となり書類を作成しなければなりません。この書類を作成し輸送してくれる代行業が転送サービスと言われるものです。

個人輸入でのトラブルもつきものです。国民生活センターに解決困難な個人輸入代行に関するトラブルが記載されています。全てが個人責任ですので、物が足りないとか違うとか、最悪途中で盗まれて箱しか無いなんてこともあります。
因みに、Nexus Sを発注された方で盗難にあったBlogがあります。最終的には保証で新しい製品が到着したようですが、人気商品(iPadとかも輸送中の盗難事件がありました)は注意した方が良いです。

私は運良くいままでは何事も無く何度も輸入していますが、勧める訳ではありませんので独力でショップを探して発注することで、発注程度の英語力は身に付けて頂けばと思います。個人的にはAmazon.comぐらいで発注するのが割と安全性が高いとは思います。が、間違った製品とかは全て英語でのやり取りになることは覚悟してくださいね。

2011年2月19日土曜日

Windows XPでAndroid JNIをやってみたが、、、

結果からいうと、現段階では上手く動作していません。

どうも、Windows版のEclipse 3.6.1ですがコンソールが正しく受け付けてくれないことが原因で、ndk-buildコマンドへ辿りつけない。仕方が無いので、.batファイルで迂回を試みるも撃沈。.batファイルでcygwinのbashをログイン起動し、パイプでndk-buildを起動させようとしてもダメ。

.batファイル中に記述したパス名(/cygdrive/c/...)を受け付けないようだ。

ってことで、いろいろ実験してみたがWindows環境ではダメっぽい。Macは基本がUnixなので恐らくは問題ないのではないかって思っています。成功された方がいましたら、コメント頂けると幸いです。

Windows利用の方はVMWare PlayerでもダウンロードしてUbuntu 10.10をインストールする方法が良いかと。(笑)

2011年2月18日金曜日

Android JNI を Eclipse CDT でプロジェクト統合する
<ubuntu 10.10編 その2>

前回の<その1>ではどこのサイトでもAndroid SDKをインストールする解説と同じですが、最後の方は面倒になったので端折ってしまいました。まぁ、あまり細かく書いても初心者さんが見ることはあまりないのでは?って思っていますので。

私(だけなのかもしれません)が今まで作業した方法は、JNIのC部分を別プロジェクトとして作成し、コマンドラインからCコンパイル後、Javaに取り込んで連携させる方法でした。EclipseにCDTをインストールしても、エディタ程度にしか使えないのであまり意味が無いと思っていました。
久しぶりにJNIを本気で取り組むことになり、何か方法が無いかと思い調査を繰り返してたどり着いたので、備忘録的に記載します。因みに参考としましたのが、CDT AndroidというYouTube動画(英語)です。そのままではNDKバージョン、Eclipseバージョン等が異なり環境もCygwinのWindows環境と違います。

では、今回はJNIのJava環境構築とEclipse CDT連携部分です。前回では環境変数として[ANDROID_NDK_ROOT]をexportしていますが、必須なのかの組み合わせテストまでは行っていないので、やや正確性に欠けるかもしれません。

#当初はexportしないで作業していましたが、設定ミス等がありどれがどれに影響したかまでは未調査です。スミマセン。
#まぁ個人的な備忘録のつもりですので。


<前提>
  • 当資料で利用するサンプルは、NDKに同梱されているHello_Jniです。格納されている場所はNDK展開ディレクトリを基本とし、[samples]->[hello-jni]が格納されています。
  • Ubuntu10.10のEclipseは日本語化していません。Ubuntu 10.04では日本語化を行ったのですが、面倒になったのと日本語化するとダメかも?っていう記述を見た記憶があるので、そのままにしています。

<Androidプロジェクト作成>
  • 最初は元となるAndroidプロジェクトを作成しなければ話になりません。メニューバーの[File]->[New]->[Other]を選択すると、下図の画面が表示されます。この中でAndroidProjectを選択します。
  • Androidプロジェクトの設定画面が表示されます。Javaのみならここで設定するだけなんですよねぇ。
  • 今回はNDKサンプルプロジェクトを選択します。下図のように選択して[Finish]ボタンを押します。因みに下図ではTargetNameがAndroid 2.2としていますが、これは単に2.2以降しか開発しないつもりな私の設定です。
  • 取り込みができれば下図のようにProjectExplorerに表示されます。
  • この時点では、単にJavaプロジェクトを生成しただけです。Propertiesを見るとJavaの設定しか存在しません。

<AndroidプロジェクトのC/C++プロジェクト化>
  • 作業対象のJavaプロジェクトを選択して右クリックします。下図のように[New]->[Other]を選択します。
    ※このメニュー中にConvert to a C/C++ Projectを直接選択してもいいです。(笑)
  • 下図の画面中からConvert to a C/C++ Projectを選択し[Next]ボタンを押下。
  • ここの設定画面では、HelloJNIがCで作成されているので、[C Project]を選択しています。次に[Project type]では[Makefile project]を選択し[Toolchain]はそのまま[Other Toolchain]とします。これでC/C++ Project化は終了です。
    というか、この辺りの設定を自分で全て行うことで出来るって意味なんですよねぇ。
  • 念のために、ProjectのPropertiesを見てみます。ちゃんとC/C++のカテゴリが追加されていますよね。

<C/C++プロジェクトのソース設定>
  • Cのビルドに必要なディレクトリを追加します。下図ではプロジェクト選択後、右クリックにて[New]->[Folder]を選択しています。作業し易い方法で構いません。
  • 追加するディレクトリ名は[libs]と[obj]です。下図ではlibsを追加しようとしている状態です。
  • プロジェクトプロパティを変更します。まず最初はコンパイルを行うための[Include]を変更しなければなりません。標準ではUbuntuのgccで必要なファイルが自動設定されています。
    変更場所は、[C/C++ General]->[Paths and Synbols]で最初は[Includes]となります。
  • [Languages]の[Assembly][GNU C][GNU C++]に設定されている内容を全て削除を行います。Shiftキーで複数選択も出来ますが、それほど多く無いので簡単に出来ますね。今回はCのみなのでアセンブラやC++は変更しなくても良いのでしょうが、まぁ勢いです。(笑
  • 全てが空になったら、上記の[Add...]ボタンを押下します。ここで[File system...]ボタンを押下してディレクトリを選択します。
  • NDKのIncludeファイルディレクトリを選択します。下図のように、NDKを展開したディレクトリの[platforms]->[ビルド選択したAndroid OSのAPI Level]->[arch-arm]->[usr]->[include]です。
  • 選択終了すると以下のように、チェックボックスも選択して[OK]ボタンを押下しておきます。
  • 次に[Source Location]の設定を変更します。初期はプロジェクト直下になっているので、本来の位置である[jni]フォルダにしなければなりません。空に出来ないので、[Add Folder...]ボタンでプロジェクト配下の[jni]フォルダを選択し、自動設定された[/HelloJni]を削除します。
  • 最後に[Output Location]です。ここでは、出力結果をどこにするのかを指定しておきます。ここでは、追加した2つのディレクトリである[libs][obj]を追加し、自動設定された[/HelloJni]を削除します。下図は完了した状態です。
  • 変更箇所を適用させるために[Apply]ボタンを押します。するとインクルードパスを変更しているためにリビルドするかを聞いてきますが、ビルド設定が完了出来ていないので[No]にしています。
  • ここまでで、ソースの設定は終了。次はビルド設定になります。
<C/C++プロジェクトのビルド設定>
  • プロジェクトプロパティの[C/C++ Build]を変更します。プロパティを表示し下図のように[C/C++ Build]を表示。その中にある[Builder Settings]の[Use default Build Command]のチェックをオフにし、[Build command]にフルパスでNDKでのビルドコマンドである[ndk-build]を設定します。
    ※フルパス以外ではコンパイルできませんので注意してください。
  • 振る舞いを変更します。下図のように、[Behaiviour]タブの[Buid(incremental build)]欄には、初期値として[all]が記述されていますが、ndk-buildのオプションである[-B]を入れます。[Clean]ですが、ndk-buildはclean動作が不安定との情報もあったのでチェックをオフにしました。
  • 次に左にある[Environment]を選択します。下図の中に<その1>で設定されたパスを通したいので、[Add...]ボタンを押します。
  • 追加用の画面です。[Name]に「PATH」を入力し、値には[Variables]ボタンを押します。
  • 選択画面の中で、PATHを選択し[OK]ボタンを押します。
  • 先ほどの入力画面に戻ります。下図の通り直接入力しても同じですね。(笑)
    [OK]ボタンで追加終了です。
  • 追加完了した[Environment]です。お疲れ様でした。これで無事設定完了となります。
<最終確認>
  • 全ての設定が問題なく行われた場合、Build Projectを行って見ます。下図のように、ナビゲーターで確認していますが、[bin]フォルダには.apkファイルが作成され、[libs][obj]には.soファイルが作成されているのが確認できます。
    コンソールにはC-Buildとしてコンパイルされていることが確認出来ますね。

お疲れ様でした。
これで、JavaやCソースを修正した後に一括ビルド後にエミュレータで確認することが出来るようになります。