Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从本机服务接收数据流';使用EventChannel广播接收器?_Java_Android_Flutter_Stream - Fatal编程技术网

Java 如何从本机服务接收数据流';使用EventChannel广播接收器?

Java 如何从本机服务接收数据流';使用EventChannel广播接收器?,java,android,flutter,stream,Java,Android,Flutter,Stream,让我们假设我有一个颤振应用程序,我有一个前台服务,它有一个工作线程,并不断向我发送有关用户位置的更新,这是该服务的代码,现在返回一个随机整数: Android服务代码 public class LocationUpdatesService extends Service { static final int NOTIFICATION_ID = 100; static final String NOTIFICATION = "com.example.fitness_app"; Notificat

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

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);
    }
}


}
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()}");
}
在MainActivity.java中,我接收到来自服务的广播,我应该将它们发送到颤振端:

main活动

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();

}
}

颤振省道代码

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);
    }
}


}
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()}");
}
void start()异步{
试一试{
wait\u methodChannel.invokeMethod(PlatformMethods.STEPS\u COUNTER\u START);
Stream=\u eventChannel.receiveBroadcastStream();
}平台上异常捕获(e){
印刷品(
“无法运行本机服务,引发异常:${e.toString()}”);
}
这里一切正常。我可以使用Methodchannel触发服务,使用BroadcastReceiver从服务接收数据。
我需要做的就是使用EventChannel从本机代码返回一个流。

创建一个扩展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)
        }
    }
}
然后,在声明中创建BroadcastReceiver,您可以在onListen中创建它,并在那里调用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) {

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


通过这种方式,同一事件的dart代码上也可能有多个侦听器。

实际上,
BroadcastReceiver
不需要作为
sink.success(步骤)
可以由绑定的本地服务代码直接调用谢谢Richard,它非常有用,我可以获取流。但是我需要我的服务继续工作,即使颤振活动被终止。那么,你建议如何处理列表广播接收器,我必须在destroy上注销它们吗?还有一个问题:如果地面服务正在运行,FlatterActivity被终止,如何保持服务的价值,以便应用程序可以从停止的位置继续运行?我正在考虑使用SharedReferences。那么你怎么看?@pskink实际上,当FlatterActivity被终止时,我需要服务继续工作,这样我就不能将其绑定到活动。@SameerAhmad,是的您可以-服务可以启动和绑定,更多