【问题标题】:My developer app problem with opening database on Android 9我的开发者应用程序在 Android 9 上打开数据库时出现问题
【发布时间】:2020-05-30 17:17:50
【问题描述】:

你能帮帮我吗?

我已在包含数据库的 Google Play 商店中创建并发布了该应用程序,我已在不同的 Android 手机上对其进行了测试。我的应用程序在 Android 版本(Android 10、8、5 等)上运行完美,但在 Android 9 上除外,你知道我该如何解决这个问题吗?我在华为 Smart Z、荣耀 P20、三星 Y6、小米米上发现了这个问题。 Play 商店控制台说我的应用程序可以在该模型上运行。我是应用程序开发的初学者。

这发生在我的Huawei Smart上:当我安装应用程序时,当我想进入数据库时​​它会打开并崩溃,当我想再次进入应用程序时它会崩溃并在logcat上:

E/Path 1: data/data/com.gema/databases/ 
E/SQLiteLog: (14) cannot open file at line 36906 of [c255889bd9]
E/SQLiteLog: (14) os_unix.c:36906: (2) open(//data/data/com.gematranslate/databases/gema_recnik.db) - 
E/SQLiteDatabase: Failed to open database 'data/data/com.gematranslate/databases/gema_recnik.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (Sqlite code 14 SQLITE_CANTOPEN): Could not open database, (OS error - 2:No such file or directory)

在 android manifest 我放了:

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

这是我检查数据库的代码:

public boolean checkDataBase() {
    SQLiteDatabase checkDB = null;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READONLY);
        myContext.getDatabasePath(DB_NAME).getPath();
        checkDB.disableWriteAheadLogging();
    } catch (SQLException e)
    {
        //
    }
    if (checkDB!= null){
        checkDB.close();
    }
    return checkDB != null? true : false;

这是我打开数据库的代码:

public void openDataBase() {
    String myPath = DB_PATH + DB_NAME;
    myContext.getDatabasePath(DB_NAME).getPath();
    db = SQLiteDatabase.openDatabase(myPath,null, SQLiteDatabase.OPEN_READWRITE);
    db.disableWriteAheadLogging();

如果有人可以帮助我,非常感谢。

【问题讨论】:

    标签: android database android-sqlite android-external-storage opendatabase


    【解决方案1】:

    这是所有 Android 版本都支持的解决方案

    public class DataBase extends SQLiteOpenHelper {
    
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "database.db";
    private static String DATABASE_PATH = "";
    private static String LAST_DATABASE_PATH = "";
    private SQLiteDatabase mDataBase;
    private final Context ctx;
    
    public DataBase2(@Nullable Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        DATABASE_PATH = context.getDatabasePath(DATABASE_NAME).getPath();
        this.ctx = context;
    
        if (!checkIfDBExists()) {
            createDataBase();
        }
    
        File dbFile = new File(Environment.getDataDirectory().getPath()+"/data/"+ BuildConfig.APPLICATION_ID +"/databases");
        if (dbFile.isDirectory()) {
            String[] child = dbFile.list();
            assert child != null;
            for (int i = 0; i < child.length; i++) {
                if (!(child[i].equals("database.db") || child[i].equals(DATABASE_NAME))) {
                    new File(dbFile, child[i]).delete();
                }
            }
        }
    }
    
    public void createDataBase() {
        this.getReadableDatabase();
        this.close();
        try {
            copyDataBase();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        try {
            File DbFile = ctx.getDatabasePath(DATABASE_NAME);
            if (DbFile.exists()) {
                copyDataBase();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private boolean checkIfDBExists() {
        File dbFile = new File(DATABASE_PATH);
        return dbFile.exists();
    }
    
    
    
    public void openDataBase() {
        close();
        mDataBase = SQLiteDatabase.openDatabase(DATABASE_PATH, null, CREATE_IF_NECESSARY);
    }
    
    private void copyDataBase() throws IOException {
        InputStream mInput = ctx.getAssets().open("database.db");
        String outfileName = DATABASE_PATH;
        OutputStream mOutput = new FileOutputStream(outfileName);
        byte[] buffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(buffer)) > 0) {
            mOutput.write(buffer, 0, mLength);
        }
        mOutput.flush();
        mInput.close();
        mOutput.close();
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
    }
    
    
    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
    
        SQLiteDatabase.releaseMemory();
        super.close();
    }
    

    }

    【讨论】:

    • 哦,谢谢您的快速响应。我按照您的要求进行操作,并且应用程序可以正常工作,但是当我想运行另一个单词 logcat 向我显示时,应用程序崩溃了,您能解决吗:
    • E/CursorWindow:无法从有 1 行 0 列的 CursorWindow 读取第 0 行第 0 列。 E/SQLiteQuery:异常:行太大,无法放入 CursorWindow requiredPos=0,totalRows=111;查询:SELECT _id, en_word FROM words WHERE en_word LIKE 'vi%' LIMIT 20 com.gematranslate E/AndroidRuntime: FATAL EXCEPTION: main Process: com.gematranslate, PID: 19027 java.lang.NullPointerException: Attempt to invoke virtual method 'int android.database.CursorWindow.getNumRows()' 在空对象引用上
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    相关资源
    最近更新 更多