2021-07-19 13:19:47 +00:00
|
|
|
package com.lagradost.cloudstream3.utils
|
|
|
|
|
2021-07-30 01:14:53 +00:00
|
|
|
import android.app.Activity
|
2021-07-19 13:19:47 +00:00
|
|
|
import android.content.ContentValues
|
|
|
|
import android.content.Context
|
2021-07-30 01:14:53 +00:00
|
|
|
import android.content.pm.PackageManager
|
|
|
|
import android.media.AudioAttributes
|
|
|
|
import android.media.AudioFocusRequest
|
|
|
|
import android.media.AudioManager
|
|
|
|
import android.net.ConnectivityManager
|
|
|
|
import android.net.NetworkCapabilities
|
2021-07-19 13:19:47 +00:00
|
|
|
import android.net.Uri
|
2021-07-30 01:14:53 +00:00
|
|
|
import android.os.Build
|
2021-07-19 13:19:47 +00:00
|
|
|
import android.provider.MediaStore
|
2021-07-30 01:14:53 +00:00
|
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
|
|
import com.google.android.gms.cast.framework.CastContext
|
|
|
|
import com.google.android.gms.cast.framework.CastState
|
|
|
|
import com.google.android.gms.common.ConnectionResult
|
|
|
|
import com.google.android.gms.common.GoogleApiAvailability
|
|
|
|
import com.google.android.gms.common.wrappers.Wrappers
|
2021-11-05 22:08:47 +00:00
|
|
|
import com.lagradost.cloudstream3.MainAPI
|
2021-07-30 01:14:53 +00:00
|
|
|
import com.lagradost.cloudstream3.R
|
|
|
|
import com.lagradost.cloudstream3.SearchResponse
|
2021-11-05 22:08:47 +00:00
|
|
|
import com.lagradost.cloudstream3.TvType
|
2021-07-30 01:14:53 +00:00
|
|
|
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
2021-09-20 21:11:36 +00:00
|
|
|
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
2021-07-19 13:19:47 +00:00
|
|
|
|
|
|
|
object AppUtils {
|
|
|
|
fun getVideoContentUri(context: Context, videoFilePath: String): Uri? {
|
|
|
|
val cursor = context.contentResolver.query(
|
|
|
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, arrayOf(MediaStore.Video.Media._ID),
|
|
|
|
MediaStore.Video.Media.DATA + "=? ", arrayOf(videoFilePath), null
|
|
|
|
)
|
|
|
|
return if (cursor != null && cursor.moveToFirst()) {
|
|
|
|
val id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID))
|
|
|
|
cursor.close()
|
|
|
|
Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "" + id)
|
|
|
|
} else {
|
|
|
|
val values = ContentValues()
|
|
|
|
values.put(MediaStore.Video.Media.DATA, videoFilePath)
|
|
|
|
context.contentResolver.insert(
|
|
|
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2021-07-30 01:14:53 +00:00
|
|
|
|
2021-08-09 14:40:20 +00:00
|
|
|
/**| S1:E2 Hello World
|
|
|
|
* | Episode 2. Hello world
|
|
|
|
* | Hello World
|
|
|
|
* | Season 1 - Episode 2
|
|
|
|
* | Episode 2
|
|
|
|
* **/
|
2021-09-02 13:19:50 +00:00
|
|
|
fun Context.getNameFull(name: String?, episode: Int?, season: Int?): String {
|
2021-08-25 15:28:25 +00:00
|
|
|
val rEpisode = if (episode == 0) null else episode
|
|
|
|
val rSeason = if (season == 0) null else season
|
2021-08-11 18:26:19 +00:00
|
|
|
|
2021-09-02 13:19:50 +00:00
|
|
|
val seasonName = getString(R.string.season)
|
|
|
|
val episodeName = getString(R.string.episode)
|
|
|
|
val seasonNameShort = getString(R.string.season_short)
|
|
|
|
val episodeNameShort = getString(R.string.episode_short)
|
|
|
|
|
2021-08-09 14:40:20 +00:00
|
|
|
if (name != null) {
|
2021-08-25 15:28:25 +00:00
|
|
|
return if (rEpisode != null && rSeason != null) {
|
2021-09-02 13:19:50 +00:00
|
|
|
"$seasonNameShort${rSeason}:$episodeNameShort${rEpisode} $name"
|
2021-08-25 15:28:25 +00:00
|
|
|
} else if (rEpisode != null) {
|
2021-09-02 13:19:50 +00:00
|
|
|
"$episodeName $rEpisode. $name"
|
2021-08-09 14:40:20 +00:00
|
|
|
} else {
|
|
|
|
name
|
|
|
|
}
|
|
|
|
} else {
|
2021-08-25 15:28:25 +00:00
|
|
|
if (rEpisode != null && rSeason != null) {
|
2021-09-02 13:19:50 +00:00
|
|
|
return "$seasonName $rSeason - $episodeName $rEpisode"
|
2021-08-25 15:28:25 +00:00
|
|
|
} else if (rSeason == null) {
|
2021-09-02 13:19:50 +00:00
|
|
|
return "$episodeName $rEpisode"
|
2021-08-09 14:40:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:39:56 +00:00
|
|
|
//private val viewModel: ResultViewModel by activityViewModels()
|
|
|
|
|
2021-08-25 15:28:25 +00:00
|
|
|
fun AppCompatActivity.loadResult(url: String, apiName: String, startAction: Int = 0, startValue: Int = 0) {
|
2021-07-30 01:14:53 +00:00
|
|
|
this.runOnUiThread {
|
2021-11-05 21:39:56 +00:00
|
|
|
// viewModelStore.clear()
|
2021-09-20 21:11:36 +00:00
|
|
|
this.navigate(R.id.global_to_navigation_results, ResultFragment.newInstance(url, apiName, startAction, startValue))
|
2021-07-30 01:14:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-25 15:28:25 +00:00
|
|
|
fun Activity?.loadSearchResult(card: SearchResponse, startAction: Int = 0, startValue: Int = 0) {
|
|
|
|
(this as AppCompatActivity?)?.loadResult(card.url, card.apiName, startAction, startValue)
|
2021-07-30 01:14:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fun Activity.requestLocalAudioFocus(focusRequest: AudioFocusRequest?) {
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && focusRequest != null) {
|
|
|
|
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
|
|
audioManager.requestAudioFocus(focusRequest)
|
|
|
|
} else {
|
|
|
|
val audioManager: AudioManager =
|
|
|
|
getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
|
|
audioManager.requestAudioFocus(
|
|
|
|
null,
|
|
|
|
AudioManager.STREAM_MUSIC,
|
|
|
|
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private var currentAudioFocusRequest: AudioFocusRequest? = null
|
|
|
|
private var currentAudioFocusChangeListener: AudioManager.OnAudioFocusChangeListener? = null
|
|
|
|
var onAudioFocusEvent = Event<Boolean>()
|
|
|
|
|
|
|
|
private fun getAudioListener(): AudioManager.OnAudioFocusChangeListener? {
|
|
|
|
if (currentAudioFocusChangeListener != null) return currentAudioFocusChangeListener
|
|
|
|
currentAudioFocusChangeListener = AudioManager.OnAudioFocusChangeListener {
|
|
|
|
onAudioFocusEvent.invoke(
|
|
|
|
when (it) {
|
|
|
|
AudioManager.AUDIOFOCUS_GAIN -> false
|
|
|
|
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE -> false
|
|
|
|
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT -> false
|
|
|
|
else -> true
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return currentAudioFocusChangeListener
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Context.isCastApiAvailable(): Boolean {
|
|
|
|
val isCastApiAvailable =
|
|
|
|
GoogleApiAvailability.getInstance()
|
|
|
|
.isGooglePlayServicesAvailable(applicationContext) == ConnectionResult.SUCCESS
|
|
|
|
try {
|
|
|
|
applicationContext?.let { CastContext.getSharedInstance(it) }
|
|
|
|
} catch (e: Exception) {
|
|
|
|
println(e)
|
|
|
|
// track non-fatal
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return isCastApiAvailable
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Context.isConnectedToChromecast(): Boolean {
|
|
|
|
if (isCastApiAvailable()) {
|
|
|
|
val castContext = CastContext.getSharedInstance(this)
|
|
|
|
if (castContext.castState == CastState.CONNECTED) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Context.isUsingMobileData(): Boolean {
|
|
|
|
val conManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
|
|
val networkInfo = conManager.allNetworks
|
|
|
|
return networkInfo.any {
|
|
|
|
conManager.getNetworkCapabilities(it)?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun Context.isAppInstalled(uri: String): Boolean {
|
|
|
|
val pm = Wrappers.packageManager(this)
|
|
|
|
var appInstalled = false
|
|
|
|
appInstalled = try {
|
|
|
|
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
|
|
|
|
true
|
|
|
|
} catch (e: PackageManager.NameNotFoundException) {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
return appInstalled
|
|
|
|
}
|
|
|
|
|
|
|
|
fun getFocusRequest(): AudioFocusRequest? {
|
|
|
|
if (currentAudioFocusRequest != null) return currentAudioFocusRequest
|
|
|
|
currentAudioFocusRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
|
|
AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
|
|
|
|
setAudioAttributes(AudioAttributes.Builder().run {
|
|
|
|
setUsage(AudioAttributes.USAGE_MEDIA)
|
|
|
|
setContentType(AudioAttributes.CONTENT_TYPE_MOVIE)
|
|
|
|
build()
|
|
|
|
})
|
|
|
|
setAcceptsDelayedFocusGain(true)
|
|
|
|
getAudioListener()?.let {
|
|
|
|
setOnAudioFocusChangeListener(it)
|
|
|
|
}
|
|
|
|
build()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
null
|
|
|
|
}
|
|
|
|
return currentAudioFocusRequest
|
|
|
|
}
|
2021-11-05 22:08:47 +00:00
|
|
|
|
|
|
|
fun filterProviderByPreferredMedia(apis: ArrayList<MainAPI>, currentPrefMedia: Int): List<MainAPI> {
|
|
|
|
val allApis = apis.filter { api -> api.hasMainPage }
|
|
|
|
return if (currentPrefMedia < 1) {
|
|
|
|
allApis
|
|
|
|
} else {
|
|
|
|
// Filter API depending on preferred media type
|
|
|
|
val listEnumAnime = listOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA)
|
|
|
|
val listEnumMovieTv = listOf(TvType.Movie, TvType.TvSeries, TvType.Cartoon)
|
|
|
|
val mediaTypeList = if (currentPrefMedia==1) listEnumMovieTv else listEnumAnime
|
|
|
|
|
|
|
|
val filteredAPI = allApis.filter { api -> api.supportedTypes.any { it in mediaTypeList } }
|
|
|
|
filteredAPI
|
|
|
|
}
|
|
|
|
}
|
2021-07-19 13:19:47 +00:00
|
|
|
}
|