簡體   English   中英

為什么我的 SQLite 數據庫沒有從 Android Studio 中的資產加載?

[英]Why isn't my SQLite database loading from Assets in Android Studio?

我正在嘗試將現有的 SQLite 數據庫加載到 Android Studio 中。 但是,數據庫適配器返回一個空數據庫,而不是給我已填充數據庫的副本。

我有我的權限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我的數據庫適配器

package com.example.testbed;

import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

public class DBAdapter extends SQLiteOpenHelper{
    public static final String TAG = DBAdapter.class.getSimpleName();
    public static int flag;
    private static SQLiteDatabase db;
    private static String DB_NAME = "recipes.db";
    public static String TABLE_NAME = "DrinkRecipes_Loaded";
    public static String DB_PATH = "";
    public static String COL_WORD = "WORD";
    String outFileName = "";
    public static Context myContext;
    private String loadedTable = "DrinkRecipes_Loaded";
    private String specialtyTable = "DrinkRecipes_Specialty";
    private String beautyTable = "DrinkRecipes_Beauty";
    private String kidsTable = "DrinkRecipes_Kids";
    private String shakesTable = "DrinkRecipes_Shakes";



    public DBAdapter(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
        ContextWrapper cw = new ContextWrapper(context);
        DB_PATH = "/data/data" + BuildConfig.APPLICATION_ID + "/databases/";
        Log.e(TAG, "Databasehelper: DB_PATH " + DB_PATH);
        outFileName = DB_PATH + DB_NAME;
        File file = new File(DB_PATH);
        Log.e(TAG, "Databasehelper: " + file.exists());
        if (!file.exists()) {
            file.mkdir();
        }
    }

