react-native-wifi-p2p
is a library to provide WiFi Direct (Peer-To-Peer, P2P) service to react-native.
Important: currently only Android support realized. If you want to provide iOS support, then you should to note to react-native-multipeer repository.
This library will not work on emulator. If you want to use this library, you should test working it on real devices.
Test project with all API cases you can find here.
- Install library from
npm
npm install react-native-wifi-p2p --save
- Allow grant permission to WiFi module
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.wifi.p2p"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+ <uses-permission
+ android:required="true"
+ android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+ <uses-permission
+ android:required="true"
+ android:name="android.permission.ACCESS_WIFI_STATE"/>
+ <uses-permission
+ android:required="true"
+ android:name="android.permission.CHANGE_WIFI_STATE"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
- Append the following lines to
android/settings.gradle
include ':react-native-wifi-p2p'
project(':react-native-wifi-p2p').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-wifi-p2p/android')
- Insert the following lines inside the dependencies block in
android/app/build.gradle
:
compile project(':react-native-wifi-p2p')
-
Open up
android/app/src/main/java/[...]/MainApplication.java
- Add import
import io.wifi.p2p.WiFiP2PManagerPackage;
to the imports at the top of the file. - Add
new WiFiP2PManagerPackage()
to the list returned by thegetPackages()
method. Add a comma to the previous item if there's already something there.
- Add import
- subscribeOnPeersUpdates(callback)
- unsubscribeFromPeersUpdates(callback)
- subscribeOnConnectionInfoUpdates(callback)
- unsubscribeFromConnectionInfoUpdates(callback)
- getAvailablePeers()
- connect(deviceAddress)
- disconnect()
- createGroup()
- removeGroup()
- sendFile(pathToFile)
- receiveFile()
- sendMessage(message)
- receiveMessage()
- getConnectionInfo()
temporary
- getGroupInfo()
future
This method must calling before any using of others method, because here happened start initialization of react-native-wifi-p2p
module.
Recommend to initialize it on root files, but if your application has specific logic, then you can call it before directly using.
Notice, that recommend called only once.
initialize();
Return boolean status true/false
of initialization method.
isSuccessfulInitialize()
.then(isSuccessfulInitialize => console.log('isSuccessfulInitialize: ', status));
startDiscoveringPeers()
starting emit action to discover available devices. Note, that this function doesn't return any information about available devices/peers. It return information about successfully start.
startDiscoveringPeers()
.then(() => console.log('Starting of discovering was successful'))
.catch(err => console.error(`Something is gone wrong. Maybe your WiFi is disabled? Error details: ${err}`));
stopDiscoveringPeers()
prevent emit action to discover available devices. Note, that this function doesn't return any information about available devices/peers. It return information about successfully stopping of discovering.
stopDiscoveringPeers()
.then(() => console.log('Stop discovering was successful'))
.catch(err => console.error(`Something is gone wrong. Maybe your WiFi is disabled? Error details: ${err}`));
subscribeOnPeersUpdates(callback)
allow to subscribe on events, that will notify about availability of nearby devices.
subscribeOnPeersUpdates(({ devices }) => {
console.log(`New devices available: ${devices}`);
});
unsubscribeFromPeersUpdates((event) => console.log(event));
subscribeOnConnectionInfoUpdates((event) => {
console.log('Connection Info Updates: ', event);
});
unsubscribeFromConnectionInfoUpdates((event) => {
console.log('Unsubscribe from ConnectionInfoUpdates action: ', event);
});
If you don't want to always get notification from event emitter, when peers list has changed, you can use this method. This method will return info about nearby devices, that is available for searching, at the time of the call this method.
Important: before using this method you also need to call startDiscoveringPeers
. In other case you always will get empty array.
getAvailablePeers()
.then(({ devices }) => console.log(devices))
Connect to network. The devices found from the subscribeOnPeersUpdates
method. Should use deviceAddress
field from necessary device from array. This field represent a MAC address
that is used to connect.
connect('22:47:da:9d:58:83')
.then(() => console.log('Successfully connected'))
.catch(err => console.error('Something gone wrong. Details: ', err));
Disconnect from network. Should use when you want to reconnect or turn off wifi.
disconnect()
.then(() => console.log('Successfully disconnected'))
.catch(err => console.error('Something gone wrong. Details: ', err));
P2P STAR is a peer-to-peer strategy that supports a 1-to-N, or star-shaped, connection topology. In other words, this enables connecting devices within radio range (~100m) in a star shape, where each device can, at any given time, play the role of either a hub (where it can accept incoming connections from N other devices), or a spoke (where it can initiate an outgoing connection to a single hub), but not both. So achieve this goal you can use createGroup
method, so create your own group.
createGroup()
.then(() => console.log('Group created successfully!'))
.catch(err => console.error('Something gone wrong. Details: ', err));
Before exit of application you need to call this method, if earlier you created group via createGroup()
method.
removeGroup()
.then(() => console.log('Currently you don\'t belong to group!'))
.catch(err => console.error('Something gone wrong. Details: ', err));
You should call this method if you want to copy file from client side to server using wi-fi p2p feature. Before sending you should execute next steps:
- Create group on server side
- Connect to server-group from client side
- After establishing connection you should call
getConnectionInfo()
on client side - Call
receiveFile()
on server side (receiveFile
returnPromise<string>
- path to saved file) - Call
sendFile(pathToFile)
on client side, after resolvinggetConnectionInfo()
Note: now this method mark as unstable, because:
- You can't set folder for receiving file
- You can't send additional info about file (file name, file type and so on). Currently it saves like
${currentMsTime}.jpeg
- This method work async, but currently promise resolved before. It mean, that file will transferring, but promise already will be resolved (
receiveFile()
resolved as should be)
import { PermissionsAndroid } from 'react-native';
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
{
'title': 'Access to read',
'message': 'READ_EXTERNAL_STORAGE'
}
)
.then(granted => {
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use read operation")
} else {
console.log("Read operation permission denied")
}
})
.then(() => {
return PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
'title': 'Access to write',
'message': 'WRITE_EXTERNAL_STORAGE'
}
)
})
.then(() => {
return sendFile('path/to/file')
.then(() => console.log('File sent successfully'))
.catch(err => console.log('Error while file sending', err));
})
.catch(err => console.log(err));
You should call this method if you want to send from client side to server (group) using wi-fi p2p feature. Before sending you should execute next steps:
- Create group on server side (side, which will receive message)
- Connect to server-group from client side
- After establishing connection you should call
getConnectionInfo()
on client side (also recommend do it on group-server side) - Call
receiveMessage()
on server side (receiveMessage
returnPromise<string>
- message from client) - Call
sendMessage(message)
on client side, after resolvinggetConnectionInfo()
Note: now this method mark as unstable, because this method work async, but currently promise resolved before. It mean, that message will transferring, but promise already will be resolved (receiveMessage()
works perfectly, and his Promise
resolved as should be).
Also you cannot send character encoding for string and by default this library uses UTF-8
.
import {
CONNECTED,
INVITED,
FAILED,
AVAILABLE,
UNAVAILABLE
} from 'react-native-wifi-p2p/device-info-statuses';
import {
PEERS_UPDATED_ACTION,
CONNECTION_INFO_UPDATED_ACTION,
} from 'react-native-wifi-p2p';
import {
subscribeOnEvent,
unsubscribeFromEvent,
} from 'react-native-wifi-p2p';
// example of usage
subscribeOnEvent(PEERS_UPDATED_ACTION, (event) => {
console.log(event);
});
import React, { Component } from 'react';
import {
StyleSheet,
View,
Button
} from 'react-native';
import {
initialize,
isSuccessfulInitialize,
startDiscoveringPeers,
stopDiscoveringPeers,
unsubscribeFromPeersUpdates,
unsubscribeFromConnectionInfoUpdates,
subscribeOnConnectionInfoUpdates,
subscribeOnPeersUpdates,
connect,
disconnect,
createGroup,
removeGroup,
getAvailablePeers,
sendFile,
receiveFile,
getConnectionInfo
} from 'react-native-wifi-p2p';
import { PermissionsAndroid } from 'react-native';
type Props = {};
export default class App extends Component<Props> {
state = {
devices: []
};
componentDidMount() {
initialize();
isSuccessfulInitialize()
.then(status => console.log(status));
startDiscoveringPeers()
.then(() => console.log('Sucessfull'))
.catch(err => console.log(err));
subscribeOnPeersUpdates(({ devices }) => this.handleNewPeers(devices));
subscribeOnConnectionInfoUpdates(this.handleNewInfo);
}
componentWillUnmount() {
unsubscribeFromConnectionInfoUpdates((event) => console.log('unsubscribeFromConnectionInfoUpdates', event));
unsubscribeFromPeersUpdates((event) => console.log('unsubscribeFromPeersUpdates', event));
}
handleNewInfo = (info, sceondParam) => {
console.log(64646776467, info);
};
handleNewPeers = (peers) => {
console.log(754862162442324, peers);
this.setState({ devices: peers });
};
connectToFirstDevice = () => {
console.log(this.state.devices[0]);
connect(this.state.devices[0].deviceAddress)
.then(() => console.log('Successfully connected'))
.catch(err => console.error('Something gone wrong. Details: ', err));
};
disconnectFromDevice = () => {
disconnect()
.then(() => console.log(2423435423, 'Successfully disconnected'))
.catch(err => console.error(2423435423, 'Something gone wrong. Details: ', err));
};
onCreateGroup = () => {
createGroup()
.then(() => console.log('Group created successfully!'))
.catch(err => console.error('Something gone wrong. Details: ', err));
};
onRemoveGroup = () => {
removeGroup()
.then(() => console.log('Currently you don\'t belong to group!'))
.catch(err => console.error('Something gone wrong. Details: ', err));
};
onStopInvestigation = () => {
stopDiscoveringPeers()
.then(() => console.log('Stopping of discovering was successful'))
.catch(err => console.error(`Something is gone wrong. Maybe your WiFi is disabled? Error details`, err));
};
onStartInvestigate = () => {
startDiscoveringPeers()
.then(status => console.log(33333333, `Status of discovering peers: ${status}`))
.catch(err => console.error(`Something is gone wrong. Maybe your WiFi is disabled? Error details: ${err}`));
};
onGetAvailableDevices = () => {
getAvailablePeers()
.then(peers => console.log(peers));
};
onSendFile = () => {
//const url = '/storage/sdcard0/Music/Rammstein:Amerika.mp3';
const url = '/storage/emulated/0/Music/Bullet For My Valentine:Letting You Go.mp3';
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
{
'title': 'Access to read',
'message': 'READ_EXTERNAL_STORAGE'
}
)
.then(granted => {
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the camera")
} else {
console.log("Camera permission denied")
}
})
.then(() => {
return PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
'title': 'Access to write',
'message': 'WRITE_EXTERNAL_STORAGE'
}
)
})
.then(() => {
return sendFile(url)
.then(() => console.log('File sent successfully'))
.catch(err => console.log('Error while file sending', err));
})
.catch(err => console.log(err));
};
onReceiveFile = () => {
receiveFile()
.then(() => console.log('File received successfully'))
.catch(err => console.log('Error while file receiving', err))
};
onGetConnectionInfo = () => {
getConnectionInfo()
.then(info => console.log(info));
};
render() {
return (
<View style={styles.container}>
<Button
title="Connect"
onPress={this.connectToFirstDevice}
/>
<Button
title="Disconnect"
onPress={this.disconnectFromDevice}
/>
<Button
title="Create group"
onPress={this.onCreateGroup}
/>
<Button
title="Remove group"
onPress={this.onRemoveGroup}
/>
<Button
title="Investigate"
onPress={this.onStartInvestigate}
/>
<Button
title="Prevent Investigation"
onPress={this.onStopInvestigation}
/>
<Button
title="Get Available Devices"
onPress={this.onGetAvailableDevices}
/>
<Button
title="Get connection Info"
onPress={this.onGetConnectionInfo}
/>
<Button
title="Send file"
onPress={this.onSendFile}
/>
<Button
title="Receive file"
onPress={this.onReceiveFile}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});