Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
下载外部.db文件以在Kotlin Android应用程序中只读使用?_Android_Kotlin_Download_Android Sqlite_Android Internal Storage - Fatal编程技术网

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

下载外部.db文件以在Kotlin Android应用程序中只读使用?,android,kotlin,download,android-sqlite,android-internal-storage,Android,Kotlin,Download,Android Sqlite,Android Internal Storage,我已经有了一个SQLite数据库(.db)文件,可以在特定的URL(比如https://mywebsite.com/mydb.db)。我想下载这个文件并在我的Kotlin Android应用程序中使用它。我可以将文件下载到我的设备模拟器中的“Downloads”文件夹中,但是我有几个关于从这里开始的问题 我是否需要将此文件复制到内部存储器,或者是否可以直接从下载文件夹中的文件创建数据库?我希望数据库数据在本地持久化,因此我不希望将数据库文件留在可能被删除的位置(下载文件夹) 基本上,我希望该应

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

  • 我是否需要将此文件复制到内部存储器,或者是否可以直接从下载文件夹中的文件创建数据库?我希望数据库数据在本地持久化,因此我不希望将数据库文件留在可能被删除的位置(下载文件夹)

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

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

  • 总的来说,我对Android开发非常陌生,所以我不确定最佳实践是什么。我提供的代码通过单击按钮成功地将我的
    .db
    文件下载到“downloads”文件夹。在从
    .db
    文件创建数据库,并在将新的
    .db
    文件上载到主机URL时自动替换数据库方面,我不确定该从何处着手

    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)
    }
    
    我是否需要将此文件复制到内部存储器,或者是否可以直接从下载文件夹中的文件创建数据库

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

    我希望数据库数据在本地持久化,因此我不希望将数据库文件留在可能被删除的位置(下载文件夹)

    您可以从下载文件夹复制文件,并根据上下文
    getDatabasePath(数据库名称)
    方法将其放置在应用程序的默认位置,以获取文件将复制到的位置。您应该(至少在第一次运行时)检查数据库文件是否存在于其最终位置,然后启动副本,然后打开并使用数据库

    或者,您可以直接将其下载到最终目的地,而不必使用中间副本

    有时,我需要向.db文件添加更多数据。将来,当我重新下载.db文件并从中创建数据库时,这会覆盖应用程序内部存储中的现有数据库吗?我是否需要手动删除数据库的旧迭代

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

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

  • 当发生更改时,检查文件大小可能并不表示有更改,因此不是故障保护选项

    • 也就是说,数据库文件保存为多个页面,其中一些页面可能包含更新数据库时可能使用的可用空间,因此数据库文件大小保持不变
  • 您可以检查文件的最后修改日期

  • 您可以使用不同的文件名,例如mydbv1.db,然后是mydbv2.db等
  • 您可以使用user_版本,如果使用SQLiteOpenHelper的子类(这是最常见的情况),则需要小心,因为这是由SQLiteOpenHelper使用的(作为第四个参数传递的数据库版本)
  • 您可以使用应用程序\u id(这类似于用户\u版本,但SQLiteOpenHelper未使用)
  • 1-3需要一种持久记录当前使用值的方法,可能记录在数据库本身的表中,也可能记录在同一目录中的空文件中

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

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

    以上假设应用程序有多个用户,因此下载文件必须始终存在于主机服务器(您的网站)上,并且您已打折将应用程序与数据库一起交付(这可能会简化问题,因为当有新版本可用时,您会引入新版本的应用程序)

    上面还假设数据库仅由最终用户读取。如果没有,用户可以更新数据,则需要一种策略来保存特定用户的数据