获取位于Assets文件夹到数据/数据​​/ mypackage中/数据库的prepopulated数据库数据库、数据、文件夹、Assets

2023-09-07 08:42:42 作者:站在巴黎铁塔上等日出

我一直在努力效仿的榜样:的 http://blog.softeq.com/2012/12/using-$p$p-populated-sqlite-database-in.html

这个例子应该向您展示如何打开存储在资产文件夹中的prepopulated数据库。

目前已经创造了与此相关的话题线程和我曾尝试提出的建议,但它不是帮助我弄清楚为什么程序无法打开数据库文件。我究竟做错了什么?以下是我得到的LogCat中的前几行:

  01-13 15:54:33.171:E /跟踪(30747):错误打开跟踪文件:没有这样的文件或目录(2)
01-13 15:54:33.171:D / ActivityThread(30747):setTargetHeapUtilization:0.25
01-13 15:54:33.171:D / ActivityThread(30747):setTargetHeapIdealFree:8388608
01-13 15:54:33.171:D / ActivityThread(30747):setTargetHeapConcurrentStart:2097152
01-13 15:54:33.251:D / AbsListView(30747):获取MotionRecognitionManager
01-13 15:54:33.261:E / SQLiteLog(30747):(14)无法打开文件在30245行[00bb9c9ce4]
01-13 15:54:33.261:E / SQLiteLog(30747):(14)os_unix.c:30245:(2)开(/data/data/com.example.$p$ppopdb/databases/yourdb.db) - 
01-13 15:54:33.261:E / SQLiteDatabase(30747):无法打开数据库'/data/data/com.example.$p$ppopdb/databases/yourdb.db。
01-13 15:54:33.261:E / SQLiteDatabase(30747):android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(code 14):无法打开数据库
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteConnection.nativeOpen(本机方法)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:278)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:464)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:186)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804​​)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在com.example prepopdb.ExternalDbOpenHelper.checkDataBase(ExternalDbOpenHelper.java:62)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在com.example prepopdb.ExternalDbOpenHelper.createDataBase(ExternalDbOpenHelper.java:43)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在com.example prepopdb.ExternalDbOpenHelper.openDataBase(ExternalDbOpenHelper.java:97)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在com.example prepopdb.ExternalDbOpenHelper< INIT>(ExternalDbOpenHelper.java:37)
01-13 15:54:33.261:E / SQLiteDatabase(30747):在com.example prepopdb prepopSqliteDbActivity.onCreate(prepopSqliteDbActivity.java:35)。
 

我创建了测试数据库SQLite数据库浏览器中提到的同是例外我的数据库扩展上述链接.DB,而不是.sqlite3。 (虽然我用.sqlite3,以及与同类/同样的错误都试过)。

下面是$ C $下我的prepopSqliteDbActivity:

 包com.example prepopdb。

。进口com.example prepopdb.ExternalDbOpenHelper;
进口的java.util.ArrayList;

进口android.app.ListActivity;
进口android.database.Cursor;
进口android.database.sqlite.SQLiteDatabase;
进口android.os.Bundle;
进口android.view.View;
进口android.widget.AdapterView;
进口android.widget.AdapterView.OnItemClickListener;
进口android.widget.ArrayAdapter;
进口android.widget.ListView;
进口android.widget.TextView;
进口android.widget.Toast;

公共类prepopSqliteDbActivity扩展ListActivity {

私有静态最后弦乐DB_NAME =yourdb.db;

//数据库字段名
私有静态最后弦乐TABLE_NAME =朋友;
私有静态最后弦乐FRIEND_ID =_id;
私有静态最后弦乐FRIEND_NAME =名;

私人SQLiteDatabase数据库;
私人的ListView ListView的;
私人的ArrayList<字符串>朋友;

公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);

    ExternalDbOpenHelper dbOpenHelper =新ExternalDbOpenHelper(这一点,
            DB_NAME);
    数据库= dbOpenHelper.openDataBase(); //数据库是开放的

    / *一些其他的code HERE * /
}
 

