Androidマーケットアプリ(version 3.1.5)データぶっ壊し方法

(追記 @jfssoさんありがとうございます)
Androidマーケットアプリのアプリ一覧回復方法 - 無頼な代表取締役エンジニア日記 に示した情報もあわせてご確認ください。

AndroidマーケットがHoneycombっぽい(Ice Cream Sandwichっぽい)新アプリにバージョンアップしている方も増えてきたかと思います。このアプリは前のものに比べて重くなったなと感じている方も多いと思うのですが、それ以前の問題で100%再現可能なデータぶっ壊しが出来るバグがあるようです。

少なくともドコモのGalaxy S (SC-02B)で、マーケット ver.3.1.5 では100%再現できる手順を特定しました。

すでにAndroidのissue tracker には登録済みです。
ログイン - Google アカウント

日本語でも手順書いておきますね。設定のアプリケーションからたどった先でアプリの管理データをクリアできる端末なら、壊れてもクリアして元の状態に戻すことは可能です。逆に言うと、そういう端末以外ではやらない方が良いかと。

(追記:@zaki50さんコメントありがとうございます)
これで壊れるのはマーケットアプリ内でのインストールしたアプリ一覧の情報です。インストールしたアプリが管理するデータが壊れるわけではありません。

また、マーケットアプリが認識しなくなったアプリは、更新されてもその更新が通知されなくなっているように見えます。

前準備

アプリの更新通知が通知バーに表示されている状態にしてください。

再現手順

  1. マーケットアプリを起動する
  2. 適当にアプリ検索する
  3. 検索されたアプリを一つ選んで開く
  4. ホームボタンでホーム画面に戻る
  5. 通知バーを開いて、アプリの更新を選択する

これだけです。
期待される動作は更新されるアプリ一覧が出てくることですが、マーケット初回起動時に出る確認画面が出てきてしまいます。

その確認画面で承諾をした後、マイアプリ一覧を見ると今までダウンロードしたアプリのほとんどがリストから消えてます。なんということでしょう。

他の端末でも同様に問題が再現できるか、追試いただけると幸いです。あと、issue tracker で重大なバグだと認識させるためのコメント追記なども行なっていただけると助かります。

(追記: @androidzaurusさんありがとうございます)
再現確認をお手伝いいただける方のご参考に。プリインアプリ(マップなど)のアップデートをアンインストールしていただけると、アップデート通知がある状態を簡単に作ることが可能です。

振り返り(KPT)

最後に、今回のABC 2011 Summerでの発表についての振り返りをKPT(Keep-Problem-Try)法でまとめます。

Keep

  • 発表する場にどんどん出て行く。
  • API仕様書を読んで終わらずにコードを書く。

Problem

  • 資料に画像が足りない(見せられるサンプルアプリを早めに用意出来なかった)。
  • ABC 前に長期間blogが放置状態だった(Google I/O 2011 報告も出来ていない)。

Try

  • 発表の前にしっかりしたアプリを作って、資料にも反映する。
  • 毎日は無理だとしても、もっと頻繁にblogを更新する。

それぞれの資料についての補足

Enterprise

3.0から追加されたパスワードに対するポリシー強化は、様々なデスクトップPCで実現されているよくあるものが追加されてます。

しかし、これは使い方を間違えると(極端に厳しいポリシーにすると)、普通の人が記憶出来る限界を越えてしまって、パスワードを紙にメモしておくような使い方をされてしまうので、バランスをよく考えてシステム設計をしなければなりません。*1

また、Device Administration は基本的にはフレームワークが提供されているだけなので、それを使って、ポリシーに違反したときにどういう制限をかけるかについては(端末をロックする、データを消去するなど含む)、あくまでも管理アプリケーション開発者に委ねられていることを注意しないといけません。

制限が緩すぎてもいけないし、厳しすぎてもいけない、抜け道があってもいけない。アプリやシステムの全体設計をユーザビリティも確保しつつしっかりと行うこと、穴が無いように実装することがともに重要です。

MTP

サンプルコードをgithub にて公開しております(au版 XOOMとiPhone4を接続して動作確認済みです)。

