mirror of
https://github.com/hackku21/nearby_connections.git
synced 2024-10-27 19:14:01 +00:00
Prep for new Release
TODO: add a way to edit the filename
This commit is contained in:
parent
73ab07452c
commit
4d666c42a5
@ -1,3 +1,9 @@
|
|||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
* Added support for Files (sendFilePayload)
|
||||||
|
* Breaking Change (sendPayload method signature is changed)
|
||||||
|
* Updated Example and Readme for file transfer
|
||||||
|
|
||||||
## 0.1.3+1
|
## 0.1.3+1
|
||||||
|
|
||||||
* Update documentation and Readme
|
* Update documentation and Readme
|
||||||
|
19
README.md
19
README.md
@ -13,6 +13,7 @@ An **android** flutter plugin for the Nearby Connections API
|
|||||||
* [Accept Connection](#accept-connection)
|
* [Accept Connection](#accept-connection)
|
||||||
* [Sending Data](#sending-data)
|
* [Sending Data](#sending-data)
|
||||||
* [Sending Bytes Payload](#sending-bytes-payload)
|
* [Sending Bytes Payload](#sending-bytes-payload)
|
||||||
|
* [Sending Files](#sending-file-payload)
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
@ -120,7 +121,23 @@ Nearby().acceptConnection(
|
|||||||
### Sending Bytes Payload
|
### Sending Bytes Payload
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
Nearby().sendPayload(endpointId, bytes_array);
|
Nearby().sendBytesPayload(endpointId, bytes_array);
|
||||||
|
|
||||||
|
// payloads are recieved by callback given to acceptConnection method.
|
||||||
|
```
|
||||||
|
### Sending File Payload
|
||||||
|
You need to send the File Payload and File Name seperately.
|
||||||
|
|
||||||
|
File is stored in DOWNLOAD_DIRECTORY and given a generic name
|
||||||
|
So you would need to rename the file on receivers end.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
|
||||||
|
//creates file with generic name (without extension) in Downloads Directory
|
||||||
|
Nearby().sendFilePayload(endpointId, filePath);
|
||||||
|
|
||||||
|
//Send filename as well so that receiver can rename the file
|
||||||
|
Nearby().sendBytesPayload(endpointId,fileNameEncoded);
|
||||||
|
|
||||||
// payloads are recieved by callback given to acceptConnection method.
|
// payloads are recieved by callback given to acceptConnection method.
|
||||||
```
|
```
|
||||||
|
@ -78,12 +78,12 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
result.success(null);
|
result.success(null);
|
||||||
break;
|
break;
|
||||||
case "stopAdvertising":
|
case "stopAdvertising":
|
||||||
Log.d("NearbyCon java", "stopAdvertising");
|
Log.d("nearby_connections", "stopAdvertising");
|
||||||
Nearby.getConnectionsClient(activity).stopAdvertising();
|
Nearby.getConnectionsClient(activity).stopAdvertising();
|
||||||
result.success(null);
|
result.success(null);
|
||||||
break;
|
break;
|
||||||
case "stopDiscovery":
|
case "stopDiscovery":
|
||||||
Log.d("NearbyCon java", "stopDiscovery");
|
Log.d("nearby_connections", "stopDiscovery");
|
||||||
Nearby.getConnectionsClient(activity).stopDiscovery();
|
Nearby.getConnectionsClient(activity).stopDiscovery();
|
||||||
result.success(null);
|
result.success(null);
|
||||||
break;
|
break;
|
||||||
@ -101,7 +101,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
.addOnSuccessListener(new OnSuccessListener<Void>() {
|
.addOnSuccessListener(new OnSuccessListener<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Void aVoid) {
|
public void onSuccess(Void aVoid) {
|
||||||
Log.d("NearbyCon java", "startAdvertising");
|
Log.d("nearby_connections", "startAdvertising");
|
||||||
result.success(true);
|
result.success(true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -125,7 +125,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
.addOnSuccessListener(new OnSuccessListener<Void>() {
|
.addOnSuccessListener(new OnSuccessListener<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Void aVoid) {
|
public void onSuccess(Void aVoid) {
|
||||||
Log.d("NearbyCon java", "startDiscovery");
|
Log.d("nearby_connections", "startDiscovery");
|
||||||
result.success(true);
|
result.success(true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -138,12 +138,12 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "stopAllEndpoints":
|
case "stopAllEndpoints":
|
||||||
Log.d("NearbyCon java", "stopAllEndpoints");
|
Log.d("nearby_connections", "stopAllEndpoints");
|
||||||
Nearby.getConnectionsClient(activity).stopAllEndpoints();
|
Nearby.getConnectionsClient(activity).stopAllEndpoints();
|
||||||
result.success(null);
|
result.success(null);
|
||||||
break;
|
break;
|
||||||
case "disconnectFromEndpoint": {
|
case "disconnectFromEndpoint": {
|
||||||
Log.d("NearbyCon java", "disconnectFromEndpoint");
|
Log.d("nearby_connections", "disconnectFromEndpoint");
|
||||||
String endpointId = call.argument("endpointId");
|
String endpointId = call.argument("endpointId");
|
||||||
assert endpointId != null;
|
assert endpointId != null;
|
||||||
Nearby.getConnectionsClient(activity).disconnectFromEndpoint(endpointId);
|
Nearby.getConnectionsClient(activity).disconnectFromEndpoint(endpointId);
|
||||||
@ -151,7 +151,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "requestConnection": {
|
case "requestConnection": {
|
||||||
Log.d("NearbyCon java", "requestConnection");
|
Log.d("nearby_connections", "requestConnection");
|
||||||
String userNickName = (String) call.argument("userNickName");
|
String userNickName = (String) call.argument("userNickName");
|
||||||
String endpointId = (String) call.argument("endpointId");
|
String endpointId = (String) call.argument("endpointId");
|
||||||
|
|
||||||
@ -220,7 +220,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
assert endpointId != null;
|
assert endpointId != null;
|
||||||
assert bytes != null;
|
assert bytes != null;
|
||||||
Nearby.getConnectionsClient(activity).sendPayload(endpointId, Payload.fromBytes(bytes));
|
Nearby.getConnectionsClient(activity).sendPayload(endpointId, Payload.fromBytes(bytes));
|
||||||
Log.d("NearbyCon java", "sentPayload");
|
Log.d("nearby_connections", "sentPayload");
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -236,10 +236,10 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
Payload filePayload = Payload.fromFile(file);
|
Payload filePayload = Payload.fromFile(file);
|
||||||
Nearby.getConnectionsClient(activity).sendPayload(endpointId, filePayload);
|
Nearby.getConnectionsClient(activity).sendPayload(endpointId, filePayload);
|
||||||
Log.d("NearbyCon java", "sentFilePayload");
|
Log.d("nearby_connections", "sentFilePayload");
|
||||||
result.success(filePayload.getId()); //return payload id to dart
|
result.success(filePayload.getId()); //return payload id to dart
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Log.e("NearbyCon java", "File not found", e);
|
Log.e("nearby_connections", "File not found", e);
|
||||||
result.error("Failure", "File Not found", null);
|
result.error("Failure", "File Not found", null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -253,7 +253,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
private final ConnectionLifecycleCallback advertConnectionLifecycleCallback = new ConnectionLifecycleCallback() {
|
private final ConnectionLifecycleCallback advertConnectionLifecycleCallback = new ConnectionLifecycleCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionInitiated(@NonNull String endpointId, @NonNull ConnectionInfo connectionInfo) {
|
public void onConnectionInitiated(@NonNull String endpointId, @NonNull ConnectionInfo connectionInfo) {
|
||||||
Log.d("NearbyCon java", "ad.onConnectionInitiated");
|
Log.d("nearby_connections", "ad.onConnectionInitiated");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
args.put("endpointName", connectionInfo.getEndpointName());
|
args.put("endpointName", connectionInfo.getEndpointName());
|
||||||
@ -264,7 +264,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionResult(@NonNull String endpointId, @NonNull ConnectionResolution connectionResolution) {
|
public void onConnectionResult(@NonNull String endpointId, @NonNull ConnectionResolution connectionResolution) {
|
||||||
Log.d("NearbyCon java", "ad.onConnectionResult");
|
Log.d("nearby_connections", "ad.onConnectionResult");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
int statusCode = -1;
|
int statusCode = -1;
|
||||||
@ -290,7 +290,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected(@NonNull String endpointId) {
|
public void onDisconnected(@NonNull String endpointId) {
|
||||||
Log.d("NearbyCon java", "ad.onDisconnected");
|
Log.d("nearby_connections", "ad.onDisconnected");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
channel.invokeMethod("ad.onDisconnected", args);
|
channel.invokeMethod("ad.onDisconnected", args);
|
||||||
@ -300,7 +300,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
private final ConnectionLifecycleCallback discoverConnectionLifecycleCallback = new ConnectionLifecycleCallback() {
|
private final ConnectionLifecycleCallback discoverConnectionLifecycleCallback = new ConnectionLifecycleCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionInitiated(@NonNull String endpointId, @NonNull ConnectionInfo connectionInfo) {
|
public void onConnectionInitiated(@NonNull String endpointId, @NonNull ConnectionInfo connectionInfo) {
|
||||||
Log.d("NearbyCon java", "dis.onConnectionInitiated");
|
Log.d("nearby_connections", "dis.onConnectionInitiated");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
args.put("endpointName", connectionInfo.getEndpointName());
|
args.put("endpointName", connectionInfo.getEndpointName());
|
||||||
@ -311,7 +311,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionResult(@NonNull String endpointId, @NonNull ConnectionResolution connectionResolution) {
|
public void onConnectionResult(@NonNull String endpointId, @NonNull ConnectionResolution connectionResolution) {
|
||||||
Log.d("NearbyCon java", "dis.onConnectionResult");
|
Log.d("nearby_connections", "dis.onConnectionResult");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
int statusCode = -1;
|
int statusCode = -1;
|
||||||
@ -337,7 +337,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected(@NonNull String endpointId) {
|
public void onDisconnected(@NonNull String endpointId) {
|
||||||
Log.d("NearbyCon java", "dis.onDisconnected");
|
Log.d("nearby_connections", "dis.onDisconnected");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
channel.invokeMethod("dis.onDisconnected", args);
|
channel.invokeMethod("dis.onDisconnected", args);
|
||||||
@ -347,7 +347,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
private final PayloadCallback payloadCallback = new PayloadCallback() {
|
private final PayloadCallback payloadCallback = new PayloadCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onPayloadReceived(@NonNull String endpointId, @NonNull Payload payload) {
|
public void onPayloadReceived(@NonNull String endpointId, @NonNull Payload payload) {
|
||||||
Log.d("NearbyCon java", "onPayloadReceived");
|
Log.d("nearby_connections", "onPayloadReceived");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
args.put("payloadId", payload.getId());
|
args.put("payloadId", payload.getId());
|
||||||
@ -366,7 +366,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
public void onPayloadTransferUpdate(@NonNull String endpointId, @NonNull PayloadTransferUpdate payloadTransferUpdate) {
|
public void onPayloadTransferUpdate(@NonNull String endpointId, @NonNull PayloadTransferUpdate payloadTransferUpdate) {
|
||||||
//required for files and streams
|
//required for files and streams
|
||||||
|
|
||||||
Log.d("NearbyCon java", "onPayloadTransferUpdate");
|
Log.d("nearby_connections", "onPayloadTransferUpdate");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
args.put("payloadId", payloadTransferUpdate.getPayloadId());
|
args.put("payloadId", payloadTransferUpdate.getPayloadId());
|
||||||
@ -381,7 +381,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
private final EndpointDiscoveryCallback endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
|
private final EndpointDiscoveryCallback endpointDiscoveryCallback = new EndpointDiscoveryCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onEndpointFound(@NonNull String endpointId, @NonNull DiscoveredEndpointInfo discoveredEndpointInfo) {
|
public void onEndpointFound(@NonNull String endpointId, @NonNull DiscoveredEndpointInfo discoveredEndpointInfo) {
|
||||||
Log.d("NearbyCon java", "onEndpointFound");
|
Log.d("nearby_connections", "onEndpointFound");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
args.put("endpointName", discoveredEndpointInfo.getEndpointName());
|
args.put("endpointName", discoveredEndpointInfo.getEndpointName());
|
||||||
@ -391,7 +391,7 @@ public class NearbyConnectionsPlugin implements MethodCallHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEndpointLost(@NonNull String endpointId) {
|
public void onEndpointLost(@NonNull String endpointId) {
|
||||||
Log.d("NearbyCon java", "onEndpointLost");
|
Log.d("nearby_connections", "onEndpointLost");
|
||||||
Map<String, Object> args = new HashMap<>();
|
Map<String, Object> args = new HashMap<>();
|
||||||
args.put("endpointId", endpointId);
|
args.put("endpointId", endpointId);
|
||||||
channel.invokeMethod("dis.onEndpointLost", args);
|
channel.invokeMethod("dis.onEndpointLost", args);
|
||||||
|
@ -32,7 +32,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "com.pkmnapps.nearby_connections_example"
|
applicationId "com.pkmnapps.nearby_connections_example"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
@ -43,7 +42,6 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ class _MyBodyState extends State<Body> {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
String a = Random().nextInt(100).toString();
|
String a = Random().nextInt(100).toString();
|
||||||
showSnackbar("Sending $a to $cId");
|
showSnackbar("Sending $a to $cId");
|
||||||
Nearby().sendPayload(cId, Uint8List.fromList(a.codeUnits));
|
Nearby().sendBytesPayload(cId, Uint8List.fromList(a.codeUnits));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
|
@ -73,7 +73,7 @@ packages:
|
|||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.1.3+1"
|
version: "1.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1,427 +1,6 @@
|
|||||||
import 'dart:async';
|
/// https://pub.dev/packages/nearby_connections#-readme-tab-
|
||||||
import 'dart:typed_data';
|
library nearby_connections;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
export 'src/classes.dart';
|
||||||
import 'package:flutter/services.dart';
|
export 'src/defs.dart';
|
||||||
|
export 'src/nearby_connections.dart';
|
||||||
/// **P2P_CLUSTER** - best for small payloads and multiplayer games
|
|
||||||
///
|
|
||||||
/// **P2P_STAR** - best for medium payloads, higher bandwidth than cluster
|
|
||||||
///
|
|
||||||
/// **P2P_POINT_TO_POINT** - single connection, very high bandwidth
|
|
||||||
enum Strategy { P2P_CLUSTER, P2P_STAR, P2P_POINT_TO_POINT }
|
|
||||||
enum Status { CONNECTED, REJECTED, ERROR }
|
|
||||||
enum PayloadStatus { NONE, SUCCESS, FAILURE, IN_PROGRRESS, CANCELED }
|
|
||||||
enum PayloadType { NONE, BYTES, FILE, STREAM }
|
|
||||||
typedef void OnConnctionInitiated(
|
|
||||||
String endpointId, ConnectionInfo connectionInfo);
|
|
||||||
typedef void OnConnectionResult(String endpointId, Status status);
|
|
||||||
typedef void OnDisconnected(String endpointId);
|
|
||||||
|
|
||||||
typedef void OnEndpointFound(
|
|
||||||
String endpointId, String endpointName, String serviceId);
|
|
||||||
typedef void OnEndpointLost(String endpointId);
|
|
||||||
|
|
||||||
/// Bytes may be null if [Payload.type] is not [PayloadType.BYTES]
|
|
||||||
class Payload {
|
|
||||||
int id;
|
|
||||||
PayloadType type;
|
|
||||||
Uint8List bytes;
|
|
||||||
|
|
||||||
Payload({
|
|
||||||
this.id,
|
|
||||||
this.bytes,
|
|
||||||
this.type = PayloadType.NONE,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// gives payload status, bytes transfered and total bytes.
|
|
||||||
class PayloadTransferUpdate {
|
|
||||||
int id, bytesTransferred, totalBytes;
|
|
||||||
PayloadStatus status;
|
|
||||||
|
|
||||||
PayloadTransferUpdate({
|
|
||||||
this.id,
|
|
||||||
this.bytesTransferred,
|
|
||||||
this.totalBytes,
|
|
||||||
this.status = PayloadStatus.NONE,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// For Bytes, this contains the bytes data
|
|
||||||
///
|
|
||||||
/// For File, this marks the start of transfer
|
|
||||||
///
|
|
||||||
/// Uint8List bytes may be null, if [type] is not [PayloadType.BYTES]
|
|
||||||
typedef void OnPayloadReceived(String endpointId, Payload payload);
|
|
||||||
|
|
||||||
/// Called only once for Bytes and repeatedly for File until transfer is complete
|
|
||||||
typedef void OnPayloadTransferUpdate(
|
|
||||||
String endpointId, PayloadTransferUpdate payloadTransferUpdate);
|
|
||||||
|
|
||||||
// typedef void OnPayloadTransferUpdate();
|
|
||||||
/// The NearbyConnection class
|
|
||||||
///
|
|
||||||
/// Only one instance is maintained
|
|
||||||
/// even on calling Nearby() multiple times
|
|
||||||
///
|
|
||||||
/// All methods are asynchronous.
|
|
||||||
class Nearby {
|
|
||||||
//for maintaining only 1 instance of this class
|
|
||||||
static Nearby _instance;
|
|
||||||
|
|
||||||
factory Nearby() {
|
|
||||||
if (_instance == null) {
|
|
||||||
_instance = Nearby._();
|
|
||||||
}
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Nearby._() {
|
|
||||||
_channel.setMethodCallHandler((handler) {
|
|
||||||
print("=========in handler============");
|
|
||||||
|
|
||||||
Map<dynamic, dynamic> args = handler.arguments;
|
|
||||||
|
|
||||||
print(handler.method);
|
|
||||||
args.forEach((s, d) {
|
|
||||||
print(s + " : " + d.toString());
|
|
||||||
});
|
|
||||||
print("=====================");
|
|
||||||
switch (handler.method) {
|
|
||||||
case "ad.onConnectionInitiated":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
String endpointName = args['endpointName'];
|
|
||||||
String authenticationToken = args['authenticationToken'];
|
|
||||||
bool isIncomingConnection = args['isIncomingConnection'];
|
|
||||||
|
|
||||||
_advertConnectionInitiated?.call(
|
|
||||||
endpointId,
|
|
||||||
ConnectionInfo(
|
|
||||||
endpointName, authenticationToken, isIncomingConnection));
|
|
||||||
|
|
||||||
return null;
|
|
||||||
case "ad.onConnectionResult":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
Status statusCode = Status.values[args['statusCode']];
|
|
||||||
|
|
||||||
_advertConnectionResult?.call(endpointId, statusCode);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
case "ad.onDisconnected":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
|
|
||||||
_advertDisconnected?.call(endpointId);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
case "dis.onConnectionInitiated":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
String endpointName = args['endpointName'];
|
|
||||||
String authenticationToken = args['authenticationToken'];
|
|
||||||
bool isIncomingConnection = args['isIncomingConnection'];
|
|
||||||
|
|
||||||
_discoverConnectionInitiated?.call(
|
|
||||||
endpointId,
|
|
||||||
ConnectionInfo(
|
|
||||||
endpointName, authenticationToken, isIncomingConnection));
|
|
||||||
|
|
||||||
return null;
|
|
||||||
case "dis.onConnectionResult":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
Status statusCode = Status.values[args['statusCode']];
|
|
||||||
|
|
||||||
_discoverConnectionResult?.call(endpointId, statusCode);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
case "dis.onDisconnected":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
|
|
||||||
_discoverDisconnected?.call(endpointId);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
case "dis.onEndpointFound":
|
|
||||||
print("in switch");
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
String endpointName = args['endpointName'];
|
|
||||||
String serviceId = args['serviceId'];
|
|
||||||
_onEndpointFound?.call(endpointId, endpointName, serviceId);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
case "dis.onEndpointLost":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
|
|
||||||
_onEndpointLost?.call(endpointId);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
case "onPayloadReceived":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
int type = args['type'];
|
|
||||||
Uint8List bytes = args['bytes'];
|
|
||||||
int payloadId = args['payloadId'];
|
|
||||||
|
|
||||||
Payload payload = Payload(
|
|
||||||
type: PayloadType.values[type],
|
|
||||||
bytes: bytes,
|
|
||||||
id: payloadId,
|
|
||||||
);
|
|
||||||
|
|
||||||
_onPayloadReceived?.call(endpointId, payload);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "onPayloadTransferUpdate":
|
|
||||||
String endpointId = args['endpointId'];
|
|
||||||
int payloadId = args['payloadId'];
|
|
||||||
int status = args['status'];
|
|
||||||
int bytesTransferred = args['bytesTransferred'];
|
|
||||||
int totalBytes = args['totalBytes'];
|
|
||||||
|
|
||||||
PayloadTransferUpdate payloadTransferUpdate = PayloadTransferUpdate(
|
|
||||||
id: payloadId,
|
|
||||||
status: PayloadStatus.values[status],
|
|
||||||
bytesTransferred: bytesTransferred,
|
|
||||||
totalBytes: totalBytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
_onPayloadTransferUpdate?.call(endpointId, payloadTransferUpdate);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
OnConnctionInitiated _advertConnectionInitiated, _discoverConnectionInitiated;
|
|
||||||
OnConnectionResult _advertConnectionResult, _discoverConnectionResult;
|
|
||||||
OnDisconnected _advertDisconnected, _discoverDisconnected;
|
|
||||||
|
|
||||||
OnEndpointFound _onEndpointFound;
|
|
||||||
OnEndpointLost _onEndpointLost;
|
|
||||||
|
|
||||||
OnPayloadReceived _onPayloadReceived;
|
|
||||||
OnPayloadTransferUpdate _onPayloadTransferUpdate;
|
|
||||||
|
|
||||||
static const MethodChannel _channel =
|
|
||||||
const MethodChannel('nearby_connections');
|
|
||||||
|
|
||||||
/// Convinience method
|
|
||||||
///
|
|
||||||
/// retruns true/false based on location permissions.
|
|
||||||
/// Discovery cannot be started with insufficient permission
|
|
||||||
Future<bool> checkPermissions() async => await _channel.invokeMethod(
|
|
||||||
'checkPermissions',
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Convinience method
|
|
||||||
///
|
|
||||||
/// Asks location permission
|
|
||||||
Future<void> askPermission() async {
|
|
||||||
await _channel.invokeMethod(
|
|
||||||
'askPermissions',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start Advertising
|
|
||||||
///
|
|
||||||
/// [userNickName] and [strategy] should not be null
|
|
||||||
Future<bool> startAdvertising(
|
|
||||||
String userNickName,
|
|
||||||
Strategy strategy, {
|
|
||||||
@required OnConnctionInitiated onConnectionInitiated,
|
|
||||||
@required OnConnectionResult onConnectionResult,
|
|
||||||
@required OnDisconnected onDisconnected,
|
|
||||||
}) async {
|
|
||||||
assert(userNickName != null && strategy != null);
|
|
||||||
|
|
||||||
this._advertConnectionInitiated = onConnectionInitiated;
|
|
||||||
this._advertConnectionResult = onConnectionResult;
|
|
||||||
this._advertDisconnected = onDisconnected;
|
|
||||||
|
|
||||||
return await _channel.invokeMethod('startAdvertising', <String, dynamic>{
|
|
||||||
'userNickName': userNickName,
|
|
||||||
'strategy': strategy.index
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stop Advertising
|
|
||||||
///
|
|
||||||
/// This doesn't disconnect from any connected Endpoint
|
|
||||||
///
|
|
||||||
/// For disconnection use
|
|
||||||
/// [stopAllEndpoints] or [disconnectFromEndpoint]
|
|
||||||
Future<void> stopAdvertising() async {
|
|
||||||
await _channel.invokeMethod('stopAdvertising');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start Discovery
|
|
||||||
///
|
|
||||||
/// [userNickName] and [strategy] should not be null
|
|
||||||
Future<bool> startDiscovery(
|
|
||||||
String userNickName,
|
|
||||||
Strategy strategy, {
|
|
||||||
@required OnEndpointFound onEndpointFound,
|
|
||||||
@required OnEndpointLost onEndpointLost,
|
|
||||||
}) async {
|
|
||||||
assert(userNickName != null && strategy != null);
|
|
||||||
this._onEndpointFound = onEndpointFound;
|
|
||||||
this._onEndpointLost = onEndpointLost;
|
|
||||||
|
|
||||||
return await _channel.invokeMethod('startDiscovery', <String, dynamic>{
|
|
||||||
'userNickName': userNickName,
|
|
||||||
'strategy': strategy.index
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stop Discovery
|
|
||||||
///
|
|
||||||
/// This doesn't disconnect from any connected Endpoint
|
|
||||||
///
|
|
||||||
/// It is reccomended to call this method
|
|
||||||
/// once you have connected to an endPoint
|
|
||||||
/// as it uses heavy radio operations
|
|
||||||
/// which may affect connection speed and integrity
|
|
||||||
Future<void> stopDiscovery() async {
|
|
||||||
await _channel.invokeMethod('stopDiscovery');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stop All Endpoints
|
|
||||||
///
|
|
||||||
/// Disconnects all connections,
|
|
||||||
/// this will call the onDisconnected method on callbacks of
|
|
||||||
/// all connected endPoints
|
|
||||||
Future<void> stopAllEndpoints() async {
|
|
||||||
await _channel.invokeMethod('stopAllEndpoints');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Disconnect from Endpoints
|
|
||||||
///
|
|
||||||
/// Disconnects the connections to given endPointId
|
|
||||||
/// this will call the onDisconnected method on callbacks of
|
|
||||||
/// connected endPoint
|
|
||||||
Future<void> disconnectFromEndpoint(String endpointId) async {
|
|
||||||
await _channel.invokeMethod(
|
|
||||||
'disconnectFromEndpoint', <String, dynamic>{'endpointId': endpointId});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Request Connection
|
|
||||||
///
|
|
||||||
/// Call this method when Discoverer calls the
|
|
||||||
/// [OnEndpointFound] method
|
|
||||||
///
|
|
||||||
/// This will call the [OnConnctionInitiated] method on
|
|
||||||
/// both the endPoint and this
|
|
||||||
Future<bool> requestConnection(
|
|
||||||
String userNickName,
|
|
||||||
String endpointId, {
|
|
||||||
@required OnConnctionInitiated onConnectionInitiated,
|
|
||||||
@required OnConnectionResult onConnectionResult,
|
|
||||||
@required OnDisconnected onDisconnected,
|
|
||||||
}) async {
|
|
||||||
this._discoverConnectionInitiated = onConnectionInitiated;
|
|
||||||
this._discoverConnectionResult = onConnectionResult;
|
|
||||||
this._discoverDisconnected = onDisconnected;
|
|
||||||
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'requestConnection',
|
|
||||||
<String, dynamic>{
|
|
||||||
'userNickName': userNickName,
|
|
||||||
'endpointId': endpointId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Needs be called by both discoverer and advertiser
|
|
||||||
/// to connect
|
|
||||||
///
|
|
||||||
/// Call this in [OnConnctionInitiated]
|
|
||||||
/// to accept an incoming connection
|
|
||||||
///
|
|
||||||
/// [OnConnectionResult] is called on both
|
|
||||||
/// only if both of them accept the connection
|
|
||||||
Future<bool> acceptConnection(
|
|
||||||
String endpointId, {
|
|
||||||
@required OnPayloadReceived onPayLoadRecieved,
|
|
||||||
OnPayloadTransferUpdate onPayloadTransferUpdate,
|
|
||||||
}) async {
|
|
||||||
this._onPayloadReceived = onPayLoadRecieved;
|
|
||||||
this._onPayloadTransferUpdate = onPayloadTransferUpdate;
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'acceptConnection',
|
|
||||||
<String, dynamic>{
|
|
||||||
'endpointId': endpointId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reject Connection
|
|
||||||
///
|
|
||||||
/// To be called by both discoverer and advertiser
|
|
||||||
///
|
|
||||||
/// Call this in [OnConnctionInitiated]
|
|
||||||
/// to reject an incoming connection
|
|
||||||
///
|
|
||||||
/// [OnConnectionResult] is called on both
|
|
||||||
/// even if one of them rejects the connection
|
|
||||||
Future<bool> rejectConnection(String endpointId) async {
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'rejectConnection',
|
|
||||||
<String, dynamic>{
|
|
||||||
'endpointId': endpointId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Send bytes [Uint8List] payload to endpoint
|
|
||||||
///
|
|
||||||
/// Convert String to Uint8List as follows
|
|
||||||
///
|
|
||||||
/// ```dart
|
|
||||||
/// String a = "hello";
|
|
||||||
/// Uint8List bytes = Uint8List.fromList(a.codeUnits);
|
|
||||||
/// ```
|
|
||||||
Future<void> sendPayload(String endpointId, Uint8List bytes) async {
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'sendPayload',
|
|
||||||
<String, dynamic>{
|
|
||||||
'endpointId': endpointId,
|
|
||||||
'bytes': bytes,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the payloadID as soon as file transfer has begun
|
|
||||||
///
|
|
||||||
/// File is received in DOWNLOADS_DIRECTORY and is given a generic name
|
|
||||||
/// without extension
|
|
||||||
/// You must also send a bytes payload to send the filename and extension
|
|
||||||
/// so that receiver can rename the file accordingly
|
|
||||||
/// Send the payloadID and filename to receiver as bytes payload
|
|
||||||
Future<int> sendFilePayload(String endpointId, String filePath) async {
|
|
||||||
return await _channel.invokeMethod(
|
|
||||||
'sendFilePayload',
|
|
||||||
<String, dynamic>{
|
|
||||||
'endpointId': endpointId,
|
|
||||||
'filePath': filePath,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ConnectionInfo class
|
|
||||||
///
|
|
||||||
/// Its a parameter in [OnConnctionInitiated]
|
|
||||||
///
|
|
||||||
/// [endPointName] is userNickName of requester
|
|
||||||
///
|
|
||||||
/// [authenticationToken] can be used to check the connection security
|
|
||||||
/// it must be same on both devices
|
|
||||||
class ConnectionInfo {
|
|
||||||
String endpointName, authenticationToken;
|
|
||||||
bool isIncomingConnection;
|
|
||||||
|
|
||||||
ConnectionInfo(
|
|
||||||
this.endpointName, this.authenticationToken, this.isIncomingConnection);
|
|
||||||
}
|
|
||||||
//TODO remove errors on failure for smooth experience
|
|
||||||
//TODO expose only relevant parts as library
|
|
||||||
//TODO publish to pub.dartlang
|
|
45
lib/src/classes.dart
Normal file
45
lib/src/classes.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// contains custom classes
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:nearby_connections/src/defs.dart';
|
||||||
|
|
||||||
|
/// Bytes may be null if [Payload.type] is not [PayloadType.BYTES]
|
||||||
|
class Payload {
|
||||||
|
int id;
|
||||||
|
PayloadType type;
|
||||||
|
Uint8List bytes;
|
||||||
|
|
||||||
|
Payload({
|
||||||
|
this.id,
|
||||||
|
this.bytes,
|
||||||
|
this.type = PayloadType.NONE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class PayloadTransferUpdate {
|
||||||
|
int id, bytesTransferred, totalBytes;
|
||||||
|
PayloadStatus status;
|
||||||
|
|
||||||
|
PayloadTransferUpdate({
|
||||||
|
this.id,
|
||||||
|
this.bytesTransferred,
|
||||||
|
this.totalBytes,
|
||||||
|
this.status = PayloadStatus.NONE,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ConnectionInfo class
|
||||||
|
///
|
||||||
|
/// Its a parameter in [OnConnctionInitiated]
|
||||||
|
///
|
||||||
|
/// [endPointName] is userNickName of requester
|
||||||
|
///
|
||||||
|
/// [authenticationToken] can be used to check the connection security
|
||||||
|
/// it must be same on both devices
|
||||||
|
class ConnectionInfo {
|
||||||
|
String endpointName, authenticationToken;
|
||||||
|
bool isIncomingConnection;
|
||||||
|
|
||||||
|
ConnectionInfo(
|
||||||
|
this.endpointName, this.authenticationToken, this.isIncomingConnection);
|
||||||
|
}
|
46
lib/src/defs.dart
Normal file
46
lib/src/defs.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// contains enums and typedefs
|
||||||
|
|
||||||
|
import 'package:nearby_connections/src/classes.dart';
|
||||||
|
|
||||||
|
/// **P2P_CLUSTER** - best for small payloads and multiplayer games
|
||||||
|
///
|
||||||
|
/// **P2P_STAR** - best for medium payloads, higher bandwidth than cluster
|
||||||
|
///
|
||||||
|
/// **P2P_POINT_TO_POINT** - single connection, very high bandwidth
|
||||||
|
enum Strategy { P2P_CLUSTER, P2P_STAR, P2P_POINT_TO_POINT }
|
||||||
|
enum Status { CONNECTED, REJECTED, ERROR }
|
||||||
|
enum PayloadStatus { NONE, SUCCESS, FAILURE, IN_PROGRRESS, CANCELED }
|
||||||
|
enum PayloadType { NONE, BYTES, FILE, STREAM }
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Advertising lifecycle callbacks
|
||||||
|
//
|
||||||
|
typedef void OnConnctionInitiated(
|
||||||
|
String endpointId, ConnectionInfo connectionInfo);
|
||||||
|
typedef void OnConnectionResult(String endpointId, Status status);
|
||||||
|
typedef void OnDisconnected(String endpointId);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Discovery lifecycle callbacks
|
||||||
|
//
|
||||||
|
typedef void OnEndpointFound(
|
||||||
|
String endpointId, String endpointName, String serviceId);
|
||||||
|
typedef void OnEndpointLost(String endpointId);
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
/// For Bytes, this contains the bytes data
|
||||||
|
///
|
||||||
|
/// For File, this marks the start of transfer
|
||||||
|
///
|
||||||
|
/// Uint8List bytes may be null, if [type] is not [PayloadType.BYTES]
|
||||||
|
typedef void OnPayloadReceived(String endpointId, Payload payload);
|
||||||
|
|
||||||
|
/// Called only once for Bytes and repeatedly for File until transfer is complete
|
||||||
|
typedef void OnPayloadTransferUpdate(
|
||||||
|
String endpointId, PayloadTransferUpdate payloadTransferUpdate);
|
345
lib/src/nearby_connections.dart
Normal file
345
lib/src/nearby_connections.dart
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:nearby_connections/src/defs.dart';
|
||||||
|
import 'package:nearby_connections/src/classes.dart';
|
||||||
|
|
||||||
|
/// The NearbyConnection class
|
||||||
|
///
|
||||||
|
/// Only one instance is maintained
|
||||||
|
/// even on calling Nearby() multiple times
|
||||||
|
///
|
||||||
|
/// All methods are asynchronous.
|
||||||
|
class Nearby {
|
||||||
|
//Singleton pattern for maintaining only 1 instance of this class
|
||||||
|
static Nearby _instance;
|
||||||
|
factory Nearby() {
|
||||||
|
if (_instance == null) {
|
||||||
|
_instance = Nearby._();
|
||||||
|
}
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nearby._() {
|
||||||
|
_channel.setMethodCallHandler((handler) {
|
||||||
|
Map<dynamic, dynamic> args = handler.arguments;
|
||||||
|
switch (handler.method) {
|
||||||
|
case "ad.onConnectionInitiated":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
String endpointName = args['endpointName'];
|
||||||
|
String authenticationToken = args['authenticationToken'];
|
||||||
|
bool isIncomingConnection = args['isIncomingConnection'];
|
||||||
|
|
||||||
|
_advertConnectionInitiated?.call(
|
||||||
|
endpointId,
|
||||||
|
ConnectionInfo(
|
||||||
|
endpointName, authenticationToken, isIncomingConnection));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case "ad.onConnectionResult":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
Status statusCode = Status.values[args['statusCode']];
|
||||||
|
|
||||||
|
_advertConnectionResult?.call(endpointId, statusCode);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case "ad.onDisconnected":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
|
||||||
|
_advertDisconnected?.call(endpointId);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case "dis.onConnectionInitiated":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
String endpointName = args['endpointName'];
|
||||||
|
String authenticationToken = args['authenticationToken'];
|
||||||
|
bool isIncomingConnection = args['isIncomingConnection'];
|
||||||
|
|
||||||
|
_discoverConnectionInitiated?.call(
|
||||||
|
endpointId,
|
||||||
|
ConnectionInfo(
|
||||||
|
endpointName, authenticationToken, isIncomingConnection));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case "dis.onConnectionResult":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
Status statusCode = Status.values[args['statusCode']];
|
||||||
|
|
||||||
|
_discoverConnectionResult?.call(endpointId, statusCode);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case "dis.onDisconnected":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
|
||||||
|
_discoverDisconnected?.call(endpointId);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case "dis.onEndpointFound":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
String endpointName = args['endpointName'];
|
||||||
|
String serviceId = args['serviceId'];
|
||||||
|
_onEndpointFound?.call(endpointId, endpointName, serviceId);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case "dis.onEndpointLost":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
|
||||||
|
_onEndpointLost?.call(endpointId);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
case "onPayloadReceived":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
int type = args['type'];
|
||||||
|
Uint8List bytes = args['bytes'];
|
||||||
|
int payloadId = args['payloadId'];
|
||||||
|
|
||||||
|
Payload payload = Payload(
|
||||||
|
type: PayloadType.values[type],
|
||||||
|
bytes: bytes,
|
||||||
|
id: payloadId,
|
||||||
|
);
|
||||||
|
|
||||||
|
_onPayloadReceived?.call(endpointId, payload);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "onPayloadTransferUpdate":
|
||||||
|
String endpointId = args['endpointId'];
|
||||||
|
int payloadId = args['payloadId'];
|
||||||
|
int status = args['status'];
|
||||||
|
int bytesTransferred = args['bytesTransferred'];
|
||||||
|
int totalBytes = args['totalBytes'];
|
||||||
|
|
||||||
|
PayloadTransferUpdate payloadTransferUpdate = PayloadTransferUpdate(
|
||||||
|
id: payloadId,
|
||||||
|
status: PayloadStatus.values[status],
|
||||||
|
bytesTransferred: bytesTransferred,
|
||||||
|
totalBytes: totalBytes,
|
||||||
|
);
|
||||||
|
|
||||||
|
_onPayloadTransferUpdate?.call(endpointId, payloadTransferUpdate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//for advertisers
|
||||||
|
OnConnctionInitiated _advertConnectionInitiated, _discoverConnectionInitiated;
|
||||||
|
OnConnectionResult _advertConnectionResult, _discoverConnectionResult;
|
||||||
|
OnDisconnected _advertDisconnected, _discoverDisconnected;
|
||||||
|
|
||||||
|
//for discoverers
|
||||||
|
OnEndpointFound _onEndpointFound;
|
||||||
|
OnEndpointLost _onEndpointLost;
|
||||||
|
|
||||||
|
//for receiving payload
|
||||||
|
OnPayloadReceived _onPayloadReceived;
|
||||||
|
OnPayloadTransferUpdate _onPayloadTransferUpdate;
|
||||||
|
|
||||||
|
static const MethodChannel _channel =
|
||||||
|
const MethodChannel('nearby_connections');
|
||||||
|
|
||||||
|
/// Convinience method
|
||||||
|
///
|
||||||
|
/// retruns true/false based on location permissions.
|
||||||
|
/// Discovery cannot be started with insufficient permission
|
||||||
|
Future<bool> checkPermissions() async => await _channel.invokeMethod(
|
||||||
|
'checkPermissions',
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Convinience method
|
||||||
|
///
|
||||||
|
/// Asks location permission
|
||||||
|
Future<void> askPermission() async => await _channel.invokeMethod(
|
||||||
|
'askPermissions',
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Start Advertising
|
||||||
|
///
|
||||||
|
/// [userNickName] and [strategy] should not be null
|
||||||
|
Future<bool> startAdvertising(
|
||||||
|
String userNickName,
|
||||||
|
Strategy strategy, {
|
||||||
|
@required OnConnctionInitiated onConnectionInitiated,
|
||||||
|
@required OnConnectionResult onConnectionResult,
|
||||||
|
@required OnDisconnected onDisconnected,
|
||||||
|
}) async {
|
||||||
|
assert(userNickName != null && strategy != null);
|
||||||
|
|
||||||
|
this._advertConnectionInitiated = onConnectionInitiated;
|
||||||
|
this._advertConnectionResult = onConnectionResult;
|
||||||
|
this._advertDisconnected = onDisconnected;
|
||||||
|
|
||||||
|
return await _channel.invokeMethod('startAdvertising', <String, dynamic>{
|
||||||
|
'userNickName': userNickName,
|
||||||
|
'strategy': strategy.index
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop Advertising
|
||||||
|
///
|
||||||
|
/// This doesn't disconnect from any connected Endpoint
|
||||||
|
///
|
||||||
|
/// For disconnection use
|
||||||
|
/// [stopAllEndpoints] or [disconnectFromEndpoint]
|
||||||
|
Future<void> stopAdvertising() async {
|
||||||
|
await _channel.invokeMethod('stopAdvertising');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Start Discovery
|
||||||
|
///
|
||||||
|
/// [userNickName] and [strategy] should not be null
|
||||||
|
Future<bool> startDiscovery(
|
||||||
|
String userNickName,
|
||||||
|
Strategy strategy, {
|
||||||
|
@required OnEndpointFound onEndpointFound,
|
||||||
|
@required OnEndpointLost onEndpointLost,
|
||||||
|
}) async {
|
||||||
|
assert(userNickName != null && strategy != null);
|
||||||
|
this._onEndpointFound = onEndpointFound;
|
||||||
|
this._onEndpointLost = onEndpointLost;
|
||||||
|
|
||||||
|
return await _channel.invokeMethod('startDiscovery', <String, dynamic>{
|
||||||
|
'userNickName': userNickName,
|
||||||
|
'strategy': strategy.index
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop Discovery
|
||||||
|
///
|
||||||
|
/// This doesn't disconnect from already connected Endpoint
|
||||||
|
///
|
||||||
|
/// It is reccomended to call this method
|
||||||
|
/// once you have connected to an endPoint
|
||||||
|
/// as discovery uses heavy radio operations
|
||||||
|
/// which may affect connection speed and integrity
|
||||||
|
Future<void> stopDiscovery() async {
|
||||||
|
await _channel.invokeMethod('stopDiscovery');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stop All Endpoints
|
||||||
|
///
|
||||||
|
/// Disconnects all connections,
|
||||||
|
/// this will call the onDisconnected method on callbacks of
|
||||||
|
/// all connected endPoints
|
||||||
|
Future<void> stopAllEndpoints() async {
|
||||||
|
await _channel.invokeMethod('stopAllEndpoints');
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disconnect from Endpoints
|
||||||
|
///
|
||||||
|
/// Disconnects the connections to given endPointId
|
||||||
|
/// this will call the onDisconnected method on callbacks of
|
||||||
|
/// connected endPoint
|
||||||
|
Future<void> disconnectFromEndpoint(String endpointId) async {
|
||||||
|
await _channel.invokeMethod(
|
||||||
|
'disconnectFromEndpoint', <String, dynamic>{'endpointId': endpointId});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Request Connection
|
||||||
|
///
|
||||||
|
/// Call this method when Discoverer calls the
|
||||||
|
/// [OnEndpointFound] method
|
||||||
|
///
|
||||||
|
/// This will call the [OnConnctionInitiated] method on
|
||||||
|
/// both the endPoint and this
|
||||||
|
Future<bool> requestConnection(
|
||||||
|
String userNickName,
|
||||||
|
String endpointId, {
|
||||||
|
@required OnConnctionInitiated onConnectionInitiated,
|
||||||
|
@required OnConnectionResult onConnectionResult,
|
||||||
|
@required OnDisconnected onDisconnected,
|
||||||
|
}) async {
|
||||||
|
this._discoverConnectionInitiated = onConnectionInitiated;
|
||||||
|
this._discoverConnectionResult = onConnectionResult;
|
||||||
|
this._discoverDisconnected = onDisconnected;
|
||||||
|
|
||||||
|
return await _channel.invokeMethod(
|
||||||
|
'requestConnection',
|
||||||
|
<String, dynamic>{
|
||||||
|
'userNickName': userNickName,
|
||||||
|
'endpointId': endpointId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Needs be called by both discoverer and advertiser
|
||||||
|
/// to connect
|
||||||
|
///
|
||||||
|
/// Call this in [OnConnctionInitiated]
|
||||||
|
/// to accept an incoming connection
|
||||||
|
///
|
||||||
|
/// [OnConnectionResult] is called on both
|
||||||
|
/// only if both of them accept the connection
|
||||||
|
Future<bool> acceptConnection(
|
||||||
|
String endpointId, {
|
||||||
|
@required OnPayloadReceived onPayLoadRecieved,
|
||||||
|
OnPayloadTransferUpdate onPayloadTransferUpdate,
|
||||||
|
}) async {
|
||||||
|
this._onPayloadReceived = onPayLoadRecieved;
|
||||||
|
this._onPayloadTransferUpdate = onPayloadTransferUpdate;
|
||||||
|
return await _channel.invokeMethod(
|
||||||
|
'acceptConnection',
|
||||||
|
<String, dynamic>{
|
||||||
|
'endpointId': endpointId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reject Connection
|
||||||
|
///
|
||||||
|
/// To be called by both discoverer and advertiser
|
||||||
|
///
|
||||||
|
/// Call this in [OnConnctionInitiated]
|
||||||
|
/// to reject an incoming connection
|
||||||
|
///
|
||||||
|
/// [OnConnectionResult] is called on both
|
||||||
|
/// even if one of them rejects the connection
|
||||||
|
Future<bool> rejectConnection(String endpointId) async {
|
||||||
|
return await _channel.invokeMethod(
|
||||||
|
'rejectConnection',
|
||||||
|
<String, dynamic>{
|
||||||
|
'endpointId': endpointId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send bytes [Uint8List] payload to endpoint
|
||||||
|
///
|
||||||
|
/// Convert String to Uint8List as follows
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// String a = "hello";
|
||||||
|
/// Uint8List bytes = Uint8List.fromList(a.codeUnits);
|
||||||
|
/// ```
|
||||||
|
Future<void> sendBytesPayload(String endpointId, Uint8List bytes) async {
|
||||||
|
return await _channel.invokeMethod(
|
||||||
|
'sendPayload',
|
||||||
|
<String, dynamic>{
|
||||||
|
'endpointId': endpointId,
|
||||||
|
'bytes': bytes,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the payloadID as soon as file transfer has begun
|
||||||
|
///
|
||||||
|
/// File is received in DOWNLOADS_DIRECTORY and is given a generic name
|
||||||
|
/// without extension
|
||||||
|
/// You must also send a bytes payload to send the filename and extension
|
||||||
|
/// so that receiver can rename the file accordingly
|
||||||
|
/// Send the payloadID and filename to receiver as bytes payload
|
||||||
|
Future<int> sendFilePayload(String endpointId, String filePath) async {
|
||||||
|
return await _channel.invokeMethod(
|
||||||
|
'sendFilePayload',
|
||||||
|
<String, dynamic>{
|
||||||
|
'endpointId': endpointId,
|
||||||
|
'filePath': filePath,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
name: nearby_connections
|
name: nearby_connections
|
||||||
description: Plugin for the android NearbyConnections API. Currently sending bytes (Uint8List) is possible.
|
description: Plugin for the android NearbyConnections API. Bytes and Files Supported.
|
||||||
version: 0.1.3+1
|
version: 1.0.0
|
||||||
author: Prerak Mann <mannprerak2@gmail.com>
|
author: Prerak Mann <mannprerak2@gmail.com>
|
||||||
homepage: https://github.com/mannprerak2/nearby_connections
|
homepage: https://github.com/mannprerak2/nearby_connections
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user