Reputation: 69
I want create a event channel in my flutter windows application for asynchronous event streams between flutter and windows app.
where I want to get a continuous data to be listened, but i am not finding any example on internet on how to create a Event channel between flutter and native windows application.
Thanks in advance if any one can help
I have tried method channel which works but event channel i am not able to create
Expecting a sample working code of flutter_windows.cpp file to create a Event Channel
Upvotes: 0
Views: 818
Reputation: 69
Now able to create the Event channel, it will be helpful for some one as me.
In Dart add below code to create a Event channel import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class PlatformChannel extends StatefulWidget {
const PlatformChannel({super.key});
@override
State<PlatformChannel> createState() => _PlatformChannelState();
}
class _PlatformChannelState extends State<PlatformChannel> {
static const EventChannel eventChannel =
EventChannel('samples.flutter.io/charging');
String _chargingStatus = 'Battery status: unknown.';
@override
void initState() {
super.initState();
eventChannel.receiveBroadcastStream().listen(_onEvent,onError:_onError);
}
void _onEvent(Object? event) {
setState(() {
_chargingStatus =
"Battery status: ${event == 'charging' ? '' : 'dis'}charging.";
});
}
void _onError(Object error) {
setState(() {
_chargingStatus = 'Battery status: unknown.';
});
}
@override
Widget build(BuildContext context) {
return Material(
child: Text(_chargingStatus),
);
}
}
void main() {
runApp(const MaterialApp(home: PlatformChannel()));
}
In Windows directory add code to below files flutter_windows.cpp
and flutter_windows.h
-> flutter_windows.cpp add the below code
#include "flutter_window.h"
#include <flutter/event_channel.h>
#include <flutter/event_sink.h>
#include <flutter/event_stream_handler_functions.h>
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#include <windows.h>
#include <memory>
#include <optional>
#include "flutter/generated_plugin_registrant.h"
static constexpr int kBatteryError = -1;
static constexpr int kNoBattery = -2;
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {
if (power_notification_handle_) {
UnregisterPowerSettingNotification(power_notification_handle_);
}
}
bool FlutterWindow::OnCreate() {
if (!Win32Window::OnCreate()) {
return false;
}
RECT frame = GetClientArea();
// The size here must match the window dimensions to avoid unnecessary surface
// creation / destruction in the startup path.
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
frame.right - frame.left, frame.bottom - frame.top, project_);
// Ensure that basic setup of the controller was successful.
if (!flutter_controller_->engine() || !flutter_controller_->view()) {
return false;
}
RegisterPlugins(flutter_controller_->engine());
/// This is the Code for Event channel creation
flutter::EventChannel<> charging_channel(
flutter_controller_->engine()->messenger(), "samples.flutter.io/charging",
&flutter::StandardMethodCodec::GetInstance());
charging_channel.SetStreamHandler(
std::make_unique<flutter::StreamHandlerFunctions<>>(
[this](auto arguments, auto events) {
this->OnStreamListen(std::move(events));
return nullptr;
},
[this](auto arguments) {
this->OnStreamCancel();
return nullptr;
}));
SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
// Flutter can complete the first frame before the "show window" callback is
// registered. The following call ensures a frame is pending to ensure the
// window is shown. It is a no-op if the first frame hasn't completed yet.
flutter_controller_->ForceRedraw();
return true;
}
void FlutterWindow::OnDestroy() {
if (flutter_controller_) {
flutter_controller_ = nullptr;
}
Win32Window::OnDestroy();
}
LRESULT
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept {
// Give Flutter, including plugins, an opportunity to handle window messages.
if (flutter_controller_) {
std::optional<LRESULT> result =
flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
lparam);
if (result) {
return *result;
}
}
switch (message) {
case WM_FONTCHANGE:
flutter_controller_->engine()->ReloadSystemFonts();
break;
case WM_POWERBROADCAST:
SendBatteryStateEvent();
break;
}
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}
void FlutterWindow::OnStreamListen(
std::unique_ptr<flutter::EventSink<>>&& events) {
event_sink_ = std::move(events);
}
void FlutterWindow::OnStreamCancel() { event_sink_ = nullptr; }
void FlutterWindow::SendBatteryStateEvent() {
SYSTEM_POWER_STATUS status;
if (GetSystemPowerStatus(&status) == 0 || status.ACLineStatus == 255) {
event_sink_->Error("UNAVAILABLE", "Charging status unavailable");
} else {
event_sink_->Success(flutter::EncodableValue(
status.ACLineStatus == 1 ? "charging" : "discharging"));
}
}
-> flutter_windows.h add the below code to header file
#ifndef RUNNER_FLUTTER_WINDOW_H_
#define RUNNER_FLUTTER_WINDOW_H_
#include <flutter/dart_project.h>
#include <flutter/event_sink.h>
#include <flutter/flutter_view_controller.h>
#include <winuser.h>
#include <memory>
#include "win32_window.h"
// A window that does nothing but host a Flutter view.
class FlutterWindow : public Win32Window {
public:
// Creates a new FlutterWindow hosting a Flutter view running |project|.
explicit FlutterWindow(const flutter::DartProject& project);
virtual ~FlutterWindow();
protected:
// Win32Window:
bool OnCreate() override;
void OnDestroy() override;
LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
LPARAM const lparam) noexcept override;
private:
// EventStream handlers:
void OnStreamListen(std::unique_ptr<flutter::EventSink<>>&& events);
void OnStreamCancel();
// Sends a state event to |event_sink_| with the current charging status.
void SendBatteryStateEvent();
// The project to run.
flutter::DartProject project_;
// The Flutter instance hosted by this window.
std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
std::unique_ptr<flutter::EventSink<>> event_sink_;
HPOWERNOTIFY power_notification_handle_ = nullptr;
};
#endif // RUNNER_FLUTTER_WINDOW_H_
Upvotes: 0