かなりはまったのでメモ。
Android SDK r16時点での情報です。
前提として、SHARP製Android携帯固有の機能を使うには、SHARPが公開しているSDKを使う必要がある。
これはいわゆるAddOnの形で提供されてるので、固有APIを使うアプリは、Build TargetをSHARPのAddOnに設定する必要がある。platform x.xx等を選んではいけない。
普通のアプリならこれで問題無いのだが、AdMobを使おうとすると事情は変わってくる。
SHARPで現在公開されているAddOnは、ベースのAndroidが2.3.3のもの。
よって、使えるAPIやManifestファイルに記述できるオプションなども、2.3.3までの物のみになる。
ところが、AdMobの最新バージョンは、
http://code.google.com/intl/ja/mobile/ads/docs/android/fundamentals.html
で指示されているように、Manifestファイル中に
<activity android:name="com.google.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
という記述をしなくてはならない。
このandroid:configChangesの内容が問題で、smallestScreenSizeなどは2.3.3の段階ではサポートされていないので、当然ビルドエラーになってしまう。
ここでさっそくぐぐってみたわけだが、SHARPの公式フォーラムで次のようなやりとりを発見した。
https://sh-dev.sharp.co.jp/android/modules/d3forum/index.php?topic_id=121
この人の場合は、Build TargetをGoogle APIsにしたままSHARP固有のAPIを使えないか、というものだが、私の問題と本質は同じである。
私の場合は、Build Targetをplatform 4.xxにして、なおかつSHARP固有のAPIを使いたいわけだ。
SHARPの公式回答として、ビルドパスにAddOn内の*.jarをユーザーライブラリの形で指定しろ、という解決策が提示されており、質問者もそれで解決したとある。
さて、実際に上記の方法を試してみると、あっさりと期待は裏切られる。
class resolved by unexpected dexというワーニングを吐いた後、class ref in pre-verified class resolved to unexpected implementationなるエラーでアプリが強制終了してしまう。
結論から言えば、apkファイルの中に既にSHARP提供のhardware.jarが存在するのに、実機のシステム内にもhardware.jarの中身に相当するものが存在するので、実行時にどちらで定義されてるクラスを呼び出せば良いか判別できずにエラーになっていると思われる。
じゃあManifestファイルでuses-libraryしなけりゃいいんじゃねって思って、<uses-library android:name=”jp.co.sharp.android.hardware” />を削ってみた。
結果、エラーは出なくなったが、まあ当然というか、実際には固有の機能が動作しない。
詳しく言えば、フラッシュライトをONに設定しても、全く光らない。
公開されてるhardware.jarの中身は恐らく定義だけなのだろう。
ここでさらにネットの海へダイブしてみると、次のようなやりとりを発見した。
http://www.mailinglistarchive.com/html/android-group-japan@googlegroups.com/2011-10/msg00427.html
質問者は、私と全く同じケースで困っており、どうもAndroid SDK r14あたりから発生しだした現象らしい。
それに対するアドバイスが「対処方法は僕のTwitterのどこかにあるよ!」とかいうかなりフリーダムなものなのだが、がんばって回答者のTLを見まくったところ、「SDKをr12にダウングレードしてね!」というものだった。
しかし、そこに提示されたリンクは既に死亡しており、そもそもr12に戻せたとしてもAndroid 4.xxに対応しなくなるので、本末転倒である。
仕方ないので、特定のライブラリをapkにパッケージングしないような方法は無いかと色々検索してみたのだが、結局それっぽいものは見つからず。
結局、まる1日費やして出した対処方法は以下の通り。
/add-ons内にあるSHARPのAddOnフォルダを別名でコピーする。仮にmy_addonという名前とする。
/add-ons/my_addon/manifest.iniというのがあるので、これを編集する。
api=から始まる行があるので、その行をapi=15にする。15は現時点での最新のAPIレベルになる。
判別しやすいように、name=から始まる行も、適当にname=my_addonなどとすれば良いと思う。
後は、この自作のAddOnをBuild Targetに指定すれば目的達成である。
Google APIsも使いたい場合は、上で指定したAPIレベルのGoogle APIs AddOn内のlibsフォルダ内にある*.jarファイルを自作AddOn内のlibsフォルダ内に全てコピーして、manifest.ini内のlibraries=から始まる行と、その下のほうにある、パッケージ名=jarファイル名の羅列を適切に記述すれば良い。
最終的に私が編集したmanifest.iniは以下のようになった。
# SDK Add-on Manifest # File encoding is UTF-8 name=my_addon vendor=S.T. description=My AddOn # version of the Android platform on which this add-on is built. api=15 # default skin skin=QHD960x540 # revision of the add-on revision=1 # list of libraries, separated by a semi-colon. # libraries=com.example.android.platform_library libraries=jp.co.sharp.android.hardware;jp.co.sharp.android.io.obex;jp.co.sharp.android.io.irrc;jp.co.sharp.android.stereo3dlcd;com.google.android.maps;com.android.future.usb.accessory;com.google.android.media.effects # details for each library # com.example.android.platform_library=platform_library.jar;Sample optional plaform library jp.co.sharp.android.hardware=hardware.jar; jp.co.sharp.android.io.obex=obex.jar; jp.co.sharp.android.io.irrc=irrc.jar; jp.co.sharp.android.stereo3dlcd=stereo3dlcd.jar; com.google.android.maps=maps.jar;API for Google Maps com.android.future.usb.accessory=usb.jar;API for USB Accessories com.google.android.media.effects=effects.jar;Collection of video effects # USB Vendor ID # This 16-bit integer allows adb to detect new devices, by extending the list # of USB Vendor IDs it knows. After installing an add-on the command # 'android update' adb' must be run to update a file that adb reads during # start-up. #usb-vendor=0x0000 usb-vendor=0x0000
以上だが、これはあくまでAPIを使いたいというだけの目的なので、このAddOnで作成したエミュレータ内でMap系のAPI等を使うと、恐らくエラーになると思われる。
他に良い方法をご存じの方がおられたら、ぜひご一報下さい。
ちょうど今、3D表示と Google MapView を両立させようとおもってたところなんだが、解決策はまさに、これなんだろうな、とおもってうきうき挑戦していたのだが、うまく行かない・・・orz
上に書いてある要領で add-ons の中にある sharp_addon_3_for_API8 ってのをコピペして、 manifest.ini の name, vendor, description を編集し、 libraries とその details に addon_google_apis_google_inc_8 のそれを追加したんだ。
それで Eclipse を起動しなおして 目的のプロジェクトの Project Build Target を変更しようとすると、確かに 新たに1行選択肢が増えているのだが、悲しいことに、それは以前からあった sharp_addon SHARP Corporation 2.2 API8 ってのが、もう1行増えているだけなのだよ。つまり、アニメで言うところの ニセ主人公が増えた状態。(しかも、視聴者にも全く区別がつかないというダメアクセシビリティ状態。)
念のため、コマンドラインから
>android update adb
>android kill-server
>android start-server
とやってみたけどおんなじ結果。
>android list target
とやって、コマンドラインから見ても eclipse で見たのと同じで、まったく同じ target が2つになっている。
なにかやっていないことってのがあるのかな・・・、コンパイルみたいな・・・。思い当たるところ、内科医?
いろいろやっていて気づいたのだが、編集したはずの my_addon が何者かにより元の内容に上書き修正されている・・・。
my_addon の libs を GoogleMaps の奴のみにして同じことをやると、今度は GoogleMaps の target に1つ同じものが増殖する・・・。
add-ons 等を管理するサービスが、libs の内容を判断し manifest.ini を復元してくれているのだろうか?
SDK-Manager 経由で third-party addons を file://ローカル からダウンロードするように細工しようと考えたが、そのためにはローカルに addon.xml を自作しなくてはならず、その内容を他のリポジトリを参考に作成しようと閲覧すると、ハッシュとか、いろいろなパラメータが書き込まれていることに気が付き、その段階で力尽きた。
なにかヒントを思いついたら助けてください。
じゃあきっと執筆当時からまたSDKの実装が変わったんだろうね。何も検証してないので分からんす。
おぉ!?
別の場所で手動編集後、 manifest.ini のアクセス権を強制的に書込み禁止にしてからadd-ons にぶち込んだら、まんまと上書きできねぇでやんのwwww まだコンパイルとかしてないからうまく行くか不明だけど、少なくとも、一覧に出すことは成功した。
おおそれはなによりですね
残念・・・。いろいろな例外が出て、結局 解決しなかった。そもそも MapView は、Google の規約がデリケートなので、イレギュラーな方法で使ったときに後が怖いから、もうあきらめることにするよ。
そんなこともあろうかと、2種類の作戦を用意しておいたんだ。
1つは、国土地理院のタイル画像を表示するライブラリをつくる作戦。けど、これは時間がかかるから後回し。いちおう、すでに国土地理院に利用申請の手紙を出して、手続きが進んでいるところ。
もう1つは、3D表示させるアクティビティは、地図表示するアクティビティと、異なるパッケージにして、intent を使ってあたかも1つのアプリのように振舞わせる作戦。遷移時間が気になるところだが、これが考え方として、正しいんだとおもう。実は3D表示させるパッケージはもう半分できたも同然の状態なんじゃよ?
そうか・・・Googleマップのライブラリを直接libに入れるのはやったのかな? これが一応シャープの公式回答だけど。
eマップのライブラリを直接libに入れるってのは、
https://sh-dev.sharp.co.jp/android/modules/d3forum/index.php?post_id=276
これ?うまくいかない・・・
やっぱうまくいかないよな、シャープは自信満々に答えてるけど。
昔のバージョンだとうまくいったのかもな。
かもね