更新日:2017年05月16日

0.環境

  • PC側

    [OS]             Windows7 (32bit 版)
    [Android Studio] 1.5.1
    
  • スマホ側

    [OS]             Android 5.1.1
    [SQLite]         3.8.6.1
    

1. 前提

  • まずSQLiteのデータをファイル形式で保存するよう設定します。

  • 例として、SQLiteを操作するライブラリにSQLiteOpenHelperを使用した場合について記載します。

  • コンストラクタの第二引数でDBファイル名を指定します。

  • (未指定の場合、データはメモリにのみ保持されます)

    class DatabaseHelper extends SQLiteOpenHelper {
    
        public DatabaseHelper(Context context) {
            //DBファイル名を指定。
            super(context, "example.db", null, 1);
        }
    
  • PCからAndroid端末にあるSQLiteのDBファイルを見る方法を調べました。

  • 試行錯誤した内容を書いているため、結論だけ知りたい場合は、4まで読み飛ばして下さい。

2. ADB(Androidデバッグ用インターフェース) 利用

  • ネットを検索して結構あったのが、ADBを使ってSQLiteのDBファイルをAndroid端末からPCへコピーし、その後DBビューワーで参照するというものです。

  • PCでコマンドプロンプトから下記コマンドを実行すると、カレントディレクトリにtarget.db(任意)というファイルができます。

    C:\Users\【ユーザー名】>adb -d shell "run-as 【アプリケーションID】 cat databases/【DBファイル名】">target.db
    
  • 【】内は読み替えて下さい。

    • 【アプリケーションID】: Android Studioの[File]-[Project Structure]-[Flavors]-[Application Id]

    • 【DBファイル名】: 上記1で指定したファイル名。

  • Database BrowserやPupSQLiteというビューワーでtarget.dbを開いても、下記エラーが出てレコードが表示されません。

    database disk image is malformed

  • この修復方法を試しましたが次のエラーが出て、上記ビューワーで見てもレコードが0件でした。

    Error: near line 6: NOT NULL constraint failed: 【テーブル名】.【カラム名】
    
  • Android(Linux系)とWindowsだからリダイレクションでデータの受け渡しがうまくいってないのかな?と推測し、Linuxコマンドも使えるPower Shellを使ってみたところ、最初の結果と異なり、target.dbのファイルサイズは倍になりました。

  • 再度、上記のビューワーで開こうとしたところ、復号化パスワードを求められ開けませんでした…

3. Android Device Monitor 利用

  • 方針を変え、Android Studioの付属ツールを使ってDBファイルをPCへコピーする方法を試しました。

    Android Studioのメニューで[Tools]-[Android]-[Android Device Monitor]-[File Explorer]タブ
    
  • “data”ディレクトリはあるのですが、その下のディレクトリが表示されず、DBファイルまでたどり着けなかったため諦めました。

4. stetho 利用

  • facebookが提供しているstethoというデバッグツールを使いました。

    • (4-1) 準備

      • このページからjarをダウンロードし、下記ディレクトリへコピーします。

        [アプリのルート]-[mobile]-[libs]

      • 僕のbuild.gradleは、もともとlibsの全jarを読み込み対象にしていたのでひとまずそのままにしました。

      • (build.gradle抜粋)

            dependencies {
                compile fileTree(dir: 'libs', include: ['*.jar'])
                wearApp project(':wear')
                compile 'com.android.support:appcompat-v7:21.0.3'
                compile 'com.google.android.gms:play-services:6.5.87'
                compile "com.android.support:support-v4:20.0.+"
                compile files('libs/gson-2.5.jar')
            }
        
      • さらに、ソースコードへ下記①、②を追記します。

        //①
        import com.facebook.stetho.Stetho;
        
        public class MainActivity extends ActionBarActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
        
                super.onCreate(savedInstanceState);
                //②
                Stetho.initializeWithDefaults(this);
        
                // 以下省略
        
    • (4-2) エラー対応

      • ビルドしたところ、下記エラーが発生しました。

      • ライブラリを重複して読み込もうとする際に出るエラーのようです。

        :mobile:dexDebug
        AGPBI: {"kind":"simple","text":"UNEXPECTED TOP-LEVEL EXCEPTION:","sources":[{}]}
        AGPBI: {"kind":"simple","text":"com.android.dex.DexException: Multiple dex files define Landroid/support/v7/appcompat/R$anim;","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:596)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:554)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:535)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.merge.DexMerger.merge(DexMerger.java:189)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:454)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.command.dexer.Main.runMonoDex(Main.java:303)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.command.dexer.Main.run(Main.java:246)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.command.dexer.Main.main(Main.java:215)","sources":[{}]}
        AGPBI: {"kind":"simple","text":"\tat com.android.dx.command.Main.main(Main.java:106)","sources":[{}]}
        
        FAILED
        
        FAILURE: Build failed with an exception.
        
      • 下記のようにbuild.gradleを変更し、stethoを個別に定義するようにしました。

      • さらに上記エラーメッセージの3行目から推測して、除外設定も追加しています。(参考ページ)

      • (2017/05/16,追記)除外設定はなくてもOKでした。まだ追いきれてませんが、fileTreeによる指定がまずかったようです。

      • (build.gradle抜粋)

        dependencies {
            //この指定はやめる。
            //compile fileTree(dir: 'libs', include: ['*.jar'])
            wearApp project(':wear')
            compile 'com.android.support:appcompat-v7:21.0.3'
            compile 'com.google.android.gms:play-services:6.5.87'
            compile "com.android.support:support-v4:20.0.+"
            compile files('libs/gson-2.5.jar')
                        
            //これを含めるのはデバッグ時のみにし、重複エラーが出たので除外設定を追加。
            //debugCompile ('com.facebook.stetho:stetho:1.5.0') {
            //  exclude group: 'android.support', module: 'library'
            //}
                        
            //(2017/05/16,追記) この指定で十分でした。
            debugCompile ('com.facebook.stetho:stetho:1.5.0')
        }
        
    • (4-3) 使い方

      • アプリをビルドして、Chromeのアドレスバーに下記URLを入力します。

        chrome://inspect

      • Android端末名の下にアプリ名が表示されるので、”inspect”をクリック。

        chrome

      • 新しいウィンドウが開き、[Web SQL]-【アプリケーションID】-【テーブル名】を開くとSQLiteのデータが参照できました。

      • さらに、【アプリケーションID】をクリックすると右ペインにプロンプト(>)が表示され、そこでSQL文も実行できるのでかなり使えそうです。

        chrome