2011年1月28日金曜日

雑談~

テニススクールの振り替えから帰ってきてプチ投稿。

自分にはフォアしかない事に凹みつつちょっと更新します。
あのレベルには半端な技術は通用しねぇ…


さりげなく Xメール の使用者が120人くらい、吉岡専用も全く宣伝してない割には
30人くらいいるんですよねー。

いや、ありがたい事なんですが、ホントに使ってんのか、どう思ってるのか気になって…。

世の有名アプリに比べたらゼロに等しい数ですけど、普通に考えたら凄い人数
ですよね?120人が目の前に現れて「良いアプリですね!」って言ってくれたら
色々勘違いすると思います、はい。


なんでこんな話してるかというと、次に作るアプリどうしようかなぁ?って考えて
いるわけです。今度は皆に喜ばれるものを作ろうと思って。

Xメールはやっぱり自分が使いやすいように、技術力がつくようにという
コンセプトでやってしまっているので、やっぱ人から見たら今一だと
思うんですよ。自分でもそう思うから余りお勧めする気にならないし…。

今は大体 Android っていうシステムがどんなもんなのか解ってきたので、
そろそろ応用してイノベーション引き起こすような何かをやりたいなと。


やっぱり、スマホがユビキタスなコミュニケーションツールである事を
念頭に置いてやりたいっすねー。

大規模な仕組みなら色々出来ますけど、ちょっとしたところを狙って
いきたいなぁ。


うーん、もうちょっと考える。
今日はもー寝よ。おやすみです☆

2011年1月26日水曜日

Android の SQLite と ContentProvider

X メール開発の中で SQLite & ContentProvider について解った事を書いておきます。

ただ、ここは深いところまで研究をしていないので
内容については曖昧なところがありますが、所詮ブログですのでご容赦を


X メールは始め「シンプルに手早く」作るつもりだったので、SQLite(以下DB)のように
複雑で処理コストのかかる仕組みは使わないでいく方針だったんです。

なので、始めは様々なデータを ObjectOutputStream を使ってファイル吐き出し
していたんです。

ただやっているうちに、処理の多重化やネットワーク断裂などの問題が
意外に大きい事が解りまして、I/O系の例外を担保したり、将来的な連携等も
視野に入れたいという思いから少しずつDB化を進めて、バージョン 2.0.0 では
添付ファイル以外は全てDB化してあります。

添付ファイルをDB化しない理由はコピーなどを簡単に他のアプリケーションから
行えるようにするという観点からです。

というわけで、X メールはメールデータも共有しています。アカウントデータ以外は
ContentProvider を通して公開しています。
※これはマニフェストの android:protectionLevel="signatureOrSystem" || "normal" で決定しています。


ContentProvider って?

というわけで、普通DBの使用はまず ContentProvider のマニフェストへの登録から始まります。

ごっちゃになりやすいんですが、ContentProvider は別にDBに特化したAPIではないです。
データ操作(update、query、insert、delete 以下DML)をURIを通して行いましょうという統一的な
方法のフレームワークです。

だから、別にDB使うから ContentProvider 使わなきゃいけないという訳じゃないのですが、
なかなか使いやすい世界観ですので、使うに越したことは無いと思います。
標準化・共有が ContentProvider の存在意義でもありますし。

考え方や動きはインテントを簡単にした感じで、マニフェストで受け付けるURIと処理する
クラス、公開レベルを宣言し、データ操作処理の実装をクラスで記述するという流れです。


ただ、Activity でいう Zygote のように、呼び出しの仕組みがどうなっているのか
という部分までは掘り下げ切れていません。ただ、この仕組みの構造上、何らかの
管理タスクがあるのだろうというところまでは想像できますが…。


【例】ContentProvider マニフェスト
<provider android:name=".mail.MailProvider"
android:protectionLevel="normal"
android:authorities="jp.sn.xmailer.provider.mails"/>

上記は実際のX メールのメールデータ ContentProvider の宣言です。
jp.sn.xmailer.provider.mails というURIを受け取りますよ、という宣言ですね。

で、処理するクラス MailProvider を書けばいいんですが、この中にDBに関する
記述をしていくので、少し頭を切り替える必要があります。




SQLiteOpenHelper の実装