GitHub - ynakanishi/Honeycomb-MTP-sample: Do slide show JPEG photos in a digital camera

サンプルコードは、スライドで示したコード断片と同じような手順ではありますが、注意として示した「UIスレッドでMTPオブジェクト取得するな」をちゃんと実践するようにしてあります(AsyncTaskを用いてバックグラウンド処理にてMTPオブジェクト処理を実施)。

このアプリでやっていることは以下のことだけです。

  • MTP対応デバイスが接続されたら、アプリを起動する
  • インテントからUSBデバイスを取得して、MTP処理の下準備を行う
  • MTPデバイスからのオブジェクト取得処理をAsyncTaskに投げる
  • オブジェクトを探索し、JPEG画像オブジェクトが見つかったらBitmapを生成した後、UIスレッドに表示処理を依頼する。

これをベースに少しいじれば、サムネイル一覧表示や、選択してからの全体画像表示、ファイルの取得なども作成できるかと思います。

あと、HoneycombアプリなのでFragmentを申し訳程度に使っています :-)

資料でも少しだけ触れていますが、APIによる支援は減りますが、JPEG画像以外のファイルも取り扱うことが可能です。動画対応デジカメと接続して、タブレットの大画面で動画再生を行うといったアプリも書けるかもしれません。

*1:ぶっちゃけ、極端に厳しいセキュリティポリシーの会社とか勤めたく無いですよね:-P

Honeycomb API 解説担当分スライド

SlideShareのサイトに私の担当分のEnterpriseとMTPの資料をアップロードしました。API仕様そのものについてはドキュメントを見ればそれほど理解は難しくないパート担当だったこともあり、使う上で気を付けないといけないところについて示すような資料となることを意図して作成しております。

Enterprise (3.0 update feature)

Honeycomb 3.0 Device Admin 解説

MTP (3.1 brand new feature)

Honeycomb 3.1 MTP 解説

震災とそれに伴う計画停電、見過ごされがちな三次被害

まだ少しの間は顕在化しないのですが、首都圏で非正規雇用(アルバイト、派遣社員)などで時給や日給で働いている方々の収入に今月末あたりから大きなダメージが行くことになるでしょう。元々そういった方々の収入は少ないことが多く、その収入減少の影響は相対的に大きいものとなります。

正社員のように年次有給休暇がある方々については、年休が減るだけで、短期的には収入に大きく影響しないことが多いだろうと思いますが。ただし、長期的にはしばらく予想される景気低迷の影響は避けられないので、いずれボディブローが効いてくることになるとは思います。

とはいえ、被災地の方がもっと大変なのでそちらが最優先となるのはいたしかたない。

かくいう弊社もまだ立ち上げたばかりの会社、つまりは零細企業です。もろに景気の影響を受けることが容易に予想されます。元々起業するときに、2〜3年は無収入でも継続していける前提でしたので、それほど大きな問題ではありませんが。

それはさておき、何が言いたいかというと、しばらくマンパワーに余裕が出来るのではないかと思いますので、弊社へのお仕事の話は大歓迎です。

子ども手当分の予算を、東北地方太平洋沖地震被災者支援の予算に回せないか

幸か不幸か、国会での予算審議が滞り、子ども手当などを含めた予算の関連法案が採決されていません。この予算分、地震被災者の支援金に回すことは出来ないでしょうか?

地震の被害はそれを回復するだけでなく、その間をつなぐ仮設住宅などを含めて非常にお金がかかります。緊急度の低い予算を組み替えて、被災者への支援に使う方が社会全体の利益になるのではないでしょうか。その緊急度の低い予算の一つは子ども手当だと思います。他にも不要不急の予算はあるでしょうが、まずは手をつけやすそうな子ども手当を停止することで、費用面での対応は加速できるのではないかと思います。

Android 2.3.3 でのNFCの注意点

Nexus SがAPI Level 10の2.3.3にアップデートされたので、実機のNFC機能について調べてみたところ、いくつか落とし穴があったのでそれをメモとして記します。

ACTION_TAG_DISCOVERED は優先度が低く、届かない場合がある

