doc(lib): add documentation for the dart side
This commit is contained in:
@@ -21,6 +21,6 @@
|
|||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>11.0</string>
|
<string>12.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
+17
-12
@@ -51,15 +51,18 @@ class MyApp extends StatelessWidget {
|
|||||||
'Platform: ${service.platformVersion}\n'
|
'Platform: ${service.platformVersion}\n'
|
||||||
'Model: ${service.platformModel}',
|
'Model: ${service.platformModel}',
|
||||||
),
|
),
|
||||||
if (service.currentDevice != null)
|
if (service.currentDeviceInfo != null)
|
||||||
Text(
|
Text(
|
||||||
'Device Name: ${service.currentDevice!.displayName}\n'
|
'Device Name: ${service.currentDeviceInfo!.displayName}\n'
|
||||||
'${Platform.isIOS ? 'Device ID: ${service.currentDevice!.id}' : ''}\n',
|
'${Platform.isIOS ? 'Device ID: ${service.currentDeviceInfo!.id}' : ''}',
|
||||||
),
|
),
|
||||||
if (Platform.isIOS)
|
if (Platform.isIOS)
|
||||||
Text(
|
Text(
|
||||||
'You are ${service.isIOSBrowser ? 'going to find your friend' : 'waiting for another user to connect'}\n',
|
'You are ${service.isIOSBrowser ? 'going to find your friend' : 'waiting for another user to connect'}',
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
'Communication channel state: ${service.communicationChannelState.name.toUpperCase()}',
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -170,12 +173,13 @@ enum AppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AppService extends ChangeNotifier {
|
class AppService extends ChangeNotifier {
|
||||||
final _nearbyService = NearbyService.getInstance();
|
late final _nearbyService = NearbyService.getInstance()
|
||||||
|
..communicationChannelState.addListener(notifyListeners);
|
||||||
|
|
||||||
AppState state = AppState.idle;
|
AppState state = AppState.idle;
|
||||||
List<NearbyDevice>? peers;
|
List<NearbyDevice>? peers;
|
||||||
NearbyDevice? connectedDevice;
|
NearbyDevice? connectedDevice;
|
||||||
NearbyDeviceInfo? currentDevice;
|
NearbyDeviceInfo? currentDeviceInfo;
|
||||||
|
|
||||||
String platformVersion = 'Unknown';
|
String platformVersion = 'Unknown';
|
||||||
String platformModel = 'Unknown';
|
String platformModel = 'Unknown';
|
||||||
@@ -183,8 +187,8 @@ class AppService extends ChangeNotifier {
|
|||||||
StreamSubscription? peersSubscription;
|
StreamSubscription? peersSubscription;
|
||||||
StreamSubscription? connectedDeviceSubscription;
|
StreamSubscription? connectedDeviceSubscription;
|
||||||
|
|
||||||
bool get isCommunicationChannelConnecting {
|
CommunicationChannelState get communicationChannelState {
|
||||||
return _nearbyService.isCommunicationChannelConnecting.value;
|
return _nearbyService.communicationChannelState.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get isIOSBrowser {
|
bool get isIOSBrowser {
|
||||||
@@ -202,7 +206,7 @@ class AppService extends ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> getSavedDeviceName() async {
|
Future<String> getSavedIOSDeviceName() async {
|
||||||
return (await _nearbyService.ios?.getSavedDeviceName()) ?? platformModel;
|
return (await _nearbyService.ios?.getSavedDeviceName()) ?? platformModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +215,7 @@ class AppService extends ChangeNotifier {
|
|||||||
await _nearbyService.initialize(
|
await _nearbyService.initialize(
|
||||||
data: NearbyInitializeData(iosDeviceName: iosDeviceName),
|
data: NearbyInitializeData(iosDeviceName: iosDeviceName),
|
||||||
);
|
);
|
||||||
currentDevice = (await _nearbyService.getCurrentDevice())?.info;
|
currentDeviceInfo = await _nearbyService.getCurrentDeviceInfo();
|
||||||
updateState(
|
updateState(
|
||||||
Platform.isAndroid ? AppState.permissions : AppState.selectClientType,
|
Platform.isAndroid ? AppState.permissions : AppState.selectClientType,
|
||||||
);
|
);
|
||||||
@@ -432,7 +436,7 @@ class _IdleBodyState extends State<_IdleBody> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
context.read<AppService>().getSavedDeviceName().then((value) {
|
context.read<AppService>().getSavedIOSDeviceName().then((value) {
|
||||||
controller.text = value;
|
controller.text = value;
|
||||||
controller.selection = TextSelection.collapsed(offset: value.length);
|
controller.selection = TextSelection.collapsed(offset: value.length);
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -719,7 +723,8 @@ class _ConnectedBody extends StatelessWidget {
|
|||||||
else
|
else
|
||||||
_DevicePreview(device: device, largeView: true),
|
_DevicePreview(device: device, largeView: true),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
if (!(service.isCommunicationChannelConnecting))
|
if (service.communicationChannelState !=
|
||||||
|
CommunicationChannelState.loading)
|
||||||
_ActionButton(
|
_ActionButton(
|
||||||
onTap: () => service.startCommunicationChannel(
|
onTap: () => service.startCommunicationChannel(
|
||||||
listener: (event) => AppShackBar.show(
|
listener: (event) => AppShackBar.show(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import MultipeerConnectivity
|
|||||||
let SERVICE_TYPE = "mp-connection"
|
let SERVICE_TYPE = "mp-connection"
|
||||||
let PEER_ID = "PEER-ID"
|
let PEER_ID = "PEER-ID"
|
||||||
let DEVICE_NAME = "DEVICE-NAME"
|
let DEVICE_NAME = "DEVICE-NAME"
|
||||||
|
let ON_MESSAGE_RECEIVED = Notification.Name("NearbySessionOnMessageReceived")
|
||||||
|
|
||||||
class MyDeviceDataGenerator {
|
class MyDeviceDataGenerator {
|
||||||
static func generate(name: String?) -> NearbyDevice {
|
static func generate(name: String?) -> NearbyDevice {
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public class NearbyServicePlugin: NSObject, FlutterPlugin {
|
|||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
NotificationCenter.default.addObserver(
|
||||||
instance,
|
instance,
|
||||||
selector: #selector(messageReceived),
|
selector: #selector(onMessageReceived),
|
||||||
name: NearbySession.messageReceived,
|
name: ON_MESSAGE_RECEIVED,
|
||||||
object: nil
|
object: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,12 +49,6 @@ public class NearbyServicePlugin: NSObject, FlutterPlugin {
|
|||||||
NearbyDevicesStore.instance.clear()
|
NearbyDevicesStore.instance.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func messageReceived(notification: Notification) {
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
let result = NearbyMessageConverter.convert(userInfo: notification.userInfo)
|
|
||||||
self.channel.invokeMethod("invoke_nearby_service_message_received", arguments: result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||||
@@ -124,6 +118,12 @@ public class NearbyServicePlugin: NSObject, FlutterPlugin {
|
|||||||
result(FlutterMethodNotImplemented)
|
result(FlutterMethodNotImplemented)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@objc func onMessageReceived(notification: Notification) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let result = NearbyMessageConverter.convert(userInfo: notification.userInfo)
|
||||||
|
self.channel.invokeMethod("invoke_nearby_service_message_received", arguments: result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func getArgument<T>(for name: String, call: FlutterMethodCall) -> T? {
|
private func getArgument<T>(for name: String, call: FlutterMethodCall) -> T? {
|
||||||
guard let data = call.arguments as? Dictionary<String, AnyObject> else {
|
guard let data = call.arguments as? Dictionary<String, AnyObject> else {
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ class NearbySession: NSObject {
|
|||||||
self.session = MCSession(peer: peerID)
|
self.session = MCSession(peer: peerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
static let messageReceived = Notification.Name("NearbySessionReceivedMessage")
|
|
||||||
|
|
||||||
static func create(peerID: MCPeerID) -> NearbySession {
|
static func create(peerID: MCPeerID) -> NearbySession {
|
||||||
let instance = NearbySession(peerID: peerID)
|
let instance = NearbySession(peerID: peerID)
|
||||||
instance.session.delegate = instance
|
instance.session.delegate = instance
|
||||||
@@ -34,7 +32,7 @@ extension NearbySession: MCSessionDelegate {
|
|||||||
|
|
||||||
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
|
func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) {
|
||||||
NotificationCenter.default.post(
|
NotificationCenter.default.post(
|
||||||
name: NearbySession.messageReceived,
|
name: ON_MESSAGE_RECEIVED,
|
||||||
object: nil,
|
object: nil,
|
||||||
userInfo: ["from": peerID, "data": data]
|
userInfo: ["from": peerID, "data": data]
|
||||||
)
|
)
|
||||||
|
|||||||
+153
-3
@@ -12,7 +12,21 @@ export 'src/models/models.dart';
|
|||||||
export 'src/utils/utils.dart';
|
export 'src/utils/utils.dart';
|
||||||
export 'src/types/types.dart';
|
export 'src/types/types.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The main tool for working with a P2P network.
|
||||||
|
/// Implementations:
|
||||||
|
/// * for Android - [NearbyAndroidService]
|
||||||
|
/// * for IOS - [NearbyIOSService]
|
||||||
|
///
|
||||||
|
/// **The plugin is not supported for other platforms yet**
|
||||||
|
///
|
||||||
abstract class NearbyService {
|
abstract class NearbyService {
|
||||||
|
///
|
||||||
|
/// The only way to get an instance of [NearbyService].
|
||||||
|
///
|
||||||
|
/// Creates a service suitable for the current platform.
|
||||||
|
/// Otherwise it throws [NearbyServiceException].
|
||||||
|
///
|
||||||
static NearbyService getInstance({NearbyServiceLogLevel? logLevel}) {
|
static NearbyService getInstance({NearbyServiceLogLevel? logLevel}) {
|
||||||
if (logLevel != null) {
|
if (logLevel != null) {
|
||||||
Logger.level = logLevel;
|
Logger.level = logLevel;
|
||||||
@@ -31,65 +45,201 @@ abstract class NearbyService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns [NearbyService] cast as [NearbyIOSService] if the current
|
||||||
|
/// platform is IOS. Otherwise, returns null.
|
||||||
|
///
|
||||||
late final NearbyIOSService? ios = get(
|
late final NearbyIOSService? ios = get(
|
||||||
onIOS: (e) => e,
|
onIOS: (e) => e,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns [NearbyService] cast as [NearbyAndroidService] if the current
|
||||||
|
/// platform is Android. Otherwise, returns null.
|
||||||
|
///
|
||||||
late final NearbyAndroidService? android = get(
|
late final NearbyAndroidService? android = get(
|
||||||
onAndroid: (e) => e,
|
onAndroid: (e) => e,
|
||||||
);
|
);
|
||||||
|
|
||||||
ValueListenable<bool> get isCommunicationChannelConnecting;
|
///
|
||||||
|
/// **A value to determine the communication channel's status.**
|
||||||
|
///
|
||||||
|
/// For **Android** this is the socket connection state.
|
||||||
|
/// The server can wait for the client to connect,
|
||||||
|
/// and the client can be waiting for the server to be created.
|
||||||
|
/// Also, both can be in connected and unconnected states.
|
||||||
|
///
|
||||||
|
/// For **IOS** this is the state of the message stream subscription.
|
||||||
|
/// which is generated for the device with the current connected device ID.
|
||||||
|
///
|
||||||
|
ValueListenable<CommunicationChannelState> get communicationChannelState;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets version of current platform.
|
||||||
|
///
|
||||||
|
/// * Sample answer for Android: "Android 14"
|
||||||
|
/// * Sample answer for iOS: "IOS 17.2"
|
||||||
|
///
|
||||||
Future<String?> getPlatformVersion() {
|
Future<String?> getPlatformVersion() {
|
||||||
return NearbyServicePlatform.instance.getPlatformVersion();
|
return NearbyServicePlatform.instance.getPlatformVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets model of current device.
|
||||||
|
///
|
||||||
|
/// * Sample answer for Android: "Android"
|
||||||
|
/// * Sample answer for iOS: "IPhone 15 Pro"
|
||||||
|
///
|
||||||
Future<String?> getPlatformModel() {
|
Future<String?> getPlatformModel() {
|
||||||
return NearbyServicePlatform.instance.getPlatformModel();
|
return NearbyServicePlatform.instance.getPlatformModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<NearbyDevice?> getCurrentDevice() {
|
///
|
||||||
return NearbyServicePlatform.instance.getCurrentDevice();
|
/// Getting info about the current device in P2P scope.
|
||||||
|
///
|
||||||
|
/// This method can be used to define the name
|
||||||
|
/// of the current device to be displayed on the network to other users.
|
||||||
|
///
|
||||||
|
/// Also [NearbyDeviceInfo] contains the connection ID. Note that
|
||||||
|
/// the ID obtained from [getCurrentDeviceInfo] for Android
|
||||||
|
/// will always be **02:00:00:00:00:00** for privacy issues.
|
||||||
|
/// For iOS, it can be safely used.
|
||||||
|
///
|
||||||
|
Future<NearbyDeviceInfo?> getCurrentDeviceInfo() {
|
||||||
|
return NearbyServicePlatform.instance.getCurrentDeviceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Since Wi-fi must be enabled to use the plugin in Android,
|
||||||
|
/// [openServicesSettings] can be used to redirect the user to the **Wi-fi**
|
||||||
|
/// service settings on Android.
|
||||||
|
///
|
||||||
|
/// For iOS it is not necessary to have Wi-fi enabled.
|
||||||
|
/// In case of its absence, the platform will try to establish a connection
|
||||||
|
/// by other methods. However, this method will open the settings page
|
||||||
|
/// for iOS, if you want the user to use Wi-fi.
|
||||||
|
///
|
||||||
Future<void> openServicesSettings() {
|
Future<void> openServicesSettings() {
|
||||||
return NearbyServicePlatform.instance.openServicesSettings();
|
return NearbyServicePlatform.instance.openServicesSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A single retrieval of the current list of devices in a P2P network.
|
||||||
|
///
|
||||||
|
/// Returns the list of [NearbyDevice] that have been stored so far.
|
||||||
|
/// If you want to use a constantly updated list of devices, use [getPeersStream].
|
||||||
|
///
|
||||||
Future<List<NearbyDevice>> getPeers() {
|
Future<List<NearbyDevice>> getPeers() {
|
||||||
return NearbyServicePlatform.instance.getPeers();
|
return NearbyServicePlatform.instance.getPeers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns a constantly updating list of [NearbyDevice] that
|
||||||
|
/// the platform-specific service has found at each point in time.
|
||||||
|
///
|
||||||
Stream<List<NearbyDevice>> getPeersStream() {
|
Stream<List<NearbyDevice>> getPeersStream() {
|
||||||
return NearbyServicePlatform.instance.getPeersStream();
|
return NearbyServicePlatform.instance.getPeersStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the constantly updating [NearbyDevice] you are currently connected to.
|
||||||
|
/// If it returns null, then there is no connection at the moment.
|
||||||
|
///
|
||||||
Stream<NearbyDevice?> getConnectedDeviceStream(NearbyDevice device) {
|
Stream<NearbyDevice?> getConnectedDeviceStream(NearbyDevice device) {
|
||||||
return NearbyServicePlatform.instance.getConnectedDeviceStream(device);
|
return NearbyServicePlatform.instance.getConnectedDeviceStream(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initialization of a platform-specific service.
|
||||||
|
///
|
||||||
|
/// The [initialize] method must be called before calling any
|
||||||
|
/// other getters and methods related to P2P network (all except
|
||||||
|
/// [getPlatformVersion] and [getPlatformModel]).
|
||||||
|
///
|
||||||
Future<bool> initialize({
|
Future<bool> initialize({
|
||||||
NearbyInitializeData data = const NearbyInitializeData(),
|
NearbyInitializeData data = const NearbyInitializeData(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Starts searching for devices using a platform-specific service.
|
||||||
|
///
|
||||||
|
/// Note that the [NearbyIOSService] implementation starts **browsing** or
|
||||||
|
/// **advertising** depending on the [NearbyIOSService.isBrowser].
|
||||||
|
///
|
||||||
Future<bool> discover();
|
Future<bool> discover();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Stops searching for devices using a platform-specific service.
|
||||||
|
///
|
||||||
|
/// Note that the [NearbyIOSService] implementation stops **browsing** or
|
||||||
|
/// **advertising** depending on the [NearbyIOSService.isBrowser].
|
||||||
|
///
|
||||||
Future<bool> stopDiscovery();
|
Future<bool> stopDiscovery();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Connects to passed [device] using a platform-specific service.
|
||||||
|
///
|
||||||
|
/// Note that the [NearbyIOSService] implementation **invites** or
|
||||||
|
/// **accepts invite** depending on the [NearbyIOSService.isBrowser].
|
||||||
|
///
|
||||||
|
/// Note that if [Platform.isIOS] == true, [NearbyIOSDevice] should be passed.
|
||||||
|
/// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed.
|
||||||
|
///
|
||||||
Future<bool> connect(NearbyDevice device);
|
Future<bool> connect(NearbyDevice device);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Disconnects from passed [device] using a platform-specific service.
|
||||||
|
///
|
||||||
|
/// Note that if [Platform.isIOS] == true, [NearbyIOSDevice] should be passed.
|
||||||
|
/// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed.
|
||||||
|
///
|
||||||
Future<bool> disconnect(NearbyDevice device);
|
Future<bool> disconnect(NearbyDevice device);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// If the device is already connected, it does not mean that you can
|
||||||
|
/// send and receive data.
|
||||||
|
///
|
||||||
|
/// There is a separate function for this in [NearbyService] - communication channel.
|
||||||
|
/// You need to call [startCommunicationChannel] before using [send].
|
||||||
|
/// A communication channel can only be created if you are connected to some device.
|
||||||
|
///
|
||||||
|
/// You can monitor changes in communication channel state using the [communicationChannelState] getter.
|
||||||
|
///
|
||||||
FutureOr<bool> startCommunicationChannel(
|
FutureOr<bool> startCommunicationChannel(
|
||||||
NearbyCommunicationChannelData data,
|
NearbyCommunicationChannelData data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// If you called [startCommunicationChannel], remember that you have
|
||||||
|
/// created a subscription to receive messages.
|
||||||
|
///
|
||||||
|
/// Accordingly, it is essential to terminate any subscription.
|
||||||
|
/// Use [endCommunicationChannel] for this purpose.
|
||||||
|
///
|
||||||
FutureOr<bool> endCommunicationChannel();
|
FutureOr<bool> endCommunicationChannel();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Method to send data to the created communication channel.
|
||||||
|
///
|
||||||
FutureOr<bool> send(OutgoingNearbyMessage message);
|
FutureOr<bool> send(OutgoingNearbyMessage message);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NearbyServiceGetterExtension on NearbyService {
|
extension NearbyServiceGetterExtension on NearbyService {
|
||||||
|
///
|
||||||
|
/// If you want to do different actions or get different data
|
||||||
|
/// **depending on the platform**, use [get].
|
||||||
|
///
|
||||||
|
/// * The [onAndroid] callback returns this instance of [NearbyService],
|
||||||
|
/// cast as [NearbyAndroidService] if [Platform.isAndroid] is true.
|
||||||
|
///
|
||||||
|
/// * The [onIOS] callback returns this instance of [NearbyService],
|
||||||
|
/// cast as [NearbyIOSService] if [Platform.isIOS] is true.
|
||||||
|
///
|
||||||
|
/// * The [onAny] callback returns this instance of [NearbyService] with
|
||||||
|
/// no casting if both [Platform.isAndroid] and [Platform.isIOS] are false.
|
||||||
|
///
|
||||||
|
/// **Note: any of the callbacks must not be null!**
|
||||||
|
///
|
||||||
T? get<T>({
|
T? get<T>({
|
||||||
T Function(NearbyAndroidService)? onAndroid,
|
T Function(NearbyAndroidService)? onAndroid,
|
||||||
T Function(NearbyIOSService)? onIOS,
|
T Function(NearbyIOSService)? onIOS,
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ class MethodChannelNearbyService extends NearbyServicePlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<NearbyDevice?> getCurrentDevice() async {
|
Future<NearbyDeviceInfo?> getCurrentDeviceInfo() async {
|
||||||
return NearbyDeviceMapper.instance.mapToDevice(
|
return NearbyDeviceMapper.instance.mapToDevice(
|
||||||
await methodChannel.invokeMethod('getCurrentDevice'),
|
await methodChannel.invokeMethod('getCurrentDevice'),
|
||||||
);
|
)?.info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ abstract class NearbyServicePlatform extends PlatformInterface {
|
|||||||
throw UnimplementedError('getPlatformModel() has not been implemented.');
|
throw UnimplementedError('getPlatformModel() has not been implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<NearbyDevice?> getCurrentDevice() {
|
Future<NearbyDeviceInfo?> getCurrentDeviceInfo() {
|
||||||
throw UnimplementedError('getCurrentDevice() has not been implemented.');
|
throw UnimplementedError('getCurrentDevice() has not been implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
///
|
||||||
|
/// The status of the communication channel for data exchange.
|
||||||
|
/// Use it to determine if you can send data over the communication channel or not.
|
||||||
|
///
|
||||||
|
enum CommunicationChannelState { notConnected, loading, connected }
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
export 'nearby_device.dart';
|
export 'nearby_device.dart';
|
||||||
export 'nearby_device_status.dart';
|
export 'nearby_device_status.dart';
|
||||||
export 'nearby_message.dart';
|
export 'nearby_message.dart';
|
||||||
|
export 'communication_channel_state.dart';
|
||||||
|
|||||||
@@ -1,15 +1,58 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
|
import 'package:nearby_service/src/utils/unknown.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The model of the device found in the P2P network.
|
||||||
|
///
|
||||||
abstract class NearbyDevice {
|
abstract class NearbyDevice {
|
||||||
static const unknown = 'unknown';
|
///
|
||||||
|
/// The base device contains [info] and [status].
|
||||||
|
/// These are parameters that devices will have independent of the platform.
|
||||||
|
///
|
||||||
const NearbyDevice({required this.info, required this.status});
|
const NearbyDevice({required this.info, required this.status});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The minimum information about the device required
|
||||||
|
/// to display it in the list and connect to it.
|
||||||
|
///
|
||||||
final NearbyDeviceInfo info;
|
final NearbyDeviceInfo info;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The connection status of the device.
|
||||||
|
///
|
||||||
final NearbyDeviceStatus status;
|
final NearbyDeviceStatus status;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is NearbyDevice &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
info == other.info &&
|
||||||
|
status == other.status;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => info.hashCode ^ status.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyDevice{info: $info, status: $status}';
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// If you want to get different data
|
||||||
|
/// **depending on the platform**, use [byPlatform].
|
||||||
|
///
|
||||||
|
/// * The [onAndroid] callback returns this instance of [NearbyDevice],
|
||||||
|
/// cast as [NearbyAndroidDevice] if [Platform.isAndroid] is true.
|
||||||
|
///
|
||||||
|
/// * The [onIOS] callback returns this instance of [NearbyDevice],
|
||||||
|
/// cast as [NearbyIOSDevice] if [Platform.isIOS] is true.
|
||||||
|
///
|
||||||
|
/// * The [onAny] callback returns this instance of [NearbyDevice] with
|
||||||
|
/// no casting if both [Platform.isAndroid] and [Platform.isIOS] are false.
|
||||||
|
///
|
||||||
T? byPlatform<T>({
|
T? byPlatform<T>({
|
||||||
T Function(NearbyDevice)? onAny,
|
T Function(NearbyDevice)? onAny,
|
||||||
T Function(NearbyAndroidDevice)? onAndroid,
|
T Function(NearbyAndroidDevice)? onAndroid,
|
||||||
@@ -25,7 +68,13 @@ abstract class NearbyDevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Converter for devices from JSON to models.
|
||||||
|
///
|
||||||
abstract interface class NearbyDeviceMapper {
|
abstract interface class NearbyDeviceMapper {
|
||||||
|
///
|
||||||
|
/// Get the mapper instance for the current platform.
|
||||||
|
///
|
||||||
static NearbyDeviceMapper get instance {
|
static NearbyDeviceMapper get instance {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
return NearbyAndroidMapper();
|
return NearbyAndroidMapper();
|
||||||
@@ -39,27 +88,59 @@ abstract interface class NearbyDeviceMapper {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Converts JSON to a list of [NearbyDevice].
|
||||||
|
///
|
||||||
List<NearbyDevice> mapToDeviceList(dynamic value);
|
List<NearbyDevice> mapToDeviceList(dynamic value);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Converts JSON to a [NearbyDevice].
|
||||||
|
///
|
||||||
NearbyDevice? mapToDevice(dynamic value);
|
NearbyDevice? mapToDevice(dynamic value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Minimal information about the device.
|
||||||
|
///
|
||||||
class NearbyDeviceInfo {
|
class NearbyDeviceInfo {
|
||||||
|
///
|
||||||
|
/// Used to connect to the device via [id].
|
||||||
|
/// Depending on the platform, [id] means different parameters.
|
||||||
|
///
|
||||||
|
/// * For Android [id] is the MAC address of the device.
|
||||||
|
/// * For IOS [id] is the [MCPeerID](https://developer.apple.com/documentation/multipeerconnectivity/mcpeerid) passed from the IOS platform.
|
||||||
|
///
|
||||||
const NearbyDeviceInfo({
|
const NearbyDeviceInfo({
|
||||||
required this.displayName,
|
required this.displayName,
|
||||||
required this.id,
|
required this.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get [NearbyDeviceInfo] from [Map].
|
||||||
|
///
|
||||||
factory NearbyDeviceInfo.fromJson(Map<String, dynamic>? json) {
|
factory NearbyDeviceInfo.fromJson(Map<String, dynamic>? json) {
|
||||||
return NearbyDeviceInfo(
|
return NearbyDeviceInfo(
|
||||||
displayName: json?['displayName'] ?? NearbyDevice.unknown,
|
displayName: json?['displayName'] ?? kNearbyUnknown,
|
||||||
id: json?['id'] ?? NearbyDevice.unknown,
|
id: json?['id'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The name of the device in the context of a P2P network.
|
||||||
|
///
|
||||||
final String displayName;
|
final String displayName;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Depending on the platform, [id] means different parameters.
|
||||||
|
///
|
||||||
|
/// * For Android [id] is the MAC address of the device.
|
||||||
|
/// * For IOS [id] is the [MCPeerID](https://developer.apple.com/documentation/multipeerconnectivity/mcpeerid) passed from the IOS platform.
|
||||||
|
///
|
||||||
final String id;
|
final String id;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get [Map] from [NearbyDeviceInfo].
|
||||||
|
///
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'id': id,
|
'id': id,
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
///
|
||||||
|
/// Status of device connection.
|
||||||
|
///
|
||||||
enum NearbyDeviceStatus {
|
enum NearbyDeviceStatus {
|
||||||
available,
|
available,
|
||||||
connected,
|
connected,
|
||||||
@@ -5,8 +8,36 @@ enum NearbyDeviceStatus {
|
|||||||
connecting,
|
connecting,
|
||||||
unavailable;
|
unavailable;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if status is [NearbyDeviceStatus.connected]
|
||||||
|
///
|
||||||
bool get isConnected => this == NearbyDeviceStatus.connected;
|
bool get isConnected => this == NearbyDeviceStatus.connected;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if status is [NearbyDeviceStatus.available]
|
||||||
|
///
|
||||||
|
bool get isAvailable => this == NearbyDeviceStatus.available;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if status is [NearbyDeviceStatus.failed]
|
||||||
|
///
|
||||||
|
bool get isFailed => this == NearbyDeviceStatus.failed;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if status is [NearbyDeviceStatus.connecting]
|
||||||
|
///
|
||||||
|
bool get isConnecting => this == NearbyDeviceStatus.connecting;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if status is [NearbyDeviceStatus.unavailable]
|
||||||
|
///
|
||||||
|
bool get isUnavailable => this == NearbyDeviceStatus.unavailable;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get [NearbyDeviceStatus] from the Android platform code.
|
||||||
|
///
|
||||||
|
/// You can read about it on the [Android developer site](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice#constants_1).
|
||||||
|
///
|
||||||
static NearbyDeviceStatus fromAndroidCode(num? code) {
|
static NearbyDeviceStatus fromAndroidCode(num? code) {
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
return NearbyDeviceStatus.failed;
|
return NearbyDeviceStatus.failed;
|
||||||
@@ -21,6 +52,11 @@ enum NearbyDeviceStatus {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get [NearbyDeviceStatus] from the IOS platform code.
|
||||||
|
///
|
||||||
|
/// You can read about it on the [IOS developer site](https://developer.apple.com/documentation/multipeerconnectivity/mcsessionstate).
|
||||||
|
///
|
||||||
static NearbyDeviceStatus fromIosCode(String? code) {
|
static NearbyDeviceStatus fromIosCode(String? code) {
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
return NearbyDeviceStatus.failed;
|
return NearbyDeviceStatus.failed;
|
||||||
|
|||||||
@@ -1,18 +1,54 @@
|
|||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
import 'package:nearby_service/src/utils/logger.dart';
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Basic Message Abstraction.
|
||||||
|
///
|
||||||
abstract class NearbyMessage {
|
abstract class NearbyMessage {
|
||||||
|
///
|
||||||
|
/// The basic message contains only [value] - the content
|
||||||
|
/// to be sent or received.
|
||||||
|
///
|
||||||
const NearbyMessage({required this.value});
|
const NearbyMessage({required this.value});
|
||||||
|
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is NearbyMessage &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
value == other.value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => value.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyMessage{value: $value}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The message that will be sent from the current device.
|
||||||
|
///
|
||||||
class OutgoingNearbyMessage extends NearbyMessage {
|
class OutgoingNearbyMessage extends NearbyMessage {
|
||||||
|
///
|
||||||
|
/// To send a message, in addition to [value], you need to pass [receiver]
|
||||||
|
/// to know to whom the message is addressed.
|
||||||
|
///
|
||||||
const OutgoingNearbyMessage({
|
const OutgoingNearbyMessage({
|
||||||
required super.value,
|
required super.value,
|
||||||
required this.receiver,
|
required this.receiver,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Data of the user to whom the message is addressed.
|
||||||
|
///
|
||||||
|
final NearbyDeviceInfo receiver;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get [Map] from [OutgoingNearbyMessage].
|
||||||
|
///
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'message': value,
|
'message': value,
|
||||||
@@ -20,26 +56,59 @@ class OutgoingNearbyMessage extends NearbyMessage {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
final NearbyDeviceInfo receiver;
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
super == other &&
|
||||||
|
other is OutgoingNearbyMessage &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
receiver == other.receiver;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => super.hashCode ^ receiver.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Message received by the current device.
|
||||||
|
///
|
||||||
class ReceivedNearbyMessage extends NearbyMessage {
|
class ReceivedNearbyMessage extends NearbyMessage {
|
||||||
|
///
|
||||||
|
/// The received message contains a [sender] in addition to [value],
|
||||||
|
/// to know from whom the message came.
|
||||||
|
///
|
||||||
const ReceivedNearbyMessage({
|
const ReceivedNearbyMessage({
|
||||||
required super.value,
|
required super.value,
|
||||||
required this.sender,
|
required this.sender,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Get [ReceivedNearbyMessage] from [Map].
|
||||||
|
///
|
||||||
factory ReceivedNearbyMessage.fromJson(Map<String, dynamic>? json) {
|
factory ReceivedNearbyMessage.fromJson(Map<String, dynamic>? json) {
|
||||||
try {
|
return ReceivedNearbyMessage(
|
||||||
return ReceivedNearbyMessage(
|
value: json?['message'] ?? '',
|
||||||
value: json?['message'] ?? '',
|
sender: NearbyDeviceInfo.fromJson(json?['sender']),
|
||||||
sender: NearbyDeviceInfo.fromJson(json?['sender']),
|
);
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
Logger.error(e);
|
|
||||||
throw NearbyServiceException('Can\'t map to device $json');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Data of the user from whom the message came.
|
||||||
|
///
|
||||||
final NearbyDeviceInfo sender;
|
final NearbyDeviceInfo sender;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
super == other &&
|
||||||
|
other is ReceivedNearbyMessage &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
sender == other.sender;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => super.hashCode ^ sender.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ReceivedNearbyMessage{sender: $sender}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,83 @@
|
|||||||
import 'dart:convert';
|
import 'package:nearby_service/src/utils/json_decoder.dart';
|
||||||
|
import 'package:nearby_service/src/utils/unknown.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The class representing the connection information
|
||||||
|
/// of a Wi-Fi p2p group connection for Android.
|
||||||
|
///
|
||||||
class NearbyConnectionAndroidInfo {
|
class NearbyConnectionAndroidInfo {
|
||||||
static const unknown = 'unknown';
|
///
|
||||||
|
/// The class representing the Android class
|
||||||
|
/// [WifiP2pInfo](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo).
|
||||||
|
///
|
||||||
const NearbyConnectionAndroidInfo({
|
const NearbyConnectionAndroidInfo({
|
||||||
required this.ownerIpAddress,
|
required this.ownerIpAddress,
|
||||||
required this.groupFormed,
|
required this.groupFormed,
|
||||||
required this.isGroupOwner,
|
required this.isGroupOwner,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory NearbyConnectionAndroidInfo.fromJson(Map<String, dynamic> json) {
|
///
|
||||||
final ownerIpAddress = (json['groupOwnerAddress'] ?? unknown) as String;
|
/// Get [NearbyConnectionAndroidInfo] from [Map].
|
||||||
|
///
|
||||||
|
factory NearbyConnectionAndroidInfo.fromJson(Map<String, dynamic>? json) {
|
||||||
|
final ownerIpAddress =
|
||||||
|
(json?['groupOwnerAddress'] ?? kNearbyUnknown) as String;
|
||||||
return NearbyConnectionAndroidInfo(
|
return NearbyConnectionAndroidInfo(
|
||||||
ownerIpAddress: ownerIpAddress.replaceFirst('/', ''),
|
ownerIpAddress: ownerIpAddress.replaceFirst('/', ''),
|
||||||
groupFormed: json['groupFormed'] ?? false,
|
groupFormed: json?['groupFormed'] ?? false,
|
||||||
isGroupOwner: json['isGroupOwner'] ?? false,
|
isGroupOwner: json?['isGroupOwner'] ?? false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Group owner address.
|
||||||
|
/// Source [WifiP2pInfo documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo)
|
||||||
|
///
|
||||||
final String ownerIpAddress;
|
final String ownerIpAddress;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Indicates if the current device is the group owner.
|
||||||
|
/// Source [WifiP2pInfo documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo)
|
||||||
|
///
|
||||||
final bool isGroupOwner;
|
final bool isGroupOwner;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Indicates if the current device is the group owner.
|
||||||
|
/// Source [WifiP2pInfo documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pInfo)
|
||||||
|
///
|
||||||
final bool groupFormed;
|
final bool groupFormed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is NearbyConnectionAndroidInfo &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
ownerIpAddress == other.ownerIpAddress &&
|
||||||
|
isGroupOwner == other.isGroupOwner &&
|
||||||
|
groupFormed == other.groupFormed;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
ownerIpAddress.hashCode ^ isGroupOwner.hashCode ^ groupFormed.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyConnectionAndroidInfo{ownerIpAddress: $ownerIpAddress, isGroupOwner: $isGroupOwner, groupFormed: $groupFormed}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mapper from JSON to [NearbyConnectionAndroidInfo]
|
||||||
class NearbyConnectionInfoMapper {
|
class NearbyConnectionInfoMapper {
|
||||||
NearbyConnectionInfoMapper._();
|
NearbyConnectionInfoMapper._();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Converts JSON to a [NearbyConnectionAndroidInfo].
|
||||||
|
///
|
||||||
static NearbyConnectionAndroidInfo? mapToInfo(dynamic value) {
|
static NearbyConnectionAndroidInfo? mapToInfo(dynamic value) {
|
||||||
final jsonValue = jsonDecode(value) as Map<String, dynamic>?;
|
if (value == null) {
|
||||||
if (jsonValue == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return NearbyConnectionAndroidInfo.fromJson(jsonValue);
|
final decoded = JSONDecoder.decodeMap(value);
|
||||||
|
return NearbyConnectionAndroidInfo.fromJson(decoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,21 @@
|
|||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
import 'package:nearby_service/src/utils/decoder.dart';
|
import 'package:nearby_service/src/utils/json_decoder.dart';
|
||||||
|
import 'package:nearby_service/src/utils/unknown.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A device on a P2P network obtained from the Android platform.
|
||||||
|
///
|
||||||
class NearbyAndroidDevice extends NearbyDevice {
|
class NearbyAndroidDevice extends NearbyDevice {
|
||||||
|
///
|
||||||
|
/// The class representing the Android class
|
||||||
|
/// [WifiP2pDevice](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice).
|
||||||
|
///
|
||||||
|
/// Automatically generates the [info] field from the [deviceName]
|
||||||
|
/// and [deviceAddress] fields.
|
||||||
|
///
|
||||||
|
/// They are used because in a Wifi Direct environment
|
||||||
|
/// the MAC address of the device is an identifier on the network.
|
||||||
|
///
|
||||||
NearbyAndroidDevice({
|
NearbyAndroidDevice({
|
||||||
required String deviceName,
|
required String deviceName,
|
||||||
required super.status,
|
required super.status,
|
||||||
@@ -20,13 +34,16 @@ class NearbyAndroidDevice extends NearbyDevice {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets [NearbyAndroidDevice] from [Map]
|
||||||
|
///
|
||||||
factory NearbyAndroidDevice.fromJson(Map<String, dynamic>? json) {
|
factory NearbyAndroidDevice.fromJson(Map<String, dynamic>? json) {
|
||||||
return NearbyAndroidDevice(
|
return NearbyAndroidDevice(
|
||||||
deviceName: json?['deviceName'] ?? NearbyDevice.unknown,
|
deviceName: json?['deviceName'] ?? kNearbyUnknown,
|
||||||
deviceAddress: json?['deviceAddress'] ?? NearbyDevice.unknown,
|
deviceAddress: json?['deviceAddress'] ?? kNearbyUnknown,
|
||||||
isGroupOwner: json?['isGroupOwner'] ?? false,
|
isGroupOwner: json?['isGroupOwner'] ?? false,
|
||||||
isServiceDiscoveryCapable: json?['isServiceDiscoveryCapable'] ?? false,
|
isServiceDiscoveryCapable: json?['isServiceDiscoveryCapable'] ?? false,
|
||||||
primaryDeviceType: json?['primaryDeviceType'] ?? NearbyDevice.unknown,
|
primaryDeviceType: json?['primaryDeviceType'] ?? kNearbyUnknown,
|
||||||
secondaryDeviceType: json?['secondaryDeviceType'],
|
secondaryDeviceType: json?['secondaryDeviceType'],
|
||||||
wpsDisplaySupported: json?['wpsDisplaySupported'] ?? false,
|
wpsDisplaySupported: json?['wpsDisplaySupported'] ?? false,
|
||||||
wpsKeypadSupported: json?['wpsKeypadSupported'] ?? false,
|
wpsKeypadSupported: json?['wpsKeypadSupported'] ?? false,
|
||||||
@@ -35,20 +52,92 @@ class NearbyAndroidDevice extends NearbyDevice {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The device MAC address uniquely identifies a Wi-Fi p2p device.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final String deviceAddress;
|
final String deviceAddress;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// True if the device is a group owner.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final bool isGroupOwner;
|
final bool isGroupOwner;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// True if the device is capable of service discovery.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final bool isServiceDiscoveryCapable;
|
final bool isServiceDiscoveryCapable;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Primary device type identifies the type of device.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final String primaryDeviceType;
|
final String primaryDeviceType;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Secondary device type is an optional attribute.
|
||||||
|
/// that can be provided by a device in addition to the primary device type.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final String? secondaryDeviceType;
|
final String? secondaryDeviceType;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// True if WPS keypad configuration is supported.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final bool wpsKeypadSupported;
|
final bool wpsKeypadSupported;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// True if WPS push button configuration is supported.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final bool wpsPbcSupported;
|
final bool wpsPbcSupported;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// True if WPS display configuration is supported.
|
||||||
|
/// Source [WifiP2pDevice documentation](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pDevice)
|
||||||
|
///
|
||||||
final bool wpsDisplaySupported;
|
final bool wpsDisplaySupported;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
super == other &&
|
||||||
|
other is NearbyAndroidDevice &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
deviceAddress == other.deviceAddress &&
|
||||||
|
isGroupOwner == other.isGroupOwner &&
|
||||||
|
isServiceDiscoveryCapable == other.isServiceDiscoveryCapable &&
|
||||||
|
primaryDeviceType == other.primaryDeviceType &&
|
||||||
|
secondaryDeviceType == other.secondaryDeviceType &&
|
||||||
|
wpsKeypadSupported == other.wpsKeypadSupported &&
|
||||||
|
wpsPbcSupported == other.wpsPbcSupported &&
|
||||||
|
wpsDisplaySupported == other.wpsDisplaySupported;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
super.hashCode ^
|
||||||
|
deviceAddress.hashCode ^
|
||||||
|
isGroupOwner.hashCode ^
|
||||||
|
isServiceDiscoveryCapable.hashCode ^
|
||||||
|
primaryDeviceType.hashCode ^
|
||||||
|
secondaryDeviceType.hashCode ^
|
||||||
|
wpsKeypadSupported.hashCode ^
|
||||||
|
wpsPbcSupported.hashCode ^
|
||||||
|
wpsDisplaySupported.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyAndroidDevice{deviceAddress: $deviceAddress, isGroupOwner: $isGroupOwner, isServiceDiscoveryCapable: $isServiceDiscoveryCapable, primaryDeviceType: $primaryDeviceType, secondaryDeviceType: $secondaryDeviceType, wpsKeypadSupported: $wpsKeypadSupported, wpsPbcSupported: $wpsPbcSupported, wpsDisplaySupported: $wpsDisplaySupported}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NearbyAndroidMapper implements NearbyDeviceMapper {
|
class NearbyAndroidMapper implements NearbyDeviceMapper {
|
||||||
@override
|
@override
|
||||||
List<NearbyDevice> mapToDeviceList(dynamic value) {
|
List<NearbyDevice> mapToDeviceList(dynamic value) {
|
||||||
final decoded = Decoder.decodeList(value);
|
final decoded = JSONDecoder.decodeList(value);
|
||||||
return [
|
return [
|
||||||
...?decoded?.map(
|
...?decoded?.map(
|
||||||
(e) => NearbyAndroidDevice.fromJson(e as Map<String, dynamic>?),
|
(e) => NearbyAndroidDevice.fromJson(e as Map<String, dynamic>?),
|
||||||
@@ -58,6 +147,6 @@ class NearbyAndroidMapper implements NearbyDeviceMapper {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
NearbyDevice? mapToDevice(dynamic value) {
|
NearbyDevice? mapToDevice(dynamic value) {
|
||||||
return NearbyAndroidDevice.fromJson(Decoder.decodeMap(value));
|
return NearbyAndroidDevice.fromJson(JSONDecoder.decodeMap(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,30 @@ import 'package:nearby_service/nearby_service.dart';
|
|||||||
|
|
||||||
import 'socket_service/nearby_socket_service.dart';
|
import 'socket_service/nearby_socket_service.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Android implementation for [NearbyService].
|
||||||
|
///
|
||||||
|
/// Uses [NearbyServiceAndroidPlatform] to perform actions.
|
||||||
|
/// Connects to the device via a socket from [NearbySocketService].
|
||||||
|
///
|
||||||
class NearbyAndroidService extends NearbyService {
|
class NearbyAndroidService extends NearbyService {
|
||||||
late final _socketService = NearbySocketService(this);
|
late final _socketService = NearbySocketService(this);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ValueListenable<bool> get isCommunicationChannelConnecting {
|
ValueListenable<CommunicationChannelState> get communicationChannelState {
|
||||||
return _socketService.isConnecting;
|
return _socketService.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
NearbyConnectionAndroidInfo? get connectionInfo {
|
NearbyConnectionAndroidInfo? get connectionInfo {
|
||||||
return _socketService.connectionInfo;
|
return _socketService.connectionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initializes Android [WifiP2PManager](https://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager)
|
||||||
|
///
|
||||||
|
/// Starts listening for changes to the P2P network.
|
||||||
|
/// Adds platform-level action listeners.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> initialize({
|
Future<bool> initialize({
|
||||||
NearbyInitializeData data = const NearbyInitializeData(),
|
NearbyInitializeData data = const NearbyInitializeData(),
|
||||||
@@ -24,40 +36,48 @@ class NearbyAndroidService extends NearbyService {
|
|||||||
return NearbyServiceAndroidPlatform.instance.initialize();
|
return NearbyServiceAndroidPlatform.instance.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Starts discovery of the Wifi Direct network.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> discover() {
|
Future<bool> discover() {
|
||||||
return NearbyServiceAndroidPlatform.instance.discover();
|
return NearbyServiceAndroidPlatform.instance.discover();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Stops discovery of the Wifi Direct network.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> stopDiscovery() {
|
Future<bool> stopDiscovery() {
|
||||||
return NearbyServiceAndroidPlatform.instance.stopDiscovery();
|
return NearbyServiceAndroidPlatform.instance.stopDiscovery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Connects to the [device] on the Wifi Direct network.
|
||||||
|
///
|
||||||
|
/// Note! Requires [NearbyAndroidDevice] to be passed.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> connect(NearbyDevice device) {
|
Future<bool> connect(NearbyDevice device) {
|
||||||
_requireAndroidDevice(device);
|
_requireAndroidDevice(device);
|
||||||
return NearbyServiceAndroidPlatform.instance.connect(device.info.id);
|
return NearbyServiceAndroidPlatform.instance.connect(device.info.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Disconnects from the [device] on the Wifi Direct network.
|
||||||
|
///
|
||||||
|
/// Note! Requires [NearbyAndroidDevice] to be passed.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> disconnect(NearbyDevice device) {
|
Future<bool> disconnect(NearbyDevice device) {
|
||||||
_requireAndroidDevice(device);
|
_requireAndroidDevice(device);
|
||||||
return NearbyServiceAndroidPlatform.instance.disconnect(device.info.id);
|
return NearbyServiceAndroidPlatform.instance.disconnect(device.info.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> requestPermissions() {
|
///
|
||||||
return NearbyServiceAndroidPlatform.instance.requestPermissions();
|
/// Starts a socket service to transfer data. Uses device with
|
||||||
}
|
/// [NearbyCommunicationChannelData.connectedDeviceId].
|
||||||
|
///
|
||||||
Future<bool> checkWifiService() {
|
|
||||||
return NearbyServiceAndroidPlatform.instance.checkWifiService();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<NearbyConnectionAndroidInfo?> getConnectionInfo() {
|
|
||||||
return NearbyServiceAndroidPlatform.instance.getConnectionInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> startCommunicationChannel(
|
FutureOr<bool> startCommunicationChannel(
|
||||||
NearbyCommunicationChannelData data,
|
NearbyCommunicationChannelData data,
|
||||||
@@ -65,16 +85,51 @@ class NearbyAndroidService extends NearbyService {
|
|||||||
return _socketService.startSocket(data: data);
|
return _socketService.startSocket(data: data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Ends the socket service to stop transferring data.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> endCommunicationChannel() {
|
FutureOr<bool> endCommunicationChannel() {
|
||||||
return _socketService.cancel();
|
return _socketService.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Adds [OutgoingNearbyMessage] to the socket.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> send(OutgoingNearbyMessage message) {
|
FutureOr<bool> send(OutgoingNearbyMessage message) {
|
||||||
return _socketService.send(message);
|
return _socketService.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Request permissions at the platform level.
|
||||||
|
/// **This is required for Android for using the plugin!**
|
||||||
|
///
|
||||||
|
/// For Android APIs less 33 requests `ACCESS_FINE_LOCATION` permission.
|
||||||
|
///
|
||||||
|
/// For Android APIs equal to 33 or more, requests `ACCESS_FINE_LOCATION`
|
||||||
|
/// and `NEARBY_WIFI_DEVICES` permissions.
|
||||||
|
///
|
||||||
|
Future<bool> requestPermissions() {
|
||||||
|
return NearbyServiceAndroidPlatform.instance.requestPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Checks if Wi-fi is enabled.
|
||||||
|
/// **Wi-fi must be enabled for Android to use the plugin!**
|
||||||
|
///
|
||||||
|
Future<bool> checkWifiService() {
|
||||||
|
return NearbyServiceAndroidPlatform.instance.checkWifiService();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns [NearbyConnectionAndroidInfo] -
|
||||||
|
/// information about the connection information.
|
||||||
|
///
|
||||||
|
Future<NearbyConnectionAndroidInfo?> getConnectionInfo() {
|
||||||
|
return NearbyServiceAndroidPlatform.instance.getConnectionInfo();
|
||||||
|
}
|
||||||
|
|
||||||
void _requireAndroidDevice(NearbyDevice device) {
|
void _requireAndroidDevice(NearbyDevice device) {
|
||||||
assert(
|
assert(
|
||||||
device is NearbyAndroidDevice,
|
device is NearbyAndroidDevice,
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ part 'ping_manager.dart';
|
|||||||
|
|
||||||
part 'network.dart';
|
part 'network.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A service for creating a communication channel on the Android platform.
|
||||||
|
///
|
||||||
class NearbySocketService {
|
class NearbySocketService {
|
||||||
NearbySocketService(this._manager);
|
NearbySocketService(this._manager);
|
||||||
|
|
||||||
@@ -19,17 +22,27 @@ class NearbySocketService {
|
|||||||
final _pingManager = NearbySocketPingManager();
|
final _pingManager = NearbySocketPingManager();
|
||||||
final _network = NearbyServiceNetwork();
|
final _network = NearbyServiceNetwork();
|
||||||
|
|
||||||
final isConnecting = ValueNotifier(false);
|
final state = ValueNotifier(CommunicationChannelState.notConnected);
|
||||||
NearbyConnectionAndroidInfo? connectionInfo;
|
NearbyConnectionAndroidInfo? connectionInfo;
|
||||||
|
|
||||||
String? _connectedDeviceId;
|
String? _connectedDeviceId;
|
||||||
WebSocket? _socket;
|
WebSocket? _socket;
|
||||||
StreamSubscription<ReceivedNearbyMessage>? _messagesSubscription;
|
StreamSubscription<ReceivedNearbyMessage>? _messagesSubscription;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Start a socket with the user's role defined.
|
||||||
|
/// If he is the owner of the group, he becomes a server.
|
||||||
|
/// Otherwise, he becomes a client.
|
||||||
|
///
|
||||||
|
/// * The server starts up and waits for a request from the
|
||||||
|
/// client to establish a connection.
|
||||||
|
/// * The client pings the server until he receives a pong.
|
||||||
|
/// When he does, he tries to connect to the server.
|
||||||
|
///
|
||||||
Future<bool> startSocket({
|
Future<bool> startSocket({
|
||||||
required NearbyCommunicationChannelData data,
|
required NearbyCommunicationChannelData data,
|
||||||
}) async {
|
}) async {
|
||||||
isConnecting.value = true;
|
state.value = CommunicationChannelState.loading;
|
||||||
_connectedDeviceId = data.connectedDeviceId;
|
_connectedDeviceId = data.connectedDeviceId;
|
||||||
connectionInfo = await _manager.getConnectionInfo();
|
connectionInfo = await _manager.getConnectionInfo();
|
||||||
if (connectionInfo != null && connectionInfo!.groupFormed) {
|
if (connectionInfo != null && connectionInfo!.groupFormed) {
|
||||||
@@ -55,15 +68,18 @@ class NearbySocketService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Add [OutgoingNearbyMessage]'s JSON representation to [_socket].
|
||||||
|
///
|
||||||
Future<bool> send(OutgoingNearbyMessage message) async {
|
Future<bool> send(OutgoingNearbyMessage message) async {
|
||||||
if (_socket != null && message.receiver.id == _connectedDeviceId) {
|
if (_socket != null && message.receiver.id == _connectedDeviceId) {
|
||||||
final sender = await _manager.getCurrentDevice();
|
final sender = await _manager.getCurrentDeviceInfo();
|
||||||
if (sender != null) {
|
if (sender != null) {
|
||||||
_socket!.add(
|
_socket!.add(
|
||||||
jsonEncode(
|
jsonEncode(
|
||||||
{
|
{
|
||||||
'message': message.value,
|
'message': message.value,
|
||||||
'sender': sender.info.toJson(),
|
'sender': sender.toJson(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -73,9 +89,11 @@ class NearbySocketService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Turns off [_messagesSubscription] and [_socket].
|
||||||
|
///
|
||||||
Future<bool> cancel() async {
|
Future<bool> cancel() async {
|
||||||
try {
|
try {
|
||||||
isConnecting.value = false;
|
|
||||||
await _messagesSubscription?.cancel();
|
await _messagesSubscription?.cancel();
|
||||||
_messagesSubscription = null;
|
_messagesSubscription = null;
|
||||||
_socket = null;
|
_socket = null;
|
||||||
@@ -153,7 +171,7 @@ class NearbySocketService {
|
|||||||
|
|
||||||
void _createSocketSubscription(NearbyServiceStreamListener socketListener) {
|
void _createSocketSubscription(NearbyServiceStreamListener socketListener) {
|
||||||
Logger.debug('Starting socket subscription');
|
Logger.debug('Starting socket subscription');
|
||||||
isConnecting.value = false;
|
|
||||||
if (_connectedDeviceId != null) {
|
if (_connectedDeviceId != null) {
|
||||||
_messagesSubscription = _socket
|
_messagesSubscription = _socket
|
||||||
?.map(MessagesStreamMapper.toMessage)
|
?.map(MessagesStreamMapper.toMessage)
|
||||||
@@ -162,17 +180,24 @@ class NearbySocketService {
|
|||||||
.map((e) => MessagesStreamMapper.replaceId(e, _connectedDeviceId!))
|
.map((e) => MessagesStreamMapper.replaceId(e, _connectedDeviceId!))
|
||||||
.listen(
|
.listen(
|
||||||
socketListener.onData,
|
socketListener.onData,
|
||||||
onDone: socketListener.onDone,
|
onDone: () {
|
||||||
|
state.value = CommunicationChannelState.notConnected;
|
||||||
|
socketListener.onDone?.call();
|
||||||
|
},
|
||||||
onError: (e, s) {
|
onError: (e, s) {
|
||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
|
state.value = CommunicationChannelState.notConnected;
|
||||||
socketListener.onError?.call(e, s);
|
socketListener.onError?.call(e, s);
|
||||||
},
|
},
|
||||||
cancelOnError: socketListener.cancelOnError,
|
cancelOnError: socketListener.cancelOnError,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (_messagesSubscription != null) {
|
if (_messagesSubscription != null) {
|
||||||
|
state.value = CommunicationChannelState.connected;
|
||||||
Logger.info('Socket subscription was created successfully');
|
Logger.info('Socket subscription was created successfully');
|
||||||
socketListener.onCreated?.call(_messagesSubscription!);
|
socketListener.onCreated?.call(_messagesSubscription!);
|
||||||
|
} else {
|
||||||
|
state.value = CommunicationChannelState.notConnected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,18 @@
|
|||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
import 'package:nearby_service/src/utils/decoder.dart';
|
import 'package:nearby_service/src/utils/json_decoder.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A device on a P2P network obtained from the IOS platform.
|
||||||
|
///
|
||||||
class NearbyIOSDevice extends NearbyDevice {
|
class NearbyIOSDevice extends NearbyDevice {
|
||||||
|
///
|
||||||
|
/// A class representing an IOS device on a P2P network.
|
||||||
|
///
|
||||||
|
/// [NearbyDeviceInfo] for IOS consists of the [MCPeerID](https://developer.apple.com/documentation/multipeerconnectivity/mcpeerid) passed from the platform
|
||||||
|
/// and a displayName passed from the platform.
|
||||||
|
///
|
||||||
|
/// [MCPeerID](https://developer.apple.com/documentation/multipeerconnectivity/mcpeerid) is an identifier on the local network for IOS.
|
||||||
|
///
|
||||||
NearbyIOSDevice({
|
NearbyIOSDevice({
|
||||||
required super.info,
|
required super.info,
|
||||||
required super.status,
|
required super.status,
|
||||||
@@ -10,6 +21,9 @@ class NearbyIOSDevice extends NearbyDevice {
|
|||||||
this.deviceType,
|
this.deviceType,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Gets [NearbyIOSDevice] from [Map].
|
||||||
|
///
|
||||||
factory NearbyIOSDevice.fromJson(Map<String, dynamic>? json) {
|
factory NearbyIOSDevice.fromJson(Map<String, dynamic>? json) {
|
||||||
return NearbyIOSDevice(
|
return NearbyIOSDevice(
|
||||||
info: NearbyDeviceInfo.fromJson(json),
|
info: NearbyDeviceInfo.fromJson(json),
|
||||||
@@ -20,15 +34,45 @@ class NearbyIOSDevice extends NearbyDevice {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// `UIDevice.current.systemName` from IOS Platform.
|
||||||
|
///
|
||||||
final String? os;
|
final String? os;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// `UIDevice.current.systemVersion` from IOS Platform.
|
||||||
|
///
|
||||||
final String? osVersion;
|
final String? osVersion;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// `UIDevice.current.model` from IOS Platform.
|
||||||
|
///
|
||||||
final String? deviceType;
|
final String? deviceType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
super == other &&
|
||||||
|
other is NearbyIOSDevice &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
os == other.os &&
|
||||||
|
osVersion == other.osVersion &&
|
||||||
|
deviceType == other.deviceType;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
super.hashCode ^ os.hashCode ^ osVersion.hashCode ^ deviceType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyIOSDevice{os: $os, osVersion: $osVersion, deviceType: $deviceType}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NearbyIOSMapper implements NearbyDeviceMapper {
|
class NearbyIOSMapper implements NearbyDeviceMapper {
|
||||||
@override
|
@override
|
||||||
List<NearbyDevice> mapToDeviceList(dynamic value) {
|
List<NearbyDevice> mapToDeviceList(dynamic value) {
|
||||||
final decoded = Decoder.decodeList(value);
|
final decoded = JSONDecoder.decodeList(value);
|
||||||
return [
|
return [
|
||||||
...?decoded?.map(
|
...?decoded?.map(
|
||||||
(e) => NearbyIOSDevice.fromJson(e as Map<String, dynamic>?),
|
(e) => NearbyIOSDevice.fromJson(e as Map<String, dynamic>?),
|
||||||
@@ -39,7 +83,7 @@ class NearbyIOSMapper implements NearbyDeviceMapper {
|
|||||||
@override
|
@override
|
||||||
NearbyDevice? mapToDevice(dynamic value) {
|
NearbyDevice? mapToDevice(dynamic value) {
|
||||||
return NearbyIOSDevice.fromJson(
|
return NearbyIOSDevice.fromJson(
|
||||||
Decoder.decodeMap(value),
|
JSONDecoder.decodeMap(value),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,22 +5,54 @@ import 'package:nearby_service/nearby_service.dart';
|
|||||||
import 'package:nearby_service/src/utils/logger.dart';
|
import 'package:nearby_service/src/utils/logger.dart';
|
||||||
import 'package:nearby_service/src/utils/stream_mapper.dart';
|
import 'package:nearby_service/src/utils/stream_mapper.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// IOS implementation for [NearbyService].
|
||||||
|
///
|
||||||
|
/// Uses [NearbyServiceIOSPlatform] to perform actions.
|
||||||
|
/// Connects to the device by subscribing to messages from the selected
|
||||||
|
/// device by identifier.
|
||||||
|
///
|
||||||
class NearbyIOSService extends NearbyService {
|
class NearbyIOSService extends NearbyService {
|
||||||
final _isBrowser = ValueNotifier<bool>(true);
|
final _isBrowser = ValueNotifier<bool>(true);
|
||||||
final _isCommunicationChannelConnecting = ValueNotifier<bool>(false);
|
final _state = ValueNotifier(CommunicationChannelState.notConnected);
|
||||||
|
|
||||||
StreamSubscription<ReceivedNearbyMessage>? _messagesSubscription;
|
StreamSubscription<ReceivedNearbyMessage>? _messagesSubscription;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ValueListenable<bool> get isCommunicationChannelConnecting =>
|
ValueListenable<CommunicationChannelState> get communicationChannelState =>
|
||||||
_isCommunicationChannelConnecting;
|
_state;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Determines whether the current device is a **Browser** or **Advertiser**.
|
||||||
|
///
|
||||||
|
/// * Browser will only see devices with Advertiser status in the peers list.
|
||||||
|
/// Browser sends connection requests.
|
||||||
|
/// * Advertiser will see in the peers list only devices with Browser
|
||||||
|
/// status that have sent it a connection request.
|
||||||
|
/// Advertiser accepts or rejects connection requests.
|
||||||
|
///
|
||||||
ValueListenable<bool> get isBrowser => _isBrowser;
|
ValueListenable<bool> get isBrowser => _isBrowser;
|
||||||
|
|
||||||
String get _currentConnectionType {
|
String get _currentConnectionType {
|
||||||
return _isBrowser.value ? 'browsing' : 'advertising';
|
return _isBrowser.value ? 'browsing' : 'advertising';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Initializes [MCNearbyServiceAdvertiser](https://developer.apple.com/documentation/multipeerconnectivity/mcnearbyserviceadvertiser)
|
||||||
|
/// and [MCNearbyServiceBrowser](https://developer.apple.com/documentation/multipeerconnectivity/mcnearbyservicebrowser)
|
||||||
|
/// to allow this device to be both.
|
||||||
|
///
|
||||||
|
/// Creates [MCPeerID](https://developer.apple.com/documentation/multipeerconnectivity/mcpeerid) for
|
||||||
|
/// this device.
|
||||||
|
///
|
||||||
|
/// The name of the device on the network can be
|
||||||
|
/// specified on initialization via the parameter [data].
|
||||||
|
///
|
||||||
|
/// [NearbyInitializeData.iosDeviceName] will be passed to the platform as initial
|
||||||
|
/// name. If a new name is not passed, the previous name stored
|
||||||
|
/// in [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults)
|
||||||
|
/// will be used. If there is no saved name, `UIDevice.current.name` will be used.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> initialize({
|
Future<bool> initialize({
|
||||||
NearbyInitializeData data = const NearbyInitializeData(),
|
NearbyInitializeData data = const NearbyInitializeData(),
|
||||||
@@ -37,6 +69,12 @@ class NearbyIOSService extends NearbyService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Starts discovery on the local P2P network.
|
||||||
|
///
|
||||||
|
/// Starts browsing for peers if [isBrowser] is true.
|
||||||
|
/// Starts advertising for peers if [isBrowser] is false.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> discover() async {
|
Future<bool> discover() async {
|
||||||
final result = _isBrowser.value
|
final result = _isBrowser.value
|
||||||
@@ -50,6 +88,12 @@ class NearbyIOSService extends NearbyService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Slops discovery on the local P2P network.
|
||||||
|
///
|
||||||
|
/// Slops browsing for peers if [isBrowser] is true.
|
||||||
|
/// Slops advertising for peers if [isBrowser] is false.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> stopDiscovery() async {
|
Future<bool> stopDiscovery() async {
|
||||||
final result = _isBrowser.value
|
final result = _isBrowser.value
|
||||||
@@ -64,6 +108,14 @@ class NearbyIOSService extends NearbyService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Connects to the [device] on the P2P network.
|
||||||
|
///
|
||||||
|
/// Invites [device] if [isBrowser] is true.
|
||||||
|
/// Accepts invite from [device] if [isBrowser] is false.
|
||||||
|
///
|
||||||
|
/// Note! Requires [NearbyIOSDevice] to be passed.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> connect(NearbyDevice device) async {
|
Future<bool> connect(NearbyDevice device) async {
|
||||||
_requireIOSDevice(device);
|
_requireIOSDevice(device);
|
||||||
@@ -81,6 +133,11 @@ class NearbyIOSService extends NearbyService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Disconnects from the [device] on the P2P network.
|
||||||
|
///
|
||||||
|
/// Note! Requires [NearbyIOSDevice] to be passed.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> disconnect(NearbyDevice device) async {
|
Future<bool> disconnect(NearbyDevice device) async {
|
||||||
_requireIOSDevice(device);
|
_requireIOSDevice(device);
|
||||||
@@ -95,12 +152,16 @@ class NearbyIOSService extends NearbyService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Starts listening for messages from device with
|
||||||
|
/// [NearbyCommunicationChannelData.connectedDeviceId].
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> startCommunicationChannel(
|
FutureOr<bool> startCommunicationChannel(
|
||||||
NearbyCommunicationChannelData data,
|
NearbyCommunicationChannelData data,
|
||||||
) async {
|
) async {
|
||||||
Logger.debug('Creating messages subscription');
|
Logger.debug('Creating messages subscription');
|
||||||
_isCommunicationChannelConnecting.value = true;
|
_state.value = CommunicationChannelState.loading;
|
||||||
await endCommunicationChannel();
|
await endCommunicationChannel();
|
||||||
final eventListener = data.eventListener;
|
final eventListener = data.eventListener;
|
||||||
_messagesSubscription = NearbyServiceIOSPlatform.instance.messagesStream
|
_messagesSubscription = NearbyServiceIOSPlatform.instance.messagesStream
|
||||||
@@ -110,9 +171,13 @@ class NearbyIOSService extends NearbyService {
|
|||||||
.cast<ReceivedNearbyMessage>()
|
.cast<ReceivedNearbyMessage>()
|
||||||
.listen(
|
.listen(
|
||||||
eventListener.onData,
|
eventListener.onData,
|
||||||
onDone: eventListener.onDone,
|
onDone: () {
|
||||||
|
_state.value = CommunicationChannelState.notConnected;
|
||||||
|
eventListener.onDone?.call();
|
||||||
|
},
|
||||||
onError: (e, s) {
|
onError: (e, s) {
|
||||||
Logger.error(e);
|
Logger.error(e);
|
||||||
|
_state.value = CommunicationChannelState.notConnected;
|
||||||
eventListener.onError?.call(e, s);
|
eventListener.onError?.call(e, s);
|
||||||
},
|
},
|
||||||
cancelOnError: eventListener.cancelOnError,
|
cancelOnError: eventListener.cancelOnError,
|
||||||
@@ -120,11 +185,18 @@ class NearbyIOSService extends NearbyService {
|
|||||||
if (_messagesSubscription != null) {
|
if (_messagesSubscription != null) {
|
||||||
Logger.info('Messages subscription was created successfully');
|
Logger.info('Messages subscription was created successfully');
|
||||||
eventListener.onCreated?.call(_messagesSubscription!);
|
eventListener.onCreated?.call(_messagesSubscription!);
|
||||||
|
_state.value = CommunicationChannelState.connected;
|
||||||
|
} else {
|
||||||
|
_state.value = CommunicationChannelState.notConnected;
|
||||||
}
|
}
|
||||||
_isCommunicationChannelConnecting.value = false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Stops listening for messages from previously passed device with
|
||||||
|
/// [NearbyCommunicationChannelData.connectedDeviceId].
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
FutureOr<bool> endCommunicationChannel() async {
|
FutureOr<bool> endCommunicationChannel() async {
|
||||||
await _messagesSubscription?.cancel();
|
await _messagesSubscription?.cancel();
|
||||||
@@ -133,15 +205,30 @@ class NearbyIOSService extends NearbyService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Sends [OutgoingNearbyMessage] to [OutgoingNearbyMessage.receiver] via
|
||||||
|
/// IOS platform.
|
||||||
|
///
|
||||||
@override
|
@override
|
||||||
Future<bool> send(OutgoingNearbyMessage message) {
|
Future<bool> send(OutgoingNearbyMessage message) {
|
||||||
return NearbyServiceIOSPlatform.instance.send(message);
|
return NearbyServiceIOSPlatform.instance.send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// If you want to ask the user to change the name on the network,
|
||||||
|
/// you can retrieve the name previously saved in
|
||||||
|
/// [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults) using this method.
|
||||||
|
///
|
||||||
|
/// Changing the name on the network is only available for IOS,
|
||||||
|
/// so the [NearbyIOSService] only can be used for that.
|
||||||
|
///
|
||||||
Future<String?> getSavedDeviceName() {
|
Future<String?> getSavedDeviceName() {
|
||||||
return NearbyServiceIOSPlatform.instance.getSavedDeviceName();
|
return NearbyServiceIOSPlatform.instance.getSavedDeviceName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Changes the [isBrowser] to the passed [value].
|
||||||
|
///
|
||||||
void setIsBrowser({required bool value}) {
|
void setIsBrowser({required bool value}) {
|
||||||
Logger.debug('Is Browser Value was set to $value');
|
Logger.debug('Is Browser Value was set to $value');
|
||||||
_isBrowser.value = value;
|
_isBrowser.value = value;
|
||||||
|
|||||||
@@ -3,26 +3,102 @@ import 'dart:io';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
|
|
||||||
class NearbyCommunicationChannelData<T> {
|
///
|
||||||
|
/// A class for creating a communication channel.
|
||||||
|
///
|
||||||
|
class NearbyCommunicationChannelData {
|
||||||
|
///
|
||||||
|
/// Contains [connectedDeviceId] of the device to be connected
|
||||||
|
/// to and additional data.
|
||||||
|
///
|
||||||
|
/// Since Android connection is more customizable,
|
||||||
|
/// additional data [androidData] is created for it.
|
||||||
|
///
|
||||||
const NearbyCommunicationChannelData(
|
const NearbyCommunicationChannelData(
|
||||||
this.connectedDeviceId, {
|
this.connectedDeviceId, {
|
||||||
required this.eventListener,
|
required this.eventListener,
|
||||||
this.androidData = const NearbyAndroidCommunicationChannelData(),
|
this.androidData = const NearbyAndroidCommunicationChannelData(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Identifier of the device to be connected to.
|
||||||
|
///
|
||||||
final String connectedDeviceId;
|
final String connectedDeviceId;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Listener for message stream changes.
|
||||||
|
///
|
||||||
final NearbyServiceStreamListener<ReceivedNearbyMessage> eventListener;
|
final NearbyServiceStreamListener<ReceivedNearbyMessage> eventListener;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Android-specific connection data.
|
||||||
|
///
|
||||||
final NearbyAndroidCommunicationChannelData androidData;
|
final NearbyAndroidCommunicationChannelData androidData;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is NearbyCommunicationChannelData &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
connectedDeviceId == other.connectedDeviceId &&
|
||||||
|
eventListener == other.eventListener &&
|
||||||
|
androidData == other.androidData;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
connectedDeviceId.hashCode ^
|
||||||
|
eventListener.hashCode ^
|
||||||
|
androidData.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyCommunicationChannelData{connectedDeviceId: $connectedDeviceId, eventListener: $eventListener, androidData: $androidData}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Android-specific connection data.
|
||||||
|
///
|
||||||
class NearbyAndroidCommunicationChannelData {
|
class NearbyAndroidCommunicationChannelData {
|
||||||
|
///
|
||||||
|
/// By default, no data needs to be passed, all values are already set.
|
||||||
|
/// This class is used to customize connection of server to client or client to server.
|
||||||
|
///
|
||||||
const NearbyAndroidCommunicationChannelData({
|
const NearbyAndroidCommunicationChannelData({
|
||||||
this.clientReconnectInterval = const Duration(seconds: 5),
|
this.clientReconnectInterval = const Duration(seconds: 5),
|
||||||
this.serverListener,
|
this.serverListener,
|
||||||
this.port = 4045,
|
this.port = 4045,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The interval at which the client will ping the server
|
||||||
|
/// while waiting for it to be created.
|
||||||
|
///
|
||||||
final Duration clientReconnectInterval;
|
final Duration clientReconnectInterval;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Listener of events that come to the server.
|
||||||
|
///
|
||||||
final ValueChanged<HttpRequest>? serverListener;
|
final ValueChanged<HttpRequest>? serverListener;
|
||||||
final int port;
|
final int port;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is NearbyAndroidCommunicationChannelData &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
clientReconnectInterval == other.clientReconnectInterval &&
|
||||||
|
serverListener == other.serverListener &&
|
||||||
|
port == other.port;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
clientReconnectInterval.hashCode ^
|
||||||
|
serverListener.hashCode ^
|
||||||
|
port.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NearbyAndroidCommunicationChannelData{clientReconnectInterval: $clientReconnectInterval, serverListener: $serverListener, port: $port}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
|
///
|
||||||
|
/// Data for plugin initialization.
|
||||||
|
///
|
||||||
class NearbyInitializeData {
|
class NearbyInitializeData {
|
||||||
|
///
|
||||||
|
/// By default, it does not require any data.
|
||||||
|
///
|
||||||
|
/// There is an option to pass the device name to IOS [iosDeviceName].
|
||||||
|
/// For Android platform changing device name in P2P network is not supported.
|
||||||
|
///
|
||||||
const NearbyInitializeData({this.iosDeviceName});
|
const NearbyInitializeData({this.iosDeviceName});
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The device name for IOS on the P2P network.
|
||||||
|
///
|
||||||
final String? iosDeviceName;
|
final String? iosDeviceName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,14 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Stream Subscription Listener.
|
||||||
|
///
|
||||||
class NearbyServiceStreamListener<T> {
|
class NearbyServiceStreamListener<T> {
|
||||||
|
///
|
||||||
|
/// It is required to pass the [onData] parameter to process the
|
||||||
|
/// data that came through the stream.
|
||||||
|
///
|
||||||
const NearbyServiceStreamListener({
|
const NearbyServiceStreamListener({
|
||||||
required this.onData,
|
required this.onData,
|
||||||
this.onCreated,
|
this.onCreated,
|
||||||
|
|||||||
@@ -2,17 +2,28 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:nearby_service/src/utils/logger.dart';
|
import 'package:nearby_service/src/utils/logger.dart';
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Nearby Service Plugin Exception.
|
||||||
|
///
|
||||||
|
/// Indicates what problem occurred in the plugin operation.
|
||||||
|
///
|
||||||
class NearbyServiceException implements Exception {
|
class NearbyServiceException implements Exception {
|
||||||
NearbyServiceException(this.error) {
|
NearbyServiceException(this.error) {
|
||||||
Logger.error(error);
|
Logger.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A call from an unsupported platform.
|
||||||
|
///
|
||||||
factory NearbyServiceException.unsupportedPlatform({required String caller}) {
|
factory NearbyServiceException.unsupportedPlatform({required String caller}) {
|
||||||
return NearbyServiceException(
|
return NearbyServiceException(
|
||||||
'$caller is not supported for platform ${Platform.operatingSystem}',
|
'$caller is not supported for platform ${Platform.operatingSystem}',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// A decoding error.
|
||||||
|
///
|
||||||
factory NearbyServiceException.unsupportedDecoding(dynamic value) {
|
factory NearbyServiceException.unsupportedDecoding(dynamic value) {
|
||||||
return NearbyServiceException(
|
return NearbyServiceException(
|
||||||
'Got unknown value=$value with runtimeType=${value.runtimeType}',
|
'Got unknown value=$value with runtimeType=${value.runtimeType}',
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
|
|
||||||
class Decoder {
|
class JSONDecoder {
|
||||||
Decoder._();
|
JSONDecoder._();
|
||||||
|
|
||||||
static Map<String, dynamic>? decodeMap(dynamic value) {
|
static Map<String, dynamic>? decodeMap(dynamic value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
///
|
||||||
|
/// Determines what level of logging the plugin will use.
|
||||||
|
///
|
||||||
|
/// * [debug] - Display all logs, including debugging operations logs.
|
||||||
|
/// * [info] - Display information logs and errors.
|
||||||
|
/// * [error] - Display only errors.
|
||||||
|
/// * [disabled] - Do not display any logs.
|
||||||
|
///
|
||||||
enum NearbyServiceLogLevel {
|
enum NearbyServiceLogLevel {
|
||||||
debug,
|
debug,
|
||||||
info,
|
info,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:nearby_service/nearby_service.dart';
|
import 'package:nearby_service/nearby_service.dart';
|
||||||
import 'package:nearby_service/src/utils/decoder.dart';
|
import 'package:nearby_service/src/utils/json_decoder.dart';
|
||||||
|
|
||||||
import 'logger.dart';
|
import 'logger.dart';
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ abstract class MessagesStreamMapper {
|
|||||||
|
|
||||||
static ReceivedNearbyMessage? toMessage(dynamic event) {
|
static ReceivedNearbyMessage? toMessage(dynamic event) {
|
||||||
try {
|
try {
|
||||||
final decoded = Decoder.decodeMap(event);
|
final decoded = JSONDecoder.decodeMap(event);
|
||||||
return ReceivedNearbyMessage.fromJson(decoded);
|
return ReceivedNearbyMessage.fromJson(decoded);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.debug(
|
Logger.debug(
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
const kNearbyUnknown = 'unknown';
|
||||||
@@ -50,7 +50,7 @@ class MockNearbyServicePlatform
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<NearbyDevice?> getCurrentDevice() {
|
Future<NearbyDeviceInfo?> getCurrentDeviceInfo() {
|
||||||
// TODO: implement getCurrentDevice
|
// TODO: implement getCurrentDevice
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user