Skip to content

Instantly share code, notes, and snippets.

@sajjadyousefnia
Created June 27, 2024 21:27
Show Gist options
  • Save sajjadyousefnia/b72de5d7a4d452f869715a1d74be8b2e to your computer and use it in GitHub Desktop.
Save sajjadyousefnia/b72de5d7a4d452f869715a1d74be8b2e to your computer and use it in GitHub Desktop.
package com.sands.android.Service
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.os.Handler
import android.os.Message
import android.content.Intent
import android.os.Binder
import android.os.Build
import android.os.Environment
import android.os.IBinder
import android.os.Looper
import android.os.Messenger
import android.util.Log
import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.downloader.PRDownloaderConfig
import com.sands.android.App.Companion.db
import com.sands.android.App.Companion.getCurrentDateTime
import com.sands.android.App.Companion.getDownloadedDirectory
import com.sands.android.R
import com.sands.android.dao.entity.DownloadModel
import com.sands.android.helper.OnServiceChangeListener
import com.sands.android.view.activity.MainActivity
import java.io.File
class DownloadService : Service() {
private val runningDownloadList = mutableListOf<DownloadModel>()
private var onServiceChangeListener: OnServiceChangeListener? = null
private val TAG = "DownloadService"
private val messenger = Messenger(IncomingHandler())
private val binder = LocalBinder()
private val notificationList = mutableListOf<Pair<Long, NotificationCompat.Builder>>()
private val CHANNEL_ID = "MyServiceChannel"
override fun onCreate() {
super.onCreate()
Log.d(TAG, "Service Started");
}
override fun onStart(intent: Intent?, startId: Int) {
super.onStart(intent, startId)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val downloadModel = db.appDao().getAllDownloads().last()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createNotificationChannel();
}
val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_MUTABLE)
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
.setOngoing(true).setPriority(
NotificationCompat.PRIORITY_DEFAULT
).setContentTitle("دانلود فیلم" + downloadModel.title)
.setContentText("فیلم مورد نظر در حال دانلود است").setSmallIcon(R.drawable.x_icon)
.setContentIntent(pendingIntent)
startForeground(1, notification.build())
try {
// val url = intent!!.extras!!.getString("url")
// val title = intent.extras!!.getString("title")
notificationList.add(Pair(downloadModel.id, notification))
// Toast.makeText(this, url.toString() + title.toString(), Toast.LENGTH_LONG).show()
// val downloadPath = provideDownloadDirectory(title.toString())
startDownload(downloadModel)
} catch (e: Exception) {
e.printStackTrace()
Log.e(TAG, "onStartCommand: Download didn't start successfully")
}
return START_STICKY
}
private fun startDownload(downloadModel: DownloadModel) {
// val downloadConfig = PRDownloaderConfig.Builder().setDatabaseEnabled(true).build()
PRDownloader.initialize(this/*, downloadConfig*/)
val directory =
File(getDownloadedDirectory())
if (!directory.exists()) {
directory.mkdir()
}
val downloadId = PRDownloader.download(
downloadModel.url, downloadModel.directory, downloadModel.fileName
).build().setOnStartOrResumeListener {
onServiceChangeListener!!.onDownloadStarted(downloadModel.id)
}.setOnPauseListener {
}.setOnCancelListener {
}.setOnProgressListener { progress ->
updateNotification(
((progress.currentBytes / progress.totalBytes) * 100).toInt(),
notificationList.first { it.first == downloadModel.id }.second
)
}.start(object : OnDownloadListener {
override fun onDownloadComplete() {
onServiceChangeListener!!.onDownloadCompleted(downloadModel.id)
db.appDao().updateFinishedDownload(downloadModel.id, getCurrentDateTime())
}
override fun onError(error: Error?) {
onServiceChangeListener!!.onDownloadFailed(downloadModel.id, error)
}
})
db.appDao().updateDownloadId(downloadModel.id, downloadId.toLong())
}
override fun onBind(intent: Intent?): IBinder? {
return binder
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "Service Stopped");
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val importance = NotificationManager.IMPORTANCE_HIGH
val serviceChannel = NotificationChannel(
CHANNEL_ID, "My Service Channel", importance
)
val manager = getSystemService(NotificationManager::class.java)
manager?.createNotificationChannel(serviceChannel)
}
}
private inner class IncomingHandler : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
// Handle messages from Activity
Toast.makeText(this@DownloadService, msg.data.getString("msg"), Toast.LENGTH_LONG)
.show()
}
}
inner class LocalBinder : Binder() {
fun getService(): DownloadService = this@DownloadService
fun getMessenger(): Messenger = messenger
}
// Method to send messages to the Activity via Broadcast
fun sendMessageToActivity(msg: String) {
val intent = Intent("com.sands.android.DOWNLOAD_COMMUNICATION")
intent.putExtra("msg", msg)
// sendBroadcast(intent)
intent.setPackage(packageName)
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
}
public fun updateServiceFromActivity(onServiceChangeListener: OnServiceChangeListener) {
this.onServiceChangeListener = onServiceChangeListener
}
private fun provideDownloadDirectory(title: String): String {
var downloadPath: String
try {
val downloadDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val mainDownloadFolder = File(downloadDir.absolutePath + "/Sands/")
if (!mainDownloadFolder.exists()) {
mainDownloadFolder.mkdirs()
}
downloadPath = mainDownloadFolder.absolutePath + title
} catch (e: Exception) {
e.printStackTrace()
downloadPath = ""
}
return downloadPath
}
/*
fun getMusicFilePath(title: String): String {
return try {
App.mainMusicFolder.absolutePath + "/music_" + music_name //+ ".mp3"
} catch (e: Exception) {
val downloadDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
App.mainDataAppFolder =
File(downloadDir.absolutePath + "/delisa")//File(getExternalFilesDir(null)!!.absolutePath)
if (!App.mainDataAppFolder.exists()) App.mainDataAppFolder.mkdirs()
App.mainMusicFolder = File(App.mainDataAppFolder.absolutePath + "/" + "music" + "/")
if (!App.mainMusicFolder.exists()) App.mainMusicFolder.mkdirs()
App.mainGalleryFolder = File(App.mainDataAppFolder.absolutePath + "/" + "gallery" + "/")
if (!App.mainGalleryFolder.exists()) App.mainGalleryFolder.mkdirs()
App.mainMusicFolder.absolutePath + "/music_" + music_name //+ ".mp3"
}
}
*/
private fun updateNotification(progress: Int, notificationBuilder: NotificationCompat.Builder) {
notificationBuilder.setProgress(100, progress, false)
notificationBuilder.setContentText("$progress% complete")
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(1, notificationBuilder.build())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment