搜索插件、代码仓与 APP 分类

插件详情v4.3.0

nearby_connections

Android Nearby Connections API 的插件。支持字节和文件。

Android
近 30 天下载
1.1万
喜欢数
144
Pub 分数
160

安装插件

flutter pub add nearby_connections

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

nearby_connections 包为 Flutter 提供了与 Android Nearby Connections API 的集成,支持通过蓝牙、Wi-Fi 和 NFC 在设备之间进行点对点通信。它支持原始字节和文件的传输,非常适合用于基于位置的本地数据共享应用。该插件轻量且专为 Android 设计,利用原生功能实现可靠、低延迟的连接。它适用于协作类应用、多人游戏或无需互联网依赖的直接设备间交互的文件共享工具。

适合场景

  • 设备间的本地文件共享
  • 实时多人游戏同步
  • 群组设置中的离线数据交换
  • 设备间通信的快速设置
  • 无云后端的协作应用功能

主要特点

  • 支持字节和文件传输
  • 使用 Android 原生 Nearby Connections API
  • 专为低延迟、短距离通信优化
  • 适用于 Android 的简单 Flutter 界面
  • 内置发现和连接管理

适合对象

  • 仅限 Android 的应用,需要本地设备连接
  • 需要快速离线数据传输的应用
  • 开发协作或社交功能的开发者
  • 项目避免依赖互联网或云服务
  • 基于接近度交互的原型

使用建议

  • 仅限 Android 平台
  • 需要适当的权限(蓝牙、位置)
  • 无 iOS 支持
  • 取决于设备与附近连接的兼容性
  • 后台操作可能受到 Android OS 的限制

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

nearby_connections

An ANDROID flutter plugin for the Nearby Connections API Currently supports Bytes and Files.

Transfer Data between multiple connected devices using fully offline peer to peer networking

pub package Stars Forks

Table of Content

Setup

Note regarding Location(GPS)

While using this, Location/GPS service must be turned on or devices may disconnect more often, some devices may disconnect immediately.

Set Permissions

Add these to your project's android/src/main/AndroidManifest.xml

<!-- Required for Nearby Connections -->
<uses-permission android:maxSdkVersion="31" android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:maxSdkVersion="31" android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:maxSdkVersion="30" android:name="android.permission.BLUETOOTH" />
<uses-permission android:maxSdkVersion="30" android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:maxSdkVersion="28" android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:minSdkVersion="29" android:maxSdkVersion="31" android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:minSdkVersion="31" android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:minSdkVersion="31" android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:minSdkVersion="31" android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:minSdkVersion="32" android:name="android.permission.NEARBY_WIFI_DEVICES" />
<!-- Optional: only required for FILE payloads -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Note: Android 12+ has introduced some new bluetooth permissions - BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, BLUETOOTH_SCAN, which need to be handled as well. You may also need to set compileSdkVersion 32 in your build.gradle file.

Request Permissions

Since ACCESS_FINE_LOCATION, BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, BLUETOOTH_SCAN and READ_EXTERNAL_STORAGE are considered to be dangerous system permissions, in addition to adding them to your manifest, you must request these permissions at runtime.

You can use:

// location permission
await Permission.location.isGranted         // Check Permission
await Permission.location.request()         // Ask

// Check Location Status
await Permission.location.serviceStatus.isEnabled;

// location enable dialog
await Location.instance.requestService()

// external storage permission
await Permission.storage.isGranted          // Check Permission
await Permission.storage.request()          // Ask

// Bluetooth permissions
bool granted = !(await Future.wait([        // Check Permissions
    Permission.bluetooth.isGranted,
    Permission.bluetoothAdvertise.isGranted,
    Permission.bluetoothConnect.isGranted,
    Permission.bluetoothScan.isGranted,
])).any((element) => false);
[                                           // Ask Permissions
    Permission.bluetooth,
    Permission.bluetoothAdvertise,
    Permission.bluetoothConnect,
    Permission.bluetoothScan
].request();

// Check Bluetooth Status
await Permission.bluetooth.serviceStatus.isEnabled;


// Android 12+
await Permission.nearbyWifiDevices.request()

Checkout the Example in Repository for more details.

NOTE

Location/GPS service must be turned on or devices may disconnect more often, some devices may disconnect immediately.

Work Flow

The work flow is similar to the Android Nearby Connections library

Advertise for connection
try {
    bool a = await Nearby().startAdvertising(
        userName,
        strategy, // https://developers.google.com/nearby/connections/strategies
        onConnectionInitiated: (String id,ConnectionInfo info) {
        // Called whenever a discoverer requests connection
        },
        onConnectionResult: (String id,Status status) {
        // Called when connection is accepted/rejected
        },
        onDisconnected: (String id) {
        // Callled whenever a discoverer disconnects from advertiser
        },
        serviceId: "com.yourdomain.appname", // uniquely identifies your app
    );
} catch (exception) {
    // platform exceptions like unable to start bluetooth or insufficient permissions
}
Discover Advertisers
try {
    bool a = await Nearby().startDiscovery(
        userName,
        strategy, // https://developers.google.com/nearby/connections/strategies
        onEndpointFound: (String id,String userName, String serviceId) {
            // called when an advertiser is found
        },
        onEndpointLost: (String id) {
            //called when an advertiser is lost (only if we weren't connected to it )
        },
        serviceId: "com.yourdomain.appname", // uniquely identifies your app
    );
} catch (e) {
    // platform exceptions like unable to start bluetooth or insufficient permissions
}
Stopping Advertising and Discovery
Nearby().stopAdvertising();
Nearby().stopDiscovery();
// endpoints already discovered will still be available to connect
// even after stopping discovery
// You should stop discovery once you have found the intended advertiser
// this will reduce chances for disconnection
Request Connection
// to be called by discover whenever an endpoint is found
// callbacks are similar to those in startAdvertising method
try{
    Nearby().requestConnection(
        userName,
        id,
        onConnectionInitiated: (id, info) {
        },
        onConnectionResult: (id, status) {
        },
        onDisconnected: (id) {
        },
    );
}catch(exception){
    // called if request was invalid
}
Accept Connection
Nearby().acceptConnection(
    id,
    onPayLoadRecieved: (endpointId, payload) {
        // called whenever a payload is recieved.
    },
    onPayloadTransferUpdate: (endpointId, payloadTransferUpdate) {
        // gives status of a payload
        // e.g success/failure/in_progress
        // bytes transferred and total bytes etc
    }
);

Sending Data

Sending Bytes Payload
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/.nearby/ and given a generic name. You need to copy the file to another directory of your choice.

//creates file with generic name (without extension) in Downloads Directory
//its your responsibility to rename the file properly
Nearby().sendFilePayload(endpointId, filePath);

//Send filename as well so that receiver can move and rename the file
Nearby().sendBytesPayload(endpointId,fileNameEncodedWithPayloadId);
//e.g send a string like "payloadId:FileExtensionOrFullName" as bytes

//payloads are recieved by callback given to acceptConnection method.

Every payload has an ID which is same for sender and receiver.

You can get the uri of the file from Payload in onPayloadReceived function. We have a convenience method to copy the file to a location you want-

// Convenience method to copy file using it's `uri`.
final newPath = '${await getExternalStorageDirectory}/$fileName';
await Nearby().copyFileAndDeleteOriginal(uri, newPath);

Checkout the Example in Repository for more details.

所属分类

源码仓库

使用此插件的项目