android - 无法在 Android 中打开数据库(预创建)

标签 android sqlite android-sqlite

我已经将我的 sqlite 数据库文件放在“assets”文件夹中并且我编写了一个 DataManager 类来从数据库中获取数据,但是我遇到了运行时错误..我使用调试工具来查看我在 CreateDataBase() 出现错误.. 请帮我解决这个问题

这是我的 Datamanager 类。我正在为 Android 预创建数据库,但我收到文件未找到异常请帮助我..我在下面显示了我的 Logcat。

(数据管理类)

package com.example.applicationdatabase;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


public class DataBaseManager extends SQLiteOpenHelper {

    // The Android's default system path of your application database.
    //data/data/ and /databases remain the same always. The one that must be changed is com.example which represents
    //the MAIN package of your project
    private static String DB_PATH = "/data/data/com.example.applicationdatabase/databases";

    //the name of your database
    private static String DB_NAME = "database";

    private static SQLiteDatabase mDataBase;

    private static DataBaseManager sInstance = null;
    // database version    
    private static final int DATABASE_VERSION = 1;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     */
    private DataBaseManager() {
        super(ApplicationContextProvider.getContext(), DB_NAME, null, DATABASE_VERSION);

        try {
            createDataBase();
            openDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Singleton for DataBase
     *
     * @return singleton instance
     */
    public static DataBaseManager instance() {

        if (sInstance == null) {
            sInstance = new DataBaseManager();
        }
        return sInstance;
    }


    /**
     * Creates a empty database on the system and rewrites it with your own
     * database.
     *
     * @throws java.io.IOException io exception
     */
    private void createDataBase() throws IOException {

        boolean dbExist = checkDataBase();

        if (dbExist) {
            // do nothing - database already exist
        } else {

            // By calling this method an 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 + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {

            // database doesn't exist yet.

        }

        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 transfering bytestream.
     *
     * @throws java.io.IOException io exception
     */
    public void copyDataBase() throws IOException {

        // Open your local db as the input stream
        InputStream myInput =ApplicationContextProvider.getContext().getAssets().open(DB_NAME);


        // Path to 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 inputfile to the outputfile
        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();

    }

    private void openDataBase() throws SQLException {

        // Open the database
        String myPath = DB_PATH + DB_NAME;
        mDataBase = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
    }

    /**
     * Select method
     *
     * @param query select query
     * @return - Cursor with the results
     * @throws android.database.SQLException sql exception
     */
    public Cursor select(String query) throws SQLException {
        return mDataBase.rawQuery(query, null);
    }

    /**
     * Insert method
     *
     * @param table  - name of the table
     * @param values values to insert
     * @throws android.database.SQLException sql exception
     */
    public void insert(String table, ContentValues values) throws SQLException {
        mDataBase.insert(table, null, values);
    }

    /**
     * Delete method
     *
     * @param table - table name
     * @param where WHERE clause, if pass null, all the rows will be deleted
     * @throws android.database.SQLException sql exception
     */
    public void delete(String table, String where) throws SQLException {

        mDataBase.delete(table, where, null);

    }

    /**
     * Update method
     *
     * @param table  - table name
     * @param values - values to update
     * @param where  - WHERE clause, if pass null, all rows will be updated
     */
    public void update(String table, ContentValues values, String where) {

        mDataBase.update(table, values, where, null);

    }

    /**
     * Let you make a raw query
     *
     * @param command - the sql comand you want to run
     */
    public void sqlCommand(String command) {
        mDataBase.execSQL(command);
    }

    @Override
    public synchronized void close() {

        if (mDataBase != null)
            mDataBase.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

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

    }

}

日志:

11-30 16:02:18.908: E/SQLiteLog(968): (14) cannot open file at line 30176 of [00bb9c9ce4]
11-30 16:02:18.938: E/SQLiteLog(968): (14) os_unix.c:30176: (2) open(/data/data/com.example.applicationdatabase/databasesdatabase) - 
11-30 16:02:18.948: E/SQLiteDatabase(968): Failed to open database '/data/data/com.example.applicationdatabase/databasesdatabase'.
11-30 16:02:18.948: E/SQLiteDatabase(968): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.example.applicationdatabase.DataBaseManager.checkDataBase(DataBaseManager.java:102)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.example.applicationdatabase.DataBaseManager.createDataBase(DataBaseManager.java:69)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.example.applicationdatabase.DataBaseManager.<init>(DataBaseManager.java:39)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.example.applicationdatabase.DataBaseManager.instance(DataBaseManager.java:55)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.example.applicationdatabase.DBActivity.onCreate(DBActivity.java:35)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.Activity.performCreate(Activity.java:5104)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.os.Looper.loop(Looper.java:137)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at android.app.ActivityThread.main(ActivityThread.java:5039)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at java.lang.reflect.Method.invokeNative(Native Method)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at java.lang.reflect.Method.invoke(Method.java:511)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-30 16:02:18.948: E/SQLiteDatabase(968):  at dalvik.system.NativeStart.main(Native Method)
11-30 16:02:19.008: E/AndroidRuntime(968): FATAL EXCEPTION: main
11-30 16:02:19.008: E/AndroidRuntime(968): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.applicationdatabase/com.example.applicationdatabase.DBActivity}: java.lang.NullPointerException
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.os.Looper.loop(Looper.java:137)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.ActivityThread.main(ActivityThread.java:5039)
11-30 16:02:19.008: E/AndroidRuntime(968):  at java.lang.reflect.Method.invokeNative(Native Method)
11-30 16:02:19.008: E/AndroidRuntime(968):  at java.lang.reflect.Method.invoke(Method.java:511)
11-30 16:02:19.008: E/AndroidRuntime(968):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-30 16:02:19.008: E/AndroidRuntime(968):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-30 16:02:19.008: E/AndroidRuntime(968):  at dalvik.system.NativeStart.main(Native Method)
11-30 16:02:19.008: E/AndroidRuntime(968): Caused by: java.lang.NullPointerException
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
11-30 16:02:19.008: E/AndroidRuntime(968):  at com.example.applicationdatabase.DataBaseManager.createDataBase(DataBaseManager.java:79)
11-30 16:02:19.008: E/AndroidRuntime(968):  at com.example.applicationdatabase.DataBaseManager.<init>(DataBaseManager.java:39)
11-30 16:02:19.008: E/AndroidRuntime(968):  at com.example.applicationdatabase.DataBaseManager.instance(DataBaseManager.java:55)
11-30 16:02:19.008: E/AndroidRuntime(968):  at com.example.applicationdatabase.DBActivity.onCreate(DBActivity.java:35)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.Activity.performCreate(Activity.java:5104)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
11-30 16:02:19.008: E/AndroidRuntime(968):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
11-30 16:02:19.008: E/AndroidRuntime(968):  ... 11 more

最佳答案

这是从 Assest 文件夹中读取数据库的工作代码。唯一的问题是无法找到 PATH。

希望对大家有所帮助,如有疑问请私信我...

package net.learn2develop.Databases;

import java.io.IOException;

import android.app.Activity;

import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class DatabasesActivity extends Activity {

    protected static final String TAG = null;
    private Button insertButton;
    private Button updateButton;
    private Button deleteButton;
    private Button displayButton;
    boolean status = false;

    private EditText name;
    private EditText email;
    protected int value1;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DBAdapter myDbHelper = new DBAdapter(null);
        myDbHelper = new DBAdapter(this);

        insertButton = (Button) findViewById(R.id.btnInsert);
        updateButton = (Button) findViewById(R.id.btnUpdate);
        deleteButton = (Button) findViewById(R.id.btnDelete);
        displayButton = (Button) findViewById(R.id.btnDisplay);
        name = (EditText) findViewById(R.id.edit_name);
        email = (EditText) findViewById(R.id.edit_email);

        // --- inserting ------
        insertButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (name.getText().toString().trim().length() == 0)
                {
                    Toast msg = Toast.makeText(getBaseContext(),
                            "Please Enter Name ", Toast.LENGTH_LONG);
                    msg.show();
                }
                else if (email.getText().toString().trim().length() == 0)
                {
                    Toast msg = Toast.makeText(getBaseContext(),
                            "Please Enter Email", Toast.LENGTH_LONG);
                    msg.show();
                }
                else

                    insertRecord();
            }
        });

        // --------Deleting the Records -----------
        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                deleteRecord();
            }
        });

        // --- Displaying the Records -------
        displayButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DisplayRecord();
            }
        });

        updateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (name.getText().toString().trim().length() == 0)
                {
                    Toast msg = Toast.makeText(getBaseContext(),
                            "Please Enter Name ", Toast.LENGTH_LONG);
                    msg.show();
                }
                else if (email.getText().toString().trim().length() == 0)
                {
                    Toast msg = Toast.makeText(getBaseContext(),
                            "Please Enter Email", Toast.LENGTH_LONG);
                    msg.show();
                }
                else
                {
                    updateRecord();
                }
            }
        });

        try {
            myDbHelper.createDataBase();
        } catch (IOException ioe) {
            throw new Error("Unable to create database");
        }

        try {
            myDbHelper.openDataBase();
        } catch (SQLException sqle) {
            throw sqle;
        }

    }

    protected void DisplayRecord() {
        DBAdapter myDbHelper1 = new DBAdapter(null);
        myDbHelper1.openDataBase();
        Cursor c = myDbHelper1.getAllContacts();

        if (c.moveToFirst()) {
            do {
                DisplayContact(c);
            } while (c.moveToNext());
        }
        myDbHelper1.close();
    }

    protected void updateRecord() {

        String Name = fetchName();
        String Email = fetchEmail();

        DBAdapter myDbHelper1 = new DBAdapter(null);
        myDbHelper1.openDataBase();
        if (myDbHelper1.updateContact(1, Name, Email))
        {
            Toast msg = Toast.makeText(getBaseContext(),
                    "Update Successfully ", Toast.LENGTH_LONG);
            msg.show();
        }
        else
        {
            Toast msg = Toast.makeText(getBaseContext(),
                    "Update Failed ", Toast.LENGTH_LONG);
            msg.show();
        }
        myDbHelper1.close();

    }

    protected void deleteRecord() {
        DBAdapter myDbHelper1 = new DBAdapter(null);

        myDbHelper1.openDataBase();
        if (myDbHelper1.deleteContact(27))
        {
            Toast msg = Toast.makeText(getBaseContext(),
                    "Delete Successfully ", Toast.LENGTH_LONG);
            msg.show();
        }
        else
        {
            Toast msg = Toast.makeText(getBaseContext(),
                    "Delete Failed ", Toast.LENGTH_LONG);
            msg.show();
        }
        myDbHelper1.close();

    }

    protected void insertRecord() {
        String Name = fetchName();
        String Email = fetchEmail();

        DBAdapter myDbHelper1 = new DBAdapter(null);
        myDbHelper1.openDataBase();
        long id = myDbHelper1.insertContact(Name, Email);
        myDbHelper1.close();
        Toast msg = Toast.makeText(getBaseContext(),
                "Record: " + id + " Successfully inserted", Toast.LENGTH_LONG);
        msg.show();
        name.setText("");
        email.setText("");

    }

    public void DisplayContact(Cursor c) {
        Toast.makeText(
                this,
                "id: " + c.getString(0) + "\n" + "Name: " + c.getString(1)
                        + "\n" + "Email: " + c.getString(2), Toast.LENGTH_LONG)
                .show();
    }

    public String fetchName()
    {
        String Name = name.getText().trim().toString();
        if (Name.contentEquals(name.getHint()))
        {

            return " ";
        }
        else
        {
            return Name;
        }
    }

    public String fetchEmail()
    {
        String Email = email.getText().trim().toString();
        if (Email.contentEquals(email.getHint()))
        {
            return " ";
        }
        else
        {
            return Email;
        }
    }

}

关于android - 无法在 Android 中打开数据库(预创建),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13642833/

相关文章:

java - 字符集编码内存不足

Android视频多次播放后停止播放错误1,2147483648

php - 如何使用 PHP PDO 删除内存中的 SQLite 数据库?

ios - 备份和接收核心数据 SQlite3 数据库

android - 我是加入、循环查询还是以其他方式从 SQLiteDatabase 检索嵌套表?

android - 如何编写sqlite查询来获取特定数据?

java - 如何从与 Firebase 数据库同步的 ArrayList 中删除条目?

Android Fragment backStack 问题

c# - Unity 引用输入字段文本框

android - Sqlite 按日期列排序