Fix: Android native connection errors are not displayed (#5)

* fix(android, lib): add error logging, handle running jobs exception

* doc(app_service): add comment

* fix(exampl_full, utils): move getCurrentDevice info and fix logs

* doc: add comments, update changelog

* doc: update changelog

* version: 0.0.7

* doc: update readme

* doc: update readme
This commit is contained in:
Kseniia Nikitina
2024-04-21 16:38:45 +02:00
committed by GitHub
parent 6abb8024dd
commit e4a8c2243f
19 changed files with 398 additions and 87 deletions
+8
View File
@@ -1,3 +1,11 @@
## 0.0.7
- Log all errors on the Android platform
- Add mapping for native Android exceptions in methods: discover(), stopDiscovery(), connect(), disconnect()
- Fix getPeers() method: correct decoding from JSON
- Update example: show empty peers state
- Update example_full: show variant of checking running jobs
## 0.0.6 ## 0.0.6
- Update README: add a Feedback form - Update README: add a Feedback form
+32 -1
View File
@@ -11,7 +11,11 @@ Nearby Service Flutter Plugin is used to create connections in a P2P network.
The plugin supports sending text messages and files. With it, The plugin supports sending text messages and files. With it,
you can easily create any kind of information sharing application **without Internet connection**. you can easily create any kind of information sharing application **without Internet connection**.
Your feedback and suggestions would be greatly appreciated! [You can leave your opinion here](https://forms.gle/FbAtW2dG5RYCxb1DA) The package does not support communication between Android and IOS devices, the connection is available for
**Android-Android** and **IOS-IOS** relations.
Your feedback and suggestions would be greatly
appreciated! [You can leave your opinion here](https://forms.gle/FbAtW2dG5RYCxb1DA)
## Table of Contents ## Table of Contents
@@ -26,6 +30,7 @@ Your feedback and suggestions would be greatly appreciated! [You can leave your
- [Data sharing](#data-sharing) - [Data sharing](#data-sharing)
- [Text messages](#text-messages) - [Text messages](#text-messages)
- [Resource messages](#resource-messages) - [Resource messages](#resource-messages)
- [Exceptions](#exceptions)
- [Additional options](#additional-options) - [Additional options](#additional-options)
- [Demo](#demo) - [Demo](#demo)
## About ## About
@@ -446,6 +451,32 @@ final filesListener = NearbyServiceFilesListener(
); );
``` ```
## Exceptions
**NearbyService** includes custom errors that you can catch in your implementation.
**Common exceptions [See here](https://github.com/ksenia312/nearby_service/blob/main/lib/src/utils/exception.dart):**
- `NearbyServiceUnsupportedPlatformException`: Usage of the plugin on an unsupported platform
- `NearbyServiceUnsupportedDecodingException`: Error decoding messages from native platform to Dart (open an issue if
this happens)
- `NearbyServiceInvalidMessageException`: An attempt to send an invalid message on the sender's side. Add content
validation to your messages
**Exceptions that can be caught from the `discover()`, `stopDiscovery()`, `connect()`, and `disconnect()` methods for
the Android platform
[See here](https://github.com/ksenia312/nearby_service/blob/main/lib/src/platforms/android/utils/exception.dart):**
- `NearbyServiceBusyException`: The Wi-Fi P2P framework is currently busy. Usually this means that you have sent a
request to some device and now one of the peers is **CONNECTING**
- `NearbyServiceP2PPUnsupportedException`: Wi-Fi P2P is not supported on this device
- `NearbyServiceNoServiceRequestsException`: No service discovery requests have been made. Ensure that you have
initiated a service discovery request before attempting to connect
- `NearbyServiceGenericErrorException`: A generic error occurred. This could be due to various reasons such as hardware
issues, Wi-Fi being turned off, or temporary issues with the Wi-Fi P2P framework
- `NearbyServiceUnknownException`: An unknown error occurred. Please check the device's Wi-Fi P2P settings and ensure
the device supports Wi-Fi P2P
## Additional options ## Additional options
- Each `NearbyDevice` contains `NearbyDeviceInfo` that presents different meanings depending on the platform. For - Each `NearbyDevice` contains `NearbyDeviceInfo` that presents different meanings depending on the platform. For
@@ -19,19 +19,19 @@ class Logger {
var level = LogLevel.DEBUG var level = LogLevel.DEBUG
fun d(message: String) { fun d(message: String) {
if (level.value <= LogLevel.DEBUG.value) { if (level.value <= LogLevel.DEBUG.value) {
Log.d(TAG, message) Log.d(TAG, "\u001B[37m$message\u001B[0m")
} }
} }
fun i(message: String) { fun i(message: String) {
if (level.value <= LogLevel.INFO.value) { if (level.value <= LogLevel.INFO.value) {
Log.i(TAG, message) Log.i(TAG, "\u001B[32m$message\u001B[0m")
} }
} }
fun e(message: String) { fun e(message: String) {
if (level.value <= LogLevel.ERROR.value) { if (level.value <= LogLevel.ERROR.value) {
Log.e(TAG, message) Log.e(TAG, "\u001B[31m$message\u001B[0m")
} }
} }
} }
@@ -51,6 +51,11 @@ class NearbyServiceBroadcastReceiver(
} }
} }
fun init() {
writeDevices()
writeConnectionInfo()
}
private fun logState(intent: Intent) { private fun logState(intent: Intent) {
when (intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1)) { when (intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1)) {
WifiP2pManager.WIFI_P2P_STATE_ENABLED -> { WifiP2pManager.WIFI_P2P_STATE_ENABLED -> {
@@ -121,7 +121,11 @@ class NearbyServiceManager(private var context: Context) {
fun discover(result: Result) { fun discover(result: Result) {
try { try {
wifiManager.discoverPeers( wifiManager.discoverPeers(
wifiChannel, getActionListener(result) wifiChannel, getActionListener(
result,
"Discovery has started successfully!",
"Discovery starting failed"
)
) )
} catch (e: SecurityException) { } catch (e: SecurityException) {
if (!permissionsHandler.checkPermissions()) { if (!permissionsHandler.checkPermissions()) {
@@ -136,7 +140,11 @@ class NearbyServiceManager(private var context: Context) {
*/ */
fun stopDiscovery(result: Result) { fun stopDiscovery(result: Result) {
wifiManager.stopPeerDiscovery( wifiManager.stopPeerDiscovery(
wifiChannel, getActionListener(result) wifiChannel, getActionListener(
result,
"Discovery has successfully stopped",
"Discovery stopping failed"
)
) )
} }
@@ -167,7 +175,7 @@ class NearbyServiceManager(private var context: Context) {
} }
val actionListener = getActionListener( val actionListener = getActionListener(
result, result,
"Connected to device $deviceAddress", "Connection request sent to device $deviceAddress",
"Connecting to device $deviceAddress failed" "Connecting to device $deviceAddress failed"
) )
config.deviceAddress = deviceAddress config.deviceAddress = deviceAddress
@@ -216,12 +224,17 @@ class NearbyServiceManager(private var context: Context) {
permissionsHandler, permissionsHandler,
) )
context.registerReceiver(receiver, intentFilter) context.registerReceiver(receiver, intentFilter)
try {
receiver.init()
} catch (error: Throwable) {
Logger.e("Failed to write initial info, error=${error.message}")
}
} }
private fun getActionListener( private fun getActionListener(
result: Result?, result: Result?,
successMessage: String? = null, successMessage: String? = null,
errorMessage: String? = null, errorMessage: String
): WifiP2pManager.ActionListener { ): WifiP2pManager.ActionListener {
return object : WifiP2pManager.ActionListener { return object : WifiP2pManager.ActionListener {
override fun onSuccess() { override fun onSuccess() {
@@ -232,10 +245,22 @@ class NearbyServiceManager(private var context: Context) {
} }
override fun onFailure(reasonCode: Int) { override fun onFailure(reasonCode: Int) {
if (errorMessage != null) { val reason = when (reasonCode) {
Logger.e("ERROR: $errorMessage Reason code: $reasonCode") WifiP2pManager.P2P_UNSUPPORTED -> "Wi-Fi P2P is not supported on this device. Please ensure your device supports Wi-Fi P2P."
WifiP2pManager.ERROR -> "A generic error occurred. This could be due to various reasons such as hardware issues, Wi-Fi being turned off, or temporary issues with the Wi-Fi P2P framework."
WifiP2pManager.BUSY -> "The Wi-Fi P2P framework is currently busy. Please wait for the current operation to complete before initiating another. Usually this means that you have sent a request to some device and now one of the peers is CONNECTING."
WifiP2pManager.NO_SERVICE_REQUESTS -> "No service discovery requests have been made. Ensure that you have initiated a service discovery request before attempting to connect."
else -> "An unknown error occurred. Please check the device's Wi-Fi P2P settings and ensure the device supports Wi-Fi P2P."
} }
result?.success(false) val stringifyReasonCode = when (reasonCode) {
WifiP2pManager.P2P_UNSUPPORTED -> "P2P_UNSUPPORTED"
WifiP2pManager.ERROR -> "ERROR"
WifiP2pManager.BUSY -> "BUSY"
WifiP2pManager.NO_SERVICE_REQUESTS -> "NO_SERVICE_REQUESTS"
else -> "UNKNOWN"
}
Logger.e("$errorMessage, Reason code: $reasonCode, Reason: $reason")
result?.success(stringifyReasonCode)
} }
} }
} }
+1
View File
@@ -112,6 +112,7 @@ class _AppBodyState extends State<AppBody> {
children: [ children: [
if (Platform.isIOS) if (Platform.isIOS)
Text('You are ${_isIosBrowser ? 'Browser' : 'Advertiser'}'), Text('You are ${_isIosBrowser ? 'Browser' : 'Advertiser'}'),
if (_peers.isEmpty) const Text('Searching for peers...'),
..._peers.map( ..._peers.map(
(e) => PeerWidget( (e) => PeerWidget(
device: e, device: e,
+70 -42
View File
@@ -50,10 +50,8 @@ class AppService extends ChangeNotifier {
updateState( updateState(
Platform.isAndroid ? AppState.permissions : AppState.selectClientType, Platform.isAndroid ? AppState.permissions : AppState.selectClientType,
); );
} catch (e) { } catch (e, s) {
if (kDebugMode) { _log(e, s);
print(e);
}
} finally { } finally {
notifyListeners(); notifyListeners();
} }
@@ -62,10 +60,8 @@ class AppService extends ChangeNotifier {
Future<void> getCurrentDeviceInfo() async { Future<void> getCurrentDeviceInfo() async {
try { try {
currentDeviceInfo = await _nearbyService.getCurrentDeviceInfo(); currentDeviceInfo = await _nearbyService.getCurrentDeviceInfo();
} catch (e) { } catch (e, s) {
if (kDebugMode) { _log(e, s);
print(e);
}
} }
} }
@@ -75,10 +71,8 @@ class AppService extends ChangeNotifier {
if (result ?? false) { if (result ?? false) {
updateState(AppState.checkServices); updateState(AppState.checkServices);
} }
} catch (e) { } catch (e, s) {
if (kDebugMode) { _log(e, s);
print(e);
}
} }
} }
@@ -101,17 +95,41 @@ class AppService extends ChangeNotifier {
updateState(AppState.readyToDiscover); updateState(AppState.readyToDiscover);
} }
Future<bool> hasRunningJobs() async {
try {
final result = await _nearbyService.getPeers();
// if one of devices is connecting, service is busy (android only)
if (result.any(
(element) => element.status == NearbyDeviceStatus.connecting,
)) {
if (kDebugMode) {
print('Service has already running jobs');
}
return true;
}
return false;
} catch (e, s) {
_log(e, s);
return false;
}
}
Future<void> discover() async { Future<void> discover() async {
try { try {
await getCurrentDeviceInfo(); await getCurrentDeviceInfo();
final result = await _nearbyService.discover(); final hasRunning = await hasRunningJobs();
if (result) { if (hasRunning) {
updateState(AppState.discoveringPeers); updateState(AppState.discoveringPeers);
} else {
final result = await _nearbyService.discover();
if (result) {
updateState(AppState.discoveringPeers);
}
} }
} catch (e) { } on NearbyServiceBusyException catch (_) {
if (kDebugMode) { _logBusyException();
print(e); } catch (e, s) {
} _log(e, s);
} }
} }
@@ -121,20 +139,20 @@ class AppService extends ChangeNotifier {
if (result) { if (result) {
updateState(AppState.readyToDiscover); updateState(AppState.readyToDiscover);
} }
} catch (e) { } on NearbyServiceBusyException catch (_) {
if (kDebugMode) { _logBusyException();
print(e); } catch (e, s) {
} _log(e, s);
} }
} }
Future<void> connect(NearbyDevice device) async { Future<void> connect(NearbyDevice device) async {
try { try {
await _nearbyService.connect(device); await _nearbyService.connect(device);
} catch (e) { } on NearbyServiceBusyException catch (_) {
if (kDebugMode) { _logBusyException();
print(e); } catch (e, s) {
} _log(e, s);
} }
notifyListeners(); notifyListeners();
} }
@@ -142,10 +160,10 @@ class AppService extends ChangeNotifier {
Future<void> disconnect([NearbyDevice? device]) async { Future<void> disconnect([NearbyDevice? device]) async {
try { try {
await _nearbyService.disconnect(device); await _nearbyService.disconnect(device);
} catch (e) { } on NearbyServiceBusyException catch (_) {
if (kDebugMode) { _logBusyException();
print(e); } catch (e, s) {
} _log(e, s);
} finally { } finally {
await stopListeningAll(); await stopListeningAll();
} }
@@ -194,10 +212,8 @@ extension ConnectionInfoExtension on AppService {
_notify(); _notify();
}, },
); );
} catch (e) { } catch (e, s) {
if (kDebugMode) { _log(e, s);
print(e);
}
} }
_notify(); _notify();
} }
@@ -218,10 +234,8 @@ extension PeersExtension on AppService {
}, },
); );
updateState(AppState.streamingPeers); updateState(AppState.streamingPeers);
} catch (e) { } catch (e, s) {
if (kDebugMode) { _log(e, s);
print(e);
}
} }
} }
@@ -310,10 +324,8 @@ extension CommunicationChannelExtension on AppService {
Future<void> endCommunicationChannel() async { Future<void> endCommunicationChannel() async {
try { try {
await _nearbyService.endCommunicationChannel(); await _nearbyService.endCommunicationChannel();
} catch (e) { } catch (e, s) {
if (kDebugMode) { _log(e, s);
print(e);
}
} }
_notify(); _notify();
} }
@@ -384,3 +396,19 @@ extension MessagingExtension on AppService {
_notify(); _notify();
} }
} }
extension LoggingExtension on AppService {
void _log(e, StackTrace s) {
if (kDebugMode) {
print('$e, \nStacktrace: $s');
}
}
void _logBusyException() {
if (kDebugMode) {
print(
'Nearby service is busy, wait a little and retry (You can implement retry in your code)',
);
}
}
}
+29
View File
@@ -168,6 +168,13 @@ abstract class NearbyService {
/// Note that the [NearbyIOSService] implementation starts **browsing** or /// Note that the [NearbyIOSService] implementation starts **browsing** or
/// **advertising** depending on the [NearbyIOSService.isBrowser]. /// **advertising** depending on the [NearbyIOSService.isBrowser].
/// ///
/// On Android can throw mapped from native platform exceptions:
/// 1. [NearbyServiceBusyException]
/// 2. [NearbyServiceP2PUnsupportedException]
/// 3. [NearbyServiceNoServiceRequestsException]
/// 4. [NearbyServiceGenericErrorException]
/// 5. [NearbyServiceUnknownException]
///
Future<bool> discover(); Future<bool> discover();
/// ///
@@ -176,6 +183,13 @@ abstract class NearbyService {
/// Note that the [NearbyIOSService] implementation stops **browsing** or /// Note that the [NearbyIOSService] implementation stops **browsing** or
/// **advertising** depending on the [NearbyIOSService.isBrowser]. /// **advertising** depending on the [NearbyIOSService.isBrowser].
/// ///
/// On Android can throw mapped from native platform exceptions:
/// 1. [NearbyServiceBusyException]
/// 2. [NearbyServiceP2PUnsupportedException]
/// 3. [NearbyServiceNoServiceRequestsException]
/// 4. [NearbyServiceGenericErrorException]
/// 5. [NearbyServiceUnknownException]
///
Future<bool> stopDiscovery(); Future<bool> stopDiscovery();
/// ///
@@ -187,6 +201,13 @@ abstract class NearbyService {
/// Note that if [Platform.isIOS] == true, [NearbyIOSDevice] should be passed. /// Note that if [Platform.isIOS] == true, [NearbyIOSDevice] should be passed.
/// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed. /// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed.
/// ///
/// On Android can throw mapped from native platform exceptions:
/// 1. [NearbyServiceBusyException]
/// 2. [NearbyServiceP2PUnsupportedException]
/// 3. [NearbyServiceNoServiceRequestsException]
/// 4. [NearbyServiceGenericErrorException]
/// 5. [NearbyServiceUnknownException]
///
Future<bool> connect(NearbyDevice device); Future<bool> connect(NearbyDevice device);
/// ///
@@ -196,6 +217,14 @@ abstract class NearbyService {
/// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed. /// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed.
/// ///
/// **For IOS [device] is required!!!** /// **For IOS [device] is required!!!**
///
/// On Android can throw mapped from native platform exceptions:
/// 1. [NearbyServiceBusyException]
/// 2. [NearbyServiceP2PUnsupportedException]
/// 3. [NearbyServiceNoServiceRequestsException]
/// 4. [NearbyServiceGenericErrorException]
/// 5. [NearbyServiceUnknownException]
///
Future<bool> disconnect([NearbyDevice? device]); Future<bool> disconnect([NearbyDevice? device]);
/// ///
+1 -1
View File
@@ -37,7 +37,7 @@ class MethodChannelNearbyService extends NearbyServicePlatform {
@override @override
Future<List<NearbyDevice>> getPeers() async { Future<List<NearbyDevice>> getPeers() async {
return NearbyDeviceMapper.instance.mapToDeviceList( return NearbyDeviceMapper.instance.mapToDeviceList(
await methodChannel.invokeMethod('fetchPeers'), await methodChannel.invokeMethod('getPeers'),
); );
} }
+4 -4
View File
@@ -6,7 +6,7 @@ import 'package:nearby_service/nearby_service.dart';
/// Contains [value] - the message to be sent or received. /// Contains [value] - the message to be sent or received.
/// ///
final class NearbyMessageTextRequest extends NearbyMessageContent { final class NearbyMessageTextRequest extends NearbyMessageContent {
const NearbyMessageTextRequest._({ const NearbyMessageTextRequest.createManually({
required this.value, required this.value,
required super.id, required super.id,
}); });
@@ -17,7 +17,7 @@ final class NearbyMessageTextRequest extends NearbyMessageContent {
/// Gets [NearbyMessageTextRequest] from [json] /// Gets [NearbyMessageTextRequest] from [json]
/// ///
factory NearbyMessageTextRequest.fromJson(Map<String, dynamic>? json) { factory NearbyMessageTextRequest.fromJson(Map<String, dynamic>? json) {
return NearbyMessageTextRequest._( return NearbyMessageTextRequest.createManually(
id: json?['id'], id: json?['id'],
value: json?['value'], value: json?['value'],
); );
@@ -76,7 +76,7 @@ final class NearbyMessageFilesRequest extends NearbyMessageContent {
/// ///
/// Adds a [NearbyFileInfo] list to [id] to identify files. /// Adds a [NearbyFileInfo] list to [id] to identify files.
/// ///
const NearbyMessageFilesRequest._({ const NearbyMessageFilesRequest.createManually({
required super.id, required super.id,
required this.files, required this.files,
}); });
@@ -91,7 +91,7 @@ final class NearbyMessageFilesRequest extends NearbyMessageContent {
/// Gets [NearbyMessageFilesRequest] from [json]. /// Gets [NearbyMessageFilesRequest] from [json].
/// ///
factory NearbyMessageFilesRequest.fromJson(Map<String, dynamic>? json) { factory NearbyMessageFilesRequest.fromJson(Map<String, dynamic>? json) {
return NearbyMessageFilesRequest._( return NearbyMessageFilesRequest.createManually(
id: json?['id'], id: json?['id'],
files: [ files: [
...?(json?['files'] as List?)?.map( ...?(json?['files'] as List?)?.map(
+1
View File
@@ -2,3 +2,4 @@ export 'nearby_android_service.dart';
export 'nearby_service_android_interface.dart'; export 'nearby_service_android_interface.dart';
export 'model/nearby_connection_info.dart'; export 'model/nearby_connection_info.dart';
export 'model/nearby_device.dart'; export 'model/nearby_device.dart';
export 'utils/exception.dart';
@@ -143,7 +143,7 @@ class NearbyAndroidMapper implements NearbyDeviceMapper {
final decoded = JSONDecoder.decodeList(value); final decoded = JSONDecoder.decodeList(value);
return [ return [
...?decoded?.map( ...?decoded?.map(
(e) => NearbyAndroidDevice.fromJson(e as Map<String, dynamic>?), (e) => NearbyAndroidDevice.fromJson(JSONDecoder.decodeMap(e)),
), ),
]; ];
} }
@@ -3,6 +3,8 @@ import 'package:flutter/services.dart';
import 'package:nearby_service/nearby_service.dart'; import 'package:nearby_service/nearby_service.dart';
import 'package:nearby_service/src/utils/logger.dart'; import 'package:nearby_service/src/utils/logger.dart';
import 'utils/mapper.dart';
/// An implementation of [NearbyServiceAndroidPlatform] that uses method channels. /// An implementation of [NearbyServiceAndroidPlatform] that uses method channels.
class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform { class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
/// The method channel used to interact with the native platform. /// The method channel used to interact with the native platform.
@@ -39,26 +41,29 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
@override @override
Future<bool> discover() async { Future<bool> discover() async {
return (await methodChannel.invokeMethod<bool>('discover')) ?? false; final result = await methodChannel.invokeMethod('discover');
return _handleBooleanResult(result);
} }
@override @override
Future<bool> stopDiscovery() async { Future<bool> stopDiscovery() async {
return (await methodChannel.invokeMethod<bool>('stopDiscovery')) ?? false; final result = await methodChannel.invokeMethod('stopDiscovery');
return _handleBooleanResult(result);
} }
@override @override
Future<bool> connect(String deviceAddress) async { Future<bool> connect(String deviceAddress) async {
return (await methodChannel.invokeMethod<bool?>( final result = await methodChannel.invokeMethod(
"connect", "connect",
{"deviceAddress": deviceAddress}, {"deviceAddress": deviceAddress},
)) ?? );
false; return _handleBooleanResult(result);
} }
@override @override
Future<bool> disconnect() async { Future<bool> disconnect() async {
return (await methodChannel.invokeMethod<bool?>("disconnect")) ?? false; final result = await methodChannel.invokeMethod("disconnect");
return _handleBooleanResult(result);
} }
@override @override
@@ -70,4 +75,16 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
(e) => NearbyConnectionInfoMapper.mapToInfo(e), (e) => NearbyConnectionInfoMapper.mapToInfo(e),
); );
} }
bool _handleBooleanResult(dynamic result) {
if (result is bool) {
return result;
} else if (result is String) {
throw NearbyServiceAndroidExceptionMapper.map(result);
} else {
throw NearbyServiceException(
'Got unknown value from native platform: $result',
);
}
}
} }
@@ -0,0 +1,86 @@
import 'package:nearby_service/nearby_service.dart';
const _kNearbyServiceMessage = 'Got error from native platform with status=';
///
/// Wi-Fi P2P is not supported on this device
///
class NearbyServiceP2PUnsupportedException extends NearbyServiceException {
NearbyServiceP2PUnsupportedException()
: super(
'${_kNearbyServiceMessage}P2P_UNSUPPORTED',
);
@override
String toString() {
return 'NearbyServiceP2PUnsupportedException{error: $error}';
}
}
///
/// The Wi-Fi P2P framework is currently busy.
/// Please wait for the current operation to complete before initiating another.
///
/// Usually this means that you have sent a request to some device and
/// now one of the peers is CONNECTING.
///
class NearbyServiceBusyException extends NearbyServiceException {
NearbyServiceBusyException()
: super(
'${_kNearbyServiceMessage}BUSY',
);
@override
String toString() {
return 'NearbyServiceBusyException{error: $error}';
}
}
///
/// No service discovery requests have been made. Ensure that you have
/// initiated a service discovery request before attempting to connect.
///
class NearbyServiceNoServiceRequestsException extends NearbyServiceException {
NearbyServiceNoServiceRequestsException()
: super(
'${_kNearbyServiceMessage}NO_SERVICE_REQUESTS',
);
@override
String toString() {
return 'NearbyServiceNoServiceRequestsException{error: $error}';
}
}
///
/// A generic error occurred. This could be due to various reasons such as
/// hardware issues, Wi-Fi being turned off, or temporary issues with the
/// Wi-Fi P2P framework.
///
class NearbyServiceGenericErrorException extends NearbyServiceException {
NearbyServiceGenericErrorException()
: super(
'${_kNearbyServiceMessage}ERROR',
);
@override
String toString() {
return 'NearbyServiceGenericErrorException{error: $error}';
}
}
///
/// An unknown error occurred. Please check the device's Wi-Fi
/// P2P settings and ensure the device supports Wi-Fi P2P.
///
class NearbyServiceUnknownException extends NearbyServiceException {
NearbyServiceUnknownException()
: super(
'${_kNearbyServiceMessage}UNKNOWN',
);
@override
String toString() {
return 'NearbyServiceUnknownException{error: $error}';
}
}
@@ -0,0 +1,26 @@
import 'package:nearby_service/nearby_service.dart';
class NearbyServiceAndroidExceptionMapper {
NearbyServiceAndroidExceptionMapper._();
static NearbyServiceException map(String error) {
AndroidFailureCodes? enumValue;
try {
enumValue = AndroidFailureCodes.values.firstWhere(
(element) => element.name == error,
);
} catch (_) {}
return switch (enumValue) {
AndroidFailureCodes.BUSY => NearbyServiceBusyException(),
AndroidFailureCodes.ERROR => NearbyServiceGenericErrorException(),
AndroidFailureCodes.P2P_UNSUPPORTED =>
NearbyServiceP2PUnsupportedException(),
AndroidFailureCodes.NO_SERVICE_REQUESTS =>
NearbyServiceNoServiceRequestsException(),
_ => NearbyServiceUnknownException(),
};
}
}
// ignore: constant_identifier_names
enum AndroidFailureCodes { P2P_UNSUPPORTED, BUSY, NO_SERVICE_REQUESTS, ERROR }
@@ -78,7 +78,7 @@ class NearbyIOSMapper implements NearbyDeviceMapper {
final decoded = JSONDecoder.decodeList(value); final decoded = JSONDecoder.decodeList(value);
return [ return [
...?decoded?.map( ...?decoded?.map(
(e) => NearbyIOSDevice.fromJson(e as Map<String, dynamic>?), (e) => NearbyIOSDevice.fromJson(JSONDecoder.decodeMap(e)),
), ),
]; ];
} }
+71 -17
View File
@@ -14,28 +14,26 @@ class NearbyServiceException implements Exception {
} }
/// ///
/// A call from an unsupported platform. /// Usage of the plugin on an unsupported platform
/// ///
factory NearbyServiceException.unsupportedPlatform({required String caller}) { factory NearbyServiceException.unsupportedPlatform({
return NearbyServiceException( required String caller,
'$caller is not supported for platform ${Platform.operatingSystem}', }) =>
); NearbyServiceUnsupportedPlatformException(caller: caller);
}
/// ///
/// A decoding error. /// Error decoding messages from native platform to Dart (open an issue if
/// this happens!)
/// ///
factory NearbyServiceException.unsupportedDecoding(dynamic value) { factory NearbyServiceException.unsupportedDecoding(dynamic value) =>
return NearbyServiceException( NearbyServiceUnsupportedDecodingException(value);
'Got unknown value=$value with runtimeType=${value.runtimeType}',
);
}
factory NearbyServiceException.invalidMessage(NearbyMessageContent content) { ///
return NearbyServiceException( /// An attempt to send an invalid message on the sender's side. Add content
'The message="$content" is not valid', /// validation to your messages
); ///
} factory NearbyServiceException.invalidMessage(NearbyMessageContent content) =>
NearbyServiceInvalidMessageException(content);
final Object? error; final Object? error;
@@ -44,3 +42,59 @@ class NearbyServiceException implements Exception {
return 'NearbyServiceException{error: $error}'; return 'NearbyServiceException{error: $error}';
} }
} }
///
/// Usage of the plugin on an unsupported platform
///
class NearbyServiceUnsupportedPlatformException extends NearbyServiceException {
///
/// Usage of the plugin on an unsupported platform - default constructor
///
NearbyServiceUnsupportedPlatformException({required String caller})
: super(
'$caller is not supported for platform ${Platform.operatingSystem}',
);
@override
String toString() {
return 'NearbyServiceUnsupportedPlatformException{error: $error}';
}
}
///
/// Error decoding messages from native platform to Dart (open an issue if
/// this happens!)
///
class NearbyServiceUnsupportedDecodingException extends NearbyServiceException {
///
/// A decoding error - default constructor
///
NearbyServiceUnsupportedDecodingException(dynamic value)
: super(
'Got unknown value=$value with runtimeType=${value.runtimeType}',
);
@override
String toString() {
return 'NearbyServiceUnsupportedDecodingException{error: $error}';
}
}
///
/// An attempt to send an invalid message on the sender's side. Add content
/// validation to your messages
///
class NearbyServiceInvalidMessageException extends NearbyServiceException {
///
/// Invalid message error - default constructor
///
NearbyServiceInvalidMessageException(NearbyMessageContent content)
: super(
'The message="$content" is not valid',
);
@override
String toString() {
return 'NearbyServiceInvalidMessageException{error: $error}';
}
}
+1 -1
View File
@@ -62,10 +62,10 @@ class FilesSocket {
addChunk(event); addChunk(event);
} else if (event == separateCommandOf(_currentFileIndex)) { } else if (event == separateCommandOf(_currentFileIndex)) {
_futures.add(_createFile(_currentFileIndex)); _futures.add(_createFile(_currentFileIndex));
Logger.info('Completed receiving file №${_currentFileIndex + 1}');
_currentFileIndex = _currentFileIndex + 1; _currentFileIndex = _currentFileIndex + 1;
_chunksCount = 0; _chunksCount = 0;
_bytesTable['$_currentFileIndex'] = []; _bytesTable['$_currentFileIndex'] = [];
Logger.info('Completed receiving file №${_currentFileIndex - 1}');
} else if (event == finishCommand) { } else if (event == finishCommand) {
await Future.wait(_futures); await Future.wait(_futures);
Logger.info('Files pack ${filesRequest.id} was created'); Logger.info('Files pack ${filesRequest.id} was created');
+1 -1
View File
@@ -1,6 +1,6 @@
name: nearby_service name: nearby_service
description: Nearby Service Flutter Plugin is used to create connections in a P2P network. Supports sending text messages and files. description: Nearby Service Flutter Plugin is used to create connections in a P2P network. Supports sending text messages and files.
version: 0.0.6 version: 0.0.7
homepage: https://github.com/ksenia312/nearby_service homepage: https://github.com/ksenia312/nearby_service
repository: https://github.com/ksenia312/nearby_service repository: https://github.com/ksenia312/nearby_service