公式のAPIリファレンス (NfcAdapter  |  Android Developers)に以下の記載があるように、先に ACTION_NDEF_DISCOVERED か ACTION_TECH_DISCOVERED のintentに反応するアプリが存在する場合には、ACTION_TAG_DISCOVERED のintentは発生しません。

public static final String ACTION_TAG_DISCOVERED

Since: API Level 9
Intent to start an activity when a tag is discovered.
This intent will not be started when a tag is discovered if any activities respond to ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED for the current tag.
Constant Value: "android.nfc.action.TAG_DISCOVERED"

よって、API Level 9で作成したアプリは、API Level 10のアプリが存在する環境では、ほとんどの場合で intent を受け取れなくなる可能性があります。*1 広くICカードのタッチに反応したいという意図で ACTION_TAG_DISCOVERD を受け取るように AndoridManifest.xml に記述した場合でも同様です。

よって、広い種類のカードに反応するアプリを作りたい場合は、ACTION_TECH_DISCOVERD を使った intent-filter を記述した上で、そのアプリがどの種類のカードに対応しているかを明示的に(広く)宣言する必要があります。

API Level 9と10の両方で動作するアプリを作りたい場合には、AndroidManifest.xml に記載するのではなく、IntentFilterクラスを用いて intent-filter を登録することも検討してみた方が良いでしょう。

公式ドキュメントの間違い

APIリファレンスのみを見ていればこの罠には引っかかりにくいのですが、NFCについてのガイドドキュメントに間違いがあります(Near field communication overview  |  Android Developers)。

ACTION_TECH_DISCOVERED でのタグの記述位置について、ガイドドキュメントに問題があります。 タグは の外に記述しましょう。APIリファレンス(NfcAdapter  |  Android Developers)に記載の方法を参考にしてください。

正解
   <activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter">
       <!-- Add a technology filter -->
       <intent-filter>
           <action android:name="android.nfc.action.TECH_DISCOVERED" />
           <!-- これも足しておく -->
           <category android:name="android.intent.category.DEFAULT" />
       </intent-filter>

       <!-- 正しい位置 -->
       <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
           android:resource="@xml/filter_nfc"
       />
   </activity>

Javaリフレクションを利用したNFC勝手アプリは正常動作しない

まだちゃんと調べていないのですが、@hiddenなメソッドや変数などが変わっているようで、2.3〜2.3.2で使えていたリフレクションでのタグへの書き込みや、transieve でのコマンド送受信が正常動作しないようです。

NFCにとってAPI Level 9とはなんだったのか

前述の ACTION_TAG_DISCOVERED の優先順位の問題もあるので、API Level 9用に作られたNFC対応アプリは API Level 10環境では不遇です。ことNFCに関しては、とっととAPI Level 9を見捨てるのも一つの手かと思います。

しかし、これから少なくとも数ヶ月間、API Level 9な端末も市場に投入されるだろうというのも容易に予想されます。その中にNFCのハードウェアを持ったものもありそうですので、それらの端末をどう相手にするかということが悩ましい期間がありそうです。

幸い(?)、FeliCa対応の日本のAndroidおサイフケータイは、2.3になったとしてもNFCをサポートする可能性が低いと思われます。ABC 2011 Winter のLTの資料などにも記載しましたが、日本のおサイフケータイはカードエミュレーションモードが標準状態であり、R/Wモードが標準状態の AndroidNFCとの相性が悪いからです。Nexus Sは日本では正式に発売されていないわけなので、日本国内にまともなNFC対応のGingerbreadな端末はしばらく存在しない可能性が高そうです :-)

頑張って IntentFilterクラスやリフレクションを駆使しつつ、API Level 9と10を両対応していくのか、API Level 9方式を使ってAPI Level 10環境での取りこぼしを許容するのか、それともAPI Level 9を切り捨てて10のみ対応していくのか、開発者はアプリを作る前にちゃんと考えましょう。

*1:API Level 9の方法で作ったアプリ(tagletなど)をインストールした2.3.3のNexus Sに、NDEFが格納されたNFC Forum Tag を端末にかざした場合、標準のTag(タグ)アプリが優先的に起動します。