Skip to content

Instantly share code, notes, and snippets.

@sajjadyousefnia
Created June 28, 2024 16:08
Show Gist options
  • Save sajjadyousefnia/3ad87e3bd2625f31b6ba7bce74dc31b4 to your computer and use it in GitHub Desktop.
Save sajjadyousefnia/3ad87e3bd2625f31b6ba7bce74dc31b4 to your computer and use it in GitHub Desktop.
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()
val downloadConfig = PRDownloaderConfig.Builder().setDatabaseEnabled(true).build()
PRDownloader.initialize(this, downloadConfig)
Log.d(TAG, "Service Started");
}
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, notification)
} catch (e: Exception) {
e.printStackTrace()
Log.e(TAG, "onStartCommand: Download didn't start successfully")
}
return START_STICKY
}
private fun startDownload(
downloadModel: DownloadModel,
notification: NotificationCompat.Builder
) {
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(),
notification
)
}.start(object : OnDownloadListener {
override fun onDownloadComplete() {
onServiceChangeListener!!.onDownloadCompleted(downloadModel.id)
db.appDao().updateFinishedDownload(downloadModel.id, getCurrentDateTime())
}
override fun onError(error: com.sands.android.downloader.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
}
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