diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index b4b01fa..f9fdf74 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,12 @@ - - + + + + + + diff --git a/example/package-lock.json b/example/package-lock.json index 84574f6..f642e9f 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -8,7 +8,6 @@ "name": "TetheringExample", "version": "0.0.1", "dependencies": { - "@react-native-community/netinfo": "^9.3.7", "react": "18.2.0", "react-native": "0.71.3" }, @@ -2973,14 +2972,6 @@ "node": ">=8" } }, - "node_modules/@react-native-community/netinfo": { - "version": "9.3.7", - "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-9.3.7.tgz", - "integrity": "sha512-+taWmE5WpBp0uS6kf+bouCx/sn89G9EpR4s2M/ReLvctVIFL2Qh8WnWfBxqK9qwgmFha/uqjSr2Gq03OOtiDcw==", - "peerDependencies": { - "react-native": ">=0.59" - } - }, "node_modules/@react-native/assets": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", @@ -11478,12 +11469,6 @@ "joi": "^17.2.1" } }, - "@react-native-community/netinfo": { - "version": "9.3.7", - "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-9.3.7.tgz", - "integrity": "sha512-+taWmE5WpBp0uS6kf+bouCx/sn89G9EpR4s2M/ReLvctVIFL2Qh8WnWfBxqK9qwgmFha/uqjSr2Gq03OOtiDcw==", - "requires": {} - }, "@react-native/assets": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@react-native/assets/-/assets-1.0.0.tgz", diff --git a/example/package.json b/example/package.json index df8f6e4..575ecb7 100644 --- a/example/package.json +++ b/example/package.json @@ -9,7 +9,6 @@ "pods": "pod-install --quiet" }, "dependencies": { - "@react-native-community/netinfo": "^9.3.7", "react": "18.2.0", "react-native": "0.71.3" }, diff --git a/example/src/App.tsx b/example/src/App.tsx index 222e039..4b057dd 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -5,316 +5,37 @@ import { View, Text, Pressable, - ToastAndroid, - ScrollView, + Image, } from 'react-native'; -import TetheringManager, { Network, Event, TetheringError } from '@react-native-tethering/wifi'; -// import WifiManager from 'react-native-wifi-reborn'; -import { useNetInfo } from '@react-native-community/netinfo'; +import HotspotScreen from './HotspotScreen'; +import WifiScreen from './WifiScreen'; export default function App() { - const [networks, setNetworks] = React.useState([]); + const [selected, setSelected] = React.useState(null); - React.useEffect(() => { - const subscriber = TetheringManager.addEventListener(Event.OnNetworkDisconnected, () => { + if (selected === 'wifi') { + return setSelected(null)} /> + } - }) + if (selected === 'hotspot') { + return setSelected(null)} /> + } - return () => subscriber.remove(); - }, []); - - const netInfo = useNetInfo(); return ( - - {/* { - try { - const state = await TetheringManager.isHotspotEnabled(); - console.log(state); - } catch (error) { - if (error instanceof TetheringError) { - console.log(error); - } - } - }} - > - Hotspot State? - - { - try { - await TetheringManager.setHotspotEnabled(true); - } catch (error) { - if (error instanceof TetheringError) { - console.log(error.code + ' ' + error.message); - } - } - }} - > - Turn on hotspot - - { - try { - await TetheringManager.setHotspotEnabled(false); - } catch (error) { - console.log(error); - } - }} - > - Turn off hotspot - - { - try { - const network = await TetheringManager.setLocalHotspotEnabled(); - console.log(network); - } catch (error) { - console.log(error); - } - }} - > - Turn on local hotspot - - { - try { - await TetheringManager.setLocalHotspotDisabled(); - } catch (error) { - console.log(error); - } - }} - > - Turn off local hotspot - - { - try { - const ip = await TetheringManager.getHotspotDeviceIp(); - console.log(ip); - } catch (error) { - console.log(error); - } - }} - > - Get my IP - - { - try { - const peers = await TetheringManager.getHotspotPeersAddresses(); - console.log(peers); - } catch (error) { - console.log(error); - } - }} - > - Get peers IP - */} - { - try { - const state = await TetheringManager.isWifiEnabled(); - console.log(state); - } catch (error) { - console.log(error); - } - }} - > - Check wifi state - - { - try { - await TetheringManager.setWifiEnabled(); - console.log('wifi enabled'); - } catch (error) { - console.log(error); - } - }} - > - Enable Wifi - - { - try { - await TetheringManager.setWifiDisabled(); - } catch (error) { - console.log(error); - } - }} - > - Disable Wifi - - { - try { - await TetheringManager.saveNetworkInDevice({ - ssid: 'Assem’s iPhone', - password: 'a123456789' - }); - console.log('Network saved'); - } catch (error) { - console.log(error); - } - }} - > - Save network - - { - try { - await TetheringManager.connectToNetwork({ - ssid: 'Assem’s iPhone', - password: 'a123456789' - }); - console.log('connected to network'); - } catch (error) { - console.log(error); - } - }} - > - Connect to wifi - - { - try { - await TetheringManager.disconnectFromNetwork(); - } catch (error) { - console.log(error); - } - }} - > - Disconnect from wifi - - { - try { - const wifiNetworks = await TetheringManager.getWifiNetworks(true); - setNetworks(wifiNetworks); - } catch (error: any) { - if (error instanceof TetheringError) { - console.log(error.code); - } - } - }} - > - Get list of networks - - { - try { - const suggestionNum = await TetheringManager.getMaxNumberOfNetworkSuggestions(); - console.log(suggestionNum); - } catch (error: any) { - if (error instanceof TetheringError) { - console.log(error.code); - } - } - }} - > - Get max suggestions - - { - try { - const ip = await TetheringManager.getDeviceIP(); - console.log(ip); - } catch (error: any) { - if (error instanceof TetheringError) { - console.log(error.code); - } - } - }} - > - Get device ip - - { - try { - const status = await TetheringManager.isDeviceAlreadyConnected(); - console.log(status); - } catch (error: any) { - if (error instanceof TetheringError) { - console.log(error.code); - } - } - }} - > - is connected to network? - - { - TetheringManager.openWifiSettings(false) - }} - > - Open wifi settings - - { - ToastAndroid.show( - `${netInfo.isInternetReachable} and ${netInfo.isConnected}`, - ToastAndroid.SHORT - ); - }} - > - Is App has internet - - - - {networks.map((n, i) => ( - - SSID: {n.ssid} - BSSID: {n.bssid} - capabilities: {n.capabilities} - frequency: {n.frequency} - level: {n.level} - timestamp: {n.timestamp} - - ))} + + + + React Native Tethering + + + setSelected('wifi')}> + Use WiFi + + setSelected('hotspot')}> + Use Hotspot + - + ); } @@ -324,11 +45,28 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, + buttonsContainer: { + width: '100%', + alignItems: 'center' + }, button: { - width: '70%', + width: '50%', padding: 14, - backgroundColor: '#A1A1A1', + backgroundColor: '#359962', borderRadius: 10, marginBottom: 10, + alignItems: 'center' + }, + buttonText: { + color: '#fff', + fontSize: 16 + }, + header: { + position: 'absolute', + top: 0 }, + headerImg: { + width: 200, + height: 200 + } }); diff --git a/example/src/HotspotScreen.tsx b/example/src/HotspotScreen.tsx new file mode 100644 index 0000000..b8c224a --- /dev/null +++ b/example/src/HotspotScreen.tsx @@ -0,0 +1,368 @@ +import * as React from 'react'; + +import { + StyleSheet, + View, + Text, + Pressable, + ToastAndroid, + ScrollView, +} from 'react-native'; +import HotspotManager, { Device, TetheringError } from '@react-native-tethering/hotspot'; + +type WifiScreenProps = { + back: () => void +} + +export default function HotspotScreen({ back }: WifiScreenProps) { + const [devices, setDevices] = React.useState([]); + + return ( + + {/* { + try { + const state = await TetheringManager.isHotspotEnabled(); + console.log(state); + } catch (error) { + if (error instanceof TetheringError) { + console.log(error); + } + } + }} + > + Hotspot State? + + { + try { + await TetheringManager.setHotspotEnabled(true); + } catch (error) { + if (error instanceof TetheringError) { + console.log(error.code + ' ' + error.message); + } + } + }} + > + Turn on hotspot + + { + try { + await TetheringManager.setHotspotEnabled(false); + } catch (error) { + console.log(error); + } + }} + > + Turn off hotspot + + { + try { + const network = await TetheringManager.setLocalHotspotEnabled(); + console.log(network); + } catch (error) { + console.log(error); + } + }} + > + Turn on local hotspot + + { + try { + await TetheringManager.setLocalHotspotDisabled(); + } catch (error) { + console.log(error); + } + }} + > + Turn off local hotspot + + { + try { + const ip = await TetheringManager.getHotspotDeviceIp(); + console.log(ip); + } catch (error) { + console.log(error); + } + }} + > + Get my IP + + { + try { + const peers = await TetheringManager.getHotspotPeersAddresses(); + console.log(peers); + } catch (error) { + console.log(error); + } + }} + > + Get peers IP + */} + + Back to home + + + + Hotspot States + + { + try { + const state = await HotspotManager.isHotspotEnabled(); + ToastAndroid.show(`Hotspot state: ${state}`, ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Check Hotspot Enabled + + { + try { + await HotspotManager.setHotspotEnabled(true); + ToastAndroid.show('Hotspot Enabled', ToastAndroid.SHORT) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + Turn on hotpot + + { + try { + await HotspotManager.setHotspotEnabled(false); + ToastAndroid.show('Hotspot Disabled', ToastAndroid.SHORT) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + Turn off hotpot + + { + try { + const network = await HotspotManager.setLocalHotspotEnabled(true); + ToastAndroid.show('Local Hotspot Enabled', ToastAndroid.SHORT) + console.log(network); + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + Turn on local hotpot + + { + try { + await HotspotManager.setLocalHotspotEnabled(false); + ToastAndroid.show('Local Hotspot Disabled', ToastAndroid.SHORT) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + Turn off local hotpot + + + + + + Hotspot Helpers + + { + try { + const state = await HotspotManager.isWriteSettingsGranted(); + ToastAndroid.show(`Write settings permission is ${state ? 'granted' : 'not graned'}`, ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Check write settings permission + + { + try { + const ip = await HotspotManager.getMyDeviceIp() + ToastAndroid.show(`Your device IP: ${ip}`, ToastAndroid.SHORT) + console.log(ip) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + Get your hotspot IP + + { + try { + const devices = await HotspotManager.getConnectedDevices(); + setDevices(devices) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + find connected devices + + { + try { + await HotspotManager.openWriteSettings(); + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + + } + }} + > + Navigate to write settings screen + + { + try { + await HotspotManager.navigateToTethering(); + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Navigate to tethering screen + + + + + {devices.map((d, i) => ( + + ipAddress: {d.ipAddress} + macAddress: {d.macAddress} + status: {d.status} + + ))} + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + button: { + width: '70%', + padding: 14, + backgroundColor: '#fff', + borderRadius: 10, + marginBottom: 10, + alignItems: 'center' + }, + wrapper: { + backgroundColor: '#359962', + padding: 15, + marginBottom: 8 + }, + wrapperHeader: { + fontSize: 16, + color: '#fff', + marginBottom: 12 + }, + row: { + flexDirection: 'row', + justifyContent: 'space-between', + width: '100%' + }, + devicesWrapper: { + padding: 12, + backgroundColor: '#ccc', + marginVertical: 6 + }, + backButton: { + backgroundColor: '#ddd', + padding: 15, + alignItems: 'center' + } +}); diff --git a/example/src/WifiScreen.tsx b/example/src/WifiScreen.tsx new file mode 100644 index 0000000..457f3b1 --- /dev/null +++ b/example/src/WifiScreen.tsx @@ -0,0 +1,331 @@ +import * as React from 'react'; + +import { + StyleSheet, + View, + Text, + Pressable, + ToastAndroid, + ScrollView, +} from 'react-native'; +import TetheringManager, { Network, Event, TetheringError } from '@react-native-tethering/wifi'; + +type WifiScreenProps = { + back: () => void +} + +export default function WifiScreen({ back }: WifiScreenProps) { + const [networks, setNetworks] = React.useState([]); + + React.useEffect(() => { + const subscriber = TetheringManager.addEventListener(Event.OnNetworkDisconnected, () => { + // disconnected from the network + }) + + return () => subscriber.remove(); + }, []); + + return ( + + + Back to home + + + WiFi States + + { + try { + const state = await TetheringManager.isWifiEnabled(); + ToastAndroid.show(`WiFi state: ${state}`, ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Check WiFi Enabled + + { + try { + await TetheringManager.setWifiEnabled(); + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Enable WiFi + + { + try { + await TetheringManager.setWifiDisabled(); + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Disable WiFi + + + + + WiFi Connections + + { + try { + await TetheringManager.saveNetworkInDevice({ + ssid: 'network name', + password: 'network password' + }); + ToastAndroid.show('Network Saved', ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Save a network in device + + { + try { + await TetheringManager.connectToLocalNetwork({ + ssid: 'network name', + password: 'network password', + isHidden: true + }); + ToastAndroid.show('WiFi Connected', ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Connect to local network + + { + try { + await TetheringManager.connectToNetwork({ + ssid: 'network name', + password: 'network password', + isHidden: true + }); + ToastAndroid.show('WiFi Connected', ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Connect to a network + + + + + + WiFi Disconnect + + { + try { + await TetheringManager.disconnectFromLocalNetwork() + ToastAndroid.show('WiFi Disconnected', ToastAndroid.SHORT) + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Disconnect from a local network + + { + try { + await TetheringManager.disconnectFromNetwork() + } catch (error) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Disconnect from a network + + + + + + WiFi Helpers + + { + try { + const wifiNetworks = await TetheringManager.getWifiNetworks(true); + setNetworks(wifiNetworks); + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Get list of networks + + { + try { + const maxSuggestions = await TetheringManager.getMaxNumberOfNetworkSuggestions() + ToastAndroid.show(`${maxSuggestions} Max suggestions per app`, ToastAndroid.SHORT) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Get max suggestions per app + + { + try { + const ip = await TetheringManager.getDeviceIP() + ToastAndroid.show(`Current Device IP: ${ip}`, ToastAndroid.SHORT) + console.log(ip) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Get device ip + + { + try { + const status = await TetheringManager.isDeviceAlreadyConnected(); + ToastAndroid.show(`Current WiFi status: ${status}`, ToastAndroid.SHORT) + } catch (error: any) { + if (error instanceof TetheringError) { + ToastAndroid.show(error.message, ToastAndroid.LONG) + } + console.log(error); + } + }} + > + Check if connected to a network + + { + TetheringManager.openWifiSettings(false) + }} + > + Open wifi settings + + + + + + + {networks.map((n, i) => ( + + SSID: {n.ssid} + BSSID: {n.bssid} + capabilities: {n.capabilities} + frequency: {n.frequency} + level: {n.level} + timestamp: {n.timestamp} + + ))} + + + ); +} + +const styles = StyleSheet.create({ + wrapper: { + backgroundColor: '#359962', + padding: 15, + marginBottom: 8 + }, + wrapperHeader: { + fontSize: 16, + color: '#fff', + marginBottom: 12 + }, + row: { + flexDirection: 'row', + justifyContent: 'space-between', + width: '100%' + }, + button: { + padding: 14, + backgroundColor: '#fff', + borderRadius: 10, + marginBottom: 10, + alignItems: 'center' + }, + networksWrapper: { + padding: 12, + backgroundColor: '#ccc', + marginVertical: 6 + }, + backButton: { + backgroundColor: '#ddd', + padding: 15, + alignItems: 'center' + } +}); diff --git a/example/src/assets/tethering-logo.webp b/example/src/assets/tethering-logo.webp new file mode 100644 index 0000000..889c08e Binary files /dev/null and b/example/src/assets/tethering-logo.webp differ diff --git a/tsconfig.json b/tsconfig.json index 4119a17..b897613 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "baseUrl": "./", "paths": { - "@react-native-tethering/wifi": ["./packages/wifi/src/index"] + "@react-native-tethering/wifi": ["./packages/wifi/src/index"], + "@react-native-tethering/hotspot": ["./packages/hotspot/src/index"] }, "allowUnreachableCode": false, "allowUnusedLabels": false,