下面是code我ExternalDbOpenHelper:

 包com.example prepopdb。

进口java.io.FileOutputStream中;
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.OutputStream中;

进口android.content.Context;
进口android.database.SQLException;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteOpenHelper;
进口android.os.Environment;
进口android.util.Log;

公共类ExternalDbOpenHelper扩展SQLiteOpenHelper {

//路径与数据库的设备文件夹
公共静态字符串DB_PATH;

//数据库文件名
公共静态字符串DB_NAME;
公共SQLiteDatabase数据库;
公众最终上下文的背景下;

公共SQLiteDatabase getDb(){
    返回数据库;
}

公共ExternalDbOpenHelper(上下文的背景下,字符串DATABASENAME){
    超(背景下,数据库名,NULL,1);
    this.context =背景;

    //写的完整路径应用程序的数据库
    串的packageName = context.getPackageName();
    DB_PATH =的String.Format(%S /数据/%S /数据库/,Environment.getDataDirectory()的packageName);
    DB_NAME =数据库名;
    的openDatabase();

}

//创建一个数据库,如果它尚未创建
公共无效的CreateDatabase(){
    布尔dbExist = checkDataBase();
    如果(!dbExist){
        this.getReadableDatabase();
        尝试 {
            copyDataBase();
        }赶上(IOException异常E){
            Log.e(this.getClass()的toString(),复制错误!);
            抛出新的错误(错误复制数据库!);
        }
    } 其他 {
        Log.i(this.getClass()的toString()数据库已经存在。);
    }
}

//执行数据库存在性检查
私人布尔checkDataBase(){
    SQLiteDatabase CHECKDB = NULL;
    尝试 {
        字符串路径= DB_PATH + DB_NAME;
        CHECKDB = SQLiteDatabase.openDatabase(路径,空,SQLiteDatabase.OPEN_READONLY);
    }赶上(的SQLException E){
        Log.e(this.getClass()的toString(),同时检查数据库错误。);
    }

    如果(CHECKDB!= NULL){
        checkDb.close();
    }
    返回CHECKDB!= NULL;
}

私人无效copyDataBase()抛出IOException异常{
    //打开一个流进行读取,坐落在资产
    InputStream的externalDbStream = context.getAssets()开(DB_NAME)。
    //的路径创建空数据库在Android设备上
    字符串outFileName = DB_PATH + DB_NAME;

    //由字节写入数据库字节创建流
    的OutputStream localDbStream =新的FileOutputStream(outFileName);

    //复制数据库
    byte []的缓冲区=新的字节[1024];
    INT读取动作;
    而((读取动作= externalDbStream.read(缓冲液))大于0){
        localDbStream.write(缓冲液,0,读取动作);
    }

    //关闭流
    localDbStream.close();
    externalDbStream.close();
}

SQLiteDatabase的openDatabase()抛出的SQLException {
    字符串路径= DB_PATH + DB_NAME;
    如果(数据库== NULL){
        的CreateDatabase();
        数据库= SQLiteDatabase.openDatabase(路径,空,
                SQLiteDatabase.OPEN_READWRITE);
        //数据库= getWritableDatabase();
    }
    返回数据库;
}

@覆盖
市民同步无效的close(){
    如果(数据库!= NULL){
        database.close();
    }
    super.close();
}

@覆盖
公共无效的onCreate(SQLiteDatabase DB){
    // TODO自动生成方法存根

}

@覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
    // TODO自动生成方法存根

}
}
 

更新

感谢您卡洛斯。我同意它不是一个好主意,到c的路径硬$ C $,因为它可能是不同的设备到设备。如你所说。我所做的更改,但我仍然得到同样的错误。我验证过yourdb.db文件的读/写权限的所有层面。

我在previous评论提到这一点,但可能任何这可以发生,因为我使用的是无根的手机吗?能否从Asssets复制后yourdb.db的许可可能更改文件夹到/data/data/com.example.$p$ppopdb/databases/,然后我的程序试图打开它?我知道如何利用亚行更改权限,但如何去从程序中这样做呢?

