我正在尝试构建一个使用某些包作为位置(https://pub.dev/packages/location)和指南针(https://pub.dev/packages/flutter_compass)的应用程序,并保留后台服务跟踪用户位置。 一切正常,直到我启动跟踪位置的服务。
当服务处于活动状态时,整个应用程序永远不会停止,例如,当我在没有服务的情况下关闭应用程序时,指南针也会停止,但随着服务运行,指南针也会保持运行。实际上它返回一个错误“尝试向 Flutter 发送平台消息,但 FlutterJNI 与本机 C++ 分离。无法发送。通道:hemanthraj/flutter_compass”。位置也会发生同样的情况:“尝试向 Flutter 发送平台消息,但 FlutterJNI 与本机 C++ 分离。无法发送。通道:lyokone/locationstream”。 在此之后,即使我再次打开该项目,它也不再工作了...... 我正在尝试使服务完全独立于项目的其余部分。
我将向您展示服务实现(Android)
public class CompassApplication extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("messages", "Messages", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
}
}
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
val intent = Intent(this, LocationService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
}
}
public class LocationService extends Service {
static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10 * 60 * 1000; // 10 minutes
static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback mLocationCallback;
@Override
public void onCreate() {
super.onCreate();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
onNewLocation(locationResult.getLastLocation());
}
};
createLocationRequest();
getLastLocation();
requestLocationUpdates();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "messages")
.setSmallIcon(R.mipmap.ic_launcher_foreground);
startForeground(101, builder.build());
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void getLastLocation() {
try {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(task -> {
if (task.isSuccessful() && task.getResult() != null) {
onNewLocation(task.getResult());
}
});
} catch (SecurityException ignored) {}
}
public void requestLocationUpdates() {
Utils.setRequestingLocationUpdates(this, true);
startService(new Intent(getApplicationContext(), LocationUpdatesService.class));
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, false);
}
}
private void onNewLocation(Location location) {
// TODO: deal with current location
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
另一个问题是,即使我不关闭应用程序,它也会消耗大量电池。 谢谢!
由于您使用的软件包导致了此问题,我会提到我在我的软件包中引起了同样的问题。
就我而言,我使用了错误(或旧)方法通道。我保存了服务(广播接收器)运行时的方法通道实例,并尝试使用它与正在运行的应用程序进行通信。
在清理服务(或广播接收器)时,我“破坏了”Flutter 引擎,因此将 Flutter JNI 从 C++ 引擎中分离出来。因此,当我去使用该方法通道(它使用分离的 Flutter JNI)时,您会收到错误:
尝试向 Flutter 发送平台消息,但 FlutterJNI 与原生 C++ 分离。我只需使用 FlutterActivity(或 FlutterFragment 或 Application)提供的 FlutterEngine 来获取新的 MethodChannel。
就我而言,我正在开发 Flutter 包插件(在 Android 上)。这意味着在插件代码内部,我不应该意外地缓存 methodChannels :
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
final MethodChannel methodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "example-method-channel-name");
}
您的问题
没有快速修复方法,必须构建包来支持这一点。
将以下代码添加到原生 android mainActivity.kt
从后台关闭应用程序。 运行“颤动清洁” 运行“颤动运行” 这对我有用。
我在使用 TFLite 检测相机上的物体时出现了这个问题。 我不太确定,但每次我注意到手机过热时,
这是我的最佳答案: 该错误会导致当 FlutterNativeView 仍然存在时 Dart->Java 消息被丢弃。这个问题看起来涉及Java->Dart消息。
**This helps me solve this problem.**
import io.flutter.embedding.engine.FlutterJNI;
private MethodChannel methodChannel = null;
private EventChannel eventChannel = null;
private EventChannel.EventSink eventSink;
private FlutterJNI flutterJNI = new FlutterJNI();
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
methodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "sariska_media_transport_flutter");
eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "sariskaMediaTransportEvent");
if (methodChannel != null) {
methodChannel.setMethodCallHandler(this);
}
if (eventChannel != null) {
eventChannel.setStreamHandler(this);
}
flutterJNI.attachToNative();
applicationContext = flutterPluginBinding.getApplicationContext();
connectionPlugin = new ConnectionPlugin(flutterPluginBinding.getBinaryMessenger());
conferencePlugin = new ConferencePlugin(flutterPluginBinding.getBinaryMessenger());
trackPlugin = new TrackPlugin(flutterPluginBinding.getBinaryMessenger());
FlutterEngine flutterEngine = flutterPluginBinding.getFlutterEngine();
PlatformViewRegistry registry = flutterEngine.getPlatformViewsController().getRegistry();
registry.registerViewFactory(
"DummyView",
new SariskaSurfaceViewFactory(flutterPluginBinding.getBinaryMessenger()));
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
if (methodChannel != null) {
methodChannel.setMethodCallHandler(null);
methodChannel = null;
}
if (eventChannel != null) {
eventChannel.setStreamHandler(null);
eventChannel = null;
}
flutterJNI.attachToNative();
}