【问题标题】:"no such table" issue in android on some devices某些设备上的 android 中的“没有这样的表”问题
【发布时间】:2013-03-18 10:48:57
【问题描述】:

我在 android 应用程序中使用了一个外部数据库,它在所有模拟器和三星真实设备上都可以正常工作。但是当我在 Acer 智能手机上查看时,我的应用程序会崩溃并出现以下异常:

android.database.sqlite.SQLiteException: no such table:

这对我来说很奇怪。我在文件资源管理器中的数据文件夹下检查了我的数据库和所有表都存在。

我不明白为什么会这样。

请指导我。提前致谢

sql helper 类的代码如下:

public class MyDatabaseHelper extends SQLiteOpenHelper {

    // System path of application database.
    private static String DB_PATH = MyApplication.getAppContext()
            .getFilesDir().getParentFile().getPath()
            + "/databases/";
    private static String DB_NAME = "myDB";
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     * 
     * @param context
     */
    public MyDatabaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }

    /**
     * Creates a empty database on the system and rewrites it with own database.
     * 
     */
    public void createDataBase() throws IOException {

        checkDataBase();
        // Creates empty database default system path
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }

    /**
     * Checks if the database already exist to avoid re-copying the file each
     * time whenever the application opened.
     * 
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase() {

        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            e.printStackTrace();
        }

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

    /**
     * Copies database from local assets-folder to the just created empty
     * database in the system folder and from where it can be accessed and
     * handled using byte stream transferring.
     * 
     */
    private void copyDataBase() throws IOException {

        // Open local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME + ".db");

        // Path of the just created empty db
        String outFileName = DB_PATH + DB_NAME;

        // Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        // transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public SQLiteDatabase openDataBase() throws SQLException {

        // Opens the database
        String myPath = DB_PATH + DB_NAME;
        return SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    }

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

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
        // TODO Auto-generated method stub
    }
}

【问题讨论】:

  • 在这里添加java代码帮助类。
  • 你使用的是默认的数据库路径吗?

标签: android sqlite android-intent android-emulator android-debug


【解决方案1】:

我终于解决了我的问题。

我只是将可读数据库放入数据库并在再次打开后将其关闭。我的完整代码如下:

 public class MyDatabaseHelper extends SQLiteOpenHelper {

    // System path of application database.
    private static String DB_PATH = MyApplication.getAppContext()
            .getFilesDir().getParentFile().getPath()
            + "/databases/";
    private static String DB_NAME = "myDB";
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     * 
     * @param context
     */
    public MyDatabaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }

    /**
     * Creates a empty database on the system and rewrites it with own database.
     * 
     */
    public void createDataBase() throws IOException {

        checkDataBase();
        SQLiteDatabase db_Read = null;

        // Creates empty database default system path
        db_Read = this.getReadableDatabase();
        db_Read.close();
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }

    /**
     * Checks if the database already exist to avoid re-copying the file each
     * time whenever the application opened.
     * 
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase() {

        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            e.printStackTrace();
        }

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

    /**
     * Copies database from local assets-folder to the just created empty
     * database in the system folder and from where it can be accessed and
     * handled using byte stream transferring.
     * 
     */
    private void copyDataBase() throws IOException {

        // Open local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME + ".db");

        // Path of the just created empty db
        String outFileName = DB_PATH + DB_NAME;

        // Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        // transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public SQLiteDatabase openDataBase() throws SQLException {

        // Opens the database
        String myPath = DB_PATH + DB_NAME;
        return SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    }

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

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
        // TODO Auto-generated method stub
    }
}

我找到了我的答案here

【讨论】:

    【解决方案2】:

    您可能已经硬编码了数据库的路径。对于不同的设备,可能会有所不同。使用Envirenment.getExternalStorageDirectory() 创建数据库路径。

    【讨论】:

    • 我通常会在代码中的哪个位置检查数据库是否是硬编码的?我认为我正在使用的代码有三个本地数据库。
    【解决方案3】:

    尝试使用这个私有静态字符串 DB_PATH = "/data/data/your package name/databases/";

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 2016-11-08
      相关资源
      最近更新 更多