iTunesがバックアップファイルを認識しない

諸事情により、iOSをリカバリモードでbeta版からリリース版にダウングレードした時のデータの復元で、iTunesがバックアップファイルを認識しないという事象に遭遇したのでメモ。

結論!
iTunesはiOSのバージョンチェックをしており、インストールしているバージョン(今回はリリース版の5.0.1)よりバックアップ時のバージョン(beta版の5.1beta2)の方が高ければ、「バックアップから復元」のリストに出てこない模様。

メニューの「環境設定」→「デバイス」を確認すると、バックアップファイルが存在しているかどうかが分かる。
ここで確認できなければ恐らくバックアップ出来ていない。
バックアップファイルの保存場所は、「/Users/[USER NAME]/Library/Application Support/MobileSync/Backup」のフォルダに「IDのみ」若しくは「ID-日付-時間」のフォルダ単位で管理されていて、フォルダの一つ一つがバックアップのリストに表示されるようになっている。
バックアップフォルダ内のinfo.plistを開いて「Product Version」を確認。
現在インストールされているiOSのバージョンよりも、このProduct Versionの方が高い場合はバックアップリストに表示されない仕様みたい。
このProduct Versionをインストールしているバージョンと同じ数値に修正して「バックアップから復元」を開いたら、お目当てのバックアップが表示されるようになり問題なく復元できた。
1ヶ月近くバックアップしてなかったのでちょっと焦ったw

広告

ActivityManagerとActivityManagerNative

「フォアグラウンドプロセスとは別のプロセスからフォアグラウンドプロセスを終了させる」
という要求があったのでActivityManager関連を調べてみた。

ActivityManager#killBackgroundProcessesを使用すればバックグラウンドのプロセスがkillできるので、フォアグラウンドプロセスをバックグラウンドに移行させてやればよい。
フォアグラウンドプロセスとは別のプロセスが、フォアグラウンドプロセスをバックグラウンドに移行させる公開APIは存在しないようだが、ActivityManager#moveTaskToFrontを使って一つ前にフォアグラウンドにいたプロセスをフォアグラウンドに持ってきてやればよさそうだ。

しかし、このAPIはAPILevel11(Android3.0)からしか使えないようだ。
ではAPILevel10以前ではどうすればいいか?
ActivityManagerのソースを読んでみるとmoveTaskToFrontの実装は次のようになっていた。

public void moveTaskToFront(int taskId, int flags) {
    try {
        ActivityManagerNative.getDefault().moveTaskToFront(taskId, flags);
    } catch (RemoteException e) {
        // System dead, we will be dead too soon!
    }
}

ActivityManagerNative.getDefault()の戻り値はIActivityManagerで、実体はActivityManagerProxyになっている。
このインタフェース自体は非公開ではあるが、実装さえあればリフレクションで呼び出すことは可能なので、APILevel4(Android1.6)のソースでgrepしてみたら見事にヒットした。
結構昔から存在してたのね。
ということで、APILevel10以前の環境でも非公開だが使用することは可能であるという結論に。

因みに、moveTaskToBack(int task),killApplicationWithUid(String pkg, int uid)なんてメソッドもある。
APILevel5(Android2.0)にはkillApplicationProcess(String processName, int uid)というメソッドも追加されている。
しかし、killApplication〜のメソッドは、起動中のActivityから自分自身のパッケージ名とProcess.myUid()で取得できるUIDを渡したがSecurityExceptionが発生して動作しなかった。
指定したUIDではkillできないようだったが、起動しているプロセスのUIDと同じだったのでダメな理由がよく分からなかった。。。

追記
プロセスをバックグラウンドに移行させても、バックグラウンドに移行するのに数100msecかかってしまい、killしようとしてもタイミング的にkillできない場合がある。
そんな時はプロセスの状態を確認して確実にバックグラウンドに移行したのを確認してからkillしてやればよい。

%d人のブロガーが「いいね」をつけました。