下面就是我的logcat说:

  12月1日至14日:18:02.240:E /跟踪(18167):错误打开跟踪文件:没有这样的文件或目录(2)
十二月1日至14日:18:02.240:D / ActivityThread(18167):setTargetHeapUtilization:0.25
十二月1日至14日:18:02.240:D / ActivityThread(18167):setTargetHeapIdealFree:8388608
十二月1日至14日:18:02.240:D / ActivityThread(18167):setTargetHeapConcurrentStart:2097152
十二月1日至14日:18:02.360:D / AbsListView(18167):获取MotionRecognitionManager
十二月1日至14日:18:02.370:E / SQLiteLog(18167):(14)无法打开文件在30245行[00bb9c9ce4]
十二月1日至14日:18:02.370:E / SQLiteLog(18167):(14)os_unix.c:30245:(2)开(/data/data/com.example.$p$ppopdb/databases/yourdb.db) - 
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):无法打开数据库'/data/data/com.example.$p$ppopdb/databases/yourdb.db。
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(code 14):无法打开数据库
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteConnection.nativeOpen(本机方法)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:278)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:464)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:186)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804​​)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.example prepopdb.ExternalDbOpenHelper.checkDataBase(ExternalDbOpenHelper.java:63)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.example prepopdb.ExternalDbOpenHelper.createDataBase(ExternalDbOpenHelper.java:45)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.example prepopdb.ExternalDbOpenHelper.openDataBase(ExternalDbOpenHelper.java:97)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.example prepopdb.ExternalDbOpenHelper< INIT>(ExternalDbOpenHelper.java:39)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.example prepopdb prepopSqliteDbActivity.onCreate(prepopSqliteDbActivity.java:35)。
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.Activity.performCreate(Activity.java:5048)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2052)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2113)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.ActivityThread.access $ 700(ActivityThread.java:139)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1224)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.os.Handler.dispatchMessage(Handler.java:99)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.os.Looper.loop(Looper.java:137)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在android.app.ActivityThread.main(ActivityThread.java:4918)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在java.lang.reflect.Method.invokeNative(本机方法)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在java.lang.reflect.Method.invoke(Method.java:511)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1004)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
十二月1日至14日:18:02.370:E / SQLiteDatabase(18167):在dalvik.system.NativeStart.main(本机方法)
十二月1日至14日:18:02.370:E /班com.example prepopdb.ExternalDbOpenHelper(18167):错误,同时检查分贝
十二月1日至14日:18:02.480:D / libEGL(18167):加载/system/lib/egl/libEGL_adreno200.so
十二月1日至14日:18:02.500:D / libEGL(18167):加载/system/lib/egl/libGLESv1_CM_adreno200.so
十二月1日至14日:18:02.500:D / libEGL(18167):加载/system/lib/egl/libGLESv2_adreno200.so
1月14号12:18:02.540的:I /的Adreno200-EGLSUB(18167):其中; ConfigWindowMatch:2087计算值:格式RGBA_8888。
十二月1日至14日:18:02.560:E /(18167):其中,s3dReadConfigFile:75计算值:无法打开文件进行读取
十二月1日至14日:18:02.560:E /(18167):其中,s3dReadConfigFile:75计算值:无法打开文件进行读取
十二月1日至14日:18:02.560:D / OpenGLRenderer(18167):启用调试模式0
十二月1日至14日:18:21.380:W / IInputConnectionWrapper(18167):beginBatchEdit上的非活动InputConnection
十二月1日至14日:18:21.380:W / IInputConnectionWrapper(18167):endBatchEdit上的非活动InputConnection
 

解决方案

您正在承担太多的数据文件夹。您而应该让系统给你正确的路径。 您可以使用数据库路径context.getDatabasePath(); 传递所需的名称到文件(不管它存在与否)。而实际上你应该这样做的

