2012/04/30

トラノマキ その3

細かい部分の作りこみが完了しました。
  1. 通信エラー時のメッセージ表示
  2. 目次の唯一展開オプションの動作実装
  3. 手順書ファイルのプロパティ表示
  4. 他の画像ビューアから戻った時の挙動の修正
4項については、参考画像の拡大表示を他の画像ビューアに委託する処理に関してなのですが、拡大表示させた後にバックキーで戻ると同じ画像が2度表示され、正規の動作とは言え少し違和感を感じる部分でした(手抜きの副作用とも言う)。


呼び出し元のActivityはViewPagerなので、戻った時に手順書が表示されていれば違和感も解消されそうです。

そこで、ギャラリーの呼び出し方法を『startActivity』から『startActivityForResult』にしてコールバックを受け取るようにし、onActivityResultにてViewPager#scrollTo(x,y)を使って手順書のページへ強制的に戻す処理を追加しました。なかなかいい感じです。


忌むべき存在 ”OutOfMemoryError”

今まで真面目にAndroidアプリを作ったという経験は少なく(クソドラムを手掛けた事実は闇に葬る)、メモリ管理に関しては無頓着なまま作り続けてきましたが、今回は比較的大きな画像を扱う事もあって、予想されていたOutOgMemoryErrorがついに発生してしまいました。

『目次から手順書へ画面遷移』の繰り返しで出る同エラーは、System#gcでGCを呼び出す事で回避できました。しかし手順書の『リンクテキスト』で大きな画像を使った手順書へのリンクを繰り替えして落ちてしまう問題は解決できません。

鋭意調査中。


2012/04/25

トラノマキ その2

ファイルを更新する部分がほぼ完成。おかげでテストが随分と楽になりました。あとはコネクションタイムアウト等で更新に失敗した時のメッセージを出したいところですが、この処理はバックグラウンドスレッドで行っているので少し頭を悩ませています…。

ずっと同じ部位にかじりついてると飽きてくるので、手順書の表示部(ListView)を改良してみました。

元々『サブタイトル』『手順』の2つの表現要素しか無かったところに新たな3つの要素を追加しています。

注意を促す『注釈』、補足説明のような内容を表す『ワイドテキスト』(←少し命名に疑問)、他の手順書へリンクする『リンクテキスト』の3つです。特にリンク機能はスマホならではのメリットで、なかなか良いんじゃないかと思います。

改良したとは言え文字ベースの手順+参考画像1枚だけという制約に変わりは無く、表現力はまだまだ乏しいです。

技術力+やる気があれば、紙媒体同様、表現力豊な物を作る事も可能でしょうが、そこまでするならブログにでも手順書をあげたほうが絶対早いと思います。

しかし、そうすると結果的に閲覧時の軽快さやメンテの手軽さが失われてしまいますし、セキュリティー上の問題もあります(例によってどうでも良さそうですが、やはりうるさい人は居るもので…)

実はトラノマキの仕様を検討する際、iPhoneユーザーもカバーしたくて、ブログやEvernote、GoogleDocs 等Webを利用する案も検討していたのですが、先述の理由により断念したという経緯あってのAndroidアプリなのです。

しかし使ってるデータはただのXMLなので、iPhoneアプリを作れる人さえ居れば解決しそうな問題ですが・・・多分企業レベルで動かないと完成しても配布すらできない予感がしますね(未調査)

まぁいずれは何らかの手段で解決したいところではあります。

2012/04/24

Intentを使いギャラリーで画像を表示する

トラノマキでSDカード内に配置された画像を表示するだけビューがあります。これは何の変哲もないImageViewで、表示する以外の機能は無いのですが、ユーザーが画像を拡大して見たくなる場合もあるだろうと考え、他の画像ビューア(ギャラリー等)にインテントを投げるという実装を試みました。

有名なファイルマネージャ『アストロビューア』で画像ファイル名をクリックしたときのあの動作です。

ところがこういったサンプルがありそうでなかなか見つからず(調べ方が悪いのか需要が無いのか)おかげで3日くらい苦しみましたが、アストロビューアのLogCatを眺めていたところ解決に至りました。

ちなみに日本Androidの会メーリングリストで同じ悩みを持っている人が居て(未解決でしたが)、そのやりとりがヒントになりました。

前置きが長くなりましたが、以下がサンプルです(一部抜粋)


String filename = "SDカードのファイルパス";
//コンテンツプロバイダのURI取得
Cursor c = getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.ImageColumns.DATA + " = ?", new String[]{filename}, null); 
c.moveToFirst(); 
String contentname = "content://media/external/images/media/" + c.getInt(c.getColumnIndex(MediaStore.MediaColumns._ID)); 
   
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse(contentname));
 
startActivity(intent);


3-5行でファイルパスからコンテンツプロバイダのURIを取得しています。コンテンツプロバイダに登録されていないファイルの場合nullが返されるので例外処理を書いた方がいいかもしれません。

