質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

1回答

5136閲覧

assets内のDBからのデータの読み込みが出来ない

heyasumi411

総合スコア11

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

0グッド

0クリップ

投稿2017/01/24 16:05

http://y-anz-m.blogspot.jp/2011/01/android-sqline-database.html
こちらの方のコードを元にassetsに格納したDBからデータを呼び出す方法を用いたのですが、一覧表示を行おうとすると強制終了してしまいました。
logcatを確認してみると
「Caused by: android.database.sqlite.SQLiteException: no such table: Item (code 1): , while compiling: SELECT * FROM Item」
といったログがあったため、正常にDBが読み込まれていないのかなと思いました。

恐らくDBのコピーが正常に行われていないと思い確認してみたのですがいまいちどこが原因なのかがわかりませんでした。
是非ご教授ください。

java

1public class MyOpenHelper extends SQLiteOpenHelper { 2 private static String DB_NAME = "LocationDB.db"; 3 private static String DB_NAME_ASSET = "LocationDB.db"; 4 private static final int DATABASE_VERSION = 17; 5 6 private SQLiteDatabase mDatabase; 7 private final Context mContext; 8 private final File mDatabasePath; 9 10 public MyOpenHelper(Context context) { 11 super(context, DB_NAME, null, DATABASE_VERSION); 12 mContext = context; 13 mDatabasePath = mContext.getDatabasePath(DB_NAME); 14 } 15 16 /** 17 * asset に格納したデータベースをコピーするための空のデータベースを作成する 18 */ 19 public void createEmptyDataBase() throws IOException { 20 boolean dbExist = checkDataBaseExists(); 21 if (dbExist) { 22 // すでにデータベースは作成されている 23 } else { 24 // 空のデータベースをデフォルトシステムパスに作成 25 SQLiteDatabase db_Read = this.getReadableDatabase(); 26 db_Read.close(); 27 28 try { 29 // asset に格納したデータベースをコピーする 30 copyDataBaseFromAsset(); 31 32 String dbPath = mDatabasePath.getAbsolutePath(); 33 SQLiteDatabase checkDb = null; 34 try { 35 checkDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE); 36 } catch (SQLiteException e) { 37 } 38 39 if (checkDb != null) { 40 checkDb.setVersion(DATABASE_VERSION); 41 checkDb.close(); 42 } 43 44 } catch (IOException e) { 45 throw new Error("Error copying database"); 46 } 47 } 48 } 49 50 /** 51 * 再コピーを防止するために、すでにデータベースがあるかどうか判定する 52 * 53 * @return 存在している場合 {@code true} 54 */ 55 private boolean checkDataBaseExists() { 56 String dbPath = mDatabasePath.getAbsolutePath(); 57 58 SQLiteDatabase checkDb = null; 59 try { 60 checkDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY); 61 } catch (SQLiteException e) { 62 // データベースはまだ存在していない 63 } 64 65 if (checkDb == null) { 66 // データベースはまだ存在していない 67 return false; 68 } 69 70 int oldVersion = checkDb.getVersion(); 71 int newVersion = DATABASE_VERSION; 72 73 if (oldVersion == newVersion) { 74 // データベースは存在していて最新 75 checkDb.close(); 76 return true; 77 } 78 79 // データベースが存在していて最新ではないので削除 80 File f = new File(dbPath); 81 f.delete(); 82 return false; 83 } 84 85 /** 86 * asset に格納したデーだベースをデフォルトのデータベースパスに作成したからのデータベースにコピーする 87 */ 88 private void copyDataBaseFromAsset() throws IOException{ 89 90 // asset 内のデータベースファイルにアクセス 91 InputStream mInput = mContext.getAssets().open(DB_NAME_ASSET); 92 93 // デフォルトのデータベースパスに作成した空のDB 94 OutputStream mOutput = new FileOutputStream(mDatabasePath); 95 96 // コピー 97 byte[] buffer = new byte[1024]; 98 int size; 99 while ((size = mInput.read(buffer)) > 0) { 100 mOutput.write(buffer, 0, size); 101 } 102 103 // Close the streams 104 mOutput.flush(); 105 mOutput.close(); 106 mInput.close(); 107 } 108 109 public SQLiteDatabase openDataBase() throws SQLException { 110 return getReadableDatabase(); 111 } 112 113 @Override 114 public void onCreate(SQLiteDatabase db) { 115 } 116 117 @Override 118 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 119 } 120 121 @Override 122 public synchronized void close() { 123 if(mDatabase != null) 124 mDatabase.close(); 125 126 super.close(); 127 } 128}

Java

1public class sdb extends Activity { 2 protected SQLiteDatabase db; 3 protected Cursor cursor; 4 protected ListAdapter adapter; 5 protected ListView cigaretteList; 6 @Override 7 public void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.showdatabase); 10 db = (new MyOpenHelper(this)).getWritableDatabase(); 11 cigaretteList = (ListView)findViewById(R.id.lvkiso); 12 Cursor c = db.query("Item",null, null, null, null, null, null); 13 c.moveToFirst(); 14 cigaretteList.setAdapter(new SimpleCursorAdapter(this, 15 R.layout.list_item, 16 c, 17 new String[] {"ID", "Name", "Temp"}, 18 new int[] {R.id.ID, R.id.Name, R.id.Temp})); 19 } 20}

確認したこと
assets内のDBの中身の確認

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Assetの中にItemテーブルが存在することは確認したんですね?
それならデータベースにselectを行う直前でデータベースファイルを適当な場所にコピーし、中身を確認してみましょう。

投稿2017/01/24 16:20

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

heyasumi411

2017/01/24 16:54

selectを行う前(sdb.java)を実行する前にasset内のDBファイルをコピーして中身を確認してみたところ、中身は元のデータベースファイルと同一の内容でした。 もしかしたらスクリプト内に文章を加えてコピーするということなのかも知れませんが、そういった場合はどのような構文を付け加えるべきでしょうか?
yona

2017/01/24 17:07

「もしかしたら」以降の文章の意味がわかりません。 assetの中のdbファイルが正しいことはわかったので、onCreateのdb.queryの直前でdbファイルをパソコンからアクセスできるパスにコピーしてください。
heyasumi411

2017/01/24 20:17

とても恥ずかしいのですが、db.queryの直前でdbファイルを出力する方法を調べたところ見当たりませんでした。実機ではなくエミュレータ上で起動している為、SDカードなどに保存するといった方法が取れませんでした。 一応db.queryの直前でreturnを挿入してsdb.javaを実行した後にコマンドプロンプトを用いて仮想デバイス内のdataフォルダの中身を確認してみたのですが、/data/data/com.example.sqlitesample1/databases/LocationDB.dbは存在しないと返ってきました。
yona

2017/01/25 00:59

assetからdata/data/com.example.sqlitesample1/databases/LocationDB.dbへのコピーが失敗しているんですね。 それなら書き込み時のエラーログが出ていると思うので確認してください。
heyasumi411

2017/01/25 01:47

上記returnを挿入したままの状態でlogcatの内容を出力してみたところ、 Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) というログが頻発していました。調べてみたところ、ファイルが存在していない時に発生する例外みたいです。素人考えですが、InputStreamが上手く機能していないのかな、と… 以下エラー部分の抜粋です。 01-25 01:13:36.710 E/Hyphenator( 1205): error loading hyphenation /system/usr/hyphen-data/hyph-en-us.pat.txt 01-25 01:13:36.710 E/Hyphenator( 1205): java.io.FileNotFoundException: /system/usr/hyphen-data/hyph-en-us.pat.txt: open failed: ENOENT (No such file or directory) 01-25 01:13:36.710 E/Hyphenator( 1205): at libcore.io.IoBridge.open(IoBridge.java:452) 01-25 01:13:36.710 E/Hyphenator( 1205): at libcore.io.IoUtils$FileReader.<init>(IoUtils.java:207) 01-25 01:13:36.710 E/Hyphenator( 1205): at libcore.io.IoUtils.readFileAsString(IoUtils.java:114) 01-25 01:13:36.710 E/Hyphenator( 1205): at android.text.Hyphenator.loadHyphenator(Hyphenator.java:96) 01-25 01:13:36.710 E/Hyphenator( 1205): at android.text.Hyphenator.init(Hyphenator.java:154) 01-25 01:13:36.710 E/Hyphenator( 1205): at com.android.internal.os.ZygoteInit.preloadTextResources(ZygoteInit.java:207) 01-25 01:13:36.710 E/Hyphenator( 1205): at com.android.internal.os.ZygoteInit.preload(ZygoteInit.java:186) 01-25 01:13:36.710 E/Hyphenator( 1205): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593) 01-25 01:13:36.710 E/Hyphenator( 1205): Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory) 01-25 01:13:36.710 E/Hyphenator( 1205): at libcore.io.Posix.open(Native Method) 01-25 01:13:36.710 E/Hyphenator( 1205): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186) 01-25 01:13:36.710 E/Hyphenator( 1205): at libcore.io.IoBridge.open(IoBridge.java:438) 01-25 01:13:36.710 E/Hyphenator( 1205): ... 7 more 01-25 01:13:36.710 E/Hyphenator( 1205): error loading hyphenation /system/usr/hyphen-data/hyph-eu.pat.txt 01-25 01:13:36.710 E/Hyphenator( 1205): java.io.FileNotFoundException: /system/usr/hyphen-data/hyph-eu.pat.txt: open failed: ENOENT (No such file or directory)
yona