SQLiteOpenHelper は一言で言うとバージョンアップに対応するために使用します。
例えばテーブルAをカラムB、Cでリリースした後に、次のアップデートでカラムDが
追加された時の事を考えれば解りやすいのではないでしょうか?

カラムDがカラムB・Cの値によってあるべき値が変わる場合、単純にテーブルに
addColumn するだけではシステムが成り立たない場合ってありますよね?

こういったときにDBのデータ操作プログラムを仕込む事が出来るのが
SQLiteOpenHelper なのです。


まず、システム上にDBヴァージョンを持たせておきます。これは、データ操作処理が
走る必要がある変更をした時にカウントアップさせます。

次に SQLiteOpenHelper を実装したクラスを作成します。


【例】
public class DBOpenHelper extends SQLiteOpenHelper{
public DBOpenHelper(Context context){
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase arg0) {
try {
arg0.execSQL("テーブルのCreate文");
...
} catch (SQLException e) {
;
}
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
更新時の処理
例えば、DBを読み込んでテーブルを削除
onCreate を呼び出し、読み込んだデータを修正しながら insert していくとか
  arg1 は更新前のDBバージョン、arg2 は新しいDBバージョン
}
}

この実装の意味するところは、「新規(DB_NAMEが見当たらない)なら onCreate が呼び出され
て終了、あった場合には DB_VERSION を比較して、現在よりも大きい値なら onUpgrade を
呼び出し、そうでなければ何もせずに処理を終了し、コンストラクトを終える」

という意味です。

この後に getWritableDatabase() を呼び出すなどして DML(さっきの insert 等) を発行できる
インスタンスを取得できるようになります。

この SQLiteOpenHelper は必ずDBに触れられる前にロードされるように仕込んでおく必要が
あるのでそこは意識しておきましょう。

例えば、アプリケーションの開始で必ず確認するようにしても構いませんし、ContentProvider
の onCreate でインスタンス化するのが最も効率的かもしれません。

SQLiteOpenHelper#onCreate に渡す引数がDB_NAMEである事と、DBインスタンスのDML
メソッドの引数の始めが TABLE_NAME である事から察しが付いている人もいると思いますが、
SQLiteOpenHelper は DB_NAME 毎に作成し、アップグレードもその単位で行われるので、
DB_NAME 毎のアップグレードプログラムを実装する必要があります。


ContentProvider の実装


後は ContentProvider のDMLメソッドで、取得したDBインスタンスのDMLメソッドを
呼び出すだけです。これらは上手く実装することで、画一的な実装になる可能性が高いでしょう。
多くの場合は、URIの記述方法で単一のデータに対する操作なのか複数なのかを判断し、
DBインスタンスのDMLメソッドを効率的に呼び出す実装をするだけです。



あまり深堀り出来ていませんが、解ったところはこんなところです。
自分はSQLに慣れているんで、まんま発行出来てもよかったんですが、
そういう所で結局独自的な記述方法が出来てしまう可能性を考えるなら
こういったAPIだけで処理をさせるというのも良いのかもしれないと感じています。

下手にSQLで何でも出来てしまうから、テーブルの正規化を怠るんじゃないの?
という逆説的な問題点に気づかせてもらったのもこれのお陰ですね。
(もしかしたら Google はそれを訴えたくてこういう仕様にしたのかも知れません)


こんなところですかねー。

2011年1月24日月曜日

ウィジェットの話

アンドロイドアプリで、ウィジェットの作り方って結構検索引っかかりますが、
恐らく作ってみて一番難しいと思われるところがあまり書かれていないので
書いておこうと思います。


ウィジェットは難しい


これは間違いない事実です。

何故か?


実際の設計者に聞いてみないと真実は解りませんが、自分は工夫を重ねた
結果なんじゃないかと思っています。

ウィジェットという常駐アプリが沢山動いても出来るだけ電池やメモリを
消費しないようによく考えられてるなと思うのです。

お陰さまでなんだか分かりにくい、作り手にとっては難しい、使い手にとっては
不安定な可能性のあるAPIになってしまったのかなと。


基本的に android は java ですので、開発はオブジェクト指向になります。

画面作成の基本である activity はそういう観点からだととても解りやすいですね。


でもウィジェットはいつもロードされている必要があるので、アプリケーションの持つ
全ての機能をロードしているわけにはいかないんです。メモリもったいないんで。


その為、以下の様な構造になっています。

