#java #android #flutter #kotlin #dart
Вопрос:
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:device_info/device_info.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter_nearby_connections/flutter_nearby_connections.dart';
import 'package:foreground_service/foreground_service.dart';
void main() {
runApp(MyApp());
// maybeStartFGS();
// foregroundServiceFunction();
}
Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (_) => Home());
case 'browser':
return MaterialPageRoute(builder: (_) => DevicesListScreen());
// case 'advertiser':
// return MaterialPageRoute(
// builder: (_) => DevicesListScreen(deviceType: DeviceType.advertiser));
default:
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
child: Text('No route defined for ${settings.name}')),
));
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
onGenerateRoute: generateRoute,
initialRoute: '/',
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: InkWell(
onTap: () {
Navigator.pushNamed(context, 'browser');
},
child: Container(
color: Colors.red,
child: Center(
child: Text(
'BROWSER',
style: TextStyle(color: Colors.white, fontSize: 40),
)),
),
),
),
Expanded(
child: InkWell(
onTap: () {
Navigator.pushNamed(context, 'advertiser');
},
child: Container(
color: Colors.green,
child: Center(
child: Text(
'ADVERTISER',
style: TextStyle(color: Colors.white, fontSize: 40),
)),
),
),
),
],
),
);
}
}
class DevicesListScreen extends StatefulWidget {
@override
_DevicesListScreenState createState() => _DevicesListScreenState();
}
class _DevicesListScreenState extends State<DevicesListScreen> {
List<Device> devices = [];
List<Device> connectedDevices = [];
NearbyService nearbyService;
StreamSubscription subscription;
StreamSubscription receivedDataSubscription;
bool isInit = false;
@override
void initState() {
super.initState();
init();
}
@override
void dispose() {
subscription.cancel();
receivedDataSubscription.cancel();
nearbyService.stopBrowsingForPeers();
nearbyService.stopAdvertisingPeer();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
),
body: ListView.builder(
itemCount: getItemCount(),
itemBuilder: (context, index) {
final device = devices[index];
print(getItemCount());
print(device.toString());
return Container(
margin: EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: GestureDetector(
onTap: () => _onTabItemListener(device),
child: Column(
children: [
Text(device.deviceName),
Text("hello"),
Text(
getStateName(device.state),
style: TextStyle(
color: getStateColor(device.state)),
),
],
crossAxisAlignment: CrossAxisAlignment.start,
),
)),
// Request connect
GestureDetector(
onTap: () => _onButtonClicked(device),
child: Container(
margin: EdgeInsets.symmetric(horizontal: 8.0),
padding: EdgeInsets.all(8.0),
height: 35,
width: 100,
color: getButtonColor(device.state),
child: Center(
child: Text(
getButtonStateName(device.state),
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
),
)
],
),
SizedBox(
height: 8.0,
),
Divider(
height: 1,
color: Colors.grey,
)
],
),
);
}));
}
String getStateName(SessionState state) {
switch (state) {
case SessionState.notConnected:
return "disconnected";
case SessionState.connecting:
return "waiting";
default:
return "connected";
}
}
String getButtonStateName(SessionState state) {
switch (state) {
case SessionState.notConnected:
case SessionState.connecting:
return "Connect";
default:
return "Disconnect";
}
}
Color getStateColor(SessionState state) {
switch (state) {
case SessionState.notConnected:
return Colors.black;
case SessionState.connecting:
return Colors.grey;
default:
return Colors.green;
}
}
Color getButtonColor(SessionState state) {
switch (state) {
case SessionState.notConnected:
case SessionState.connecting:
return Colors.green;
default:
return Colors.red;
}
}
_onTabItemListener(Device device) {
if (device.state == SessionState.connected) {
showDialog(
context: context,
builder: (BuildContext context) {
final myController = TextEditingController();
return AlertDialog(
title: Text("Send message"),
content: TextField(controller: myController),
actions: [
TextButton(
child: Text("Cancel"),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text("Send"),
onPressed: () {
nearbyService.sendMessage(
device.deviceId, myController.text);
myController.text = '';
},
)
],
);
});
}
}
int getItemCount() {
return devices.length;
}
_onButtonClicked(Device device) {
switch (device.state) {
case SessionState.notConnected:
nearbyService.invitePeer(
deviceID: device.deviceId,
deviceName: device.deviceName,
);
break;
case SessionState.connected:
nearbyService.disconnectPeer(deviceID: device.deviceId);
break;
case SessionState.connecting:
break;
}
}
void init() async {
nearbyService = NearbyService();
String devInfo = '';
String userName='';
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
devInfo = androidInfo.model;
userName = Random().nextInt(10000).toString();
print("devinfo" devInfo);
print("Username" userName);
}
if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
devInfo = iosInfo.localizedModel;
}
await nearbyService.init(
serviceType: 'mpconn',
deviceName: userName,
strategy: Strategy.P2P_CLUSTER,
callback: (isRunning) async {
if (isRunning) {
try {
print("start browsing peer");
nearbyService.startAdvertisingPeer();
await nearbyService.startBrowsingForPeers();
} catch (e) {
print("Error:" e.toString());
}
}
});
subscription =
nearbyService.stateChangedSubscription(callback: (devicesList) {
devicesList.forEach((element) {
print(
" deviceId: ${element.deviceId} | deviceName: ${element.deviceName} | state: ${element.state}");
if (Platform.isAndroid) {
if (element.state == SessionState.connected) {
} else {
nearbyService.startBrowsingForPeers();
}
}
});
setState(() {
devices.clear();
devices.addAll(devicesList);
connectedDevices.clear();
connectedDevices.addAll(devicesList
.where((d) => d.state == SessionState.connected)
.toList());
});
});
receivedDataSubscription =
nearbyService.dataReceivedSubscription(callback: (data) {
print("dataReceivedSubscription: ${jsonEncode(data)}");
showToast(jsonEncode(data),
context: context,
axis: Axis.horizontal,
alignment: Alignment.center,
position: StyledToastPosition.bottom);
});
}
}
Я успешно получаю близлежащие устройства с помощью этого кода.Моя проблема в том,что я хочу выполнить его в фоновом режиме,для чего я использовал плагин flutter foreground_service, но когда я пишу соседний код в служебной функции переднего плана.Я получаю исключение Здесь, это код:
static final _auth = FirebaseAuth.instance;
static FirebaseFirestore _firestore = FirebaseFirestore.instance;
static User user;
static String userEmail;
static NearbyService nearbyService;
static StreamSubscription subscription;
static StreamSubscription receivedDataSubscription;
bool isInit = false;
static void foregroundServiceFunction() async {
await Firebase.initializeApp();
nearbyService = NearbyService();
debugPrint("The current time is: ${DateTime.now()}");
debugPrint("The second time is: ${DateTime.now()}");
debugPrint("The third time is: ${DateTime.now()}");
debugPrint("The fourth time is: ${DateTime.now()}");
try {
debugPrint("in try block");
user = await FirebaseAuth.instance.currentUser;
String devInfo = '';
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
devInfo = androidInfo.model;
userEmail = await user.email.toString();
print("useremail:" userEmail);
}
if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
userEmail = iosInfo.localizedModel;
}
try {
print("in init block");
await nearbyService.init(
serviceType: 'mpconn',
deviceName: userEmail,
// deviceName:"unzilla",
strategy: Strategy.P2P_CLUSTER,
callback: (isRunning) async {
if (isRunning) {
try {
print("start browsing peer");
nearbyService.startAdvertisingPeer();
await nearbyService.startBrowsingForPeers();
} catch (e) {
print("browsing Error:" e.toString());
}
} else {
print("else");
}
});
} catch (e) {
print("EEEEEE" e.toString());
}
debugPrint("after nearbyservice.init is: ${DateTime.now()}");
// subscription =
// nearbyService.stateChangedSubscription(callback: (devicesList) {
// devicesList.forEach((element) async {
// Future<Map<String, dynamic>> votedown() async {
// Map<String, dynamic> comdata = <String, dynamic>{
// 'username': await getUsernameOfEmail(email: element.deviceName),
// 'contact time': DateTime.now(),
// };
// return comdata;
// }
// debugPrint("after subscription is: ${DateTime.now()}");
// print(
// " deviceId: ${element.deviceId} | deviceName: ${element.deviceName} | state: ${element.state}");
// if (Platform.isAndroid) {
// if (element.state == SessionState.connected) {
// } else {
// nearbyService.startBrowsingForPeers();
// }
// }
// });
// receivedDataSubscription =
// nearbyService.dataReceivedSubscription(callback: (data) {
// print("dataReceivedSubscription: ${jsonEncode(data)}");
// showToast(jsonEncode(data),
// axis: Axis.horizontal,
// alignment: Alignment.center,
// position: StyledToastPosition.bottom);
// });
// });
debugPrint("after received data is: ${DateTime.now()}");
debugPrint("last is: ${DateTime.now()}");
ForegroundService.notification.setText("The time was: ${DateTime.now()}");
}
catch (e) {
debugPrint("In catch block");
print(e.toString());
}
}
}/ static void maybeStartFGS() async {
// print("maybe start fgs");
// if (!(await ForegroundService.foregroundServiceIsStarted())) {
// await ForegroundService.setServiceIntervalSeconds(5);
// await ForegroundService.notification
// .setPriority(AndroidNotificationPriority.LOW);
// await ForegroundService.notification.startEditMode();
// await ForegroundService.notification
// .setTitle("Example Title: ${DateTime.now()}");
// await ForegroundService.notification
// .setText("Example Text: ${DateTime.now()}");
// await ForegroundService.notification.finishEditMode();
// await ForegroundService.startForegroundService(foregroundServiceFunction);
// await ForegroundService.getWakeLock();
// }
// await ForegroundService.setupIsolateCommunication((data) {
// debugPrint("main received: $data");
// });
// }
Error Logs:
E/MethodChannel#flutter_nearby_connections(16947): Failed to handle method call
E/MethodChannel#flutter_nearby_connections(16947): kotlin.UninitializedPropertyAccessException: lateinit property activity has not been initialized
E/MethodChannel#flutter_nearby_connections(16947): at com.nankai.flutter_nearby_connections.FlutterNearbyConnectionsPlugin.onMethodCall(FlutterNearbyConnectionsPlugin.kt:77)
E/MethodChannel#flutter_nearby_connections(16947): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/MethodChannel#flutter_nearby_connections(16947): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
E/MethodChannel#flutter_nearby_connections(16947): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818)
E/MethodChannel#flutter_nearby_connections(16947): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#flutter_nearby_connections(16947): at android.os.MessageQueue.next(MessageQueue.java:336)
E/MethodChannel#flutter_nearby_connections(16947): at android.os.Looper.loop(Looper.java:184)
E/MethodChannel#flutter_nearby_connections(16947): at android.app.ActivityThread.main(ActivityThread.java:7864)
E/MethodChannel#flutter_nearby_connections(16947): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#flutter_nearby_connections(16947): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/MethodChannel#flutter_nearby_connections(16947): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:998)
E/flutter (16947): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: PlatformException(error, lateinit property activity has not been initialized, null, kotlin.UninitializedPropertyAccessException: lateinit property activity has not been initialized
E/flutter (16947): at com.nankai.flutter_nearby_connections.FlutterNearbyConnectionsPlugin.onMethodCall(FlutterNearbyConnectionsPlugin.kt:77)
E/flutter (16947): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/flutter (16947): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
E/flutter (16947): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818)
E/flutter (16947): at android.os.MessageQueue.nativePollOnce(Native Method)
E/flutter (16947): at android.os.MessageQueue.next(MessageQueue.java:336)
E/flutter (16947): at android.os.Looper.loop(Looper.java:184)
E/flutter (16947): at android.app.ActivityThread.main(ActivityThread.java:7864)
E/flutter (16947): at java.lang.reflect.Method.invoke(Native Method)
E/flutter (16947): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/flutter (16947): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:998)
E/flutter (16947): )
E/flutter (16947): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:597:7)
E/flutter (16947): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)
E/flutter (16947): <asynchronous suspension>
I am calling this maybestartFgs() function on initState() or button click it is throwing exception
Late init property activity could not be initialized in Flutter Nearby Connections
How to give activity to nearby connections plugin while calling it in foreground service function?I have no idea why nearby connection is not getting activity when I am calling it inside function.This nearby code is working fine if I am not calling it in foreground service function.
Also I have used alarm manager and background fetch plugins for background and have passed nearby devices code in their callback but still getting same error.
Anyone kindly know how to solve this.I will be very thankful to you.