2017/01/25 01:51

関係なさそうです。 copyDataBaseFromAssetメソッドの最後にログ出力を行いログが出力されるかを確認してください。
heyasumi411

2017/01/26 07:04

返信遅れました。 copyDataBaseFromAssetメソッドの最後にログ出力をする為には、copyDataBaseFromAssetメソッドの次にlog.eなどを挿入してlogcatのログを確認すれば良いのでしょうか?
yona

2017/01/26 07:09

メソッドの外じゃないですよ。メソッドの中の最後に書いてください。 mInput.close();の後です。
heyasumi411

2017/01/26 11:41

コメント頂いた位置にLogを挿入しlogcatでログを取ってみたところ出力されました。open failed: ENOENTが数回と、下記のようなエラーログが発生していました。 --------- beginning of crash 01-26 08:38:23.915 E/AndroidRuntime( 1885): FATAL EXCEPTION: main 01-26 08:38:23.915 E/AndroidRuntime( 1885): Process: com.android.launcher3, PID: 1885 01-26 08:38:23.915 E/AndroidRuntime( 1885): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.launcher3/com.android.launcher3.Launcher}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.appwidget.AppWidgetHostView$ParcelableSparseArray instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x4. Make sure other views do not use the same id. 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread.-wrap15(ActivityThread.java) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.os.Handler.dispatchMessage(Handler.java:102) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.os.Looper.loop(Looper.java:148) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread.main(ActivityThread.java:5417) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at java.lang.reflect.Method.invoke(Native Method) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-26 08:38:23.915 E/AndroidRuntime( 1885): Caused by: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.appwidget.AppWidgetHostView$ParcelableSparseArray instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x4. Make sure other views do not use the same id. 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.View.onRestoreInstanceState(View.java:14771) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.widget.TextView.onRestoreInstanceState(TextView.java:4058) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.View.dispatchRestoreInstanceState(View.java:14746) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3127) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.view.View.restoreHierarchyState(View.java:14724) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2035) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.Activity.onRestoreInstanceState(Activity.java:1004) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at com.android.launcher3.Launcher.onRestoreInstanceState(Launcher.java:1950) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.Activity.performRestoreInstanceState(Activity.java:959) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1163) 01-26 08:38:23.915 E/AndroidRuntime( 1885): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2389) 01-26 08:38:23.915 E/AndroidRuntime( 1885): ... 10 more
yona