有关,在任何地方,你正在使用类似字符串outFileName = DB_PATH + DB_NAME; 你应该改变它

 字符串outFileName = myContext.getDatabasePath(DB_NAME).getPath();
 

,这对你的文件真实有效的位置。所以wour帮手会是这样

 公共类ExternalDbOpenHelper扩展SQLiteOpenHelper {

//路径与数据库的设备文件夹
公共静态字符串DB_PATH;

//数据库文件名
公共静态字符串DB_NAME;
公共SQLiteDatabase数据库;
公众最终上下文的背景下;

公共SQLiteDatabase getDb(){
    返回数据库;
}

公共ExternalDbOpenHelper(上下文的背景下,字符串DATABASENAME){
    超(背景下,数据库名,NULL,1);
    this.context =背景;
        DB_NAME =数据库名;
            DB_PATH = context.getDatabasePath(DB_NAME).getPath();
    的openDatabase();

}

//创建一个数据库,如果它尚未创建
公共无效的CreateDatabase(){
    布尔dbExist = checkDataBase();
    如果(!dbExist){
        this.getReadableDatabase();
        尝试 {
            copyDataBase();
        }赶上(IOException异常E){
            Log.e(this.getClass()的toString(),复制错误!);
            抛出新的错误(错误复制数据库!);
        }
    } 其他 {
        Log.i(this.getClass()的toString()数据库已经存在。);
    }
}

//执行数据库存在性检查
私人布尔checkDataBase(){
    SQLiteDatabase CHECKDB = NULL;
    尝试 {

        CHECKDB = SQLiteDatabase.openDatabase(DB_PATH,空,SQLiteDatabase.OPEN_READONLY);
    }赶上(的SQLException E){
        Log.e(this.getClass()的toString(),同时检查数据库错误。);
    }

    如果(CHECKDB!= NULL){
        checkDb.close();
    }
    返回CHECKDB!= NULL;
}

私人无效copyDataBase()抛出IOException异常{
    //打开一个流进行读取,坐落在资产
    InputStream的externalDbStream = context.getAssets()开(DB_NAME)。



    //由字节写入数据库字节创建流
    的OutputStream localDbStream =新的FileOutputStream(DB_PATH);

    //复制数据库
    byte []的缓冲区=新的字节[1024];
    INT读取动作;
    而((读取动作= externalDbStream.read(缓冲液))大于0){
        localDbStream.write(缓冲液,0,读取动作);
    }

             //刷新输出流
             localDbStream.flush();

    //关闭流
    localDbStream.close();
    externalDbStream.close();
}

SQLiteDatabase的openDatabase()抛出的SQLException {

    如果(数据库== NULL){
        的CreateDatabase();
        数据库= SQLiteDatabase.openDatabase(DB_PATH,空,
                SQLiteDatabase.OPEN_READWRITE);
        //数据库= getWritableDatabase();
    }
    返回数据库;
}

@覆盖
市民同步无效的close(){
    如果(数据库!= NULL){
        database.close();
    }
    super.close();
}

@覆盖
公共无效的onCreate(SQLiteDatabase DB){
    // TODO自动生成方法存根

}

@覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
    // TODO自动生成方法存根

}
}
 

这个它应该工作

更新

呦可能需要几方面的考虑:

一起来看看什么路是将系统返回的数据库

  DB_PATH = context.getDatabasePath(DB_NAME).getPath();
Log.i(对myApp,DB_PATH);
 

检查在模拟器中code,就看你有同样的问题。在那里,你可以手动检查文件是否被实际创建,作为解释这里

补充权限写入和读取的SD卡( READ_EXTERNAL_STORAG​​E和WRITE_EXTERNAL_STORAG​​E)。但我不真的相信你需要这个

I have been trying to follow the example: http://blog.softeq.com/2012/12/using-pre-populated-sqlite-database-in.html

This example is supposed to show you how to open a prepopulated database stored in the Assets folder.

