From 5c82074e2faa06de4c47c665a97b06e730480427 Mon Sep 17 00:00:00 2001 From: Angelo Cassano Date: Wed, 12 Apr 2023 19:51:14 +0200 Subject: [PATCH] Bumped dependencies to support Android API 33 --- android/build.gradle | 21 +++--- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../FlutterCastFrameworkPlugin.kt | 66 ++++++++----------- .../cast/CastDialogOpener.kt | 4 +- .../cast/MessageCastingChannel.kt | 25 ++++--- .../FlutterMediaLoadRequestDataHelper.kt | 4 +- .../media/HostMediaLoadRequestDataHelper.kt | 10 +-- example/android/app/build.gradle | 2 +- example/android/build.gradle | 6 +- 9 files changed, 71 insertions(+), 69 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index e472f08..569dd6f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -2,14 +2,14 @@ group 'com.gianlucaparadise.flutter_cast_framework' version '1.0-SNAPSHOT' buildscript { - ext.kotlin_version = '1.5.31' + ext.kotlin_version = '1.8.20' repositories { google() - jcenter() + mavenCentral() } 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" } } @@ -17,7 +17,7 @@ buildscript { rootProject.allprojects { repositories { google() - jcenter() + mavenCentral() } } @@ -25,13 +25,13 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 31 + compileSdkVersion 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { - minSdkVersion 16 + minSdkVersion 21 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { @@ -40,16 +40,17 @@ android { } 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" - 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 implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" - implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" // To open TracksChooserDialogFragment - implementation "androidx.activity:activity-ktx:1.3.1" + implementation "androidx.activity:activity-ktx:1.7.0" } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 622ab64..31cca49 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME 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 zipStorePath=wrapper/dists diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt index b6cc15f..012a625 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/FlutterCastFrameworkPlugin.kt @@ -4,16 +4,12 @@ import android.app.Activity import android.content.Context import android.util.Log import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent -import androidx.lifecycle.ProcessLifecycleOwner +import androidx.lifecycle.* import com.gianlucaparadise.flutter_cast_framework.cast.CastDialogOpener import com.gianlucaparadise.flutter_cast_framework.cast.MessageCastingChannel import com.gianlucaparadise.flutter_cast_framework.media.* import com.google.android.gms.cast.MediaError 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.framework.CastContext 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 -class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, LifecycleObserver { +class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, DefaultLifecycleObserver { companion object { const val TAG = "AndroidCastPlugin" @@ -64,7 +60,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa mMessageCastingChannel = MessageCastingChannel(castFlutterApi) - CastContext.getSharedInstance(applicationContext).addCastStateListener { i -> + CastContext.getSharedInstance(applicationContext, ).addCastStateListener { i -> Log.d(TAG, "Cast state changed: $i") flutterApi?.onCastStateChanged(i.toLong()) { } } @@ -153,14 +149,12 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa field = value } - //region LifecycleObserver - @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) - fun onCreate() { + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) Log.d(TAG, "App: ON_CREATE") } - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - fun onResume() { + override fun onResume(owner: LifecycleOwner) { Log.d(TAG, "App: ON_RESUME") mSessionManager.addSessionManagerListener(mSessionManagerListener, CastSession::class.java) mCastSession = mSessionManager.currentCastSession @@ -174,8 +168,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa flutterApi?.onCastStateChanged(castState.toLong()) { } } - @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) - fun onPause() { + override fun onPause(owner: LifecycleOwner) { Log.d(TAG, "App: ON_PAUSE") mSessionManager.removeSessionManagerListener( mSessionManagerListener, @@ -247,7 +240,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa flutterApi?.onAdBreakStatusUpdated(flutterMediaStatus) { } } - override fun onMediaError(error: MediaError?) { + override fun onMediaError(error: MediaError) { Log.d(TAG, "RemoteMediaClient - onMediaError $error") super.onMediaError(error) flutterApi?.onMediaError { } @@ -257,8 +250,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa val isPlayingAd = remoteMediaClient?.mediaStatus?.isPlayingAd ?: false if (isPlayingAd) { fireAdBreakClipProgress() - } - else { + } else { flutterApi?.onProgressUpdated(progressMs, durationMs) { } } } @@ -290,43 +282,41 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa override fun mediaQueueWillChange() { Log.d(TAG, "MediaQueue - mediaQueueWillChange") super.mediaQueueWillChange() - flutterApi?.mediaQueueWillChange { } + flutterApi?.mediaQueueWillChange { } } override fun mediaQueueChanged() { Log.d(TAG, "MediaQueue - mediaQueueChanged") super.mediaQueueChanged() - flutterApi?.mediaQueueChanged { } + flutterApi?.mediaQueueChanged { } } override fun itemsReloaded() { Log.d(TAG, "MediaQueue - itemsReloaded") super.itemsReloaded() - flutterApi?.itemsReloaded { } + flutterApi?.itemsReloaded { } } override fun itemsInsertedInRange(insertIndex: Int, insertCount: Int) { Log.d(TAG, "MediaQueue - itemsInsertedInRange") 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") super.itemsUpdatedAtIndexes(indexes) - if (indexes == null) return 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") super.itemsRemovedAtIndexes(indexes) - if (indexes == null) return 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) { val remoteMediaClient: RemoteMediaClient = remoteMediaClient ?: return - val mediaQueueItem = getMediaQueueItem(item) + val mediaQueueItem = getMediaQueueItem(item) ?: return remoteMediaClient.queueAppendItem(mediaQueueItem, null) } @@ -443,9 +433,9 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa val castDevice = castSession.castDevice return PlatformBridgeApis.CastDevice().apply { - deviceId = castDevice.deviceId - friendlyName = castDevice.friendlyName - modelName = castDevice.modelName + deviceId = castDevice?.deviceId + friendlyName = castDevice?.friendlyName + modelName = castDevice?.modelName } } } @@ -458,7 +448,7 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa namespaces.forEach { namespace -> try { oldSession?.removeMessageReceivedCallbacks(namespace) - newSession?.setMessageReceivedCallbacks(namespace, mMessageCastingChannel) + if (mMessageCastingChannel != null) newSession?.setMessageReceivedCallbacks(namespace, mMessageCastingChannel!!) } catch (e: java.lang.Exception) { Log.e(TAG, "Updating mCastSession - Exception while creating channel", e) } @@ -468,36 +458,36 @@ class FlutterCastFrameworkPlugin : FlutterPlugin, MethodCallHandler, ActivityAwa private inner class CastSessionManagerListener : SessionManagerListener { private var TAG = "SessionManagerListenerImpl" - override fun onSessionSuspended(session: CastSession?, p1: Int) { + override fun onSessionSuspended(session: CastSession, p1: Int) { Log.d(TAG, "onSessionSuspended") flutterApi?.onSessionSuspended { } } - override fun onSessionStarting(session: CastSession?) { + override fun onSessionStarting(session: CastSession) { Log.d(TAG, "onSessionStarting") flutterApi?.onSessionStarting { } mCastSession = session } - override fun onSessionResuming(session: CastSession?, p1: String?) { + override fun onSessionResuming(session: CastSession, p1: String) { Log.d(TAG, "onSessionResuming") flutterApi?.onSessionResuming { } mCastSession = session } - override fun onSessionEnding(session: CastSession?) { + override fun onSessionEnding(session: CastSession) { Log.d(TAG, "onSessionEnding") flutterApi?.onSessionEnding { } } - override fun onSessionStartFailed(session: CastSession?, p1: Int) { + override fun onSessionStartFailed(session: CastSession, p1: Int) { Log.d(TAG, "onSessionStartFailed") flutterApi?.onSessionStartFailed { } } - override fun onSessionResumeFailed(session: CastSession?, p1: Int) { + override fun onSessionResumeFailed(session: CastSession, p1: Int) { Log.d(TAG, "onSessionResumeFailed") flutterApi?.onSessionResumeFailed { } } diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/CastDialogOpener.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/CastDialogOpener.kt index 26b5f5b..21fa3e2 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/CastDialogOpener.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/CastDialogOpener.kt @@ -20,10 +20,10 @@ object CastDialogOpener { // This dialog allows the user to control or disconnect from the currently selected route. MediaRouteControllerDialog(activity, themeResId) .show() - } else { + } else if (castContext.mergedSelector != null) { // This dialog allows the user to choose a route that matches a given selector. MediaRouteChooserDialog(activity, themeResId).apply { - routeSelector = castContext.mergedSelector + routeSelector = castContext.mergedSelector!! show() } } diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/MessageCastingChannel.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/MessageCastingChannel.kt index d638f97..69b10c7 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/MessageCastingChannel.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/cast/MessageCastingChannel.kt @@ -11,7 +11,7 @@ class MessageCastingChannel(private val flutterApi : PlatformBridgeApis.CastFlut 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:") val castMessage = PlatformBridgeApis.CastMessage() castMessage.namespace = namespace @@ -24,21 +24,30 @@ class MessageCastingChannel(private val flutterApi : PlatformBridgeApis.CastFlut Log.d(TAG, "Send Message arguments: $castMessage:") if (castMessage == null) return + if (castSession == null) { + Log.d(TAG, "No session") + return + } + val namespace = castMessage.namespace 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) } - private fun sendMessage(castSession: CastSession?, namespace: String?, message: String?) { + private fun sendMessage(castSession: CastSession, namespace: String, message: String) { try { - if (castSession == null) { - Log.d(TAG, "No session") - return - } - castSession.sendMessage(namespace, message) - } catch (ex: Exception) { Log.e(TAG, "Error while sending ${message}:") Log.e(TAG, ex.toString()) diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/FlutterMediaLoadRequestDataHelper.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/FlutterMediaLoadRequestDataHelper.kt index a5f9b27..aaa8997 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/FlutterMediaLoadRequestDataHelper.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/FlutterMediaLoadRequestDataHelper.kt @@ -161,9 +161,9 @@ fun getFlutterMediaType(mediaType: Int?): PlatformBridgeApis.MediaType { } } -fun getFlutterStrings(mediaMetadata: MediaMetadata?): Map { +fun getFlutterStrings(mediaMetadata: MediaMetadata?): Map { 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 { diff --git a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt index eba95b0..89a8046 100644 --- a/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt +++ b/android/src/main/kotlin/com/gianlucaparadise/flutter_cast_framework/media/HostMediaLoadRequestDataHelper.kt @@ -25,7 +25,9 @@ fun getMediaInfo(mediaInfo: PlatformBridgeApis.MediaInfo?): MediaInfo? { ?: throw IllegalArgumentException("streamType is a required field")) 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) .setContentType(mediaInfo.contentType) .setStreamDuration(mediaInfo.streamDuration @@ -160,10 +162,10 @@ fun getTrackSubtype(trackSubtype: PlatformBridgeApis.TrackSubtype): Int { } } -fun getMediaQueueItem(item: PlatformBridgeApis.MediaQueueItem?): MediaQueueItem? { - if (item?.media == null) return null +fun getMediaQueueItem(item: PlatformBridgeApis.MediaQueueItem): MediaQueueItem? { + if (item.media == null) return null - val mediaInfo = getMediaInfo(item.media) + val mediaInfo = getMediaInfo(item.media) ?: return null val builder = MediaQueueItem.Builder(mediaInfo) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index b6ecd24..616a891 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -36,7 +36,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.gianlucaparadise.flutter_cast_framework_example" - minSdkVersion 16 + minSdkVersion 21 targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/example/android/build.gradle b/example/android/build.gradle index e8f7526..ec3244c 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,8 +1,8 @@ buildscript { - ext.kotlin_version = '1.6.21' + ext.kotlin_version = '1.8.20' repositories { google() - jcenter() + mavenCentral() } dependencies { @@ -14,7 +14,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } }