gpt4 book ai didi

java - 如何使用 EventChannel 从 native 服务广播接收器接收数据流?

转载 作者:行者123 更新时间:2023-12-01 19:58:02 28 4
gpt4 key购买 nike

假设我有一个 flutter 应用程序,并且有一个前台服务,该服务有一个工作线程并不断向我发送有关用户位置的更新,这是目前返回随机整数的服务代码:

Android 服务代码

public class LocationUpdatesService extends Service {
static final int NOTIFICATION_ID = 100;
static final String NOTIFICATION = "com.example.fitness_app";
NotificationManagerCompat m_notificationManager;
private Intent m_broadcastInent;
private final String TAG = this.getClass().getSimpleName();
private AtomicBoolean working = new AtomicBoolean(true);
private int steps = 0;
private Runnable runnable = new Runnable() {
@Override
public void run() {
while(working.get()) {
steps++;
m_notificationManager.notify(NOTIFICATION_ID,
createNotification("Steps Counter" + steps ,
R.drawable.common_full_open_on_phone, 1));
m_broadcastInent.putExtra("steps", steps);
sendBroadcast(m_broadcastInent);
}

}
};



@Override
public void onCreate() {
m_broadcastInent = new Intent(NOTIFICATION);
m_notificationManager = NotificationManagerCompat.from(this);
createNotificationChannel();
startForeground(NOTIFICATION_ID, createNotification("Steps Counter" ,
R.drawable.common_full_open_on_phone, 0));
super.onCreate();

}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(runnable).start();
return Service.START_STICKY;
}


@Override
public void onDestroy() {
working.set(false);
m_notificationManager.cancel(NOTIFICATION_ID);
super.onDestroy();

}


private Notification createNotification(String title, int icon, int steps) {

NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
getString(R.string.BACKGROUND_SERVICE_NOTIFICATION_CHANNEL_ID));
builder.setNumber(steps);
builder.setSmallIcon(icon);
builder.setContentTitle(title);
builder.setOnlyAlertOnce(true);
return builder.build();

}

private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.BACKGROUND_SERVICE_NOTIFICATION_CHANNEL_ID);
String description =
getString(R.string.BACKGROUND_SERVICE_NOTIFICATION_CHANNEL_DESCRIPTION);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel =
new NotificationChannel(getString(
R.string.BACKGROUND_SERVICE_NOTIFICATION_CHANNEL_ID), name, importance);
channel.setDescription(description);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}


}

在 MainActivity.java 中,我正在从服务接收广播,我应该将它们发送到 flutter 端:

主要 Activity

public class MainActivity extends FlutterActivity {

private static final String TAG = MainActivity.class.getSimpleName();
private static final String ONE_TIME_BACKGROUND_METHOD_CHANNEL = "fitness_app/method_one_time_service";
private static final String EVENTS_STREAM_CHANNEL = "fitness_app/event_one_time_service";

private Intent m_serviceIntent;
private MethodChannel m_methodChannel;
private EventChannel m_eventchannel;
private EventChannel.EventSink m_stepsStreamSink;
private EventChannel.StreamHandler m_eventCallHandler;
private MethodChannel.Result m_result;
private EventChannel.EventSink m_eventSink;
private BroadcastReceiver m_serviceBroadcastReciever = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Log.d(TAG, "milliseconds " + intent.getIntExtra("steps", 0));

Bundle bundle = intent.getExtras();
if (bundle != null) {
int steps = bundle.getInt("steps");
/////////////////////////////////////////
/////////////////////////////////////////
// I need Here To add Data To the stream
/////////////////////////////////////////
/////////////////////////////////////////

}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);

m_serviceIntent = new Intent(this, LocationUpdatesService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, m_serviceIntent, 0);
m_methodChannel = new MethodChannel(getFlutterView(), ONE_TIME_BACKGROUND_METHOD_CHANNEL);

m_methodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if (methodCall.method.equals("START_STEPS_COUNTER")) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(m_serviceIntent);
} else {
startService(m_serviceIntent);
}
} else {
stopService(m_serviceIntent);
}
}
});
m_eventchannel = new EventChannel(getFlutterView(), EVENTS_STREAM_CHANNEL);
m_eventCallHandler = new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
m_eventSink = eventSink;
}

@Override
public void onCancel(Object o) {

}
};
m_eventchannel.setStreamHandler(m_eventCallHandler);

}

@Override
protected void onStart() {
super.onStart();

}

@Override
protected void onResume() {
super.onResume();
registerReceiver(m_serviceBroadcastReciever, new IntentFilter(LocationUpdatesService.NOTIFICATION));
}

@Override
protected void onDestroy() {
super.onDestroy();

}

}

Flutter dart 代码

void start() async {
try {
await _methodChannel.invokeMethod(PlatformMethods.STEPS_COUNTER_START);
Stream<int> stream = _eventChannel.receiveBroadcastStream();
} on PlatformException catch (e) {
print(
" Faild to run native service with thrown exception : ${e.toString()}");
}

这里一切正常。我可以使用 Methodchannel 触发服务,我使用 BroadCastREciever 从服务接收数据。我需要做的就是使用 EventChannel 从 native 代码返回流。

最佳答案

创建一个扩展 BroadcastReceiver 的类并传递 EventChannel.EventSink。

class SinkBroadcastReceiver(private val sink: EventChannel.EventSink) {
override fun onReceive(context: Context, intent: Intent) {
val bundle = intent.getExtras()
if (bundle != null) {
val steps = bundle.getInt("steps")
sink.success(steps)
}
}
}

然后,您可以在 onListen 中创建 BroadcastReceiver 并在那里调用 registerReceiver:

m_eventCallHandler = new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
SinkBroadcastReceiver receiver = new SinkBroadcastReceiver(eventSink);
registerReceiver(receiver, new IntentFilter(LocationUpdatesService.NOTIFICATION));
// TODO : Save receiver in a list to call unregisterReceiver later
}

@Override
public void onCancel(Object o) {

}
};

您可能需要跟踪列表中的所有接收者,因为您可能需要在 Activity 停止时取消注册。此外,当您停止服务时,您可能需要遍历已注册的 BroadcastReceiver 列表以取消注册所有实例。

这样一来,您就可以在 dart 代码上为同一事件拥有多个监听器。

关于java - 如何使用 EventChannel 从 native 服务广播接收器接收数据流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59022897/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com