I'm making an APK file download screen and i show progress which is the percent of the file downloaded in the screen and also i have a notification to use a Foreground service because the file download must be downloaded from a service. During downloading, users can leave the app and can go back to my app through the notification. But the problem is, to achieve this logic, i use PendingIntent
and when user click my app's notification, it recreates the app instead of going back to the previous screen earlier. I don't know why. please check my codes below.
File Download Fragment
class FileDownloadFragment(private val uri: String) : DialogFragment() {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
startDownloadService()
}
private fun startDownloadService() {
val downloadService = AppUpdateAPKDownloadService()
val startIntent = Intent(context, downloadService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(startIntent)
} else {
context.startService(startIntent)
}
}
...
}
Foreground Service
class AppUpdateAPKDownloadService: LifecycleService() {
...
/** Dispatcher */
private val ioDispatcher = Dispatchers.IO
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
if (intent != null) {
createNotificationChannel()
val notification = getNotification()
startForeground(NOTIFICATION_ID, notification)
lifecycleScope.launch{
downloadAPK(intent.getStringExtra(UPDATE_APK_URI).toString())
}
}
return START_NOT_STICKY
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT
).apply {
enableVibration(true)
enableLights(true)
}
val manager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
}
}
private fun getNotification(): Notification {
val intent = Intent(applicationContext, SplashActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
val pendingIntent = TaskStackBuilder.create(applicationContext).run {
addNextIntentWithParentStack(intent)
getPendingIntent(APP_UPDATE_PENDING_INTENT_REQUEST_CODE, PendingIntent.FLAG_IMMUTABLE)
}
// val pendingIntent = PendingIntent.getActivity(
// applicationContext,
// APP_UPDATE_PENDING_INTENT_REQUEST_CODE,
// intent,
// PendingIntent.FLAG_IMMUTABLE
// )
val notification = NotificationCompat.Builder(this, CHANNEL_ID).apply {
setContentTitle("DownloadApp")
setContentText("Downloading...")
setSmallIcon(R.drawable.icon)
setLargeIcon(BitmapFactory.decodeResource(this@AppUpdateAPKDownloadService.applicationContext.resources, R.mipmap.icon))
priority = NotificationCompat.PRIORITY_HIGH
setContentIntent(pendingIntent)
setOngoing(true)
setAutoCancel(true)
}.build()
val notificationManager = NotificationManagerCompat.from(this)
notificationManager.notify(NOTIFICATION_ID, notification)
return notification
}
private suspend fun downloadAPK(uri: String) = withContext(ioDispatcher) {
kotlin.runCatching {
URL(uri)
}.onSuccess { url ->
val connection: URLConnection = url.openConnection()
connection.connect()
val fileFullSize = connection.contentLength
val directory = applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
directory?.let {
if (!directory.exists()) directory.mkdirs()
}
val inputDataStream = DataInputStream(BufferedInputStream(url.openStream(), fileFullSize))
val file = File(directory, "my_app.apk")
val outputDataStream = DataOutputStream(BufferedOutputStream(FileOutputStream(file), fileFullSize))
processDownload(
inputStream = inputDataStream,
outputStream = outputDataStream,
fileFullSize = fileFullSize
)
val bundle = Bundle().apply {
putInt(UPDATE_APK_RECEIVER_MODE, UPDATE_APK_DOWNLOAD_COMPLETE)
}
uiUpdateReceiver?.send(Activity.RESULT_OK, bundle)
}.onFailure {
}
}
private fun processDownload(
inputStream: DataInputStream,
outputStream: DataOutputStream,
fileFullSize: Int
) {
val data = ByteArray(fileFullSize)
var downloadSize: Long = 0
var count: Int
while (inputStream.read(data).also { count = it } != -1) {
downloadSize += count
val percent = (downloadSize.toFloat() / fileFullSize) * 100
Log.d("TEST", "writing...$percent% in Service")
val bundle = Bundle().apply {
putInt(UPDATE_APK_RECEIVER_MODE, UPDATE_APK_UI_UPDATE)
putFloat(UPDATE_API_UI_PERCENT, percent)
}
uiUpdateReceiver?.send(Activity.RESULT_OK, bundle)
outputStream.write(data, 0, count)
}
outputStream.flush()
outputStream.close()
inputStream.close()
}
...
}
I also add android:launchMode="singleTop"
to SplashActivity in AndroidManifest.xml
but it's still not working...
What mistake did I make?