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

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

ただいまの
回答率

90.12%

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

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,041

heyasumi411

score 9

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のコピーが正常に行われていないと思い確認してみたのですがいまいちどこが原因なのかがわかりませんでした。
是非ご教授ください。

public class MyOpenHelper extends SQLiteOpenHelper {
    private static String DB_NAME = "LocationDB.db";  
    private static String DB_NAME_ASSET = "LocationDB.db";  
    private static final int DATABASE_VERSION = 17;  

    private SQLiteDatabase mDatabase;  
    private final Context mContext;  
    private final File mDatabasePath;  

    public MyOpenHelper(Context context) {
        super(context, DB_NAME, null, DATABASE_VERSION);  
        mContext = context;  
        mDatabasePath = mContext.getDatabasePath(DB_NAME);  
    }  

    /** 
     * asset に格納したデータベースをコピーするための空のデータベースを作成する 
     */  
    public void createEmptyDataBase() throws IOException {  
        boolean dbExist = checkDataBaseExists();  
        if (dbExist) {  
            // すでにデータベースは作成されている  
        } else {  
            // 空のデータベースをデフォルトシステムパスに作成
            SQLiteDatabase db_Read = this.getReadableDatabase();
            db_Read.close();

            try {  
                // asset に格納したデータベースをコピーする  
                copyDataBaseFromAsset();  

                String dbPath = mDatabasePath.getAbsolutePath();  
                SQLiteDatabase checkDb = null;  
                try {  
                    checkDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);  
                } catch (SQLiteException e) {  
                }  

                if (checkDb != null) {  
                    checkDb.setVersion(DATABASE_VERSION);  
                    checkDb.close();  
                }  

            } catch (IOException e) {  
                throw new Error("Error copying database");  
            }  
        }  
    }   

    /** 
     * 再コピーを防止するために、すでにデータベースがあるかどうか判定する 
     * 
     * @return 存在している場合 {@code true} 
     */  
    private boolean checkDataBaseExists() {  
        String dbPath = mDatabasePath.getAbsolutePath();  

        SQLiteDatabase checkDb = null;  
        try {  
            checkDb = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READONLY);  
        } catch (SQLiteException e) {  
            // データベースはまだ存在していない  
        }  

        if (checkDb == null) {  
            // データベースはまだ存在していない  
            return false;  
        }  

        int oldVersion = checkDb.getVersion();  
        int newVersion = DATABASE_VERSION;  

        if (oldVersion == newVersion) {  
            // データベースは存在していて最新  
            checkDb.close();  
            return true;  
        }  

        // データベースが存在していて最新ではないので削除  
        File f = new File(dbPath);  
        f.delete();  
        return false;  
    }  

    /** 
     * asset に格納したデーだベースをデフォルトのデータベースパスに作成したからのデータベースにコピーする 
     */  
    private void copyDataBaseFromAsset() throws IOException{  

        // asset 内のデータベースファイルにアクセス  
        InputStream mInput = mContext.getAssets().open(DB_NAME_ASSET);  

        // デフォルトのデータベースパスに作成した空のDB  
        OutputStream mOutput = new FileOutputStream(mDatabasePath);  

        // コピー  
        byte[] buffer = new byte[1024];  
        int size;  
        while ((size = mInput.read(buffer)) > 0) {  
            mOutput.write(buffer, 0, size);  
        }  

        // Close the streams  
        mOutput.flush();  
        mOutput.close();  
        mInput.close();  
    }  

    public SQLiteDatabase openDataBase() throws SQLException {  
        return getReadableDatabase();  
    }  

    @Override  
    public void onCreate(SQLiteDatabase db) {  
    }  

    @Override  
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
    }  

    @Override  
    public synchronized void close() {  
        if(mDatabase != null)  
            mDatabase.close();  

            super.close();  
    }  
}  
public class sdb extends Activity {  
     protected SQLiteDatabase db;
     protected Cursor cursor;
     protected ListAdapter adapter;
     protected ListView cigaretteList;
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.showdatabase);
      db = (new MyOpenHelper(this)).getWritableDatabase();
      cigaretteList = (ListView)findViewById(R.id.lvkiso);
      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}));
    }  
}  

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/28 12:50

    パーミッションは大丈夫そうですね。
    とりあえずリード権限も付けておきましょう。

    また、エミュレータからアプリケーションをアンインストールしてから再度アプリを実行してください。

    キャンセル

  • 2017/01/28 13:39

    >リード権限
    すいません、パーミッションの一覧から該当するパーミッションを探してみましたが、どれが当てはまるものかの判別がつきませんでした。READ_INPUT_STATEでしょうか?

    エミュレータを起動した後アプリケーションのアンインストールをした後、コマンドプロンプトを用いて再度アプリケーションをインストールしsdbを始動させたところtrueが返ってきました

    キャンセル

  • 2017/01/28 20:42

    リファレンスを読みましょう、パーミッションはREAD_EXTERNAL_STORAGEです。

    ・データベースにアクセスしているのはsdbだけですか?
    ・copyDataBaseFromAssetの先頭にあるdbExistの値をトーストで出力してください。その後アプリをアンインストールして再度実行してください。

    キャンセル

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

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる