カテゴリ別アーカイブ: Java

Tumblife for Androidをダッシュボードの状態を保存するアップデートした

2011年01月10日 22時42分 | Android, Java | By: mitukiii

̃Gg[͂ĂȃubN}[Nɒlj

先日Tumblife for Androidをver.1.1.5, ver.1.1.6, ver.1.1.7とアップデートしました。

ユーザーの声

@tumblife 自分のpostをlikeできないようにしてもらえると嬉しいです。誤ってlikeしてしまうと簡単には取り消せない気がします。Sat Dec 25 08:53:54 via Tween

@tumblife 度々すいません。先日の件で「自分のポストをスキップ」するようにしていて気付いたのですが、この設定だと自分のポストが最後のポストになっているとき「Last Post in Last Session」の表示が出ず、若干不便なような気がします。そういう仕様かな?Tue Dec 28 07:11:33 via Tween

@tumblife いつも利用させて頂いております。最高です!今IS01で使ってるのですが、Tumblife起動中にメールやブラウザ機動してまたTumblifeに戻ると再読み込みすしてしまいます。これ、読み込まないようにできませんか?さっきの続きをそのまま見たいです。Fri Jan 07 17:01:26 via web

tumblife?はアプリのフォーカスを切り替えると今まで読んだ部分がクリアされちゃうからめんどくさいのぅ……Sat Jan 08 13:32:29 via twicca

アップデート内容

上記ツイートを反映しいくつか修正と機能追加のアップデートをしました。アプリがバックグラウンドにいっても、プロセスが動いてる間は状態を保持しているのですが、IS01は高確率でプロセスがSATSUGAIされてしまうようです。ついでに、2,3週間ほど前くらいからプライベートポストがダッシュボードで見えなくなったようで、ここまで読んだ機能も削除しました。

ver.1.1.5

  • プライベートポストがダッシュボードで見えなくなったためここまで読んだ機能削除
  • SkipしたポストにLastSessionのポストがあった場合にToastを表示
  • 自分のポストをLike出来ないように変更

ver.1.1.6

  • 起動時にダッシュボードの状態を復元する機能をオプションで追加

ver.1.1.7

  • バグ修正

既知の問題

状態保存のアップデートに際して、再起動して復元した後、LastPostのIDが設定とダッシュボードとで保持してるものが異なるものになります。(実際のLastPostと、ToastでLastPostと表示されるポストが異なる。)また、状態保存とキャッシュの削除が相性が悪く(再起動後にHTMLを再作成しないといけなくなる)ので、自動的にキャッシュの削除がオフになります。どちらも使用には問題ありません。両方共次のアップデートで修正します。

なお、キャッシュは溜まり過ぎるとアクセスが遅くなったり、容量がいっぱいになるとファイルが作成出来なくなるので、定期的に削除することをオススメします。

参考リンク

データを簡単に保存する方法(シリアライズ編) – Tech Booster
Java直列化メモ(Hishidama’s Java Serializable Memo)

状態保存のために、インスタンスを丸々シリアライズして、ファイルに保存することにしました。
コードを書くに際して上記のリンクを参考にさせて頂きました。

ソースコード

そういえば、ソースコード公開しました。GPLです。

mitukiii/TumblifeForAndroid – GitHub

̃Gg[͂ĂȃubN}[Nɒlj

Androidアプリをハードウェアキー対応する

2010年11月16日 10時32分 | Android, Java | By: mitukiii

̃Gg[͂ĂȃubN}[Nɒlj

Tumblife for Androidをハードウェアキー対応しました
以前Tumblifeをハードウェアキー対応しました。

その時のメモとして、Androidアプリをハードウェアキー対応するやり方を残しておきます。下記にサンプルアプリケーションのソースコードへのリンクを貼ってあります。

やりたい事

設定画面で、ハードウェアキーの設定を自由に変えたい。
特定のアクティビティで、設定されたハードウェアキーが押された時に、特定の動作をしたい。

イメージ図

アクティビティ。button1〜button3が押された時に、テキストビューに「button1 clicled.」とどのボタンが押されたか表示するだけの簡単なサンプルです。また、ハードウェアキー設定されたキーが押された時は、対応する動作が呼ばれます。

設定画面。どのハードウェアキーが押された時にbutton1〜button3のどの動作を呼び出すか設定します。

button1の設定。この状態でハードウェアキーを押すと、そのキーが設定されます。OKで変更を適用、キャンセルで元々設定してあったキーに戻す、クリアで設定解除です。今は「I」が設定されています。なので、アクティビティで「I」キーを押すとbutton1を押した時と同じ動作が呼ばれテキストビューに「button1 clicked.」と表示されます。

設定画面でハードウェアキーの設定をする

まず、PreferenceActivity用のレイアウトのxmlを作成します。ここではハードウェアキーの設定に使いたい項目に、PreferenceScreenタグを使います。このタグは本来、Intentを設定し別Activityを開くためのものです。Intentタグを設定しなければ何の動作せず、ハードウェアキーの設定を作るのに都合が良いのでこのタグを使います。

こちらはPreferenceActivityを継承したカスタムActivityです。onPreferenceTreeClickメソッドをオーバーライドして、各項目のクリックイベントを取得します。クリックされた時に自前でダイアログを生成し、ダイアログのdispatchKeyEventメソッドを
オーバーライドし、キーイベントを取得/設定するようにしています。

キーコードと名前のマップ

後先が逆になりました。Androidにはキーコードの定数からそれに対応するキーの名前を取得するクラスやメソッドというものがないようです。なので、HTKeyCodeMapというenumを作って、そこからキーコードの名前を取得/表示するようにしています。(valueOfの最後はUNKNOWNを返すんじゃなくて例外投げたほうが良いかもしれません。)

キーイベントにフックして動作させる

Activityを継承したカスタムActivityでキーイベントにフックして、設定値を元に動作させます。本来は各ソフトウェアボタンにイベントリスナーを登録して動作し、設定されたハードウェアキーが押された時にも同じ動作をする、という状況を仮定してます。

レイアウトのxmlはこんな感じ。

まず各ボタンにイベントリスナーを登録しています。ActivityのdispatchKeyEventメソッドをオーバーライドして、設定されたハードウェアキーが押された時に対応するアクションを呼び出すようにしています。その他のキーはデフォルトの動作を返します。

ソースコード

mitukiii/HardwareKeySupportSample – GitHub

gist: 701214 – Androidアプリをハードウェアキー対応するサンプル- GitHub

以上のソースコード及びサンプルアプリケーションはgist、githubに上げてあります。ご自由にお使いください。

参考リンク

ハードキーフックの方法 – 明日の鍵

̃Gg[͂ĂȃubN}[Nɒlj

Androidアプリで画面の回転に対応する

2010年09月26日 19時36分 | Android, Java | By: mitukiii

̃Gg[͂ĂȃubN}[Nɒlj

Androidアプリは画面回転時にActivityの『onStop→onDestroy→onCreate→onResume』が順番に呼ばれUIを再構築します。そのためアプリケーション側で何もしていないと一度終了した上で起動されることになります。

static変数にアプリケーションの状態を持ったインスタンスを保持してみる

Tumblife for AndroidではHTTPリクエストやロードしたポストの配列の管理を別のクラスに分け、そのクラスのインスタンスをActivity内でstatic変数に保持していました。onDestoyが呼ばれた後も、アプリケーションのプロセスがシステムに殺されるまでstatic変数は保持されたままになります。こうやって、onCreate/onResume時にstatic変数の状態を見て、処理を振り分けるようにしていました。しかしこの方法だと問題が発生しました。

static変数に保持する方法で問題が発生

例えば、Activityで処理中を示すProgressDialogを表示します。処理はstatic変数に保持した別クラスで処理しています。その状態のまま画面を回転させます。すると、UIが再構築されるためにProgressDialogの表示がなくなります。ですが、static変数で保持した別クラスの処理が動いたまま、という状況になります。これはまずい。ProgressDialogもstatic変数で保持する、という方法も考えてみました。しかし、他に良い方法があるはずだと調べてみました。ありました。

configChangesで画面の回転をアプリケーションに管理させる

androidManifest.xmlのタグの属性にandroid:configChangesという属性があります。

<activity> – ソフトウェア技術ドキュメントを勝手に翻訳

android:configChanges
アクティビティ自身がハンドリングする設定の変更を列挙します。列挙していない変更が発生した場合、アクティビティは停止後に再起動され、アクティビティは実行を維持し、その onConfigurationChanged() メソッドが呼び出されます。

つまり、ここに記述した設定の変更が生じた場合は、Activityは停止せずアプリケーションに管理を任せることとなるようです。

<activity android:name=".Main"
      android:label="@string/main_label"
      android:configChanges="orientation|keyboardHidden">

早速このように記述しました。

試してみたところ、画面を回転させてもActivityの再構築は起こらず、そのまま動き続けることを確認しました。orientationは画面の回転、keyboardHiddenはキーボードの出し入れです。keyboardHiddenは僕が参考にしたサイト(下記参照)に書いてあったのでそのままコピペしました。キーボード付きのAndroid端末を持ってないので、検証はしてません。因みに、MainのActivityにだけconfigChanges属性を追加しましたが、その他のActivityでも有効となるようです。

まとめ

画面の回転に対応させたい時は、androidManifest.xmlのactivityタグにandroid:configChanges=”orientation|keyboardHidden”属性を追加しましょう。

参考サイト

画面の向きを切り替えた時の問題 – hyoromoの日記

起動時にDialogを表示させるActivityで、横向き(LANDSCAPE)から縦向き(PORTRAIT)へ向きを変えたときに発生するエラーの対処方法 | mucchinのAndroid戦記

<activity> – ソフトウェア技術ドキュメントを勝手に翻訳

<activity> | Android Developers

̃Gg[͂ĂȃubN}[Nɒlj