我正在使用[background_locator_2][1]插件,但是当我运行它并进行一些修改时,我收到此错误
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'LocationDto'
这是我正在使用的代码
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ReceivePort port = ReceivePort();
String logStr = '';
bool? isRunning;
LocationDto? lastLocation;
@override
void initState() {
super.initState();
if (IsolateNameServer.lookupPortByName(
LocationServiceRepository.isolateName) !=
null) {
IsolateNameServer.removePortNameMapping(
LocationServiceRepository.isolateName);
}
IsolateNameServer.registerPortWithName(
port.sendPort, LocationServiceRepository.isolateName);
port.listen(
(dynamic data) async {
await updateUI(data);
},
);
initPlatformState();
}
@override
void dispose() {
super.dispose();
}
Future<void> updateUI(LocationDto data) async {
final log = await FileManager.readLogFile();
await _updateNotificationText(data);
setState(() {
lastLocation = data;
logStr = log;
});
}
Future<void> _updateNotificationText(LocationDto data) async {
if (data == null) {
return;
}
await BackgroundLocator.updateNotificationText(
title: "new location received",
msg: "${DateTime.now()}",
bigMsg: "${data.latitude}, ${data.longitude}");
}
Future<void> initPlatformState() async {
print('Initializing...');
await BackgroundLocator.initialize();
logStr = await FileManager.readLogFile();
print('Initialization done');
final _isRunning = await BackgroundLocator.isServiceRunning();
setState(() {
isRunning = _isRunning;
});
print('Running ${isRunning.toString()}');
}
@override
Widget build(BuildContext context) {
final start = SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: Text('Start'),
onPressed: () {
_onStart();
},
),
);
final stop = SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: Text('Stop'),
onPressed: () {
onStop();
},
),
);
final clear = SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: Text('Clear Log'),
onPressed: () {
FileManager.clearLogFile();
setState(() {
logStr = '';
});
},
),
);
String msgStatus = "-";
if (isRunning != null) {
if (isRunning!) {
msgStatus = 'Is running';
} else {
msgStatus = 'Is not running';
}
}
final status = Text("Status: $msgStatus");
final log = Text(
logStr,
);
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter background Locator'),
),
body: Container(
width: double.maxFinite,
padding: const EdgeInsets.all(22),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[start, stop, clear, status, log],
),
),
),
),
);
}
void onStop() async {
await BackgroundLocator.unRegisterLocationUpdate();
final _isRunning = await BackgroundLocator.isServiceRunning();
setState(() {
isRunning = _isRunning;
});
}
void _onStart() async {
//if (await isLocationAlwaysGranted()) {
await _startLocator();
final _isRunning = await BackgroundLocator.isServiceRunning();
setState(() {
isRunning = _isRunning;
lastLocation = null;
});
// } else {
// show error
}
}
Future<bool> isLocationAlwaysGranted() async =>
await Permission.locationAlways.isGranted;
/// Tries to ask for "location always" permissions from the user.
/// Returns `true` if successful, `false` othervise.
Future<bool> askForLocationAlwaysPermission() async {
bool granted = await Permission.locationAlways.isGranted;
if (!granted) {
granted =
await Permission.locationAlways.request() == PermissionStatus.granted;
}
return granted;
}
Future<void> _startLocator() async {
Map<String, dynamic> data = {'countInit': 1};
return await BackgroundLocator.registerLocationUpdate(
LocationCallbackHandler.callback,
initCallback: LocationCallbackHandler.initCallback,
initDataCallback: data,
disposeCallback: LocationCallbackHandler.disposeCallback,
iosSettings: IOSSettings(
accuracy: LocationAccuracy.NAVIGATION,
distanceFilter: 0,
stopWithTerminate: true),
autoStop: false,
androidSettings: AndroidSettings(
accuracy: LocationAccuracy.NAVIGATION,
interval: 5,
distanceFilter: 0,
client: LocationClient.google,
androidNotificationSettings: AndroidNotificationSettings(
notificationChannelName: 'Location tracking',
notificationTitle: 'Start Location Tracking',
notificationMsg: 'Track location in background',
notificationBigMsg:
'Background location is on to keep the app up-tp-date with your location. This is required for main features to work properly when the app is not running.',
notificationIconColor: Colors.grey,
notificationTapCallback:
LocationCallbackHandler.notificationCallback)));
}
当我启动或停止插件时,错误出现在initState
下的这一行中。
port.listen(
(dynamic data) async {
await updateUI(data);
},
);
原来的代码没有null安全,所以我试着修改它。但是很明显我的知识是有限的。[1]:https://pub.dev/packages/background_locator_2
1条答案
按热度按时间a7qyws3x1#
您从端口
(dynamic data)
监听的数据可以为空,并且您将其发送到不接受可空类型的函数updateUI
。您可以在调用
await updateUI(data);
之前检查data
是否不为空,也可以使函数updateUI
接受空值,即(Future<void> updateUI(LocationDto? data) async {
),并处理函数内部数据可为空的情况