・「画面にこういうウィジェットを表示しなさい」という命令がAPIにあり、それで描画する。
・画面要素の動作に、「仕込まれたインテント(PendingIntent)」を定義できる。
・もしくは時間間隔で発行される PendingIntent を準備する。
・【重要】PendingIntent の受け取りはウィジェットのクラス=マニフェスト定義で受け取る
・だから自分が作ったウィジェットの全てのインスタンスは同じウィジェットインスタンスが受け取る
・OnReceiveで受け取り、サービスなどを使って、PendingIntent を受け取り実行する。


…はい、全然わかりませんね。

解りやすく一言で言うと、ウィジェットのインスタンスはシングルトンなんです。
下手にスタティックじゃないので解りずらいんです。

なんでこうなっているのかというと、それは Zygote というプロセスの親玉が
マニフェストからインテントフィルターを判断してインスタンスを生成する、という
androidの基本構造があるためなんですが、たいていの人はどうでもいいですね。

とにかく解ってしまえば話は簡単で、いつもウィジェットID配列を気にしてループ処理
を入れておけばオーケー(時間間隔実行の場合は例外時とか大変ですが)。貼られている
ウィジェットごとにインスタンスが出来ないんだという事を常に意識しておきましょう。


余り書かれていないウィジェットに関するお話でした。どうでしたか?
同じ(クラスの)ウィジェットをいっぱい貼り付けられる事を考えて作りましょうねー☆


…ん?まさか悩んだの俺だけ!?

X メール 2.0.0 公開

やっと完成しました!

結構大きな修正が入ったのでバージョンを2に上げました。
名前のβも取りました。そろそろ安定もしてきたので…。

とはいえ実は対応端末以外は、カレンダーと連絡先へのリンクは
まともに動かない可能性高いっす。そのうち確認して対応したいなぁ。


今回の修正は以下の通りです

【機能追加】
・絵文字送受信対応
・デコメ送信・転送対応
・画面が自動で回転しないようにした
・メールを受信したときにライトを点滅させるようにした
・ポーリング中一覧とポーリング削除機能を追加
・受信メールのテキストバックグラウンドを白に変更
・受信メールの枠色に選択した色を反映


【不具合修正】
・メールフィルタ機能に関するバグを修正
・アップグレード時に受信プロトコルがPOPになってしまう不具合を修正
・あるドメインからのメールを受け取ると、一覧表示が出来なくなっていた不具合を修正

【絵文字メール送信に関する制限事項】
複数キャリアに同時に送信する場合は、png画像を使った3キャリア対応のHTMLメールとして送信します。ただし、png画像に対応していない端末には表示されませんので、複数キャリア同時送信を行う場合は注意してください


なんかやっと一人前になったかなぁ…?
ここまで来るのに、まるまる半年かかりました。

勉強になると思ってメーラーを選んだんですが、勉強になりすぎましたね。
おいおいネタ出していくつもりです。

あと、絵文字の png 送信なんですけど、これは最初悩んだんですよね。
gif にすれば全部出るのは解ってたんですが、なんとなく gif を選択するのが
嫌だったんで(まぁ例のあれで俺も png 推進派です)、こういう仕様になったんですが、
そもそも png も流行らずに svg に持っていかれそうな予感もしますね。


次はちょっと違うアプリに挑戦してみます。
あ、これの更新もすると思うよ!
実はもう仕掛けは埋め込んであったりするものもあるので!

2011年1月15日土曜日

年内って言ってたのにね

いやー、全然ダメでしたね、Xメール年内リリース。

というか、まだ出来てないんでもうちょっと先になると思います。


デコメはね、全然イケたんですよ。

ただ、au の絵文字送信が上手くいっていない事に気がついて
対応してたら年越すわさらに忙しくなって時間ないわで今に至ります。

アプリ公開って適当に考えてましたが、とても大変ですね。
仕事とかやってたらまともに更新でけん。


多分来月くらいになりそうです。

何故かというと、HP作成の頼まれ仕事を進めないといけないのと
今月末に「みゅーじかる」をボランティアでやるため、その練習時間が必要だからっす。

簡単な奴ですが、英語だし(俺はしゃべれん)皆気合いが入ってるので
頑張らないといけないんす。


目黒区青少年フェスティバルだって。
興味ある人は見に来てみてー☆