Open laterdayi opened 7 months ago
Do you mean 'to wake up' the device when a notification arrives?
yes, in latest OS the screen does not necessarily wakeup when the notification arrives. And this could cause to miss important notifications. 'Wake up' means if the screen is locked we can "wake up" somehow for few seconds so user knows some important notification has come
I am using firebase_messaging and a background handler (separate isolates/thread) (@pragma('vm:entry-point') Future
private fun wakeUp() {
val pm = applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
val isScreenOn = if (Build.VERSION.SDK_INT >= 20) pm.isInteractive else pm.isScreenOn // check if screen is on
if (!isScreenOn) {
val wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "myApp:notificationLock")
wl.acquire(3000) //set your time in milliseconds
Log.i("Wakeup","Wakeup !")
}
}
yes, even i have created the plugin, but are you able to call this native code from background isolate (i.e. firebaseMessagingBackgroundHandler())? As far as i know methodchannel is dependent on flutter engine and since you are on separate isolate you cannot use methodchannel the way we normally use.
I'm using this to invoke native code :
try { const platform = MethodChannel('com.example.app/native'); await platform.invokeMethod('wakeupscreen'); } on PlatformException catch (e) { print("Failed to invoke the method: '${e.message}'."); }
but it show unimplemented error Unhandled Exception: MissingPluginException(No implementation found for method wakeupscreen on com.example.app/native) if i call nativemethod on fcmbackgroundmessagehandler
package com.amervelic.wake_device
import android.content.Context
import android.os.Build
import android.os.PowerManager
import android.util.Log
import androidx.annotation.NonNull
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.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.StandardMethodCodec
/** WakeDevicePlugin */
class WakeDevicePlugin : FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private lateinit var channel: MethodChannel
private lateinit var applicationContext: Context
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
applicationContext = flutterPluginBinding.applicationContext
val taskQueue =
flutterPluginBinding.binaryMessenger.makeBackgroundTaskQueue()
channel = MethodChannel(
flutterPluginBinding.binaryMessenger,
"wake_device",
StandardMethodCodec.INSTANCE,
taskQueue
)
channel.setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
}
else if (call.method == "wakeDevice") {
wakeUp()
result.success(null)
}
else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
private fun wakeUp() {
val pm = applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
val isScreenOn = if (Build.VERSION.SDK_INT >= 20) pm.isInteractive else pm.isScreenOn // check if screen is on
if (!isScreenOn) {
val wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "myApp:notificationLock")
wl.acquire(3000) //set your time in milliseconds
Log.i("Wakeup","Wakeup !")
}
}
}
Nope see i get the same error when calling it inside a firebaseMessagingBackgroundHandler() callback function:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method wakeDevice on channel wake_device)
But if I call it outside the firebaseMessagingBackgroundHandler() then it works well.
@amervelic can you show your implementation on flutter side?
Nope, the example in the repo does not call the method inside a background isolate. The example you have uploaded call the native method inside main UI isolate and not background isolate. Try the same example inside a background isolate it won't work.
I use it in the application and it is called without any issues.
// Entry point for handling background messages received by Firebase Messaging.
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// Ensure Flutter notifications are set up before showing a notification.
await NotificationService.setupFlutterNotifications();
// Show a notification using the received message.
NotificationService.handleFlutterNotification(message);
await NotificationService.wakeDevice();
print('Handling a background message ${message.messageId}');
await NotificationService.keepSync();
@pragma('vm:entry-point') Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { const MethodChannel _channel = MethodChannel('wake_device'); //wake up screen try { await _channel.invokeMethod('wakeDevice'); } on PlatformException catch (e) { print("Failed to invoke method: '${e.message}'."); }
here.. this is my code to invoke method, looks almost similar to yours.
Hi @amervelic I can make a sample project on git and you can do the changes that worked for you on that project. Should we do it? That will help both of us understand exactly what's working and what's not.
How can flutter_local_notifications wake up the screen and make notifications when the screen is off