    /**
     * Creates a empty database on the system and rewrites it with your own database.
     */
    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
            //do nothing - database already exist
        } else {
            //By calling this method and empty database will be created into the default system path
            //of your application so we are gonna be able to overwrite that database with our database.
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     *
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            checkDB = SQLiteDatabase.openDatabase(outFileName, null, SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            try {
                copyDataBase();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }

        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     */

    private void copyDataBase() throws IOException {

        Log.i("Database",
                "New database is being copied to device!");
        byte[] buffer = new byte[1024];
        OutputStream myOutput = null;
        int length;
        // Open your local db as the input stream
        InputStream myInput = null;
        try {
            myInput = myContext.getAssets().open(DB_NAME);
            // transfer bytes from the inputfile to the
            // outputfile
            myOutput = new FileOutputStream(DB_PATH + DB_NAME);
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.close();
            myOutput.flush();
            myInput.close();
            Log.i("Database",
                    "New database has been copied to device!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void openDataBase() throws SQLException {
        //Open the database
        String myPath = DB_PATH + DB_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        Log.e(TAG, "openDataBase: Open " + db.isOpen());
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<recipeModal> readLoadedRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor cursorRecipes = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);

        // on below line we are creating a new array list.
        ArrayList<recipeModal> recipeModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (cursorRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                recipeModalArrayList.add(new recipeModal(cursorRecipes.getString(0),
                        cursorRecipes.getString(1),
                        cursorRecipes.getString(2),
                        cursorRecipes.getString(3),
                        cursorRecipes.getString(4),
                        cursorRecipes.getString(5),
                        cursorRecipes.getString(6),
                        cursorRecipes.getString(7),
                        cursorRecipes.getString(8)));
            } while (cursorRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        cursorRecipes.close();
        return recipeModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<beautyModal> readBeautyRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor beautyRecipes = db.rawQuery("SELECT * FROM " + beautyTable, null);

        // on below line we are creating a new array list.
        ArrayList<beautyModal> beautyModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (beautyRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                beautyModalArrayList.add(new beautyModal(beautyRecipes.getString(0),
                        beautyRecipes.getString(1),
                        beautyRecipes.getString(2),
                        beautyRecipes.getString(3),
                        beautyRecipes.getString(4),
                        beautyRecipes.getString(5)));
            } while (beautyRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        beautyRecipes.close();
        return beautyModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<specialtyModal> readSpecialtyRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor specialtyRecipes = db.rawQuery("SELECT * FROM " + specialtyTable, null);

        // on below line we are creating a new array list.
        ArrayList<specialtyModal> specialtyModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (specialtyRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                specialtyModalArrayList.add(new specialtyModal(specialtyRecipes.getString(0),
                        specialtyRecipes.getString(1),
                        specialtyRecipes.getString(2),
                        specialtyRecipes.getString(3),
                        specialtyRecipes.getString(4),
                        specialtyRecipes.getString(5),
                        specialtyRecipes.getString(6),
                        specialtyRecipes.getString(7)));
            } while (specialtyRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        specialtyRecipes.close();
        return specialtyModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<kidsModal> readKidsRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor kidsRecipes = db.rawQuery("SELECT * FROM " + kidsTable, null);

        // on below line we are creating a new array list.
        ArrayList<kidsModal> kidsModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (kidsRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                kidsModalArrayList.add(new kidsModal(kidsRecipes.getString(0),
                        kidsRecipes.getString(1),
                        kidsRecipes.getString(2),
                        kidsRecipes.getString(3),
                        kidsRecipes.getString(4)));
            } while (kidsRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        kidsRecipes.close();
        return kidsModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<shakesModal> readShakesRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor shakesRecipes = db.rawQuery("SELECT * FROM " + shakesTable, null);

        // on below line we are creating a new array list.
        ArrayList<shakesModal> shakesModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (shakesRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                shakesModalArrayList.add(new shakesModal(shakesRecipes.getString(0),
                        shakesRecipes.getString(1),
                        shakesRecipes.getString(2),
                        shakesRecipes.getString(3),
                        shakesRecipes.getString(4)));
            } while (shakesRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        shakesRecipes.close();
        return shakesModalArrayList;
    }


    @Override
    public synchronized void close() {
        if (db != null)
            db.close();
        super.close();
    }

    public void onCreate(SQLiteDatabase arg0) {


    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

    }
}

當我調用它時,我唯一得到的是一個崩潰的應用程序和一個寫入正確路徑的空數據庫。 我非常渴望找到解決此問題的方法,並希望得到任何反饋。

我嘗試了幾種在 Google 上看起來很有前途的不同解決方案,但沒有成功。

編輯:錯誤的堆棧跟蹤


    E/SQLiteLog: (1) no such table: DrinkRecipes_Loaded in "SELECT * FROM DrinkRecipes_Loaded"
    D/AndroidRuntime: Shutting down VM
    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.testbed, PID: 4732
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testbed/com.example.testbed.ViewRecipes}: android.database.sqlite.SQLiteException: no such table: DrinkRecipes_Loaded (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM DrinkRecipes_Loaded
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3851)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4027)
            at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:247)
            at android.app.ActivityThread.main(ActivityThread.java:8676)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
         Caused by: android.database.sqlite.SQLiteException: no such table: DrinkRecipes_Loaded (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM DrinkRecipes_Loaded
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1463)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:901)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:62)
            at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
            at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
            at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:2063)
            at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:2002)
            at com.example.testbed.DBAdapter.readLoadedRecipes(DBAdapter.java:128)
            at com.example.testbed.ViewRecipes.onCreate(ViewRecipes.java:84)
            at android.app.Activity.performCreate(Activity.java:8215)
            at android.app.Activity.performCreate(Activity.java:8199)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3824)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4027) 
            at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336) 
            at android.os.Handler.dispatchMessage(Handler.java:106) 
            at android.os.Looper.loop(Looper.java:247) 
            at android.app.ActivityThread.main(ActivityThread.java:8676) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) 

您的代碼存在一些問題。

  1. 您正在嘗試將數據庫文件設為目錄而不是將父目錄設為目錄。

  2. 您不適合后來的 android 版本,這些版本默認使用 WAL(預寫日志記錄),而不是在創建(復制資產)時使用getReabableDatabase進行日志記錄。

  • getReadableDatabase將按照它所說的那樣創建數據庫。 然后副本會覆蓋它(如果有效)。
  • 但是,在 WAL 模式下,會為 WAL 日志記錄創建兩個附加文件並相應地進行填充。 然后:
  • 復制資產后,SQLite 確定 WAL 文件不是復制數據庫的 WAL 文件,因此無法打開可能損壞的數據庫。
  • Android API 檢測到此故障,但按照要求執行並創建一個空數據庫,因此找不到表

使用getReadableDatabase只是為了繞過不存在的數據庫目錄是矯枉過正/效率低下的,因為創建新數據庫的所有處理都已進行。

這是您的代碼的重寫,請注意:-

  • 所有的訪問方法都被注釋掉了(而不是創建所有的類)
  • createDatabasecheckDatabase方法已被注釋掉。 它們已被getDatabase方法取代。
  • 如果發生 io 錯誤, CopyDatabase方法已更改為返回 false(getDatabase 然后拋出 runTimeException)

