我的一个应用程序从服务器下载数据库。 当我将应用程序安装到手机上时,它会正确下载文件并加载信息,不会抛出任何异常或其他任何内容。
然而,当我将apk上传到Android Market Place并将其下载到手机上时,应用程序会下载数据库然后崩溃,说sqlite处理程序无法打开数据库。
以下是代码的进展:
在SQLiteOpenHelper中:
this.FULL_DB_PATH = new String(this.getWritableDatabase().getPath());
this.getWritableDatabase();
// Code for retrieving the database off of the server:
private void copyDataBase(){
InputStream myInput=null;
OutputStream myOutput=null;
try{
// opening connections
URL url = new URL("server_url_here");
URLConnection ucon=url.openConnection();
myInput = ucon.getInputStream();
myOutput = new FileOutputStream(this.FULL_DB_PATH);
// write to the db here
byte[] buffer = new byte[1024*1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
catch(Exception e)
{
try{
myOutput.flush();
myOutput.close();
myInput.close();
}
catch(Exception es){}
}
}
我不知道为什么我的同事用mp3扩展程序保存数据库但是......当我们安装apk ad-hoc时它会起作用。
有关:
myOutput = new FileOutputStream(this.FULL_DB_PATH);
我也试过了:
myOutput = this.getApplicationContext().openFileOutput(this.FULL_DB_PATH, Context.MODE_WORLD_READABLE);
但这也不起作用。
非常感谢任何帮助!!我已经把头发撕了几个小时了,我只想让它结束哈哈。
答案 0 :(得分:1)
模拟器为您提供真正的手机无法访问的特殊权限。换句话说,我怀疑你是直接将文件复制到手机上的数据库目录中?如果是这样,您就无法在非root电话上执行此操作。希望有人会插话并证明我错了,因为这对我来说也是一个问题。我想轻松下载一个db文件并安装它。我最终需要做的解决方法是创建一个新的数据库并通过查询加载模式和数据。
编辑:
我想和你分享一个技巧。这真的很简单。不是仅使用db.insert
/ db.update
/,而是将它们作为交易范围。实际上,我将整个DB Build作为一个事务,或者至少只是单个表。我们经历了交易速度提高了10-50倍,当他们确定交易时,然后一次性提交。
答案 1 :(得分:1)
您正在做的是将文件复制到android文件系统中的/ data文件夹中。在具有正常权限的普通电话上,出于安全原因,不允许这样做。您可以在模拟器和root电话上执行此操作,因为您已被授予写入/ data(通常只读取)的权限。
要解决此问题,您需要使用db.insert(String, String, ContentValues)和db.update(String, ContentValues, String, String[])
手动将信息添加到数据库中能够做你正在尝试的事情会很好但是出于安全考虑,这是一件非常好的事情。
答案 2 :(得分:0)
另外两个答案是不正确的,我相信。我的应用程序中有一个备份系统,备份被复制到SD卡,然后在备份恢复时复制回/ data / -folder。虽然我不知道为什么你的代码不能工作,但这是我的代码从sd-card复制数据库:
final InputStream in = new FileInputStream(from);
final OutputStream out = new FileOutputStream(to);
final byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
为了更仔细地调查错误,请尝试下载到SD卡,然后使用我的代码将其复制到数据文件夹。我的代码中的“to”对象是这样的:
public static final String DATABASE_PATH = "/data/data/"+SomeClass.class.getPackage().getName()+"/databases/"+ DATABASE_NAME;
final File to = new File(Constant.DATABASE_PATH);