Android SQLiteLog:(14)无法打开文件

Android SQLiteLog:(14)无法打开文件,android,Android,我正在设计我的第一个应用程序,我遇到以下错误: 运行应用程序时出错: 03-10 05:21:14.767 15427-15427/com.example.pratik.walkmeter E/SQLiteLog: (14) cannot open file at line 32456 of [bda77dda96] 03-10 05:21:14.767 15427-15427/com.example.pratik.walkmeter E/SQLiteLog: (14) os_unix.c:32

我正在设计我的第一个应用程序,我遇到以下错误:

运行应用程序时出错:

03-10 05:21:14.767 15427-15427/com.example.pratik.walkmeter E/SQLiteLog: (14) cannot open file at line 32456 of [bda77dda96]
03-10 05:21:14.767 15427-15427/com.example.pratik.walkmeter E/SQLiteLog: (14) os_unix.c:32456: (13) open(/data/user/0/com.example.pratik.walkmeter/databases/newuserdataDB.db) - 

03-10 05:21:14.767 15427-15427/com.example.pratik.walkmeter E/SQLiteDatabase: Failed to open database '/data/user/0/com.example.pratik.walkmeter/databases/newuserdataDB.db'.                                                     android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:808)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:652)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:289)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.pratik.walkmeter.DBHelper.databaseToString(DBHelper.java:54)
at com.example.pratik.walkmeter.NewUserInformation.printDatabase(NewUserInformation.java:55)
at com.example.pratik.walkmeter.NewUserInformation.onCreate(NewUserInformation.java:51)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

03-10 05:21:14.768 15427-15427/com.example.pratik.walkmeter D/AndroidRuntime: Shutting down VM
03-10 05:21:14.768 15427-15427/com.example.pratik.walkmeter E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.pratik.walkmeter, PID: 15427

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.pratik.walkmeter/com.example.pratik.walkmeter.NewUserInformation}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:808)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:793)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:652)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:289)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.pratik.walkmeter.DBHelper.databaseToString(DBHelper.java:54)
at com.example.pratik.walkmeter.NewUserInformation.printDatabase(NewUserInformation.java:55)
at com.example.pratik.walkmeter.NewUserInformation.onCreate(NewUserInformation.java:51)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 
我已经创建了一个数据库帮助器类,它使用SQLite,但每次我开始接受新用户信息的活动时,应用程序都会在emulator上停止。以下是数据库帮助器的代码:

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME="newuserdataDB.db";
    public static final String TABLE_NAME = "newusertable";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_NAME= "name";
    private static String DB_PATH = "";

    public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String query = "CREATE TABLE " + TABLE_NAME + "(" +
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_NAME + " TEXT " +
                ");";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    public void addProduct(NewUserData product){
        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME, product.get_newusernamedata());
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_NAME, null, values);
        db.close();
    }

    public String databaseToString(){
        String dbString = "";
        SQLiteDatabase db = getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME + " WHERE 1";// why not leave out the WHERE  clause?

        //Cursor points to a location in your results
        Cursor recordSet = db.rawQuery(query, null);
        //Move to the first row in your results
        recordSet.moveToFirst();

        //Position after the last row means the end of the results
        while (!recordSet.isAfterLast()) {
            // null could happen if we used our empty constructor
            if (recordSet.getString(recordSet.getColumnIndex("name")) != null) {
                dbString += recordSet.getString(recordSet.getColumnIndex("name"));
                dbString += "\n";
            }
            recordSet.moveToNext();
        }
        db.close();
        return dbString;
    }
}
新用户数据代码

package com.example.pratik.walkmeter;

public class NewUserData {
    private int _id;
    private String _newusernamedata;

    public NewUserData(){}

    public NewUserData(String newusernamedata) {
        this._newusernamedata = newusernamedata;
    }

    public int get_id() {
        return _id;
    }

    public void set_id(int _id) {
        this._id = _id;
    }

    public String get_newusernamedata() {
        return _newusernamedata;
    }

    public void set_newusernamedata(String _newusernamedata) {
        this._newusernamedata = _newusernamedata;
    }
}
为新用户调用数据库以保存其信息的位置

public class NewUserInformation extends AppCompatActivity {

