BacklogDroidをGooglePlayに公開しました

自分用に作って使っていた、Android用のbacklogのクライアントアプリケーションBacklogDroid
ですが、せっかくなのでGooglePlayに公開しみました。
もしよければご利用ください。もちろん無料です。

https://play.google.com/store/apps/details?id=jp.ceed.android.backlog

GoogleAnalyticsのEasyTrackerでパスを個別に指定する

先日、あるアプリにGoogleAnalyticsSDKを入れようとしたら、SDKにV2が出ていたので早速使ってみました。まだ少ししか触ってないのですが、あまり情報が出回っていないようなので少し書いておこうと思います。

まず気になったのが、trackEvent, trackView などのメソッドが軒並み deprecated になっているという点です。かわりに、sendEvent, sendView などが追加されていました。まあこの辺はよしとして。

つぎに目を引いたのは、EasyTracker というクラスです。Easyっていい響きですね。早速これを使ってみます。
といっても使い方はここ↓に書いてあるとおりで簡単なのですが。
https://developers.google.com/analytics/devguides/collection/android/v2/

ただ、ちょっと気になるのが、上記のドキュメントのとおり実装すると、トラッキングされる各アクティビティのURLが、アクティビティのクラスの完全修飾名(いわゆるClass#getCanonicalName で返されるString値)になってしまうという点です。ちょっと嫌ですね。
でEasyTrackerのソースを眺めてみたところ(といってもJadClipseですが)ありました、よさげなやり方が。
上記のドキュメントにも出てくる設定ファイルの中(というかリソースファイルの中ならどこでも良いのですが)に、下記のように、Activityのクラスの完全修飾名をキーにしたstring リソースを定義してやります。

	<string name="my.package.name.MainActivity">/Main</string>
	<string name="my.package.name.HogeActivity">/Hoge</string>
	<string name="my.package.name.FooActivity">/Foo</string>

このように定義しておいてやると、EasyTrackerが勝手に、context#getString(id) して対象のURLを書き換えて出力してくれます。
よしよし。

ContentProviderを自動で実装する

AndroidのContentProviderを実装するのって非常に面倒ですよね。
いつも実装するたびに、「何でこんなめんどくさいんだー!」と愚痴りたくなるのですが、これを自動生成する方法があったので書いておこうと覆います。

EclipseのプラグインでMOTODEV Studioというのがあるのですがこれを利用します。
もともとはAndroid開発用のプラグインのようなのですが、この中にSQLite関係のクラスを自動生成してくれる機能があって、それを利用します。
まずは、Eclipse MarketPlaceでMOTODEV Studioで検索してインストールします。(ユーザー登録を求められたと思います)

次に必要なテーブル定義をしたSQLiteのDBファイルをSQLite用のクライアントツールなどで作成します。(僕は、TkSqliteというのを使っています。)

次に、EclipseのパースペクティブをMOTODEV Databaseに切り替えて、MOTODEV DatabaseExplorerビューの中の、「Create Database Management Classes」というアイコンをクリックします。
すると、設定ダイアログが開きますので、DataBase File の箇所に先ほど作成しておいたSQLiteファイルを指定します。
あとは、必要な箇所を入力して「完了」をクリックすれば、先ほどのテーブル定義に対応したSQLiteOpenHelperクラスとContentProviderクラスを一瞬で生成してくれます。
また、先ほど指定したSQLiteファイルはassets配下にコピーされていて、生成されたSQLiteOpenHelperクラスを見ると、コンストラクターの中で上記のSQLiteファイルを適切な位置、(/data/data/packagename/databases/)にコピーする処理が書かれています。
つまり、DBの初期化時にDBファイルごとコピーしてしまうのですね。なので、必要なレコードを最初からインサートしておいておく、といったことも可能です。

という感じに非常にらくちんな機能なのですが、一つだけ残念な点があって、それは、これで生成されるコンテンツプロバイダーは、各テーブルごとに別々のコンテンツプロバイダーとして生成される、っと言うことです。つまり、ひとつのDBで3つのテーブルがある場合コンテンツプロバイダーも3つになってしまいます。
これで何が問題かというと、OpenHelperも個別になってしまうので、場合によっては、Database locked などのExceptionが発生してしまう可能性があるという点です。
これについては、ちょっと長くなってしまうので別の機会に書きたいと思います。

ちなみに、上記の機能以外にも、スニペットというビューがあって、一般的によく使用するようなコードがスニペットになって並んでいます。エディターにドラッグすることでコードを挿入できるので、こちらも使い方によっては重宝するかもしれないです。(自分は使ってないですが)

GalaxyNexusでメニューボタンが出ないケース

毎度のAndroidの不具合ネタですが、、、、
GalaxyNexusでメニューボタンが表示されいという状況に陥ったので書いておこうと思います。
ご存知のとおりGalaxyNexusにはハードのメニューボタンがなく、Activityにオプションメニューが設定されている場合のみ、ディスプレイのボタン領域にメニューボタンが表示されます。
今までであれば、オプションメニューを設定しておけば普通にメニューボタンが表示されていたのですが、今回新しいプロジェクトで、メニューボタンが表示されないという状況になりました。
で、調べてみたところ、どうやら、targetSdkVersionを14以上に設定しているとこのような状況になるようです。
どうも、ADT20あたりからは、新規プロジェクトウィザードでプロジェクトを作成するときに、ビルドターゲットを8以上に設定していると、勝手に下記のように

	<uses-sdk
		android:minSdkVersion="7"
		android:targetSdkVersion="15" />

targeSdkVersionが15に設定されてしまうようです。
おそらく、android compatibility package を使用する関係だと思うのですが、、、
で、仕方がないので、

	<uses-sdk
		android:minSdkVersion="8"
		android:targetSdkVersion="8" />

としてやることで解決できました。
よくわからない仕様ですね…

androidのshapeのバグ

androidのshapeに関して、APIレベル10以下で左右が逆になるバグがあるのですが、これに関して日本語の情報があまり見当たらなかったので書いておこうと思います。
例えば下記

のような形を描きたい時に、普通に考えれば下のようなXMLを書くと思います。

<shape android:shape="rectangle">
<corners
  android:topLeftRadius="10dp"
  android:topRightRadius="0.1dp"
  android:bottomLeftRadius="10dp"
  android:bottomRightRadius="0.1dp"/>
</shape>

ところが、これを実行すると、APIレベル11(Android3.0)以上では期待通り上のような形が描画されるのですが、APIレベル10以下ではなぜか下記のような形に描画がされます。

あれれれ?な感じですが…
これは、APIレベル10以下のバグで、下辺の左右の指定が逆に扱われてしまうのです。なんともお粗末のバグですが…
で、仕方なく下辺の左右の指定を逆にして

<shape android:shape="rectangle">
<corners
  android:topLeftRadius="10dp"
  android:topRightRadius="0.1dp"
  android:bottomLeftRadius="0.1dp"
  android:bottomRightRadius="10dp"/>
</shape>

こんな風に書くとAPIレベル10以下で正常になるのですが、当然APIレベル11(Android3.0)以上の方がおかしなことになります。
でどうするかというと、drawable-v11 というディレクトリを、res 配下に配置してそれぞれ使い分けられるようにします。
具体的にはdrawable-v11に上のXMLを、drawableに下のXMLを置いてあげると、それぞれのXMLが適用されるので、どちらも丸く収まるという感じです。
ちなみに、0.1dpとしているのは、0dpと指定するとAPIレベル7などで、radiusが効かなくなってしまうためやむを得ず微小なradiusを指定しているものです。
どうにも残念な仕様ですね…

GalaxyNexusのUSBドライバー

やっとドコモのAndroid4.0端末が発売になりました。で、早速入手してきました。
で、早速実機検証をと思ったのですが、なかなかUSBドライバーが見つからなくて苦労しました。
サムスンのサイトにもまだ出ていないみたいですが、下記のサイトで見つけました。
http://androidforums.com/galaxy-nexus-all-things-root/451898-galaxy-nexus-adb-usb-driver.html
落としてきてインストールしてみると、無事デバッグできました。
きっと同じ苦労をする人がいると思うので載せておこうと思います。

android:tileMode=”repeat”が効かないケース

例えばWebでの背景画像のように、画像を繰り返しで配置することで表現するような背景を使いたい場合に、bitmapとしてdrawableを作ると実現できる。
こんな感じ

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
	android:tileMode="repeat"
	android:src="@drawable/some_drawable" />

ところが、このリソースをリストビューなどの各アイテムの背景に指定したい場合に、レイアウトのXMLの中で、android:background=””として指定した場合には期待通りの表示になるのですが、adapter#getView()の中で動的に設定した場合に、繰り返しにならずに、1つの画像(ここではsome_drawable)がViewの大きさいっぱいに引き伸ばされたようになる場合があるようです。
そのViewの高さが確定できていないせいなのか?
また、一度上記のような引き伸ばされた状態の表示がおきると、その後、別のActivityで本来正常に表示されていたケースでも、(同じdrawableが背景に指定されている場合)、リストビューのケースと同様に引き伸ばされた表示になってしまうようです。
drawableのリソースってキャッシュされているのかな、、、

もう少し調査してみたいです、、、

Data exceeds UNCOMPRESS_DATA_MAX

AssetManager#open() でasset内のファイルを開く場合、1.6だと1Mb以上のファイルを開こうとすると

Data exceeds UNCOMPRESS_DATA_MAX 1234567 vs 10488567 

見たいなエラーが出て開けなくて、IO Exception が発生するみたいです。
2.2あたりでは起きないようなので、テストの際に注意が必要かもです。

AndroidManifest.xml内で参照が使えないケース

先日苦労した点があったので覚え書を。
ManifestのActivity要素内で、intent-filterを定義する際に、data 要素のandroid:host, android:name, android:path, などを@string/xxxx という感じで参照で書いていたところ、そのアクションが呼ばれた時に一部端末(IS03)で、acitivity not found Exceptionが発生した。
っていうか、Activityがあったから受け取ったのでは?と思うのですが、、、
で、参照をやめて直接書くようにしたら正常に動作した。
正確な原因は不明ですがどうもIS03では参照を正しく解決できない模様です。

SoftInputの処理

前回、Androidのキーボードのモードオプション、でキーボードのモードについて書きましたが、このエンターボタンが押された時の処理で嵌ったことがあったので覚書を。
キーボードのエンターボタンが押された時の処理を、EditText.OnEditorAction 等で拾う場合、実際の必要な処理を行う前に、

InputMethodManager#hideSoftInputFromWindw();

を呼んで明示的にキーボードを非表示にしておかないと、例えば、そこから遷移した次の画面で、Viewが更新されないとか、dialog.show(); したのにダイアログが画面に表示されない、などの問題が起きるよようです。
どうやら、明示的にキーボードを消してやらないと、Activityのレイアウトがフォーカスを持っていないようだ。(次の画面に遷移すればもちろんキーボードはすでに消えているのだけど、内部的にはまだキーボードにフォーカスがあるのか????)

詳細未確認なので、認識違いだったらつっこみ入れてください。

getting health insurance in new york buy clomid online UK major health insurance companies buy levitra uk online what are wells fargo hours buy finasteride affordable health insurance for children accutane no prescription medical center of trinity viagra online uten resept midwestern university wellness center dapoxetine top individual health insurance companies viagra ireland