【问题标题】:Database seems to disappear after my application downloads it. Ideas?我的应用程序下载后,数据库似乎消失了。想法?
【发布时间】:2010-08-13 19:10:05
【问题描述】:

我的一个应用程序从服务器下载数据库。 当我将应用程序安装到手机上时,它会正确下载文件并加载信息,没有抛出异常或任何东西。

但是,当我将 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);

但这也不起作用。

非常感谢任何帮助!我已经为此扯了几个小时的头发,我只是希望它结束​​哈哈。

【问题讨论】:

    标签: android database sqlite file-io download


    【解决方案1】:

    您正在做的是将文件复制到 android 文件系统中的 /data 文件夹中。在具有正常权限的普通手机上,出于安全原因,这是不允许的。您可以在模拟器和 root 手机上执行此操作,因为您已被授予写入 /data 的权限(通常只能读取)。

    要解决这个问题,您需要使用 db.insert(String, String, ContentValues)db.update(String, ContentValues, String, String[]) 手动将信息添加到数据库中

    能够做你正在尝试的事情会很好,但出于安全原因,你不能这样做是一件非常好的事情。

    【讨论】:

    • 但是使用预构建的数据库打包应用程序呢?我有大量数据,手动插入所有数据会使应用从用户角度无法使用。
    • 你真的有两个选择。如果您可以以 XML 格式提供它,则可以将其添加到项目的 res/xml 文件夹中,然后从那里访问它。如果这是您所追求的选项,我可以在另一个答案中提供代码。另一个打开是在第一次运行时从服务器下载一个文件,然后通过文件添加每一行。这可以是 XML 或 JSON,或其他类似的东西。通常将其作为 XML 是推荐的方式,但枯萎会起作用。
    • 将预建的db直接添加到eclipse的res文件夹中不行吗?我很困惑...特别是因为在我拥有的原始版本中,我将 db 包含在项目的 res 文件夹中,但 apk 本身从未完成上传。
    【解决方案2】:

    模拟器为您提供真正手机所没有的特殊访问权限。也就是说,我怀疑你是直接将文件复制到手机上的数据库目录中?如果是这样,您将无法在非 root 手机上执行此操作。希望有人会插话并证明我错了,因为这对我来说也是一个问题。我想轻松下载一个 db 文件并安装它。作为解决方法,我最终要做的是创建一个新数据库并通过查询加载架构和数据。

    编辑: 我想和你分享一个技巧。真的很简单。与其单独使用db.insert/db.update/,不如将它们限定为事务。事实上,我会将整个 DB Build 定义为一个事务,或者至少只是单个表。当它们被确定范围然后一次全部提交时,我的交易速度提高了 10-50 倍。

    【讨论】:

    • 您是否尝试过将数据库与应用程序包打包并上传?当我尝试这个时,我的应用程序大约有 40 MB,但它不会上传到商店......
    • 哇,这是一个大数据库。我会考虑将您的数据库保留在服务器端。在本地手机上也有一个数据库,但允许手机只下载“它需要的东西”“它需要它”。因此,本地 DB 只是 40MB DB 中与给定订阅者相关的部分的缓存。 40MB 相当大,尽管我确信这很重要
    【解决方案3】:

    我相信其他两个答案都不正确。我的应用程序中有一个备份系统,其中备份被复制到 sd 卡,然后在备份恢复时复制回 /data/-文件夹。虽然我不知道为什么您的代码不起作用,但这是我从 sd 卡复制数据库的代码:

    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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多