gpt4 book ai didi

android - 下载外部 .db 文件以在 Kotlin Android 应用程序中以只读方式使用?

转载 作者:行者123 更新时间:2023-11-29 22:51:00 30 4
gpt4 key购买 nike

我已经有一个 SQLite 数据库 (.db) 文件可以在特定的 URL 上下载(比如 https://mywebsite.com/mydb.db) .我想下载此文件并在我的 Kotlin Android 应用程序中使用它。我可以将文件下载到我的设备模拟器中的“下载”文件夹,但我有几个关于从这里去哪里的问题。

  1. 我是否需要将此文件复制到内部存储,或者我是否可以直接从“下载”文件夹中的文件创建数据库?我希望数据库数据保留在本地,所以我不想将数据库文件留在可能被删除的地方(下载文件夹)。

    • 基本上,我希望该应用能够从持久的内部 .db 文件中读取
  2. 有时,我需要向 .db 文件中添加更多数据。将来,当我重新下载 .db 文件并从中创建数据库时,这是否会覆盖应用程序内部存储中的现有数据库?我是否需要手动删除数据库的旧迭代?

  3. 我想在应用程序第一次运行时自动下载 .db 文件,并在每次上传新版本的 .db 时自动下载文件到 https://mywebsite.com/mydb.db

总的来说,我是 Android 开发的新手,所以我不确定最佳实践是什么。单击按钮,我提供的代码成功地将我的 .db 文件下载到“下载”文件夹。在从 .db 文件创建数据库以及在我将新的 .db 文件上传到时自动替换数据库方面,我不确定从哪里开始我的主机网址。

private const val PERMISSION_CODE = 1000

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

downloadButton.setOnClickListener {
// Checks if version of Android is >= Marshmallow
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
// request permission if denied
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_CODE)
}
else {
startDownload()
}
}
else {
// OS is out of date, no permissions are needed
startDownload()
}
}

private fun startDownload() {
val request = DownloadManager.Request(Uri.parse(getString(R.string.db_URL)))
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
request.setTitle("my_database.db")
request.setDescription("My database is downloading.")
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "mydb_" + "${System.currentTimeMillis()}")

val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
manager.enqueue(request)
}

最佳答案

Do I need to copy this file to internal storage, or can I create a database directly from the file in the Downloads folder?

该文件是数据库,因此可以从下载文件夹中打开。

I want the database data to persist locally, so I don't want to leave the database file in a place where it may get deleted (the Downloads folder).

您可以根据ContextgetDatabasePath(the_database_name)方法,将下载文件夹中的文件复制到App的默认位置,获取文件将被复制到的位置。您将(至少在第一次运行时)检查数据库文件是否存在于它的最终位置,然后启动复制,之后可以打开和使用数据库。

或者,您可以直接将其下载到最终目的地,而无需中间副本。

Sometimes, I'll need to add more data to the .db file. In the future, when I re-download the .db file and create a database from it, will this overwrite the existing database in the app's internal storage? Do I need to manually delete old iterations of the database?

有多种方法,但基本上如果引入新文件,那么您可能会在旧位置覆盖现有数据库文件(存储在应用程序的数据中)(尽管这不是唯一的选择)。虽然,如果引入新数据而不是新模式(后者可能需要新代码,因此您可以利用数据库版本强制重新复制)。

问题是如何知道是否引入了新文件,因为数据库文件名至少在最终目的地可能是相同的。

  1. 检查文件的大小可能并不表示发生了变化,因此这不是一个故障安全选项。

    • 即数据库文件保存为页面 block ,其中一些页面可能包含更新数据库时可能使用的可用空间,因此数据库文件大小保持不变。
  2. 您可以查看文件的最后修改日期。

  3. 您可以使用不同的文件名,例如mydbv1.db 然后是 mydbv2.db 等
  4. 您可以使用 user_version,如果使用 SQLiteOpenHelper 的子类(最常见的情况),则需要小心,因为 SQLiteOpenHelper 使用它(数据库版本作为第四个参数传递)。
  5. 您可以使用 application_id(这类似于 user_version,但 SQLiteOpenHelper 不使用它)。

1-3 需要一种方法来持久记录当前使用的值,可能在数据库本身的表中,也可能是同一目录中的空文件。

4 和 5 实际上存储在数据库头中,您可以通过 pragma 访问值或以编程方式提取它们(后者不需要将文件作为数据库打开,并且通常资源密集度较低,因为您只需要阅读获取完整 header 的前 100 个字节)。

一旦您检测到新版本,只需重新下载和复制即可。

以上假设该应用程序有多个用户,因此主机服务器(您的网站)上始终必须存在一个下载文件,并且您已经将应用程序与数据库一起运送打折(这可以简化问题,因为当一个新的版本可用,请介绍应用程序的新版本)。

以上还假设数据库仅由最终用户读取。如果没有,并且用户可以更新数据,那么就需要一种策略来满足保留特定用户数据的需求。

关于android - 下载外部 .db 文件以在 Kotlin Android 应用程序中以只读方式使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57911101/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com