新手在这里。我在上一篇文章中收到了一些很好的信息,我希望能得到更多的帮助:)谢谢你的回复。
我正在运送带有应用程序的预先填充的sqlite数据库。我已经完成了通过我在网上找到的例程将数据库从源代码中的assets文件夹复制到/ database /文件夹的过程,我相信你们都熟悉(http://www.reigndesign) .COM /博客/使用 - 你自己的sqlite的数据库功能于Android的应用程序/)。这似乎工作正常。使用DDMS我能够看到数据库被复制并显示在正确的目录中。
然而,现在,我没有得到任何结果。当我检查logcat时,我在尝试打开数据库时看到以下错误:
02-19 14:59:40.490: I/Database(4071): sqlite returned: error code = 14, msg = cannot open file at source line 25467
02-19 14:59:40.490: E/Database(4071): sqlite3_open_v2("/data/data/com.testapp.test/databases/pbaMainDb.sqlite", &handle, 2, NULL) failed
编辑:这是我用于在安装后打开数据库的ListScreen类,并从以下位置执行简单查询:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lists);
DbHelper db = new DbHelper(this);
db = new DbHelper(this);
try {
db.createDatabase();
} catch (IOException ioe) {
throw new Error ("Unable to create database");
}
try {
myDbHelper.close();
db.openDataBase();
} catch(SQLException sqle){
throw sqle;
}
}
public Cursor fetchAllTables() {
return myDbHelper.rawQuery("SELECT name FROM sqlite_master WHERE type='table'",
new String[]{});
}
private void fillData() {
//Cursor c = fetchAllTables();
//startManagingCursor(c);
String[] from = new String[] {"name"};
int[] to = new int[] {R.id.listview};
SimpleCursorAdapter notes =
new SimpleCursorAdapter (this, R.layout.list_view, cursor, from, to);
setListAdapter(notes);
}
}
编辑:另外,从我的DbHelper类(代码是复制我现有的Db),这里是我做的代码(道歉,这是一个转储):
public class DbHelper extends SQLiteOpenHelper {
// the default android path of the database files it creates
private static String DB_PATH = "/data/data/com.testdata.test/databases/";
private static String DB_NAME = "pbaMainDb.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;
// constructor to keep a reference of the passed context in order to access the
public DbHelper (Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
// Create an empty database and then rewrite with original
public void createDatabase() throws IOException {
boolean dbExist = CheckDataBase();
if (dbExist) {
// if exists, do nothing
}else {
//when we call this method the empty database will be created into
this.getReadableDatabase();
try {
copyDataBase();
}
catch (IOException e) {
throw new Error("Error copying database");
}
}
this.close();
}
// Check if the database already exists to avoid re-copy
private boolean CheckDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null SQLiteDatabase.OPEN_READWRITE);
//File dbfile = new File(myPath);
//return dbfile.exists();
} catch (SQLiteException e) {
//database doesn't exist yet
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
// Copies database from assets folder to new empty folder
private void copyDataBase() throws IOException {
InputStream myInput = myContext.getAssets().open(DB_NAME);
//path to just created DB
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream (outFileName);
//transfer bytes from input file to output file
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
// open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int OldVersion, int newVersion) {
}
}
答案 0 :(得分:1)
这看似简单,但尝试从数据库名称中取消扩展名。即,当你把它放在你的资产文件夹中时,制作路径"/data/data/com.testapp.test/databases/pbaMainDb"
并从文件中取出扩展名。
另外,我认为数据库文件大小可能存在大小限制。你的档案有多大?
最后一种可能性:在应用程序崩溃后,再次打开它(不是编译和安装,只是在设备上再打开它),看看它是否有效。有时第一次创建databases
文件夹时,您可能需要进入并使用某些内容创建它
File f = new File(DB_PATH);
if (!f.exists()) {
f.mkdir();
}
编辑:还有一个问题。查看您使用的教程后,您是否也使用了最后显示的createDataBase()
方法?
此外,在执行查询之前,请尝试调用myDbHelper.close();
,然后再次调用open方法。他在教程中创建的空版本可能仍处于打开状态,需要在第一时间关闭
让我知道这些如何发展,如果有必要,我会尽力帮助你。
编辑:将我的onCreate
和fetchAllTables
替换为以下编辑内容。出于某种原因,您创建了DbHelper
类的两个实例,因此我删除了它。此外,我无法看到您在onCreate上使用的myDbHelper
声明的位置,但是除去了对它的所有引用。我们将只使用一个DbHelper实例与数据库进行交互,即db
。正如您所看到的,我将其创建为一个类变量,我们将在整个类中使用它,并在onCreate
中实例化并打开一次。如果错误发生变化也要注意,因为我现在只关注数据库的开放工作。
DbHelper db;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lists);
db = new DbHelper(this);
try {
db.createDatabase();
}
catch (IOException ioe) {
throw new Error ("Unable to create database");
}
try {
db.close();
db.openDataBase();
} catch(SQLException sqle){
throw sqle;
}
}
public Cursor fetchAllTables() {
return db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
}
答案 1 :(得分:0)
我遇到了同样的问题,但作为其中一条评论" http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications"说,我刚刚这样做了:
替换此行
String myPath = DB_PATH + DB_NAME;
在checkDataBase()
方法中:
String myPath = Environment.getExternalStorageDirectory() + "/" + DB_NAME;
对我来说效果很好。