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:
@@ -168,6 +168,13 @@ abstract class NearbyService {
|
||||
/// Note that the [NearbyIOSService] implementation starts **browsing** or
|
||||
/// **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();
|
||||
|
||||
///
|
||||
@@ -176,6 +183,13 @@ abstract class NearbyService {
|
||||
/// Note that the [NearbyIOSService] implementation stops **browsing** or
|
||||
/// **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();
|
||||
|
||||
///
|
||||
@@ -187,6 +201,13 @@ abstract class NearbyService {
|
||||
/// Note that if [Platform.isIOS] == true, [NearbyIOSDevice] 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);
|
||||
|
||||
///
|
||||
@@ -196,6 +217,14 @@ abstract class NearbyService {
|
||||
/// If [Platform.isAndroid] == true, [NearbyAndroidDevice] should be passed.
|
||||
///
|
||||
/// **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]);
|
||||
|
||||
///
|
||||
|
||||
@@ -37,7 +37,7 @@ class MethodChannelNearbyService extends NearbyServicePlatform {
|
||||
@override
|
||||
Future<List<NearbyDevice>> getPeers() async {
|
||||
return NearbyDeviceMapper.instance.mapToDeviceList(
|
||||
await methodChannel.invokeMethod('fetchPeers'),
|
||||
await methodChannel.invokeMethod('getPeers'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:nearby_service/nearby_service.dart';
|
||||
/// Contains [value] - the message to be sent or received.
|
||||
///
|
||||
final class NearbyMessageTextRequest extends NearbyMessageContent {
|
||||
const NearbyMessageTextRequest._({
|
||||
const NearbyMessageTextRequest.createManually({
|
||||
required this.value,
|
||||
required super.id,
|
||||
});
|
||||
@@ -17,7 +17,7 @@ final class NearbyMessageTextRequest extends NearbyMessageContent {
|
||||
/// Gets [NearbyMessageTextRequest] from [json]
|
||||
///
|
||||
factory NearbyMessageTextRequest.fromJson(Map<String, dynamic>? json) {
|
||||
return NearbyMessageTextRequest._(
|
||||
return NearbyMessageTextRequest.createManually(
|
||||
id: json?['id'],
|
||||
value: json?['value'],
|
||||
);
|
||||
@@ -76,7 +76,7 @@ final class NearbyMessageFilesRequest extends NearbyMessageContent {
|
||||
///
|
||||
/// Adds a [NearbyFileInfo] list to [id] to identify files.
|
||||
///
|
||||
const NearbyMessageFilesRequest._({
|
||||
const NearbyMessageFilesRequest.createManually({
|
||||
required super.id,
|
||||
required this.files,
|
||||
});
|
||||
@@ -91,7 +91,7 @@ final class NearbyMessageFilesRequest extends NearbyMessageContent {
|
||||
/// Gets [NearbyMessageFilesRequest] from [json].
|
||||
///
|
||||
factory NearbyMessageFilesRequest.fromJson(Map<String, dynamic>? json) {
|
||||
return NearbyMessageFilesRequest._(
|
||||
return NearbyMessageFilesRequest.createManually(
|
||||
id: json?['id'],
|
||||
files: [
|
||||
...?(json?['files'] as List?)?.map(
|
||||
|
||||
@@ -2,3 +2,4 @@ export 'nearby_android_service.dart';
|
||||
export 'nearby_service_android_interface.dart';
|
||||
export 'model/nearby_connection_info.dart';
|
||||
export 'model/nearby_device.dart';
|
||||
export 'utils/exception.dart';
|
||||
|
||||
@@ -143,7 +143,7 @@ class NearbyAndroidMapper implements NearbyDeviceMapper {
|
||||
final decoded = JSONDecoder.decodeList(value);
|
||||
return [
|
||||
...?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/src/utils/logger.dart';
|
||||
|
||||
import 'utils/mapper.dart';
|
||||
|
||||
/// An implementation of [NearbyServiceAndroidPlatform] that uses method channels.
|
||||
class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
|
||||
/// The method channel used to interact with the native platform.
|
||||
@@ -39,26 +41,29 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
|
||||
|
||||
@override
|
||||
Future<bool> discover() async {
|
||||
return (await methodChannel.invokeMethod<bool>('discover')) ?? false;
|
||||
final result = await methodChannel.invokeMethod('discover');
|
||||
return _handleBooleanResult(result);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> stopDiscovery() async {
|
||||
return (await methodChannel.invokeMethod<bool>('stopDiscovery')) ?? false;
|
||||
final result = await methodChannel.invokeMethod('stopDiscovery');
|
||||
return _handleBooleanResult(result);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> connect(String deviceAddress) async {
|
||||
return (await methodChannel.invokeMethod<bool?>(
|
||||
"connect",
|
||||
{"deviceAddress": deviceAddress},
|
||||
)) ??
|
||||
false;
|
||||
final result = await methodChannel.invokeMethod(
|
||||
"connect",
|
||||
{"deviceAddress": deviceAddress},
|
||||
);
|
||||
return _handleBooleanResult(result);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> disconnect() async {
|
||||
return (await methodChannel.invokeMethod<bool?>("disconnect")) ?? false;
|
||||
final result = await methodChannel.invokeMethod("disconnect");
|
||||
return _handleBooleanResult(result);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -70,4 +75,16 @@ class MethodChannelAndroidNearbyService extends NearbyServiceAndroidPlatform {
|
||||
(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);
|
||||
return [
|
||||
...?decoded?.map(
|
||||
(e) => NearbyIOSDevice.fromJson(e as Map<String, dynamic>?),
|
||||
(e) => NearbyIOSDevice.fromJson(JSONDecoder.decodeMap(e)),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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}) {
|
||||
return NearbyServiceException(
|
||||
'$caller is not supported for platform ${Platform.operatingSystem}',
|
||||
);
|
||||
}
|
||||
factory NearbyServiceException.unsupportedPlatform({
|
||||
required String caller,
|
||||
}) =>
|
||||
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) {
|
||||
return NearbyServiceException(
|
||||
'Got unknown value=$value with runtimeType=${value.runtimeType}',
|
||||
);
|
||||
}
|
||||
factory NearbyServiceException.unsupportedDecoding(dynamic value) =>
|
||||
NearbyServiceUnsupportedDecodingException(value);
|
||||
|
||||
factory NearbyServiceException.invalidMessage(NearbyMessageContent content) {
|
||||
return NearbyServiceException(
|
||||
'The message="$content" is not valid',
|
||||
);
|
||||
}
|
||||
///
|
||||
/// An attempt to send an invalid message on the sender's side. Add content
|
||||
/// validation to your messages
|
||||
///
|
||||
factory NearbyServiceException.invalidMessage(NearbyMessageContent content) =>
|
||||
NearbyServiceInvalidMessageException(content);
|
||||
|
||||
final Object? error;
|
||||
|
||||
@@ -44,3 +42,59 @@ class NearbyServiceException implements Exception {
|
||||
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}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ class FilesSocket {
|
||||
addChunk(event);
|
||||
} else if (event == separateCommandOf(_currentFileIndex)) {
|
||||
_futures.add(_createFile(_currentFileIndex));
|
||||
Logger.info('Completed receiving file №${_currentFileIndex + 1}');
|
||||
_currentFileIndex = _currentFileIndex + 1;
|
||||
_chunksCount = 0;
|
||||
_bytesTable['$_currentFileIndex'] = [];
|
||||
Logger.info('Completed receiving file №${_currentFileIndex - 1}');
|
||||
} else if (event == finishCommand) {
|
||||
await Future.wait(_futures);
|
||||
Logger.info('Files pack ${filesRequest.id} was created');
|
||||
|
||||
Reference in New Issue
Block a user