download resume and stuff

This commit is contained in:
LagradOst 2021-07-08 19:46:47 +02:00
parent 3ef14b93fb
commit 576377e4bb
5 changed files with 136 additions and 24 deletions

View file

@ -33,6 +33,19 @@
</intent-filter>
</activity>
<receiver
android:name=".recivers.VideoDownloadRestartReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="restart_service" />
</intent-filter>
</receiver>
<service
android:name=".services.VideoDownloadKeepAliveService"
android:enabled="true" >
</service>
<service
android:name=".services.VideoDownloadService"
android:enabled="true"

View file

@ -1,39 +1,28 @@
package com.lagradost.cloudstream3
import android.Manifest
import android.app.PictureInPictureParams
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.documentfile.provider.DocumentFile
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.callback.StorageAccessCallback
import com.anggrayudi.storage.file.StorageId
import com.anggrayudi.storage.file.StorageType
import com.anggrayudi.storage.file.getStorageId
import com.google.android.gms.cast.ApplicationMetadata
import com.google.android.gms.cast.Cast
import com.google.android.gms.cast.LaunchOptions
import com.google.android.gms.cast.framework.CastButtonFactory
import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.listener.multi.BaseMultiplePermissionsListener
import com.lagradost.cloudstream3.UIHelper.checkWrite
import com.lagradost.cloudstream3.UIHelper.hasPIPPermission
import com.lagradost.cloudstream3.UIHelper.requestRW
import com.lagradost.cloudstream3.UIHelper.shouldShowPIPMode
import com.lagradost.cloudstream3.recivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.services.RESTART_ALL_DOWNLOADS_AND_QUEUE
import com.lagradost.cloudstream3.services.RESTART_NONE
import com.lagradost.cloudstream3.services.START_VALUE_KEY
import com.lagradost.cloudstream3.services.VideoDownloadKeepAliveService
import com.lagradost.cloudstream3.utils.VideoDownloadManager
import kotlinx.android.synthetic.main.fragment_result.*
@ -125,6 +114,14 @@ class MainActivity : AppCompatActivity() {
storage.onRestoreInstanceState(savedInstanceState)
}
override fun onDestroy() {
val broadcastIntent = Intent()
broadcastIntent.action = "restart_service"
broadcastIntent.setClass(this, VideoDownloadRestartReceiver::class.java)
this.sendBroadcast(broadcastIntent)
super.onDestroy()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainContext = this
@ -161,6 +158,12 @@ class MainActivity : AppCompatActivity() {
}
CastButtonFactory.setUpMediaRouteButton(this, media_route_button)
if (!VideoDownloadManager.isMyServiceRunning(this, VideoDownloadKeepAliveService::class.java)) {
val mYourService = VideoDownloadKeepAliveService()
val mServiceIntent = Intent(this, mYourService::class.java).putExtra(START_VALUE_KEY, RESTART_ALL_DOWNLOADS_AND_QUEUE)
this.startService(mServiceIntent)
}
/*
val castContext = CastContext.getSharedInstance(applicationContext)
fun buildMediaQueueItem(video: String): MediaQueueItem {

View file

@ -0,0 +1,23 @@
package com.lagradost.cloudstream3.recivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import com.lagradost.cloudstream3.services.RESTART_ALL_DOWNLOADS_AND_QUEUE
import com.lagradost.cloudstream3.services.START_VALUE_KEY
import com.lagradost.cloudstream3.services.VideoDownloadKeepAliveService
class VideoDownloadRestartReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.i("Broadcast Listened", "Service tried to stop")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context?.startForegroundService(Intent(context, VideoDownloadKeepAliveService::class.java).putExtra(START_VALUE_KEY, RESTART_ALL_DOWNLOADS_AND_QUEUE))
} else {
context?.startService(Intent(context, VideoDownloadKeepAliveService::class.java).putExtra(START_VALUE_KEY, RESTART_ALL_DOWNLOADS_AND_QUEUE))
}
}
}

View file

@ -0,0 +1,51 @@
package com.lagradost.cloudstream3.services
import android.app.Service
import android.content.Intent
import android.os.IBinder
import com.lagradost.cloudstream3.recivers.VideoDownloadRestartReceiver
import com.lagradost.cloudstream3.utils.DataStore.getKey
import com.lagradost.cloudstream3.utils.DataStore.getKeys
import com.lagradost.cloudstream3.utils.VideoDownloadManager
const val RESTART_ALL_DOWNLOADS_AND_QUEUE = 1
const val RESTART_NONE = 0
const val START_VALUE_KEY = "start_value"
class VideoDownloadKeepAliveService : Service() {
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val startValue = intent?.getIntExtra(START_VALUE_KEY, RESTART_NONE) ?: RESTART_NONE
if (startValue == RESTART_ALL_DOWNLOADS_AND_QUEUE) {
val keys = this.getKeys(VideoDownloadManager.KEY_RESUME_PACKAGES)
val resumePkg = keys.mapNotNull { k -> this.getKey<VideoDownloadManager.DownloadResumePackage>(k) }
for (pkg in resumePkg) { // ADD ALL CURRENT DOWNLOADS
VideoDownloadManager.downloadFromResume(this, pkg)
}
// ADD QUEUE
val resumeQueue =
this.getKey<List<VideoDownloadManager.DownloadQueueResumePackage>>(VideoDownloadManager.KEY_RESUME_QUEUE_PACKAGES)
if (resumeQueue != null && resumeQueue.isNotEmpty()) {
val sorted = resumeQueue.sortedBy { item -> item.index }
for (queueItem in sorted) {
VideoDownloadManager.downloadFromResume(this, queueItem.pkg)
}
}
}
return START_STICKY//super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
val broadcastIntent = Intent()
broadcastIntent.action = "restart_service"
broadcastIntent.setClass(this, VideoDownloadRestartReceiver::class.java)
this.sendBroadcast(broadcastIntent)
super.onDestroy()
}
}

View file

@ -1,5 +1,6 @@
package com.lagradost.cloudstream3.utils
import android.app.ActivityManager
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
@ -20,6 +21,9 @@ import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
import com.lagradost.cloudstream3.services.RESTART_NONE
import com.lagradost.cloudstream3.services.START_VALUE_KEY
import com.lagradost.cloudstream3.services.VideoDownloadKeepAliveService
import com.lagradost.cloudstream3.services.VideoDownloadService
import com.lagradost.cloudstream3.utils.Coroutines.main
import com.lagradost.cloudstream3.utils.DataStore.getKey
@ -33,8 +37,7 @@ import java.lang.Thread.sleep
import java.net.URL
import java.net.URLConnection
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
const val DOWNLOAD_CHANNEL_ID = "cloudstream3.general"
const val DOWNLOAD_CHANNEL_NAME = "Downloads"
@ -119,6 +122,11 @@ object VideoDownloadManager {
val path: Uri,
)
data class DownloadQueueResumePackage(
val index: Int,
val pkg: DownloadResumePackage,
)
private const val SUCCESS_DOWNLOAD_DONE = 1
private const val SUCCESS_STOPPED = 2
private const val ERROR_DELETING_FILE = -1
@ -131,8 +139,9 @@ object VideoDownloadManager {
private const val ERROR_CONTENT_RESOLVER_CANT_OPEN_STREAM = -8
private const val ERROR_CONTENT_RESOLVER_NOT_FOUND = -9
private const val KEY_RESUME_PACKAGES = "download_resume"
private const val KEY_DOWNLOAD_INFO = "download_info"
const val KEY_RESUME_PACKAGES = "download_resume"
const val KEY_DOWNLOAD_INFO = "download_info"
const val KEY_RESUME_QUEUE_PACKAGES = "download_q_resume"
val downloadStatus = HashMap<Int, DownloadType>()
val downloadStatusEvent = Event<Pair<Int, DownloadType>>()
@ -249,7 +258,7 @@ object VideoDownloadManager {
} else if (state == DownloadType.IsDone) {
"Download Done - $rowTwo"
} else {
"Download Stopped - $rowTwo"
"Download Canceled - $rowTwo"
}
val bodyStyle = NotificationCompat.BigTextStyle()
@ -263,7 +272,7 @@ object VideoDownloadManager {
} else if (state == DownloadType.IsDone) {
"Download Done - $rowTwo"
} else {
"Download Stopped - $rowTwo"
"Download Canceled - $rowTwo"
}
builder.setContentText(txt)
@ -312,7 +321,7 @@ object VideoDownloadManager {
}, when (i) {
DownloadActionType.Resume -> "Resume"
DownloadActionType.Pause -> "Pause"
DownloadActionType.Stop -> "Stop"
DownloadActionType.Stop -> "Cancel"
}, pending
)
)
@ -628,6 +637,9 @@ object VideoDownloadManager {
downloadEvent.invoke(Pair(id, DownloadActionType.Resume))
return
}
val dQueue = downloadQueue.toList().mapIndexed { index, any -> DownloadQueueResumePackage(index, any) }
context.setKey(KEY_RESUME_QUEUE_PACKAGES, dQueue)
currentDownloads.add(id)
main {
@ -722,6 +734,16 @@ object VideoDownloadManager {
downloadCheck(context)
}
fun isMyServiceRunning(context: Context, serviceClass: Class<*>): Boolean {
val manager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager?
for (service in manager!!.getRunningServices(Int.MAX_VALUE)) {
if (serviceClass.name == service.service.className) {
return true
}
}
return false
}
fun downloadEpisode(
context: Context,
source: String?,