gpt4 book ai didi

java - IntentService/Service - 即使应用程序终止也保持运行 - Android

转载 作者:行者123 更新时间:2023-12-02 10:09:33 25 4
gpt4 key购买 nike

我正在实现 IntentService要下载 PDF 文件,它会在 downloadStart 上向用户显示一条通知并在此过程中不断更新进度,服务工作正常并且进度更新正确,问题是一旦我从“最近”中删除我的应用程序,下载就会停止,甚至不会显示错误。

  • 这是我的 DownloadService 类:

class DownloadService : IntentService("DownloadService") {

lateinit var downloadNotification : DownloadNotification
lateinit var book : BookData
private lateinit var fileName : String
private lateinit var fileFolder : String
private lateinit var filePath : String
lateinit var fileUrl : String
var isCancelled = false
private lateinit var handler : Handler

override fun onCreate() {
super.onCreate()
handler = Handler()
}


override fun onHandleIntent(p0: Intent?) {
book = Gson().fromJson<BookData>(p0?.getStringExtra("book"), BookData::class.java)
downloadNotification = DownloadNotification(this, book.id!!)
init(book)
}

fun getFilePath() : String {
val directory = File(fileFolder)
if (!directory.exists()) {
directory.mkdirs()
}
return filePath
}

private fun init(book : BookData) {
fileName = "${book.id}.pdf"
fileFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString() + File.separator + "Libranova/Books/"
filePath = fileFolder + fileName
fileUrl = book.downloadLink!!
startDownload()
}

private fun startDownload() {
downloadNotification.setTitle(book.name!!).setText("Preparing...").notificationCompat.apply {
downloadNotification.notifyManager(true)
DownloadUtils.downloadFile(this@DownloadService, object : DownloadListener {
override fun onStarted() {
handler.post {
Toast.makeText(this@DownloadService,"Download Started", Toast.LENGTH_LONG).show()
}
}

override fun onSuccess() {
downloadNotification.onFinishDownload().freeUp().setSuccess().notifyManager(true)
}

override fun onError(message: String) {
downloadNotification.onFinishDownload().freeUp().setError(message).notifyManager(true)
}

override fun onCanceled() {
downloadNotification.cancel()
}

override fun onProgress(progress: Int) {
downloadNotification.setProgress(progress).setText("$progress%").notifyManager(false)
}

})
}

}
}

  • 这是我的 downloadFile 方法,位于 object :

object DownloadUtils {

fun downloadFile(downloadService: DownloadService, downloadListener: DownloadListener) {
try {
val url = URL(downloadService.fileUrl)
val connection = url.openConnection()
connection.connect()
val lengthOfFile = connection.contentLength
val input = BufferedInputStream(url.openStream(), 8192)
val output = FileOutputStream(downloadService.getFilePath())
val data = ByteArray(1024)
var total: Long = 0
var count = input.read(data)
downloadListener.onStarted()
while (count != -1) {
if (!downloadService.isCancelled) {
total += count.toLong()
downloadListener.onProgress(((total * 100) / lengthOfFile).toInt())
output.write(data, 0, count)
count = input.read(data)
}
else break
}
output.flush()
output.close()
input.close()
if (downloadService.isCancelled) downloadListener.onCanceled() else downloadListener.onSuccess()
}
catch (e : Exception) {
downloadListener.onError(e.message ?: "Unknown Error")
}
}

fun fastFileDownload(downloadService: DownloadService) {
URL(downloadService.fileUrl).openStream().use { input ->
val folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString() + File.separator + "Libranova/Books/"
val directory = File(folder)
if (!directory.exists()) {
directory.mkdirs()
}
FileOutputStream(File(downloadService.getFilePath())).use { output ->
input.copyTo(output)
}
}
}
}

经过在互联网上的长时间搜索,我发现使用 Service而不是IntentService将解决问题,我已更改我的类结构以继承 Service()相反,除了 onError(message : String) 之外,一切正常返回 null e.message (在本例中,它在 "Unknown Error" 中启动进程后立即从 downloadFile 方法返回 catch (e : Exception) ) 。有什么方法/替代方案可以保持文件下载并更新某些事件的通知吗?

注释:

  • 我用过AsyncTask之前,但我的文件需要很长时间才能下载,这不是一个好方法(文件大小为 5..150 MB)。
  • 我用过ThreadPoolExcuter/Thread使用 runOnUiThread 更新通知但它也会在应用程序终止时被杀死。谢谢!

编辑:关注m0skit0's Answer在 onCreate 方法中,我创建了一个在整个下载过程中可见的通知,显示等待处理的下载数量,同时显示其他通知以及每个下载过程的进度。通过调用 startForeground(ID, notification)在onCreate中,即使应用程序被杀死,服务也将可用。

  • 这是我的新 onCreate() 方法:

    override fun onCreate() {
    super.onCreate()
    handler = Handler()
    val notificationBuilder = NotificationCompat.Builder(this, "LibranovaDownloadService")
    val notification = notificationBuilder.setOngoing(true)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    .setSubText("Download Queue")
    .setContentText("Waiting For Download : 1 Book")
    .setCategory(NotificationCompat.CATEGORY_SERVICE)
    .build()
    startForeground(123, notification)

    }

最佳答案

要保持 Service 处于 Activity 状态,您可以使用 startForeground API。

来自documentation :

A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)

关于java - IntentService/Service - 即使应用程序终止也保持运行 - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55104486/

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