2017/01/26 12:33

なにをやったんですか? ログ出力しただけではそんなエラーは発生しません。
heyasumi411

2017/01/26 12:55

手順としましては、mInput.close(); の直後にlogを挿入した後、コマンドプロンプトからadb logcat -v time > log.txtを入力してログをテキストファイルで出力されるようにした後exlipseのデバッグモードでエミュレータを起動させました。エミュレータの起動後エミュレータを閉じて作成されたテキストファイルからログを転載した形です。
yona

2017/01/26 13:34

「logを挿入した」とは、具体的になにを書いたんですか?
heyasumi411

2017/01/26 14:24

Log.v("it", "debuglog text"); Log.d("it", "debuglog text"); Log.i("it", "debuglog text"); Log.w("it", "debuglog text"); Log.e("it", "debuglog text"); と書き込みました
yona

2017/01/26 16:45

プロジェクト内でView#setIdとか使っていますか?
heyasumi411

2017/01/26 17:27

いえ、このプロジェクト内のクラス全てでsetIdは使っていません。
yona

2017/01/27 01:42

ログを出力するのは諦めましょう、何かが変です。 sdb#onCreateのデータベースにアクセスする直前で下記を行なってください。 ・new File("data/data/com.example.sqlitesample1/databases/LocationDB.db").exist()をToastで表示してください。
heyasumi411