自前アプリで作成・保存した、あるいはダウンロードした等のケースではコンテンツプロバイダに登録されてないので、MediaScannerConnection を使ってコンテンツプロバイダに登録させる処理が必要になります。

詳細は以下のURLを参照しください。


参考URL

MediaScannerConnectionを使って画像をギャラリーに反映させる http://techbooster.jpn.org/andriod/multimedia/5341/

contentスキーマとfileスキーマの相互変換 http://yagni.jp/android/interconversion_between_file_and_content

Android URI
http://ee72078.moo.jp/chinsan/pc/MobileApp/index.php?Android%20URI

2012/04/19

HttpURLConnectionでBasic認証を使ったサイトにアクセスする

現在トラノマキアプリでデータを更新する処理を作っています。

このアプリで使うベースとなるデータファイルはネット上に置いてあり、先ずはこれらの更新日を取得する必要があります。オープンな場所のファイル更新日を取得するだけならHttpURLConnectionを使う方法がお手軽で良い感じですが、今回は対象となるサイトにBasic認証を掛けてある為(大した情報は無いのですが保身的な人に知れると面倒なので)ひと工夫必要です。

という訳で、Basic認証を使ってネット上のファイルの更新日を取得する方法を調べてみました。

以下、一部抜粋

private Date getLastModified(String filename) {

 URL url;
 Date date = null;

 try {
  Authenticator.setDefault(new Authenticator() {
   protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("userId", "password".toCharArray());
   }
  });

  url = new URL("http://www.hoge.com/" + filename);

  HttpURLConnection con = (HttpURLConnection) url.openConnection();

  con.setRequestMethod("HEAD");
  date = new Date(con.getLastModified());

 } catch (MalformedURLException e) {
  e.printStackTrace();
 } catch (IOException e) {
  e.printStackTrace();
 }
  return date;
}

こんな感じで良いみたいです。

上記コードでは 便宜上Authenticator.setDefault~の部分をメソッド内部に書いてますが、その必要はありません。まだ勉強中で曖昧なのですが、VMがパスワード要求を受けた時に返せるように設定しておくイメージ?


ちなみにこの方法だとID,パスは暗号化されないので、シビアな場所に使うならHTTPSと併用した方が良いとの事です。


参考URL
http://developer.android.com/intl/ja/reference/java/net/HttpURLConnection.html

2012/04/15

トラノマキforAndroid

会社で役立つツールをAndroid端末で作る、という計画はゆっくりと進んでいます。今年の初めに少し、しばらく休止後、4月に入ってまた再開。本当にゆっくりですが、自身のモチベ維持の為に書いてみます。

名前は 『トラノマキ for Android』

基本的には作業手順書なんですが、それを見れば誰でも出来るという物にはせず、あくまで”記憶を助けるツール”という事をコンセプトとしています。また、現存する紙媒体の虎の巻では困難だった情報の共有化というのも一つの狙いです。

アプリケーション自体は単純で、起動すると機種等でカテゴライズされた手順書等のタイトルがあり、それをタッチすると内容が表示されるというものです。手順書画面はViewPagerで構成され、手順を書いたリストと参考画像の画面をスワイプで切り替える、という物になります。



手順書データは端末に無い場合に自動的に取得する仕組みで、一度取得すれば内部のデータを参照します。また、データを編集/追加していく事も必要なのですが、Android端末でその作業は厳しいので別途PCソフトを用意する必要があるかなと考えています。

現在はアプリの枠組みと呼べるものがおおよそ完成した状態です。まだ最新のファイルに更新する仕組みが未実装。データを編集するソフトについては未着手(これが一番大変そう)。コンテンツを充実させる作業もあるし、まだまだ先は長い。

完成したら若者を中心に広げてもらい、末永く業務に役立ててくれたら嬉しいと思います。


2012/04/14

ブログ引っ越し

JUGEMブログからBloggerへ引っ越ししました。

たまにコードも載せるのでいい機会だと思い、Syntaxhighlighterを導入。こいつはバージョンがいくつかあったので色々比較してたのですが、スクロールバーが出ずに折り返して表示してくれる1.5.1にしました。

導入は、rmascoさんの 怠け者が頑張るブログ のブログを参考にしました。感謝!


後から再び試してみたのですが、結局のところこれはBloggerの新しいインターフェイスで、

レイアウト→ガジェット追加→HTML/JavaScript→コード貼り付け

だけで出来るんですね。ただし、テンプレートを動的ビューにしていると駄目みたいで、他にも旧インターフェイスで選択できるテンプレートでも出来ないものがあるみたいです(出来ない=手軽に出来ない、という意味ね)

2012/04/07

宇宙戦艦ヤマト2199

宇宙戦艦ヤマト2199観てきました。なかなか良かったと思います。ストーリそのものはオリジナルと大差ないのですが、少し思った事を書いてみます。

(以下、多少のネタバレ含みます)