Skip to content

Commit

Permalink
fix(Android): Added method to ensure lock screen permission on Android (
Browse files Browse the repository at this point in the history
#814)

* Added method to ensure lock screen permission on Android

* added changelog

* renamed ensure method
  • Loading branch information
Brazol authored Dec 30, 2024
1 parent a1f61e8 commit 8e9cc0f
Show file tree
Hide file tree
Showing 16 changed files with 206 additions and 11 deletions.
3 changes: 3 additions & 0 deletions dogfooding/lib/screens/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:flutter_dogfooding/widgets/stream_button.dart';
import 'package:stream_video_flutter/stream_video_flutter.dart';
import 'package:stream_video_flutter/stream_video_flutter_background.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:stream_video_push_notification/stream_video_push_notification.dart';

import '../app/user_auth_controller.dart';
import '../di/injector.dart';
Expand Down Expand Up @@ -43,6 +44,8 @@ class _HomeScreenState extends State<HomeScreen> {
Permission.microphone,
].request();

StreamVideoPushNotificationManager.ensureFullScreenIntentPermission();

StreamBackgroundService.init(
StreamVideo.instance,
onButtonClick: (call, type, serviceType) async {
Expand Down
1 change: 1 addition & 0 deletions packages/stream_video/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

✅ Added
* Added the 'call.collectUserFeedback()' method which allows users to send call quality rating. These ratings are visible on the Dashboard and are aggregated in call stats for easy tracking. For a sample implementation, please refer to the [cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/call-quality-rating/).
* Added device thermal status reporting to better optimize call quality.

## 0.6.0

Expand Down
7 changes: 7 additions & 0 deletions packages/stream_video_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

✅ Added
* Added the 'call.collectUserFeedback()' method which allows users to send call quality rating. These ratings are visible on the Dashboard and are aggregated in call stats for easy tracking. For a sample implementation, please refer to the [cookbook](https://getstream.io/video/docs/flutter/ui-cookbook/call-quality-rating/).
* Added device thermal status reporting to better optimize call quality.
* Added the `StreamVideoPushNotificationManager.ensureFullScreenIntentPermission()` method. This resolves an issue on some Android 14 devices where full-screen notifications would not appear due to missing permissions.
You can now invoke this method to show a settings screen, allowing users to enable the required permission if it's not already enabled.

🐞 Fixed
* Resolved an issue where CallKit calls would not connect when accepted while the screen was locked.
* Fixed a bug where the Android foreground service would not stop when the app was killed, keeping the call connection active.

## 0.6.0

Expand Down
13 changes: 8 additions & 5 deletions packages/stream_video_push_notification/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.

version:
revision: "2f708eb8396e362e280fac22cf171c2cb467343c"
revision: "2663184aa79047d0a33a14a3b607954f8fdd8730"
channel: "stable"

project_type: plugin
Expand All @@ -13,11 +13,14 @@ project_type: plugin
migration:
platforms:
- platform: root
create_revision: 2f708eb8396e362e280fac22cf171c2cb467343c
base_revision: 2f708eb8396e362e280fac22cf171c2cb467343c
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: android
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
- platform: ios
create_revision: 2f708eb8396e362e280fac22cf171c2cb467343c
base_revision: 2f708eb8396e362e280fac22cf171c2cb467343c
create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730
base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730

# User provided section

Expand Down
9 changes: 9 additions & 0 deletions packages/stream_video_push_notification/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## Unreleased

✅ Added
* Added the `StreamVideoPushNotificationManager.ensureFullScreenIntentPermission()` method. This resolves an issue on some Android 14 devices where full-screen notifications would not appear due to missing permissions.
You can now invoke this method to show a settings screen, allowing users to enable the required permission if it's not already enabled.

🐞 Fixed
* Resolved an issue where CallKit calls would not connect when accepted while the screen was locked.

## 0.6.0

🔄 Dependency updates
Expand Down
9 changes: 9 additions & 0 deletions packages/stream_video_push_notification/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx
65 changes: 65 additions & 0 deletions packages/stream_video_push_notification/android/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
buildscript {
ext.kotlin_version = "1.9.10"
repositories {
google()
mavenCentral()
}

dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}

allprojects {
repositories {
google()
mavenCentral()
}
}

apply plugin: "com.android.library"
apply plugin: "kotlin-android"

android {
if (project.android.hasProperty("namespace")) {
namespace = "com.example.stream_video_push_notification"
}

compileSdk = 34

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}

sourceSets {
main.java.srcDirs += "src/main/kotlin"
test.java.srcDirs += "src/test/kotlin"
}

defaultConfig {
minSdk = 21
}

dependencies {
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.mockito:mockito-core:5.0.0")
}

testOptions {
unitTests.all {
useJUnitPlatform()

testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'stream_video_push_notification'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.stream_video_push_notification">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.getstream.video.flutter.stream_video_push_notification

import android.app.Activity
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import com.hiennv.flutter_callkit_incoming.CallkitNotificationManager

/** StreamVideoPushNotificationPlugin */
class StreamVideoPushNotificationPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
private lateinit var channel : MethodChannel
private var activity: Activity? = null
private var context: Context? = null
private lateinit var callkitNotificationManager: CallkitNotificationManager

override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext

channel = MethodChannel(flutterPluginBinding.binaryMessenger, "stream_video_push_notification")
channel.setMethodCallHandler(this)

callkitNotificationManager = CallkitNotificationManager(flutterPluginBinding.applicationContext)
}

override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
if (call.method == "ensureFullScreenIntentPermission") {
val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= 34) {
if (!notificationManager.canUseFullScreenIntent()) {
callkitNotificationManager?.requestFullIntentPermission(activity)
}
}
result.success(true)
} else {
result.notImplemented()
}
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
activity = binding.activity
}

override fun onDetachedFromActivityForConfigChanges() {
activity = null
}

override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
activity = binding.activity
}

override fun onDetachedFromActivity() {
activity = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class StreamVideoPushNotificationPlugin: NSObject, FlutterPlugin {
let persistentState: UserDefaults = UserDefaults.standard

public static func register(with registrar: FlutterPluginRegistrar) {
let mainChannel = FlutterMethodChannel(name: "stream_video_push_notifications", binaryMessenger: registrar.messenger())
let mainChannel = FlutterMethodChannel(name: "stream_video_push_notification", binaryMessenger: registrar.messenger())
let instance = StreamVideoPushNotificationPlugin()

registrar.addMethodCallDelegate(instance, channel: mainChannel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,11 @@ class StreamVideoPushNotificationManager implements PushNotificationManager {
Future<void> dispose() async {
_subscriptions.cancelAll();
}

static Future ensureFullScreenIntentPermission() {
return StreamVideoPushNotificationPlatform.instance
.ensureFullScreenIntentPermission();
}
}

const _defaultPushParams = StreamVideoPushParams(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:stream_video/stream_video.dart';

import 'stream_video_push_notification_platform_interface.dart';

Expand All @@ -11,7 +12,7 @@ class MethodChannelStreamVideoPushNotification
extends StreamVideoPushNotificationPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('stream_video_push_notifications');
final methodChannel = const MethodChannel('stream_video_push_notification');

CallerCustomizationFunction? callerCustomizationCallback;

Expand Down Expand Up @@ -51,4 +52,11 @@ class MethodChannelStreamVideoPushNotification
}
await methodChannel.invokeMethod<String>('initData', pushParams);
}

@override
Future<void> ensureFullScreenIntentPermission() async {
if (!CurrentPlatform.isAndroid) return;

await methodChannel.invokeMethod<void>('ensureFullScreenIntentPermission');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ abstract class StreamVideoPushNotificationPlatform extends PlatformInterface {
CallerCustomizationFunction? callerCustomizationCallback,
BackgroundVoipCallHandler? backgroundVoipCallHandler,
) {
throw UnimplementedError('platformVersion() has not been implemented.');
throw UnimplementedError('init() has not been implemented.');
}

Future<void> ensureFullScreenIntentPermission() {
throw UnimplementedError(
'ensureFullScreenIntentPermission() has not been implemented.');
}
}
7 changes: 4 additions & 3 deletions packages/stream_video_push_notification/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ dependencies:
flutter:
sdk: flutter
flutter_webrtc: ^0.11.7
flutter_callkit_incoming: ^2.0.4+1
flutter_callkit_incoming: ^2.0.4+2
json_annotation: ^4.9.0
meta: ^1.9.1
plugin_platform_interface: ^2.1.8
rxdart: ^0.28.0
stream_video: ^0.6.0
uuid: ^4.2.1
shared_preferences: ^2.3.2

dev_dependencies:
build_runner: ^2.4.4
flutter_lints: ^2.0.2
Expand All @@ -50,7 +50,8 @@ flutter:
ios:
pluginClass: StreamVideoPushNotificationPlugin
android:
default_package: stream_video_push_notification
package: io.getstream.video.flutter.stream_video_push_notification
pluginClass: StreamVideoPushNotificationPlugin

topics:
- video
Expand Down

0 comments on commit 8e9cc0f

Please sign in to comment.