我可以通过React Native应用程序连接wifi,但无法使用互联网

问题描述 投票:0回答:1

我正在开发 React Native 应用程序,该应用程序具有扫描所有可用 wifi、使用正确密码连接 wifi 的功能,并使用它来通过云技术控制设备。 我已成功从应用程序完成 WiFi 连接,但我无法从中使用互联网。 我已经安装了 wifi reborn 库和 wifi 管理器以及更多来执行此操作,但没有一个工作。

`import React, {useState, useEffect} from 'react';
import {
  View,
  Text,
  FlatList,
  TouchableOpacity,
  TextInput,
  PermissionsAndroid,
  Platform,
  Modal,
  ToastAndroid,
  Image,
  StyleSheet,
} from 'react-native';
import WifiManager from 'react-native-wifi-reborn';
import {check, request, PERMISSIONS, RESULTS} from 'react-native-permissions';
// import OpenSettings from 'react-native-open-settings';

const WifiScannerScreen = () => {
  const [wifiList, setWifiList] = useState([]);
  const [password, setPassword] = useState('');
  const [connectingSSID, setConnectingSSID] = useState('');
  const [selectedSSID, setSelectedSSID] = useState('');
  const [isPasswordModalVisible, setPasswordModalVisible] = useState(false);

  const checkWifiPermissions = async () => {
    try {
      if (Platform.OS === 'android') {
        const wifiPermissionResult = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        );

        if (wifiPermissionResult === PermissionsAndroid.RESULTS.GRANTED) {
          scanWifi();
        } else {
          console.error('Wi-Fi permissions denied.');
        }
      } else {
        const wifiPermissionResult = await check(
          PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
        );

        if (wifiPermissionResult === RESULTS.GRANTED) {
          scanWifi();
        } else {
          const permissionRequestResult = await request(
            PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
          );

          if (permissionRequestResult === RESULTS.GRANTED) {
            scanWifi();
          } else {
            console.error('Wi-Fi permissions denied.');
          }
        }
      }
    } catch (error) {
      console.error('Error checking Wi-Fi permissions:', error);
    }
  };

  const scanWifi = async () => {
    try {
      const wifiArray = await WifiManager.loadWifiList();
      setWifiList(wifiArray);
    } catch (error) {
      console.error('Error scanning for Wi-Fi:', error);
    }
  };

  const connectToWifi = async (ssid, password) => {
    try {
      if (!validatePassword(password)) {
        console.error('Invalid password');
        return;
      }

      setConnectingSSID(ssid);
      await WifiManager.connectToProtectedSSID(ssid, password, false, true);
      console.log('Connected to Wi-Fi:', ssid);

      setTimeout(() => {
        checkInternetConnectivity(ssid);
      }, 5000);
    } catch (error) {
      console.error('Error connecting to Wi-Fi:', error);
    } finally {
      setConnectingSSID('');
      setSelectedSSID('');
      setPasswordModalVisible(false);
    }
  };

  const checkInternetConnectivity = async ssid => {
    try {
      const response = await fetch('https://www.google.com', {method: 'HEAD'});

      if (response.ok) {
        console.log('Connected to the internet');
        showToast('Wi-Fi connected!');
      } else {
        console.error('No internet connection');
      }
    } catch (error) {
      console.error('Error checking internet connectivity:', error);
    }
  };

  const showToast = message => {
    ToastAndroid.show(message, ToastAndroid.SHORT);
  };

  const validatePassword = password => {
    return true;
  };

  useEffect(() => {
    checkWifiPermissions();
    // OpenSettings.openSettings();
  }, []);

  const showPasswordInputModal = ssid => {
    setSelectedSSID(ssid);
    setPasswordModalVisible(true);
  };

  const hidePasswordInputModal = () => {
    setSelectedSSID('');
    setPassword('');
    setPasswordModalVisible(false);
  };

  const getSignalStrengthCategory = level => {
    if (level >= -50) {
      return 'full';
    } else if (level >= -70) {
      return 'medium';
    } else {
      return 'poor';
    }
  };

  const getImageSource = category => {
    switch (category) {
      case 'full':
        return require('./src/assets/wifi-high-icon-original.png');
      case 'medium':
        return require('./src/assets/wifi-medium-icon-original.png');
      case 'poor':
        return require('./src/assets/wifi-low-icon-original.png');
      default:
        return require('./src/assets/wifi-none-icon-original.png');
    }
  };

  const renderItem = ({item}) => (
    <TouchableOpacity
      onPress={() => showPasswordInputModal(item.SSID)}
      style={{
        padding: 10,
        borderBottomWidth: 1,
        borderBottomColor: '#ccc',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
      }}>
      <View>
        <Text style={styles.wifiNames}>{`${item.SSID}`}</Text>
        {/* <Text>{`BSSID: ${item.BSSID}`}</Text> */}
        <Text>{`Signal Strength: ${item.level} dBm`}</Text>
      </View>
      <Image
        source={getImageSource(getSignalStrengthCategory(item.level))}
        style={{width: 30, height: 30}}
      />
    </TouchableOpacity>
  );

  return (
    <View style={{flex: 1, padding: 20}}>
      <Text style={styles.headerText}>Available Networks</Text>

      <FlatList
        data={wifiList}
        keyExtractor={item => item.BSSID}
        renderItem={renderItem}
        ListEmptyComponent={<Text>No Wi-Fi networks found</Text>}
      />

      <Modal
        animationType="slide"
        transparent={false}
        visible={isPasswordModalVisible}
        onRequestClose={hidePasswordInputModal}>
        <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <View style={styles.modalContent}>
            <Text
              style={
                styles.modalHeader
              }>{`Enter the password for ${selectedSSID}`}</Text>
            <TextInput
              style={styles.passwordTextInput}
              placeholder="Wi-Fi Password"
              secureTextEntry
              value={password}
              onChangeText={text => setPassword(text)}
            />
            <View style={styles.okCancelContainer}>
              <TouchableOpacity
                style={styles.okButton}
                onPress={() => connectToWifi(selectedSSID, password)}>
                <Text style={styles.buttonText}>OK</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.cancelButton}
                onPress={hidePasswordInputModal}>
                <Text style={styles.buttonText}>Cancel</Text>
              </TouchableOpacity>
            </View>
          </View>
        </View>
      </Modal>
    </View>
  );
};

const styles = StyleSheet.create({
  headerText: {
    fontSize: 24,
    color: 'black',
    textAlign: 'center',
    marginBottom: 12,
  },
  wifiNames: {
    color: 'gray',
    fontSize: 20,
  },
  modalContent: {
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 10,
    elevation: 5,
    justifyContent: 'center',
    alignItems: 'center',
    flexWrap: 'wrap',
  },
  modalHeader: {
    color: 'red',
    marginBottom: 12,
  },
  passwordTextInput: {
    height: 50,
    borderColor: 'black',
    borderWidth: 1,
    marginBottom: 10,
    borderRadius: 12,
  },
  okCancelContainer: {
    flexDirection: 'row',
    justifyContent: 'space-evenly',
    width: '80%',
  },
  okButton: {
    borderWidth: 2,
    borderColor: 'black',
    paddingHorizontal: 40,
    paddingVertical: 10,
    borderRadius: 18,
    marginVertical: 5,
  },
  cancelButton: {
    borderWidth: 2,
    borderColor: 'black',
    paddingHorizontal: 40,
    paddingVertical: 10,
    borderRadius: 18,
    marginVertical: 5,
  },
  buttonText: {
    color: 'black',
    textAlign: 'center',
  },
});

export default WifiScannerScreen;
`