    EditText NewUserName, NewUserAge;
    RadioGroup NewUserSex;
    TextView dataoutput;
    String sexlabel;
    DBHelper dbHandler;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_user_information);

        //intialize the fields
        NewUserName = (EditText) findViewById(R.id.NewUserName);
        NewUserAge = (EditText) findViewById(R.id.NewUserAge);
        NewUserSex = (RadioGroup) findViewById(R.id.NewUserSex);
        dataoutput = (TextView) findViewById(R.id.dataoutput);

        //Sex Group Selector
        NewUserSex.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
            @Override
            public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
                RadioButton rb = (RadioButton) group.findViewById(checkedId);
                switch (rb.getId()){
                    case R.id.Male:
                        sexlabel = "M";
                        break;
                    case R.id.Female:
                        sexlabel = "F";
                        break;
                }

            }
        });

        //Intialize Database
        dbHandler = new DBHelper(this, null, null, 1);
        printDatabase();
    }

    public void printDatabase(){
        String dbString = dbHandler.databaseToString();
        dataoutput.setText(dbString);
        NewUserName.setText("");
    }

    public void addButtonClicked(View view){
        // dbHandler.add needs an object parameter.
        NewUserData product = new NewUserData(NewUserName.getText().toString());
        dbHandler.addProduct(product);
        printDatabase();
    }
}

获取可写数据库时
getWritableDatabase()
使用
this
调用它,比如:
this.getWritableDatabase()同样适用于
getReadableDatabase()
类似的
这个.getReadableDatabase
,因为在编写数据库之前,您没有打开它。 将此方法添加到
DBHelper

// check the state of db ??....
    public boolean isOpen() {
        return database != null && database.isOpen();
    }

    @Override
    public synchronized void close() {
        if (database!= null)
            database.close();
        super.close();
    }
现在,您的
addProduct
方法将是-

public void addProduct(NewUserData product) {
        if (!isOpen()) openDataBase();

        SQLiteDatabase database = this.getWritableDatabase();
        // perform your operations here...
        // call close to close the db after writing it.
}

Tadaaa…

似乎您没有将数据库复制到该位置。错误似乎是db文件不可用。请尝试以下代码:

public class DatabaseHelper extends SQLiteOpenHelper {

class DB {
    public static Uri URI;
    public static int VERSION = 1;
    public static final String NAME = "yourdatabase.db";
    public static String PATH = "";

}
    //region Variable Declarations
    // The Android's default system path of your application database.

    public static SQLiteDatabase myDataBase;

    private final Context myContext;


    //endregion

    //region Private Methods

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     */
    public DatabaseHelper(Context context) {

        super(context, DB.NAME, null, 1);
        this.myContext = context;

        DB.PATH = myContext.getDatabasePath(DB.NAME).getPath();
        DB.URI = Uri.fromFile(myContext.getDatabasePath(DB.NAME));
        // try {
        // openDataBase();
        // } catch (SQLException e) {
        // // TODO Auto-generated catch block
        // Utils.PrintStackTrace(e);
        // } catch (IOException e) {
        // // TODO Auto-generated catch block
        // Utils.PrintStackTrace(e);
        // }
    }

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

        boolean dbExist = checkDataBase();

        if (!dbExist) {
            // 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 {
            String myPath = DB.PATH;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY
                            | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
            /*int DB_EXIST_VERSION = PreferenceManager
                    .getDefaultSharedPreferences(myContext).getInt(
                            "DB_VERSION", 0);
            if (DB.VERSION != DB_EXIST_VERSION) {
                checkDB = null;
            }*/

        } catch (SQLiteException e) {

            Utils.PrintStackTrace(e);

        } catch (Exception e1) {
            Utils.PrintStackTrace(e1);
        }

        if (checkDB != null) {

            checkDB.close();

        }

        return checkDB != null;
    }

    /**
     * *******************************************
     * 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 transferring bytestream.
     * *******************************************
     */
    private void copyDataBase() throws IOException {

        // Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB.NAME);

        // Path to the just created empty db
        String outFileName = DB.PATH;

        // 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();
        PreferenceManager.getDefaultSharedPreferences(myContext).edit()
                .putInt("DB_VERSION", DB.VERSION).commit();
    }

    /**
     * *****************************************
     * Method to open the database
     * ******************************************
     */
    public void openDataBase() throws SQLException, IOException {
        createDataBase();
        // Open the database
        String myPath = DB.PATH;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.NO_LOCALIZED_COLLATORS);

    }

    /**
     * *****************************************
     * Method to close database
     * ******************************************
     */
    @Override
    public synchronized void close() {

        try {
            if (myDataBase != null)
                myDataBase.close();
            myDataBase = null;
            super.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            Utils.PrintStackTrace(e);
        }

    }

    /**
     * *****************************************
     * Method onCreate
     * ******************************************
     */
    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    /**
     * *****************************************
     * Method onUpgrade
     * ******************************************
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
//endregion

}