[英]Android Database download online
您好,我是 Android 开发的新手,我的应用程序完全面向数据库。 在我的应用程序中,我正在使用从资产文件夹复制数据库文件的方法。 它会增加apk的大小。
我想在我的应用程序第一次在手机上运行时从 inte.net 复制它。
如何将数据库文件下载到我的应用程序数据库文件夹中。
我就是这样做的:
我有一个处理下载数据库的DownloadManager实现。 在我的例子中,数据库非常大,因此 DownloadManager 是有效处理大量下载的好选择。
实现 DownloadManager 时需要注意的一件事; 建议您先将文件下载为临时文件,然后将它们移动到最终位置。 这是为了避免我在这样做时遇到奇怪的安全问题。 此外,下载通知可见性可能会影响所需的权限,如果您决定根本没有通知,则需要添加DOWNLOAD_WITHOUT_NOTIFICATION 。
所需权限:
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE " />
下载管理器实现
/**
* Manages all DB retrieval and file level validation.
*
*/
class DataBaseInitializationRepository(private val app: Application, private val dbHelper: DatabaseFileHelper) {
fun initiateDB( callback: DownloadCompleteCallback){
val dbUrl = dbHelper.getDbUrl()
val tempDbFile = dbHelper.getTempDbFile()
val permanentDbFile = dbHelper.getPermanentDbFile()
if (!permanentDbFile.exists() && tempDbFile.length() <= 0) {
val downloadManager = app.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downLoadDBRequest = DownloadManager.Request(Uri.parse( dbUrl ))
.setTitle( app.getString( R.string.download_db_title ) )
.setDescription(app.getString( R.string.download_db_description ))
.setDestinationInExternalFilesDir( app,
null,
tempDbFile.path
)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
val downloadId = downloadManager.enqueue( downLoadDBRequest )
registerReceiver( callback, downloadId )
}else{
callback.onComplete(0L)
}
}
private fun registerReceiver(callback: DownloadCompleteCallback, downloadId: Long){
val receiver = object: BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (id == downloadId){
//Move index reads to reusable function
val downloadManager = app.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val query = DownloadManager.Query()
query.setFilterById( downloadId )
val data = downloadManager.query( query )
if(data.moveToFirst() && data.count > 0){
val statusIndex = data.getColumnIndex(DownloadManager.COLUMN_STATUS)
val status = data.getInt( statusIndex )
if(status == DownloadManager.STATUS_SUCCESSFUL){
val localUriIndex = data.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)
val localFile = File(
data.getString( localUriIndex )
.replace("file://","" )
)
if(localFile.exists()){
permanentlyStoreDb(localFile)
callback.onComplete(id)
}else{
callback.onFail("Initial Database Download Failed - File not found")
}
}else if(status == DownloadManager.STATUS_FAILED){
val reasonIndex = data.getColumnIndex(DownloadManager.COLUMN_REASON)
val reason = data.getInt( reasonIndex )
if(reason == DownloadManager.ERROR_FILE_ALREADY_EXISTS){
callback.onComplete(id)
}else{
callback.onFail("Initial Database Download Failed: $reason")
}
}
}else{
callback.onFail("Initial Database Download Failed - Unable to read download metadata")
}
}
}
}
app.registerReceiver( receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE) )
}
private fun permanentlyStoreDb(tempFile: File): File {
val permanentDbFile = dbHelper.getPermanentDbFile()
try {
if(tempFile.exists()) {
tempFile.copyTo(
permanentDbFile,
true,
1024
)
tempFile.delete()
}else{
throw IOException("Temporal DB file doesn't exist")
}
}catch (ioex: IOException) {
throw IOException("Unable to copy DB to permanent storage:", ioex)
}
return permanentDbFile
}
/**
* Allows download completion to be notified back to the calling view model
*/
interface DownloadCompleteCallback{
fun onComplete(downloadId: Long)
fun onFail(message: String)
}
}
DatabaseFileHelper 包含确定临时文件、永久数据库位置和下载将发生的数据库 URL 的逻辑。 这是我用于临时文件的逻辑:
fun getTempDbFile(): File {
return File.createTempFile(<FILE-LOCATION>, null, app.cacheDir)
}
因此,如果您想通知正在运行的 Activity/Fragment,您只需将DownloadCompleteCallback实现传递给该组件即可获取它。
如果您使用的是 Room,只需确保您的 RoomDatabase 实现在您的getInstance方法中使用以下内容
.createFromFile( dbFileHelper.getPermanentDbFile() )
只需从网络复制它,而不是复制表单资产。 暗示
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.