There have been threads created related to this topic and I have tried the suggestions made, but its not helping me to figure out why the program doesn't open the database file. What am I doing wrong? Here is what I'm getting in the first few lines of LogCat:

01-13 15:54:33.171: E/Trace(30747): error opening trace file: No such file or directory (2)
01-13 15:54:33.171: D/ActivityThread(30747): setTargetHeapUtilization:0.25
01-13 15:54:33.171: D/ActivityThread(30747): setTargetHeapIdealFree:8388608
01-13 15:54:33.171: D/ActivityThread(30747): setTargetHeapConcurrentStart:2097152
01-13 15:54:33.251: D/AbsListView(30747): Get MotionRecognitionManager
01-13 15:54:33.261: E/SQLiteLog(30747): (14) cannot open file at line 30245 of [00bb9c9ce4]
01-13 15:54:33.261: E/SQLiteLog(30747): (14) os_unix.c:30245: (2) open(/data/data/com.example.prepopdb/databases/yourdb.db) - 
01-13 15:54:33.261: E/SQLiteDatabase(30747): Failed to open database '/data/data/com.example.prepopdb/databases/yourdb.db'.
01-13 15:54:33.261: E/SQLiteDatabase(30747): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:278)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:464)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:186)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at com.example.prepopdb.ExternalDbOpenHelper.checkDataBase(ExternalDbOpenHelper.java:62)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at com.example.prepopdb.ExternalDbOpenHelper.createDataBase(ExternalDbOpenHelper.java:43)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at com.example.prepopdb.ExternalDbOpenHelper.openDataBase(ExternalDbOpenHelper.java:97)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at com.example.prepopdb.ExternalDbOpenHelper.<init>(ExternalDbOpenHelper.java:37)
01-13 15:54:33.261: E/SQLiteDatabase(30747):    at com.example.prepopdb.PrepopSqliteDbActivity.onCreate(PrepopSqliteDbActivity.java:35)

I created the test database with SQLite Database Browser as mentioned in the above link with the exception of my database extension being ".db" instead of ".sqlite3". (Though I have tried using ".sqlite3" as well, with similar/same errors).

Here is the code for my PrepopSqliteDbActivity:

package com.example.prepopdb;

import com.example.prepopdb.ExternalDbOpenHelper;
import java.util.ArrayList;

import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class PrepopSqliteDbActivity extends ListActivity {

private static final String DB_NAME = "yourdb.db";

// Database field names
private static final String TABLE_NAME = "friends";
private static final String FRIEND_ID = "_id";
private static final String FRIEND_NAME = "name";

private SQLiteDatabase database;
private ListView listView;
private ArrayList<String> friends;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ExternalDbOpenHelper dbOpenHelper = new ExternalDbOpenHelper(this,
            DB_NAME);
    database = dbOpenHelper.openDataBase(); // Database is open

    /*SOME OTHER CODE HERE*/
}

Here is the code for my ExternalDbOpenHelper:

package com.example.prepopdb;

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

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.util.Log;

public class ExternalDbOpenHelper extends SQLiteOpenHelper {

// Path to the device folder with database
public static String DB_PATH;

// Database filename
public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;

public SQLiteDatabase getDb() {
    return database;
}

public ExternalDbOpenHelper(Context context, String databaseName) {
    super(context, databaseName, null, 1);
    this.context = context;

    // Write the full path to the databases of your application
    String packageName = context.getPackageName();
    DB_PATH = String.format("%s/data/%s/databases/", Environment.getDataDirectory(), packageName);
    DB_NAME = databaseName;
    openDataBase();

}

// Create a database if its not yet created
public void createDataBase() {
    boolean dbExist = checkDataBase();
    if (!dbExist) {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            Log.e(this.getClass().toString(), "Copying error!");
            throw new Error("Error copying database!");
        }
    } else {
        Log.i(this.getClass().toString(), "Database already exists");
    }
}