getDatabase方法

  • 檢查數據庫是否存在,如果存在則返回。 否則,它
  • 檢查 parentFile(數據庫目錄)是否存在,
    • 如果不是,那么它會生成目錄(可能還有其他目錄,盡管它們應該始終存在)
  • 調用CopyDatabase方法

所以代碼(大部分原始代碼被注釋掉了)是:-

public class DBAdapter extends SQLiteOpenHelper {
   public static final String TAG = DBAdapter.class.getSimpleName();
   public static int flag;
   private static SQLiteDatabase db;
   private static String DB_NAME = "recipes.db";
   public static String TABLE_NAME = "DrinkRecipes_Loaded";
   public static String DB_PATH = "";
   public static String COL_WORD = "WORD";
   String outFileName = "";
   public static Context myContext;
   private String loadedTable = "DrinkRecipes_Loaded";
   private String specialtyTable = "DrinkRecipes_Specialty";
   private String beautyTable = "DrinkRecipes_Beauty";
   private String kidsTable = "DrinkRecipes_Kids";
   private String shakesTable = "DrinkRecipes_Shakes";



   public DBAdapter(Context context) {
      super(context, DB_NAME, null, 1);
      this.myContext = context;
      //ContextWrapper cw = new ContextWrapper(context); Not used
      DB_PATH = context.getDatabasePath(DB_NAME).getPath();  // no need to hard code anything bar the DB name
      /*
      //DB_PATH = "/data/data" + BuildConfig.APPLICATION_ID + "/databases/";
      Log.e(TAG, "Databasehelper: DB_PATH " + DB_PATH);
      outFileName = DB_PATH + DB_NAME;
      File file = new File(DB_PATH);
      Log.e(TAG, "Databasehelper: " + file.exists());
      if (!file.exists()) {
         file.getParentFile().mkdirs(); // CHANGED you don't want the database to be a directory
      }
       */
      getDatabase(context);
   }

   /*<<<<< ADDED >>>>>*/
   private void getDatabase(Context context) {
      File dbFile = new File(context.getDatabasePath((DB_NAME)).getPath());
      if (dbFile.exists()) return; // Database found so all done
      // Otherwise ensure that the database directory exists (does not by default until later versions)
      if (!dbFile.getParentFile().exists()) {
         dbFile.getParentFile().mkdirs();
      }
      if (!copyDataBase()) {
         throw new RuntimeException("Unable to copy database from the asset (check the stack-trace).");
      }
   }

   /**
    * Creates a empty database on the system and rewrites it with your own database.
    */
   /* NOTE NEEDED/UNSAFE as getDatabase create a database and for later version of Android it will be in WAL mode
      thus the additional WAL files are created. When the database is then opened SQLite see that the WAL files are not
      for the copied database and thus the open fails. Android's API then creates an new empty database file
    */
   /*
   public void createDataBase() throws IOException {
      boolean dbExist = checkDataBase();
      if (dbExist) {
         //do nothing - database already exist
      } else {
         //By calling this method and empty database will be created into the default system path
         //of your application so we are gonna be able to overwrite that database with our database.
         this.getReadableDatabase(); // Causes issues if in WAL mode and result in database
         try {
            copyDataBase();
         } catch (IOException e) {
            throw new Error("Error copying database");
         }
      }
   }

    */

   /**
    * Check if the database already exist to avoid re-copying the file each time you open the application.
    *
    * @return true if it exists, false if it doesn't
    */
   /*
   private boolean checkDataBase() {
      SQLiteDatabase checkDB = null;
      try {
         checkDB = SQLiteDatabase.openDatabase(outFileName, null, SQLiteDatabase.OPEN_READONLY);
      } catch (SQLiteException e) {
         try {
            copyDataBase();
         } catch (IOException e1) {
            e1.printStackTrace();
         }
      }

      if (checkDB != null) {
         checkDB.close();
      }
      return checkDB != null ? true : false;
   }

    */

   /**
    * Copies your database from your local assets-folder to the just created empty database in the
    * system folder, from where it can be accessed and handled.
    * This is done by transfering bytestream.
    */

