[英]EventChannel not being called every time
我對 flutter+dart 框架很陌生。 我試圖了解EventChannel
的工作原理。 我已經設置了EventChannel
來捕獲來電號碼。
在android
這邊,我設置了一個BroadcastReceiver
如下。
public class CallEventHandler extends BroadcastReceiver implements EventChannel.StreamHandler {
private static final String TAG = "[SAMPLE]";
private static final int NUMBER_LEN = 10;
private EventChannel.EventSink eventSink = null;
private Activity activity = null;
public CallEventHandler(Activity activity) {
this.activity = activity;
}
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
Log.i(TAG, "[onListen] setting up events");
eventSink = events;
}
@Override
public void onCancel(Object arguments) {
Log.i(TAG, "[onCancel] cancel events");
eventSink = null;
activity = null;
}
@Override
public void onReceive(Context context, Intent intent) {
try {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
if(incomingNumber != null) {
Log.i(TAG, "[CallEventHandler] Incoming number : " + incomingNumber);
if(incomingNumber.length() > NUMBER_LEN) {
incomingNumber = incomingNumber.substring(incomingNumber.length() - NUMBER_LEN, incomingNumber.length());
Log.i(TAG, "[CallEventHandler] Incoming number after : " + incomingNumber);
if(activity != null) {
String finalIncomingNumber = incomingNumber;
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(eventSink != null) {
Log.i(TAG, "[CallEventHandler] HERESSSSS : " + finalIncomingNumber);
eventSink.success(finalIncomingNumber);
}
}
});
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
在onReceive
方法中,我獲取傳入號碼並將其發送到EventSink
。
在我的MainActivity
中,我按如下方式設置CallEventHandler
:
private final String eventId = "SAMPLE_ID";
private CallEventHandler handler = new CallEventHandler(this);
@Override
public void onStart() {
super.onStart();
...
registerReceiver(handler, filter);
}
@Override
public void onStop() {
super.onStop();
unregisterReceiver(handler);
}
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), eventId)
.setStreamHandler(handler);
}
在Flutter
這邊,代碼如下:
class EventHandler {
static const String TAG = "[SAMPLE]";
final String _eventId = "SAMPLE_ID";
EventChannel? _evtChannel;
Stream<String>? _evtStream;
EventHandler() {
debugPrint(TAG + " Setting up EventHandler");
_evtChannel = EventChannel(_eventId);
_evtStream = _evtChannel?.receiveBroadcastStream().distinct().map((dynamic
event) => getString(event as String));
}
void startListening(void Function(String data)? onData) {
debugPrint(TAG + " starting listening");
_evtStream?.listen((data) {
debugPrint(TAG + " In listening");
onData!(data);
});
}
}
在我的 UI 代碼中,我有一個StatefulWidget
(MySamplePage),我在收到調用時在其中注冊我的回調
void initState() {
widget.handler.startListening((incomingNumber) {
debugPrint(_tag + " data : $incomingNumber");
...
});
}
在我的有狀態主頁構建方法中,我在initState
中初始化處理程序並在build
方法中添加route
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
debugPrint(_tag + "initState");
_handler = EventHandler();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/caller': (context) => MySamplePage(
handler: _handler
),
},
...
);
}
}
我面臨的問題是,當小部件打開時,我收到了第一個來電,正如預期的那樣。 但是,如果我再打一個電話,那么第二個電話就不會被 stream 捕獲。如果我按下后退按鈕,然后重新打開小部件,一切都會按預期進行,第一個來電將打印在控制台中。 我知道 Android 代碼正在從onReceive
方法發送事件(每次都會打印“HERESSSSS”行),但是 flutter stream 沒有獲取值。 我不確定我在這里做錯了什么。 有人可以幫忙嗎?
我的日志是
I/flutter (11836): [SAMPLE][HomeScreen]initState
I/flutter (11836): [SAMPLE][EventHandler] Setting up EventHandler
V/AutofillManager(11836): requestHideFillUi(null): anchor = null
I/flutter (11836): [SAMPLE][EventHandler] starting listening
I/[SAMPLE] (11836): [onListen] setting up events
I/[SAMPLE] (11836): [CallEventHandler] Receiver start
I/[SAMPLE] (11836): [CallEventHandler] Receiver start
I/[SAMPLE] (11836): [CallEventHandler] Incoming number : +91XXXXXXXXXX
I/[SAMPLE] (11836): [CallEventHandler] Incoming number after : XXXXXXXXXX
I/[SAMPLE] (11836): [CallEventHandler] HERESSSSS : XXXXXXXXXX
I/flutter (11836): [SAMPLE][EventHandler] In listening
I/flutter (11836): [SAMPLE] data : XXXXXXXXXX
在隨后的來電中,不打印最后一行
謝謝
好的,我已經設法解決了它,但不知道這是否是正確的方法。 問題是MySamplePage
是一個StatefulWidget
,我在其State
object 中調用setState
。這可能是它無法再收聽 stream 的原因。 我已經調用startListening
是setState
方法並相應地更改了代碼(刪除之前的訂閱並重新收聽流)
void startListening(void Function(String data)? onData) {
debugPrint(TAG + " starting listening");
if(_subscription != null) {
_subscription?.cancel();
_subscription = null;
}
_subscription ??= _evtStream?.listen((data) {
debugPrint(TAG + " In listening");
onData!(data);
});
}
這里_subscription
是StreamSubscription<String>?
. 希望這個答案有幫助。 我應該早點發布完整的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.