这是组件的代码。

我尝试了 wifi reborn、wifi manager、tethring 和更多库来做到这一点。 我希望用户应该能够使用互联网。

javascript android react-native mobile
1个回答
0
投票

如何修复

  • 请确保在扫描 Wi-Fi 之前请求位置权限。 - 对于 Android,请求
    ACCESS_FINE_LOCATION
    。 - 对于 iOS,请请求
    LOCATION_WHEN_IN_USE
  • 确保网络可以访问互联网:
  • 您可以通过向网页(例如 Google)发送请求来检查这一点 连接到 Wi-Fi。 -测试网络功能: -测试连接的Wi-Fi网络是否提供本地设备控制和 互联网接入。
import React, { useState, useEffect } from "react";
import {
  View,
  Text,
  FlatList,
  TouchableOpacity,
  TextInput,
  PermissionsAndroid,
  Platform,
  Modal,
  ToastAndroid,
  Image,
  StyleSheet,
} from "react-native";
import WifiManager from "react-native-wifi-reborn";
import { check, request, PERMISSIONS, RESULTS } from "react-native-permissions";

const WifiScannerScreen = () => {
  const [wifiList, setWifiList] = useState([]);
  const [password, setPassword] = useState("");
  const [connectingSSID, setConnectingSSID] = useState("");
  const [selectedSSID, setSelectedSSID] = useState("");
  const [isPasswordModalVisible, setPasswordModalVisible] = useState(false);

  const checkWifiPermissions = async () => {
    try {
      if (Platform.OS === "android") {
        const wifiPermission = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
        );

        if (wifiPermission === PermissionsAndroid.RESULTS.GRANTED) {
          scanWifi();
        } else {
          console.error("Wi-Fi permissions denied.");
        }
      } else {
        const wifiPermission = await check(
          PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
        );

        if (wifiPermission === RESULTS.GRANTED) {
          scanWifi();
        } else {
          const permissionRequestResult = await request(
            PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
          );
          if (permissionRequestResult === RESULTS.GRANTED) {
            scanWifi();
          } else {
            console.error("Wi-Fi permissions denied.");
          }
        }
      }
    } catch (error) {
      console.error("Error checking Wi-Fi permissions:", error);
    }
  };

  const scanWifi = async () => {
    try {
      const wifiArray = await WifiManager.loadWifiList();
      setWifiList(wifiArray);
    } catch (error) {
      console.error("Error scanning for Wi-Fi:", error);
    }
  };

  const connectToWifi = async (ssid, password) => {
    try {
      if (!validatePassword(password)) {
        console.error("Invalid password");
        return;
      }

      setConnectingSSID(ssid);
      await WifiManager.connectToProtectedSSID(ssid, password, false, true);
      console.log(`Connected to Wi-Fi: ${ssid}`);

      if (Platform.OS === "android" && Platform.Version >= 29) {
        await WifiManager.forceWifiUsage(true);
      }

      setTimeout(() => {
        checkInternetConnectivity(ssid);
      }, 5000);
    } catch (error) {
      console.error("Error connecting to Wi-Fi:", error);
    } finally {
      resetModalState();
    }
  };

  const checkInternetConnectivity = async (ssid) => {
    try {
      const response = await fetch("https://www.google.com", {
        method: "HEAD",
      });
      if (response.ok) {
        showToast("Wi-Fi connected with internet!");
      } else {
        console.error("No internet connection");
      }
    } catch (error) {
      console.error("Error checking internet connectivity:", error);
    }
  };

  const validatePassword = (password) => password.length > 0;

  const showToast = (message) => {
    ToastAndroid.show(message, ToastAndroid.SHORT);
  };

  const resetModalState = () => {
    setConnectingSSID("");
    setSelectedSSID("");
    setPasswordModalVisible(false);
  };

  useEffect(() => {
    checkWifiPermissions();
  }, []);

  const renderItem = ({ item }) => (
    <TouchableOpacity
      onPress={() => {
        setSelectedSSID(item.SSID);
        setPasswordModalVisible(true);
      }}
      style={styles.listItem}
    >
      <Text style={styles.ssidText}>{item.SSID}</Text>
      <Image source={getSignalIcon(item.level)} style={styles.signalIcon} />
    </TouchableOpacity>
  );

  const getSignalIcon = (level) => {
    if (level >= -50) return require("./assets/wifi-full.png");
    if (level >= -70) return require("./assets/wifi-medium.png");
    return require("./assets/wifi-low.png");
  };

  return (
    <View style={styles.container}>
      <Text style={styles.header}>Available Wi-Fi Networks</Text>
      <FlatList
        data={wifiList}
        keyExtractor={(item) => item.BSSID}
        renderItem={renderItem}
        ListEmptyComponent={<Text>No Wi-Fi networks found</Text>}
      />

      <Modal
        animationType="slide"
        transparent={false}
        visible={isPasswordModalVisible}
        onRequestClose={resetModalState}
      >
        <View style={styles.modalContainer}>
          <Text style={styles.modalTitle}>
            Enter password for {selectedSSID}
          </Text>
          <TextInput
            style={styles.passwordInput}
            placeholder="Wi-Fi Password"
            secureTextEntry
            value={password}
            onChangeText={setPassword}
          />
          <View style={styles.modalButtons}>
            <TouchableOpacity
              style={styles.okButton}
              onPress={() => connectToWifi(selectedSSID, password)}
            >
              <Text style={styles.buttonText}>OK</Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={styles.cancelButton}
              onPress={resetModalState}
            >
              <Text style={styles.buttonText}>Cancel</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20 },
  header: { fontSize: 24, textAlign: "center", marginVertical: 10 },
  listItem: {
    padding: 10,
    borderBottomWidth: 1,
    borderBottomColor: "#ccc",
    flexDirection: "row",
    justifyContent: "space-between",
  },
  ssidText: { fontSize: 18, color: "gray" },
  signalIcon: { width: 30, height: 30 },
  modalContainer: { flex: 1, justifyContent: "center", padding: 20 },
  modalTitle: { fontSize: 18, marginBottom: 10, textAlign: "center" },
  passwordInput: {
    borderWidth: 1,
    borderColor: "black",
    padding: 10,
    borderRadius: 5,
  },
  modalButtons: {
    flexDirection: "row",
    justifyContent: "space-around",
    marginTop: 20,
  },
  okButton: { padding: 10, borderRadius: 5, backgroundColor: "#4CAF50" },
  cancelButton: { padding: 10, borderRadius: 5, backgroundColor: "#f44336" },
  buttonText: { color: "white", textAlign: "center" },
});

export default WifiScannerScreen;

Android

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

iOS

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need access to your location to scan Wi-Fi networks.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>We need access to your location to scan Wi-Fi networks.</string>
© www.soinside.com 2019 - 2024. All rights reserved.