Androidの開発でお手軽にデータベースが使えるSQLite
ローカルアプリ開発時の強い味方ですが、いちいちアプリからSQL発行するのが面倒くさい場合もありますよね?
初期設定くらい、DB直接登録できたら楽なのに・・・
2台の携帯でデータ共有したいけど、いちいちサーバ建てるほどでもないし・・・
そこで今日は、スマホ本体に保管されているデータベースをパソコン側に取り出して加工する方法を紹介していきます。
ADBの準備(環境変数の設定)
ADBとは、「Android Debug Bridge」の略で、USB接続されたスマホに対して、パソコン側から命令を出すことができる仕組みのことです。
データベースの取り出しに必須となるので、まずはこの環境を整えましょう。
まずは、AndroidStudioから、AndroidSDKのインストール先を調べます。
Tools – Android – SDK Manager ⇒SystemSetteing – AndroidSDK
赤枠の記述を後から使用します。
続いて、環境変数を設定します。
エクスプローラーを開いて、PCのプロパティを開きます。
左端の「システムの詳細設定」
詳細設定タブの「環境変数」
下のエリアから「Path」という変数を探して、「編集」
右側のボタンの一番上にある、「新規」を押すと、左の一覧表に書き込めるようになります。
最初に調べた、SDKのパス+「\platform-tools」と打ち込みます。
デフォルトだと、
「C:\Users\XXXX\AppData\Local\Android\sdk\platform-tools」
という感じです。
そもそも、Pathがなくて編集できない!という場合は、「新規」から登録してください。
こんな感じです。
これでADBの準備が整いました。
ADBの動作確認
スマホをデバックモードでUSB接続してください。
コマンドプロンプトを起動します。
※左下のウインドウズボタン右クリック⇒ファイル名を指定して実行⇒「cmd」と入力
「adb」と打ち込んでみて、つらつらと文字が出てこれば、成功です。
コマンドが認識されません的なこと言われる場合は、何かが間違っているようです。。
OSや環境差異によって手順が異なるかもしれませんので、Googleセンセーに聞いてみてください。。
データベースの保存先を特定しよう
そもそも、Androidアプリのデータベースってどこに保存されているのでしょうか?
アプリ側でデータデースを利用するときに、ファイル名を指定しましたよね?
私のアプリの場合、PlaceList.dbです。
つまり、スマホのどこかに、PlaceList.dbというファイルが転がってるはずなので、
理屈としては、それをパソコン側にコピペするだけで良いはずなんですけど、これがまた面倒なんです。
見てください!
本来、自作アプリのデータが保管されているはずの場所が、空っぽなんです!!!
ひどいですね。 どうやらPCからは閲覧できない設定になっている模様。
仕方がないので、先ほど導入したADBを利用してのぞいてみましょう。
コマンドプロンプトにて、「adb shell」と打ち込んでください。
ADBモードになります。
左側の文字が、「shell@SH-M04:/」となりましたね?
これは私がSHARPの機種を使っているからで、皆様の環境では繋いでいるスマホ機種によって文字列は変わります。
これが、パソコン側から、SH-M04(つまりスマホ側)を操作できますよ~という状態です。
早速、先ほど、空っぽだったフォルダに行ってみましょう。
普通に、cd、ls、pwdといったコマンドが利用可能です。
cd /data/data/{パッケージ名}/database/
パッケージ名は説明しなくても大丈夫ですよね?
ソースコードの先頭に書いてあるやつです。
フォルダを移ったら、lsしてみましょう。
ええ。。権限がない。。。
そうなんです。どうやらスマホ本体ではない、よそ様のパソコン様からはアクセスが拒否されてしまう模様。。
むむむ、そこまでデータを守りたいか。このセキュリティの鬼め。
それならこちらにも、策があるのじゃ。
run-as {パッケージ名}
と打ち込んでみてください。
そしてもう一度、databaseフォルダへcdして、lsしましょう。
おお!!!
ついに.dbの姿を捉えたぞっ!!!
何をしたかというと、run as 命令で、自作アプリに成りすましてアクセスしてるんです。
厳重なセキュリティでも、さすがにアプリそのもののアクセスを拒否するわけにはいきませんからね。
データファイルをパソコンにコピーしよう
場所さえわかればこっちのもんでぃ!
PULL命令で、スマホ側のデータを頂いてきましょう!
ADBモードを解除する必要があるので、一度コマンドプロンプトは「×」で落とします。
再度「cmd」で開きましょう。
※exitでも抜けれます。C:\\_という入力ラインになればOKです。
ファイルの取り出しはPULL命令を使います。
adb pull {スマホ側の欲しいファイル} {パソコン側の保存先}
つまり、
「adb pull /data/data/com.example.XXXX.mapmemo/databases/PlaceList.db ␣C:\\」
.dbが見つからない・・・だとっ!? そんな馬鹿な!?
どうも、/database/内のデータは直接コピーできないようになっているようです。
いちいち世話の焼ける奴め・・
.dbファイルをPULL可能領域へコピー
仕方がないので、.dbを別の場所に退避します。
SDカードの中は、PULLコピーが許容されているので、そこへ移しましょう。
まずは、ADBモードでrun as 成りすましでしたね。
以下でコピーが可能です。
cp {コピーしたいファイル} {コピー先}
こんな感じです。
「cp data/data/XXXX.mapmemo/databases/PlaceList.db␣/sdcard/output.db」
output.dbという名前で出力してみます。
SDカードのパスは機種依存かもしれません。
「cd /」とすれば、ルートフォルダへ移動できるので、そこからlsとcdを駆使して、それっぽいパスを探してください。
(まぁふつうはルート直下にあると思いますけど。)
ちゃんとSDカードにコピーされたか確認してみましょう。
(∩´∀`)∩ここまでこればあと一歩ですよ。
Androidにコピー命令がない、はデマ?
この手の情報をネットで調べると、最も多くHITするやり方が、
cat {パッケージ名}/AAA.db >/sdcard/BBB.db
なんです。
なにやら、androidにはコピー命令がないから、一度参照命令であるcatで開いたテキストを、「>」で別のファイルに吐き出してやるしかないとか解説されている。
確かにこのやり方、Android4.4だった旧スマホで一度うまくいったんですけど、
現役のAndroid6.0だと、何故か失敗・・・
このせいで半日棒に振ってしまいました・・・(/_;)
バージョンが新しいとコピーに対応してるということなんでしょうか、、、
機種によってはSDカードに書き込み権限がない!?
スマホ2台持ちの私ですが、SHARP端末では上記のやり方で成功しましたが、
HTC端末では、同じ命令を投げているのに、/sdcard/output.dbでPermission denied(権限ないよ)エラーが出ました・・・
一応sdcardフォルダにoutput.dbはできるみたいなんですが、0バイト・・・
う~ん、端末によってはこの方法では無理な場合があるのかもです、、
改めてPULLしてパソコン側に取り込み
PULL命令は下記でしたね。
adb pull {スマホ側の欲しいファイル} {パソコン側の保存先}
ADBモードを解除して、試してみましょう!
今度はSDカードがコピー元なので、
「adb pull /sdcard/output.db␣C:\Users\XXXX」
となりますね。
なにやら100%と出れております。
早速フォルダをあさってみましょう。
やっとキタ━━━━(゚∀゚)━━━━!!
ここまでこれば、あとは煮るなり焼くなり。
DBツールで加工してやりましょう!
DB Browser for SQLiteを使えば、この通り、中身が見れる~
転送先は、Androidインストールフォルダ限定??
普通に考えて、PULLする先は、どこでもいい気がするのですが、
何故かほかのフォルダを指定するとエラーになるようです。
適当に関係ないpythonフォルダにコピーしようとすると、このザマです。
よくわかりませんが、AndroidStudioインストール先か、AndroidStudioProjectsと同列フォルダじゃないとだめなのかもしれません。
まとめ
SQLiteのデータ取り出しの手順をまとめると、次の通りです。
①adb shell
②run-as {パッケージ名}
③cp /data/data/{パッケージ名}/databases/{データベース名}.db␣/sdcard/output.db
④exit ※2回
⑤adb pull /sdcard/output.db␣C:XXX (AndroidStudio導入先)
加工データの戻し方
さて、喜ぶのはまだ早い。
加工データをスマホ側に戻さないと、目標達成できませんね。
適当にDB値を変えて、input.dbとして保存しました。
これをスマホに戻してみましょう。
基本的には、取り出しの逆をやるだけなので、簡単ですよ。
①cd {input.dbの保存先}
②adb push ./input.db␣/sdcard/
③adb shell
④run-as {パッケージ名}
⑤cp /sdcard/input.db␣/data/data/{パッケージ名}/databases/{データベース名}.db
そのままアプリを起動すると、この通り!
やりましたっ!ちゃんと値が変わっている!!