//Performing a database existence check
private boolean checkDataBase(){
    SQLiteDatabase checkDb = null;
    try {
        String path = DB_PATH + DB_NAME;
        checkDb = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
    } catch (SQLException e){
        Log.e(this.getClass().toString(), "Error while checking db");
    }

    if (checkDb != null){
        checkDb.close();
    }
    return checkDb !=null;
}

private void copyDataBase() throws IOException {
    //Open a stream for reading, located in the assets
    InputStream externalDbStream = context.getAssets().open(DB_NAME);
    //Path to the created empty database on your Android device
    String outFileName = DB_PATH + DB_NAME;

    //Create a stream for writing the database byte by byte
    OutputStream localDbStream = new FileOutputStream(outFileName);

    //Copy the database
    byte[] buffer = new byte[1024];
    int bytesRead;
    while((bytesRead = externalDbStream.read(buffer)) > 0){
        localDbStream.write(buffer, 0, bytesRead);
    }

    //Close the streams
    localDbStream.close();
    externalDbStream.close();
}

SQLiteDatabase openDataBase() throws SQLException {
    String path = DB_PATH + DB_NAME;
    if (database == null) {
        createDataBase();
        database = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READWRITE);
        //database = getWritableDatabase();
    }
    return database;
}

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

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

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

}
}

UPDATE

Thank you Carlos. I agree its not a good idea to hardcode the path as it might be different device to device. I made the changes as you suggested, however I'm still getting the same error. I've verified that the yourdb.db file has read/write permissions for all levels.

I mentioned this in a previous comment, but could any of this be happening because I'm using a non-rooted phone? Could the permission of "yourdb.db" possibly change after copying it from the Asssets folder into /data/data/com.example.prepopdb/databases/ and then my program attempting to open it? I know how to change the permission using adb, but how do go about doing this from within the program?

Here's what my Logcat says:

01-14 12:18:02.240: E/Trace(18167): error opening trace file: No such file or directory (2)
01-14 12:18:02.240: D/ActivityThread(18167): setTargetHeapUtilization:0.25
01-14 12:18:02.240: D/ActivityThread(18167): setTargetHeapIdealFree:8388608
01-14 12:18:02.240: D/ActivityThread(18167): setTargetHeapConcurrentStart:2097152
01-14 12:18:02.360: D/AbsListView(18167): Get MotionRecognitionManager
01-14 12:18:02.370: E/SQLiteLog(18167): (14) cannot open file at line 30245 of [00bb9c9ce4]
01-14 12:18:02.370: E/SQLiteLog(18167): (14) os_unix.c:30245: (2) open(/data/data/com.example.prepopdb/databases/yourdb.db) - 
01-14 12:18:02.370: E/SQLiteDatabase(18167): Failed to open database '/data/data/com.example.prepopdb/databases/yourdb.db'.
01-14 12:18:02.370: E/SQLiteDatabase(18167): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:278)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:464)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:186)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.example.prepopdb.ExternalDbOpenHelper.checkDataBase(ExternalDbOpenHelper.java:63)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.example.prepopdb.ExternalDbOpenHelper.createDataBase(ExternalDbOpenHelper.java:45)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.example.prepopdb.ExternalDbOpenHelper.openDataBase(ExternalDbOpenHelper.java:97)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.example.prepopdb.ExternalDbOpenHelper.<init>(ExternalDbOpenHelper.java:39)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.example.prepopdb.PrepopSqliteDbActivity.onCreate(PrepopSqliteDbActivity.java:35)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.Activity.performCreate(Activity.java:5048)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2052)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2113)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.ActivityThread.access$700(ActivityThread.java:139)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1224)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.os.Looper.loop(Looper.java:137)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at android.app.ActivityThread.main(ActivityThread.java:4918)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at java.lang.reflect.Method.invokeNative(Native Method)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at java.lang.reflect.Method.invoke(Method.java:511)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
01-14 12:18:02.370: E/SQLiteDatabase(18167):    at dalvik.system.NativeStart.main(Native Method)
01-14 12:18:02.370: E/class com.example.prepopdb.ExternalDbOpenHelper(18167): Error while checking db
01-14 12:18:02.480: D/libEGL(18167): loaded /system/lib/egl/libEGL_adreno200.so
01-14 12:18:02.500: D/libEGL(18167): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
01-14 12:18:02.500: D/libEGL(18167): loaded /system/lib/egl/libGLESv2_adreno200.so
01-14 12:18:02.540: I/Adreno200-EGLSUB(18167): <ConfigWindowMatch:2087>: Format RGBA_8888.
01-14 12:18:02.560: E/(18167): <s3dReadConfigFile:75>: Can't open file for reading
01-14 12:18:02.560: E/(18167): <s3dReadConfigFile:75>: Can't open file for reading
01-14 12:18:02.560: D/OpenGLRenderer(18167): Enabling debug mode 0
01-14 12:18:21.380: W/IInputConnectionWrapper(18167): beginBatchEdit on inactive InputConnection
01-14 12:18:21.380: W/IInputConnectionWrapper(18167): endBatchEdit on inactive InputConnection

