Android 上のアプリの多くは 「共有」 機能を用いて他のアプリへデータを送ることができる。 例えば画像ビューアだと、 「メニュー」 から 「共有」 を選び、 「Picasa」 を選ぶことで Android 標準の com.google.android.apps.uploader (マイアップロード) アプリを使って、 Picasa ウェブアルバムへ画像をアップロードできる (← 左図)。
ところが、 この Picasa には Google アカウントとの連係に問題があって、 Android 端末の状態によっては Picasa へのアップロードができなくなってしまう。 つまり、 「Picasa」 を選んだときに、 「Googleアカウントを追加」 する画面に遷移してしまい先に進めない (↓ 下図)。
既にこの携帯に登録済の Googleアカウントで、 画像をアップロードしたいのに、 「マイアップロード」 が現在の登録済アカウントを認識できず、 アカウントの追加を求めてくる。
[戻る] ボタンを押すと 「マイアップロード」 が終了してしまうので、 仕方なく [次へ] をタップして Googleアカウントを追加しようとすると、 「アカウントが既に存在します」 と言われてしまう (↓ 下図)。
「アカウントが存在する」 のが分かってるなら、 そのアカウントで画像をアップロードしろよ! と言いたくなるが、 画面には [戻る] しかないのでどうにもならない。
Google ヘルプを見ると、 http://picasaweb.google.com に一度もアクセスしない状態でアップロードを試みると、 このような二進も三進も行かない状態に陥る、 ということらしい。 そこまで分かってるなら対策しろよ、 と言いたくなる。 まあ、 Google 的には、 Picasa へ直接アップロードするのではなく、 Google+ 経由で使って欲しいということなのかもしれないが。
もちろん、 現在の Googleアカウントをいったん削除すれば、 アカウントを追加することは可能になる (はず)。 しかし、 アカウントを削除しようとすると、 「携帯のメール、連絡先などのすべてのデータも削除されます」 などと脅される (右図 →)。
アカウントを削除しても、 再度アカウントを追加すれば、 削除されたメールや連絡先も再同期されるのだとは思うが、 「1つ目のアカウントを絶対削除したらだめ」 という先達の意見をスルーするのも気が引ける。
また、 知らぬ間にPicasaとの同期が始まるケースもあるらしいが、 ただ待ってるというのも能がないし、 待っていれば必ず始まるというものでもないだろう。
そこで、 アカウントを削除すること無く、 他への影響を最小限に抑えつつ、 Picasa Web Albums を同期させる方法を考えてみた。
要は、 マイアップロードにおいて Googleアカウントを追加する際、 追加したいアカウント (この場合だと sengoku@gmail.com) が存在しないと判定されれば、 前述したようなエラーが出ること無く、 Picasa Web Albums の同期のセットアップが完了できるはず。
Android には、 /data/system/accounts.db というデータベース (DB) がある:
senri:~ $ adb shell↓ $ su↓ # sqlite3 /data/system/accounts.db↓ SQLite version 3.6.22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables↓ accounts authtokens grants android_metadata extras meta sqlite> .schema accounts↓ CREATE TABLE accounts ( _id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, type TEXT NOT NULL, password TEXT, UNIQUE(name,type)); CREATE TRIGGER accountsDelete DELETE ON accounts BEGIN DELETE FROM authtokens WHERE accounts_id=OLD._id ; DELETE FROM extras WHERE accounts_id=OLD._id ; DELETE FROM grants WHERE accounts_id=OLD._id ; END; sqlite> select * from accounts;↓ 1|sengoku@gmail.com|com.google|《暗号化してBase64エンコードしたパスワード》 2|gcd_org|com.twitter.android.auth.login| 3|hiroaki_sengoku|com.skype.contacts.sync| sqlite>
Android は同期を行なう際、 この DB のデータを使ってサーバへのログインを行なっているようだ。 ということは、 この DB 内の accounts テーブルにおいて、 「sengoku@gmail.com」 のレコードを削除してしまえば、 sengoku@gmail.com が存在しないと判定されて、 Googleアカウントを追加することが可能になる?
DB のレコードを削除した直後にアカウントの追加を行なえば、 レコードが存在しない時間を最小限にできる。 この DB を参照するプログラムが動いたりしない限り、 悪影響を及ぼすことはないだろう。 もちろん、 「自動同期」 はオフにしておくべき。 また、 動いているアプリをできる限り終了させておく。
accounts.db のコピーをどこかへ保存しておけば、 万一、 なにか異常事態に陥っても、 accounts.db の内容を元に戻すことにより復旧は可能だろう。 万万が一に備えて、 念のためにシステム全体のバックアップも取っておく。
万全の備えをした後に、 画像ビューアにて適当な画像を選び、 「共有」 メニューから 「Picasa」 を選ぶ。 すると、 前述したように 「Googleアカウントを追加」 する画面に遷移するので、 [次へ] をタップし、 (携帯に登録済の) Googleアカウントを入力する (右図→)。
ここで [ログイン] をタップすると、 前述したように 「アカウントが既に存在します」 と言われてしまうので、 [ログイン] をタップする前に、 accounts テーブルから、 「sengoku@gmail.com」 のレコードを削除する:
sqlite> delete from accounts where _id=1;↓ sqlite> select * from accounts;↓ 2|gcd_org|com.twitter.android.auth.login| 3|hiroaki_sengoku|com.skype.contacts.sync| sqlite>
そして、
間をおかずに
[ログイン]
をタップ。
すると、
めでたく登録が完了した (右図→)。
これで、
[設定]→
[アカウントと同期] に、
「Picasa Web Albums を同期」
の項目が表示されるようになった。
メールや連絡先の同期も問題無く行なうことができた。 3日ほど普通に使っているが、 特に問題は起きていない。
accounts テーブルの schema を見ると分かる通り、 DELETE TRIGGER が定義されていて、 レコードが削除されると、 grants テーブルからも該当レコードが削除される。 なので、 アクセスリクエストを再度許可する必要は生じる (← 左図)。
その一方で、 accounts.db は Android ID 等の端末固有情報とは関係がないので、 Android マーケットにおけるアカウントには影響しない。 私は有料アプリ/コンテンツを買ったことがないので確認はできないが、 おそらくアプリからはレコード削除後も同一端末と見なされるはず (ライセンスが無効になったりはしないと思われる)。