Skip to content

Commit

Permalink
Use EventChannel instead of MethodChannel for sending ring event
Browse files Browse the repository at this point in the history
  • Loading branch information
gdelataillade committed Mar 15, 2024
1 parent c9f8c2c commit 8a4034f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,39 @@ import android.content.Context
import android.content.Intent
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel
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.BinaryMessenger
import io.flutter.Log

class AlarmPlugin: FlutterPlugin, MethodCallHandler {
private lateinit var context: Context
private lateinit var channel : MethodChannel
private lateinit var methodChannel : MethodChannel
private lateinit var eventChannel: EventChannel

companion object {
@JvmStatic
lateinit var binaryMessenger: BinaryMessenger
var eventSink: EventChannel.EventSink? = null
}

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.gdelataillade.alarm/alarm")
channel.setMethodCallHandler(this)
binaryMessenger = flutterPluginBinding.binaryMessenger

methodChannel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.gdelataillade.alarm/alarm")
methodChannel.setMethodCallHandler(this)

eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, "com.gdelataillade.alarm/events")
eventChannel.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
eventSink = events
}

override fun onCancel(arguments: Any?) {
eventSink = null
}
})
}

override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
Expand Down Expand Up @@ -156,6 +168,7 @@ class AlarmPlugin: FlutterPlugin, MethodCallHandler {
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
methodChannel.setMethodCallHandler(null)
eventChannel.setStreamHandler(null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ import android.os.IBinder
import android.os.PowerManager
import android.os.Build
import io.flutter.Log
import io.flutter.plugin.common.MethodChannel
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.embedding.engine.FlutterEngine

class AlarmService : Service() {
private var channel: MethodChannel? = null
private var audioService: AudioService? = null
private var vibrationService: VibrationService? = null
private var volumeService: VolumeService? = null
Expand All @@ -33,15 +31,6 @@ class AlarmService : Service() {
override fun onCreate() {
super.onCreate()

try {
val messenger = AlarmPlugin.binaryMessenger
if (messenger != null) {
channel = MethodChannel(messenger, "com.gdelataillade.alarm/alarm")
}
} catch (e: Exception) {
Log.e("AlarmService", "Error while creating method channel: $e")
}

audioService = AudioService(this)
vibrationService = VibrationService(this)
volumeService = VolumeService(this)
Expand Down Expand Up @@ -93,15 +82,7 @@ class AlarmService : Service() {
Log.e("AlarmService", "Error in starting foreground service", e)
}

try {
if (channel != null) {
channel?.invokeMethod("alarmRinging", mapOf("id" to id))
} else {
Log.e("AlarmService", "Method channel is null")
}
} catch (e: Exception) {
Log.e("AlarmService", "Error while invoking alarmRinging channel: $e")
}
AlarmPlugin.eventSink?.success(mapOf("id" to id))

if (volume >= 0.0 && volume <= 1.0) {
volumeService?.setVolume(volume, showSystemUI)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class AudioService(private val context: Context) {
if (isPlaying) {
stop()
}
reset()
release()
}
mediaPlayers.remove(id)
Expand Down Expand Up @@ -121,6 +122,7 @@ class AudioService(private val context: Context) {
if (mediaPlayer.isPlaying) {
mediaPlayer.stop()
}
mediaPlayer.reset()
mediaPlayer.release()
}
mediaPlayers.clear()
Expand Down
7 changes: 3 additions & 4 deletions lib/alarm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ class Alarm {
if (showDebugLogs) print('[Alarm] $message');
};

await Future.wait([
if (android) AndroidAlarm.init(),
AlarmStorage.init(),
]);
if (android) AndroidAlarm.init();
await AlarmStorage.init();

await checkAlarm();
}

Expand Down
40 changes: 23 additions & 17 deletions lib/src/android_alarm.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,35 @@ import 'package:flutter/services.dart';

/// Uses method channel to interact with the native platform.
class AndroidAlarm {
/// Method channel for the alarm.
/// Method channel for the alarm operations.
static const platform = MethodChannel('com.gdelataillade.alarm/alarm');

/// Event channel for the alarm events.
static const eventChannel = EventChannel('com.gdelataillade.alarm/events');

/// Whether there are other alarms set.
static bool get hasOtherAlarms => AlarmStorage.getSavedAlarms().length > 1;

/// Initializes the method channel.
static Future<void> init() async {
platform.setMethodCallHandler(handleMethodCall);
}
/// Starts listening to the alarm events.
static void init() => listenToAlarmEvents();

/// Handles the method call from the native platform.
static Future<dynamic> handleMethodCall(MethodCall call) async {
try {
if (call.method == 'alarmRinging') {
final arguments = call.arguments as Map<dynamic, dynamic>;
final id = arguments['id'] as int;
final settings = Alarm.getAlarm(id);
if (settings != null) Alarm.ringStream.add(settings);
}
} catch (e) {
alarmPrint('Handle method call "${call.method}" error: $e');
}
/// Listens to the alarm events.
static void listenToAlarmEvents() {
eventChannel.receiveBroadcastStream().listen(
(dynamic event) {
try {
final eventMap = Map<String, dynamic>.from(event as Map);
final id = eventMap['id'] as int;
final settings = Alarm.getAlarm(id);
if (settings != null) Alarm.ringStream.add(settings);
} catch (e) {
alarmPrint('Error receiving alarm events: $e');
}
},
onError: (dynamic error, StackTrace stackTrace) {
alarmPrint('Error listening to alarm events: $error, $stackTrace');
},
);
}

/// Schedules a native alarm with given [settings] with its notification.
Expand Down

0 comments on commit 8a4034f

Please sign in to comment.