解决方案

You are assuming too much about the data folder. You rather should let the system give you the correct path. You can get database path with context.getDatabasePath(); you pass the desired name to the file (no matter if it exists or not). And actually you are supposed to do it that way

For that, at any place you are using something like String outFileName = DB_PATH + DB_NAME; you should change it for

 String outFileName =myContext.getDatabasePath(DB_NAME).getPath() ;

and that's the real valid location for your file. So wour helper will be like this

public class ExternalDbOpenHelper extends SQLiteOpenHelper {

// Path to the device folder with database
public static String DB_PATH;

// Database filename
public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;

public SQLiteDatabase getDb() {
    return database;
}

public ExternalDbOpenHelper(Context context, String databaseName) {
    super(context, databaseName, null, 1);
    this.context = context;
        DB_NAME = databaseName;
            DB_PATH =context.getDatabasePath(DB_NAME).getPath() ;
    openDataBase();

}

// Create a database if its not yet created
public void createDataBase() {
    boolean dbExist = checkDataBase();
    if (!dbExist) {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            Log.e(this.getClass().toString(), "Copying error!");
            throw new Error("Error copying database!");
        }
    } else {
        Log.i(this.getClass().toString(), "Database already exists");
    }
}

//Performing a database existence check
private boolean checkDataBase(){
    SQLiteDatabase checkDb = null;
    try {

        checkDb = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READONLY);
    } catch (SQLException e){
        Log.e(this.getClass().toString(), "Error while checking db");
    }

    if (checkDb != null){
        checkDb.close();
    }
    return checkDb !=null;
}

private void copyDataBase() throws IOException {
    //Open a stream for reading, located in the assets
    InputStream externalDbStream = context.getAssets().open(DB_NAME);



    //Create a stream for writing the database byte by byte
    OutputStream localDbStream = new FileOutputStream(DB_PATH);

    //Copy the database
    byte[] buffer = new byte[1024];
    int bytesRead;
    while((bytesRead = externalDbStream.read(buffer)) > 0){
        localDbStream.write(buffer, 0, bytesRead);
    }

             //FLUSH THE OUT STREAM
             localDbStream.flush();

    //Close the streams
    localDbStream.close();
    externalDbStream.close();
}

SQLiteDatabase openDataBase() throws SQLException {

    if (database == null) {
        createDataBase();
        database = SQLiteDatabase.openDatabase(DB_PATH, null,
                SQLiteDatabase.OPEN_READWRITE);
        //database = getWritableDatabase();
    }
    return database;
}

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

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

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

}
}

with this it should work

UPDATE

Yo can take a few of considerations:

take a look at what path is the system returning for your database

DB_PATH =context.getDatabasePath(DB_NAME).getPath() ;
Log.i ("myApp", DB_PATH);

check the code in the emulator, to see if you have the same problems. there you can manually check if the file is actually created, as explained here

add permissions to write and read the sdcard (READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE). but i dont actually believe you need this