2017/01/27 04:18

sdb#onCreateの直前にToastの出力をしようとしたところToastが表示されませんでした。 そこで、sdbに遷移する前のactivityでstartActivity(intent);でsdbに遷移する直前に上記Toastの出力を行ったところ、Trueが返ってきました。
yona

2017/01/27 05:30

クラスの上から順番にメソッドが呼ばれると思っていますか?
heyasumi411

2017/01/27 06:14

確かに考えてみたら、sdb#onCreateだとアクティビティの開始と共に処理が行われるので、それより前に記述しても意味がないことに気づきました、申し訳ありません。 override以下を下記のように書き直してエミュレータを起動して確認したところ、ToastにTrueが表示されました。 @Override public void onCreate(Bundle savedInstanceState) { File file = new File("data/data/com.example.sqlitesample1/databases/LocationDB.db"); boolean a=file.exists(); String str1 = String.valueOf( a ); Toast.makeText(this,str1,Toast.LENGTH_LONG).show(); super.onCreate(savedInstanceState); setContentView(R.layout.showdatabase); db = (new MyOpenHelper(this)).getWritableDatabase(); cigaretteList = (ListView)findViewById(R.id.lvkiso); return; // Cursor c = db.query("Item",null, null, null, null, null, null); // c.moveToFirst(); // cigaretteList.setAdapter(new SimpleCursorAdapter(this, // R.layout.list_item, // c, // new String[] {"ID", "Name", "Temp"}, // new int[] {R.id.ID, R.id.Name, R.id.Temp})); }
yona

2017/01/27 06:33 編集

やっぱり理解していないですね。 クラス内でメソッドA、メソッドBの順に記載したからと言ってメソッドAが必ずメソッドBよりも先に呼ばれるというわけではありません。 一度アプリケーションを削除してから実行してください。
heyasumi411

2017/01/27 07:39

一度アプリケーションを削除してから実行というのはどのようにすればよいのでしょうか? アプリケーションが指すものが何かがわからないです…
abs123

2017/01/27 08:01

横から失礼します。 heyasumi411さん、推測ですが、 MyOpenHelperクラスはとあるサイトのサンプルコードを参考に実装したものではないでしょうか? そのような場合は、参考にされたサイトのURL等を張っておくことをおすすめします。
yona

2017/01/27 08:16

パーミッションは書いていますか?
heyasumi411

2017/01/27 08:22

android.Manifest.xmlに書き込むものでしたら、android.permission.WRITE_EXTERNAL_STORAGEだけは書き込んでいます。
yona

2017/01/27 08:49

Android端末側の設定でパーミッションは与えていますか?
heyasumi411

2017/01/27 09:24

エミュレータ上で設定からアプリの項目を開き当該アプリの権限を確認したところ、ストレージに対して許可が行われていました。
yona

2017/01/28 03:50

パーミッションは大丈夫そうですね。 とりあえずリード権限も付けておきましょう。 また、エミュレータからアプリケーションをアンインストールしてから再度アプリを実行してください。
heyasumi411

2017/01/28 04:39

>リード権限 すいません、パーミッションの一覧から該当するパーミッションを探してみましたが、どれが当てはまるものかの判別がつきませんでした。READ_INPUT_STATEでしょうか? エミュレータを起動した後アプリケーションのアンインストールをした後、コマンドプロンプトを用いて再度アプリケーションをインストールしsdbを始動させたところtrueが返ってきました
yona

2017/01/28 11:42

リファレンスを読みましょう、パーミッションはREAD_EXTERNAL_STORAGEです。 ・データベースにアクセスしているのはsdbだけですか? ・copyDataBaseFromAssetの先頭にあるdbExistの値をトーストで出力してください。その後アプリをアンインストールして再度実行してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問