   private boolean /* <<<<< CHANGED SIGNATURE */ copyDataBase() {
      Log.i("Database",
              "New database is being copied to device!");
      byte[] buffer = new byte[4096]; //Probably more efficient as default page size will be 4k
      OutputStream myOutput = null;
      int length;
      // Open your local db as the input stream
      InputStream myInput = null;
      try {
         myInput = myContext.getAssets().open(DB_NAME);
         // transfer bytes from the inputfile to the
         // outputfile
         myOutput = new FileOutputStream(DB_PATH);
         while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
         }
         myOutput.close();
         myOutput.flush();
         myInput.close();
         Log.i("Database",
                 "New database has been copied to device!");
      } catch (IOException e) {
         e.printStackTrace();
         return false;
      }
      return true;
   }

   public void openDataBase() throws SQLException {
      //Open the database
      String myPath = DB_PATH + DB_NAME;
      db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
      Log.e(TAG, "openDataBase: Open " + db.isOpen());
   }
   /*
   // we have created a new method for reading loaded recipes.
   public ArrayList<recipeModal> readLoadedRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor cursorRecipes = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);

      // on below line we are creating a new array list.
      ArrayList<recipeModal> recipeModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (cursorRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            recipeModalArrayList.add(new recipeModal(cursorRecipes.getString(0),
                    cursorRecipes.getString(1),
                    cursorRecipes.getString(2),
                    cursorRecipes.getString(3),
                    cursorRecipes.getString(4),
                    cursorRecipes.getString(5),
                    cursorRecipes.getString(6),
                    cursorRecipes.getString(7),
                    cursorRecipes.getString(8)));
         } while (cursorRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      cursorRecipes.close();
      return recipeModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<beautyModal> readBeautyRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor beautyRecipes = db.rawQuery("SELECT * FROM " + beautyTable, null);

      // on below line we are creating a new array list.
      ArrayList<beautyModal> beautyModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (beautyRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            beautyModalArrayList.add(new beautyModal(beautyRecipes.getString(0),
                    beautyRecipes.getString(1),
                    beautyRecipes.getString(2),
                    beautyRecipes.getString(3),
                    beautyRecipes.getString(4),
                    beautyRecipes.getString(5)));
         } while (beautyRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      beautyRecipes.close();
      return beautyModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<specialtyModal> readSpecialtyRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor specialtyRecipes = db.rawQuery("SELECT * FROM " + specialtyTable, null);

      // on below line we are creating a new array list.
      ArrayList<specialtyModal> specialtyModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (specialtyRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            specialtyModalArrayList.add(new specialtyModal(specialtyRecipes.getString(0),
                    specialtyRecipes.getString(1),
                    specialtyRecipes.getString(2),
                    specialtyRecipes.getString(3),
                    specialtyRecipes.getString(4),
                    specialtyRecipes.getString(5),
                    specialtyRecipes.getString(6),
                    specialtyRecipes.getString(7)));
         } while (specialtyRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      specialtyRecipes.close();
      return specialtyModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<kidsModal> readKidsRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor kidsRecipes = db.rawQuery("SELECT * FROM " + kidsTable, null);

      // on below line we are creating a new array list.
      ArrayList<kidsModal> kidsModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (kidsRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            kidsModalArrayList.add(new kidsModal(kidsRecipes.getString(0),
                    kidsRecipes.getString(1),
                    kidsRecipes.getString(2),
                    kidsRecipes.getString(3),
                    kidsRecipes.getString(4)));
         } while (kidsRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      kidsRecipes.close();
      return kidsModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<shakesModal> readShakesRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor shakesRecipes = db.rawQuery("SELECT * FROM " + shakesTable, null);

      // on below line we are creating a new array list.
      ArrayList<shakesModal> shakesModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (shakesRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            shakesModalArrayList.add(new shakesModal(shakesRecipes.getString(0),
                    shakesRecipes.getString(1),
                    shakesRecipes.getString(2),
                    shakesRecipes.getString(3),
                    shakesRecipes.getString(4)));
         } while (shakesRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      shakesRecipes.close();
      return shakesModalArrayList;
   }


    */

   @Override
   public synchronized void close() {
      if (db != null)
         db.close();
      super.close();
   }

   public void onCreate(SQLiteDatabase arg0) {
   }

   @Override
   public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
   }
}

以上已經過測試,但使用重命名為 recipes.db 的替代數據庫(NorthWind,因為它非常大)新安裝的日志:-

2022-03-27 10:22:11.223 I/Database: New database is being copied to device!
2022-03-27 10:22:11.455 I/Database: New database has been copied to device!

AppInspection 確認數據庫已成功復制(盡管不是您的數據庫):-

在此處輸入圖像描述

同樣,設備文件資源管理器顯示:- 在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM