Bumped dependencies to support Android API 33

This commit is contained in:
Angelo Cassano 2023-04-12 19:51:14 +02:00
parent 67552c43dd
commit 5c82074e2f
9 changed files with 71 additions and 69 deletions

View file

@ -2,14 +2,14 @@ group 'com.gianlucaparadise.flutter_cast_framework'
version '1.0-SNAPSHOT' version '1.0-SNAPSHOT'
buildscript { buildscript {
ext.kotlin_version = '1.5.31' ext.kotlin_version = '1.8.20'
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.2.2' classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@ -17,7 +17,7 @@ buildscript {
rootProject.allprojects { rootProject.allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }
@ -25,13 +25,13 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
android { android {
compileSdkVersion 31 compileSdkVersion 33
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
lintOptions { lintOptions {
@ -40,16 +40,17 @@ android {
} }
dependencies { dependencies {
def lifecycle_version = "2.0.0" def lifecycle_version = "2.2.0"
def appcompat_version = "1.6.1"
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api "com.google.android.gms:play-services-cast-framework:19.0.0" api "com.google.android.gms:play-services-cast-framework:21.3.0"
// Lifecycle // Lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// To open TracksChooserDialogFragment // To open TracksChooserDialogFragment
implementation "androidx.activity:activity-ktx:1.3.1" implementation "androidx.activity:activity-ktx:1.7.0"
} }

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View file

@ -4,16 +4,12 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle import androidx.lifecycle.*
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import com.gianlucaparadise.flutter_cast_framework.cast.CastDialogOpener import com.gianlucaparadise.flutter_cast_framework.cast.CastDialogOpener
import com.gianlucaparadise.flutter_cast_framework.cast.MessageCastingChannel import com.gianlucaparadise.flutter_cast_framework.cast.MessageCastingChannel
import com.gianlucaparadise.flutter_cast_framework.media.* import com.gianlucaparadise.flutter_cast_framework.media.*
import com.google.android.gms.cast.MediaError import com.google.android.gms.cast.MediaError
import com.google.android.gms.cast.MediaSeekOptions import com.google.android.gms.cast.MediaSeekOptions
import com.google.android.gms.cast.MediaSeekOptions.ResumeState
import com.google.android.gms.cast.MediaStatus.* import com.google.android.gms.cast.MediaStatus.*
import com.google.android.gms.cast.framework.CastContext import com.google.android.gms.cast.framework.CastContext
import com.google.android.gms.cast.framework.CastSession import com.google.android.gms.cast.framework.CastSession
@ -32,7 +28,7 @@ import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar import io.flutter.plugin.common.PluginRegistry.Registrar
class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, LifecycleObserver { class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, DefaultLifecycleObserver {
companion object { companion object {
const val TAG = "AndroidCastPlugin" const val TAG = "AndroidCastPlugin"
@ -64,7 +60,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
mMessageCastingChannel = MessageCastingChannel(castFlutterApi) mMessageCastingChannel = MessageCastingChannel(castFlutterApi)
CastContext.getSharedInstance(applicationContext).addCastStateListener { i -> CastContext.getSharedInstance(applicationContext, ).addCastStateListener { i ->
Log.d(TAG, "Cast state changed: $i") Log.d(TAG, "Cast state changed: $i")
flutterApi?.onCastStateChanged(i.toLong()) { } flutterApi?.onCastStateChanged(i.toLong()) { }
} }
@ -153,14 +149,12 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
field = value field = value
} }
//region LifecycleObserver override fun onCreate(owner: LifecycleOwner) {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE) super.onCreate(owner)
fun onCreate() {
Log.d(TAG, "App: ON_CREATE") Log.d(TAG, "App: ON_CREATE")
} }
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) override fun onResume(owner: LifecycleOwner) {
fun onResume() {
Log.d(TAG, "App: ON_RESUME") Log.d(TAG, "App: ON_RESUME")
mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java) mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java)
mCastSession = mSessionManager.currentCastSession mCastSession = mSessionManager.currentCastSession
@ -174,8 +168,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
flutterApi?.onCastStateChanged(castState.toLong()) { } flutterApi?.onCastStateChanged(castState.toLong()) { }
} }
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) override fun onPause(owner: LifecycleOwner) {
fun onPause() {
Log.d(TAG, "App: ON_PAUSE") Log.d(TAG, "App: ON_PAUSE")
mSessionManager.removeSessionManagerListener( mSessionManager.removeSessionManagerListener(
mSessionManagerListener, mSessionManagerListener,
@ -247,7 +240,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
flutterApi?.onAdBreakStatusUpdated(flutterMediaStatus) { } flutterApi?.onAdBreakStatusUpdated(flutterMediaStatus) { }
} }
override fun onMediaError(error: MediaError?) { override fun onMediaError(error: MediaError) {
Log.d(TAG, "RemoteMediaClient - onMediaError $error") Log.d(TAG, "RemoteMediaClient - onMediaError $error")
super.onMediaError(error) super.onMediaError(error)
flutterApi?.onMediaError { } flutterApi?.onMediaError { }
@ -257,8 +250,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
val isPlayingAd = remoteMediaClient?.mediaStatus?.isPlayingAd ?: false val isPlayingAd = remoteMediaClient?.mediaStatus?.isPlayingAd ?: false
if (isPlayingAd) { if (isPlayingAd) {
fireAdBreakClipProgress() fireAdBreakClipProgress()
} } else {
else {
flutterApi?.onProgressUpdated(progressMs, durationMs) { } flutterApi?.onProgressUpdated(progressMs, durationMs) { }
} }
} }
@ -290,43 +282,41 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
override fun mediaQueueWillChange() { override fun mediaQueueWillChange() {
Log.d(TAG, "MediaQueue - mediaQueueWillChange") Log.d(TAG, "MediaQueue - mediaQueueWillChange")
super.mediaQueueWillChange() super.mediaQueueWillChange()
flutterApi?.mediaQueueWillChange { } flutterApi?.mediaQueueWillChange { }
} }
override fun mediaQueueChanged() { override fun mediaQueueChanged() {
Log.d(TAG, "MediaQueue - mediaQueueChanged") Log.d(TAG, "MediaQueue - mediaQueueChanged")
super.mediaQueueChanged() super.mediaQueueChanged()
flutterApi?.mediaQueueChanged { } flutterApi?.mediaQueueChanged { }
} }
override fun itemsReloaded() { override fun itemsReloaded() {
Log.d(TAG, "MediaQueue - itemsReloaded") Log.d(TAG, "MediaQueue - itemsReloaded")
super.itemsReloaded() super.itemsReloaded()
flutterApi?.itemsReloaded { } flutterApi?.itemsReloaded { }
} }
override fun itemsInsertedInRange(insertIndex: Int, insertCount: Int) { override fun itemsInsertedInRange(insertIndex: Int, insertCount: Int) {
Log.d(TAG, "MediaQueue - itemsInsertedInRange") Log.d(TAG, "MediaQueue - itemsInsertedInRange")
super.itemsInsertedInRange(insertIndex, insertCount) super.itemsInsertedInRange(insertIndex, insertCount)
flutterApi?.itemsInsertedInRange(insertIndex.toLong(), insertCount.toLong()) { } flutterApi?.itemsInsertedInRange(insertIndex.toLong(), insertCount.toLong()) { }
} }
override fun itemsUpdatedAtIndexes(indexes: IntArray?) { override fun itemsUpdatedAtIndexes(indexes: IntArray) {
Log.d(TAG, "MediaQueue - itemsUpdatedAtIndexes") Log.d(TAG, "MediaQueue - itemsUpdatedAtIndexes")
super.itemsUpdatedAtIndexes(indexes) super.itemsUpdatedAtIndexes(indexes)
if (indexes == null) return
val longIndexes = indexes.map { it.toLong() } val longIndexes = indexes.map { it.toLong() }
flutterApi?.itemsUpdatedAtIndexes(longIndexes) { } flutterApi?.itemsUpdatedAtIndexes(longIndexes) { }
} }
override fun itemsRemovedAtIndexes(indexes: IntArray?) { override fun itemsRemovedAtIndexes(indexes: IntArray) {
Log.d(TAG, "MediaQueue itemsRemovedAtIndexeseWillChange") Log.d(TAG, "MediaQueue itemsRemovedAtIndexeseWillChange")
super.itemsRemovedAtIndexes(indexes) super.itemsRemovedAtIndexes(indexes)
if (indexes == null) return
val longIndexes = indexes.map { it.toLong() } val longIndexes = indexes.map { it.toLong() }
flutterApi?.itemsRemovedAtIndexes(longIndexes) { } flutterApi?.itemsRemovedAtIndexes(longIndexes) { }
} }
} }
@ -407,7 +397,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
override fun queueAppendItem(item: PlatformBridgeApis.MediaQueueItem) { override fun queueAppendItem(item: PlatformBridgeApis.MediaQueueItem) {
val remoteMediaClient: RemoteMediaClient = remoteMediaClient ?: return val remoteMediaClient: RemoteMediaClient = remoteMediaClient ?: return
val mediaQueueItem = getMediaQueueItem(item) val mediaQueueItem = getMediaQueueItem(item) ?: return
remoteMediaClient.queueAppendItem(mediaQueueItem, null) remoteMediaClient.queueAppendItem(mediaQueueItem, null)
} }
@ -443,9 +433,9 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
val castDevice = castSession.castDevice val castDevice = castSession.castDevice
return PlatformBridgeApis.CastDevice().apply { return PlatformBridgeApis.CastDevice().apply {
deviceId = castDevice.deviceId deviceId = castDevice?.deviceId
friendlyName = castDevice.friendlyName friendlyName = castDevice?.friendlyName
modelName = castDevice.modelName modelName = castDevice?.modelName
} }
} }
} }
@ -458,7 +448,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
namespaces.forEach { namespace -> namespaces.forEach { namespace ->
try { try {
oldSession?.removeMessageReceivedCallbacks(namespace) oldSession?.removeMessageReceivedCallbacks(namespace)
newSession?.setMessageReceivedCallbacks(namespace, mMessageCastingChannel) if (mMessageCastingChannel != null) newSession?.setMessageReceivedCallbacks(namespace, mMessageCastingChannel!!)
} catch (e: java.lang.Exception) { } catch (e: java.lang.Exception) {
Log.e(TAG, "Updating mCastSession - Exception while creating channel", e) Log.e(TAG, "Updating mCastSession - Exception while creating channel", e)
} }
@ -468,36 +458,36 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa
private inner class CastSessionManagerListener : SessionManagerListener<CastSession> { private inner class CastSessionManagerListener : SessionManagerListener<CastSession> {
private var TAG = "SessionManagerListenerImpl" private var TAG = "SessionManagerListenerImpl"
override fun onSessionSuspended(session: CastSession?, p1: Int) { override fun onSessionSuspended(session: CastSession, p1: Int) {
Log.d(TAG, "onSessionSuspended") Log.d(TAG, "onSessionSuspended")
flutterApi?.onSessionSuspended { } flutterApi?.onSessionSuspended { }
} }
override fun onSessionStarting(session: CastSession?) { override fun onSessionStarting(session: CastSession) {
Log.d(TAG, "onSessionStarting") Log.d(TAG, "onSessionStarting")
flutterApi?.onSessionStarting { } flutterApi?.onSessionStarting { }
mCastSession = session mCastSession = session
} }
override fun onSessionResuming(session: CastSession?, p1: String?) { override fun onSessionResuming(session: CastSession, p1: String) {
Log.d(TAG, "onSessionResuming") Log.d(TAG, "onSessionResuming")
flutterApi?.onSessionResuming { } flutterApi?.onSessionResuming { }
mCastSession = session mCastSession = session
} }
override fun onSessionEnding(session: CastSession?) { override fun onSessionEnding(session: CastSession) {
Log.d(TAG, "onSessionEnding") Log.d(TAG, "onSessionEnding")
flutterApi?.onSessionEnding { } flutterApi?.onSessionEnding { }
} }
override fun onSessionStartFailed(session: CastSession?, p1: Int) { override fun onSessionStartFailed(session: CastSession, p1: Int) {
Log.d(TAG, "onSessionStartFailed") Log.d(TAG, "onSessionStartFailed")
flutterApi?.onSessionStartFailed { } flutterApi?.onSessionStartFailed { }
} }
override fun onSessionResumeFailed(session: CastSession?, p1: Int) { override fun onSessionResumeFailed(session: CastSession, p1: Int) {
Log.d(TAG, "onSessionResumeFailed") Log.d(TAG, "onSessionResumeFailed")
flutterApi?.onSessionResumeFailed { } flutterApi?.onSessionResumeFailed { }
} }

View file

@ -20,10 +20,10 @@ object CastDialogOpener {
// This dialog allows the user to control or disconnect from the currently selected route. // This dialog allows the user to control or disconnect from the currently selected route.
MediaRouteControllerDialog(activity, themeResId) MediaRouteControllerDialog(activity, themeResId)
.show() .show()
} else { } else if (castContext.mergedSelector != null) {
// This dialog allows the user to choose a route that matches a given selector. // This dialog allows the user to choose a route that matches a given selector.
MediaRouteChooserDialog(activity, themeResId).apply { MediaRouteChooserDialog(activity, themeResId).apply {
routeSelector = castContext.mergedSelector routeSelector = castContext.mergedSelector!!
show() show()
} }
} }

View file

@ -11,7 +11,7 @@ class MessageCastingChannel(private val flutterApi : PlatformBridgeApis.CastFlut
const val TAG = "MessageCastingChannel" const val TAG = "MessageCastingChannel"
} }
override fun onMessageReceived(castDevice: CastDevice?, namespace: String?, message: String?) { override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) {
Log.d(TAG, "Message received: $message:") Log.d(TAG, "Message received: $message:")
val castMessage = PlatformBridgeApis.CastMessage() val castMessage = PlatformBridgeApis.CastMessage()
castMessage.namespace = namespace castMessage.namespace = namespace
@ -24,21 +24,30 @@ class MessageCastingChannel(private val flutterApi : PlatformBridgeApis.CastFlut
Log.d(TAG, "Send Message arguments: $castMessage:") Log.d(TAG, "Send Message arguments: $castMessage:")
if (castMessage == null) return if (castMessage == null) return
if (castSession == null) {
Log.d(TAG, "No session")
return
}
val namespace = castMessage.namespace val namespace = castMessage.namespace
val message = castMessage.message val message = castMessage.message
if (namespace == null) {
Log.d(TAG, "No namespace")
return
}
if (message == null) {
Log.d(TAG, "No message")
return
}
sendMessage(castSession, namespace, message) sendMessage(castSession, namespace, message)
} }
private fun sendMessage(castSession: CastSession?, namespace: String?, message: String?) { private fun sendMessage(castSession: CastSession, namespace: String, message: String) {
try { try {
if (castSession == null) {
Log.d(TAG, "No session")
return
}
castSession.sendMessage(namespace, message) castSession.sendMessage(namespace, message)
} catch (ex: Exception) { } catch (ex: Exception) {
Log.e(TAG, "Error while sending ${message}:") Log.e(TAG, "Error while sending ${message}:")
Log.e(TAG, ex.toString()) Log.e(TAG, ex.toString())

View file

@ -161,9 +161,9 @@ fun getFlutterMediaType(mediaType: Int?): PlatformBridgeApis.MediaType {
} }
} }
fun getFlutterStrings(mediaMetadata: MediaMetadata?): Map<String, String> { fun getFlutterStrings(mediaMetadata: MediaMetadata?): Map<String, String?> {
val stringsKeys = mediaMetadata?.keySet() ?: return emptyMap() val stringsKeys = mediaMetadata?.keySet() ?: return emptyMap()
return stringsKeys.map { getFlutterMediaMetadataKey(it) to mediaMetadata.getString(it) }.toMap() return stringsKeys.associate { getFlutterMediaMetadataKey(it) to mediaMetadata.getString(it) }
} }
fun getFlutterMediaMetadataKey(mediaMetadataKey: String): String { fun getFlutterMediaMetadataKey(mediaMetadataKey: String): String {

View file

@ -25,7 +25,9 @@ fun getMediaInfo(mediaInfo: PlatformBridgeApis.MediaInfo?): MediaInfo? {
?: throw IllegalArgumentException("streamType is a required field")) ?: throw IllegalArgumentException("streamType is a required field"))
val customData = JSONObject(mediaInfo.customDataAsJson ?: "{}") val customData = JSONObject(mediaInfo.customDataAsJson ?: "{}")
val builder = MediaInfo.Builder(mediaInfo.contentId) if (mediaInfo.contentId == null) return null
val builder = MediaInfo.Builder(mediaInfo.contentId!!)
.setStreamType(streamType) .setStreamType(streamType)
.setContentType(mediaInfo.contentType) .setContentType(mediaInfo.contentType)
.setStreamDuration(mediaInfo.streamDuration .setStreamDuration(mediaInfo.streamDuration
@ -160,10 +162,10 @@ fun getTrackSubtype(trackSubtype: PlatformBridgeApis.TrackSubtype): Int {
} }
} }
fun getMediaQueueItem(item: PlatformBridgeApis.MediaQueueItem?): MediaQueueItem? { fun getMediaQueueItem(item: PlatformBridgeApis.MediaQueueItem): MediaQueueItem? {
if (item?.media == null) return null if (item.media == null) return null
val mediaInfo = getMediaInfo(item.media) val mediaInfo = getMediaInfo(item.media) ?: return null
val builder = MediaQueueItem.Builder(mediaInfo) val builder = MediaQueueItem.Builder(mediaInfo)

View file

@ -36,7 +36,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.gianlucaparadise.flutter_cast_framework_example" applicationId "com.gianlucaparadise.flutter_cast_framework_example"
minSdkVersion 16 minSdkVersion 21
targetSdkVersion 33 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName

View file

@ -1,8 +1,8 @@
buildscript { buildscript {
ext.kotlin_version = '1.6.21' ext.kotlin_version = '1.8.20'
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
@ -14,7 +14,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }