画面を割ってしまいタッチ操作不能になったAndroidからadbでデータを救出・移行した記録

先日、Xperia Z3をアスファルトに落としてしまい、画面が操作不能になってしまいました。僕は画面ロックにパターンロックを使っていたのですが、これの解除に一苦労しました。結果的にadbとその仲間たち、特にパターンロックの解除にuiautomatorが大活躍しました。
以下に、パターンロックを開く→データを救出・移行→初期化までの流れをメモしておきます。

この方法の条件・注意点としては、

  • USBデバッグが必要。前提条件として「開発者向けオプション」を解禁しており、かつUSBデバッグモードをONにしている必要があります。
  • JDKAndroid SDKEclipse、およびantなど多くのツールを使います。
  • root化は必要ありません。

また、これは私の携帯の復旧記録なので、実機で行う場合は自己責任でお願いします。

1. uiautomatorを使ってパターンロックを解除する

adbではキー入力や一方向のスワイプ操作はできるのですが、連続した折れ線スワイプはできないため、adbだけではパターンロックが解除できません。ここを解決するのが最も難しい箇所でした。これにはuiautomatorを使って行いました。uiautomatorはJUnitを用いたAndroid向けのUIテスト用の機能で、複雑な操作を行うことができます。
ちなみに未確認ですが、スワイプパターンの入力だけならAndroid用のマウスなるものでもできるそうです。

uiautomatorviewerでスワイプ座標を取得

まずは、スワイプパターンの座標を取得するためuiautomatorviewerを使いました。
これには以下のサイトを参考にしました:
スマホ向け無料システムテスト自動化ツール(3):Androidテストで便利なuiautomatorviewer、UiScrollableの使い方、テキスト入力API制限事項の回避方法 (1/4) - @IT

uiautomatorクラスの作製

続いて、uiautomatorを使って実際にスワイプパターンを入力していきます。
これには、以下のサイトを参考にしました:
[Android] はじめてのuiautomator - adakoda

このサイト中の、次の4つの手順を行いました:

  • テストプロジェクトを作成する
  • テストクラスを作成する
  • ant を使用してビルドする
  • ビルドしたファイルを使用してテストを実行する

実際に作製したテストクラスは以下のものでした。(座標の値は変えてあります。)

// XperiaRedemption.java
package com.woodrush.xperiaredemption;
import android.graphics.Point;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;

public class XperiaRedemptionTest extends UiAutomatorTestCase {
    public void testUnlockScreen() throws Exception {
        Point[] points = new Point[4];
        points[0] = new Point(100,200);
        points[1] = new Point(300,400);
        points[2] = new Point(500,600);
        points[3] = new Point(700,800);
        getUiDevice().swipe(points, 10);
    }
}

テストクラスの作製には以下のサイトを参考にしました:
Android - UiAutomatorを使用しての多段swipeの実現 - Qiita

次にantを使ってこれをビルドするため、ターミナルから以下を実行しました。

android create uitest-project -n XperiaRedemption -t 15 p .
ant build
adb push ./bin/XperiaRedemption.jar /data/local/tmp
adb shell uiautomator runtest XperiaRedemption.jar -c android.woodrush.xperiaredemption.XperiaRedemptionTest

これらの三行目までを行えば、あとは任意のディレクトリから4行目を実行するだけでロックパターンが入力できるようになります。

2. adbを使ってタッチ・キー操作

パターン入力後の操作は全てadbで行いました。これには以下のサイトを参考にしました:
Remote Input shell scripts for your Android Device, or my screen is cracked | The Grymoire

usage: input ...
 input text <string>
 input keyevent <key code number or name>
 input [touchscreen|touchpad] tap <x> <y>
 input [touchscreen|touchpad] swipe <x1> <y1> <x2> <y2>

これらのコマンドを使うには、まずターミナルからadb shellを実行してAndroid側のシェルを起動し、そこでコマンドを入力していきます。
特に、戻るキーが押せなくなっていたのですが、これは

input keyevent 4

を実行して押しました。
キーコードはKeyEvent | Android Developersを参照しました。

3. adb backupを使ってデータを救出

バックアップは、アプリデータのバックアップと、写真などのバックアップを行いました。
写真については、Xperia付属のソフトで行いました。
後から同ソフトでアプリのバックアップも行えることに気付き、このソフトも使ったのですが、最初にadb backupも使ったのでこちらについても記しておきます。

adb backupの引数は以下のようになっています:

  adb backup [-f <file>] [-apk|-noapk] [-shared|-noshared] [-all] 
              [-system|-nosystem] [<packages...>]
            - write an archive of the device's data to <file>.
              If no -f option is supplied then the data is written
              to "backup.ab" in the current directory.
              (-apk|-noapk enable/disable backup of the .apks 
                 themselves in the archive; the default is noapk.)
              (-shared|-noshared enable/disable backup of the device's
                 shared storage / SD card contents; the default is 
                 noshared.)
              (-all means to back up all installed applications)
              (-system|-nosystem toggles whether -all automatically 
                 includes system applications; the default is to 
                 include system apps)
              (<packages...> is the list of applications to be backed 
                 up. If the -all or -shared flags are passed, then the
                 package list is optional. Applications explicitly 
                 given on the command line will be included even if 
                 -nosystem would ordinarily cause them to be omitted.)

今回は新しい携帯の本体がすでにあるため-nosystemとしました。

adb backup -f xperiaredemption.ab -apk -shared -all -nosystem

また、念のため新しい携帯の完全バックアップをとるべく、-systemフラグを入れた状態で以下も実行しました:

adb backup -f newandroid.ab -apk -shared -all -system


バックアップ後はデータの移行を行います。
これにはadb restoreを使いました:

adb restore xperiaredemption.ab

このコマンドでは、バックアップを行ったアプリのみが、バックアップのデータをもとに上書きされる、という具合に移行が行われました。

また、携帯の初期化はadbで画面操作を行いながら携帯の機能を使って行いました。

おしまい

今回はUSBデバッグモードをONにしておいて助かりました。しかしやはり携帯を壊してしまったのは前の携帯にも申し訳ないです。僕はカバーはあまり好きではないのですが今回の一件でカバーを買ってあげるのが一番だと思いました。