Expo Networkを使ってwifiの接続を確認してみた
What Expo Network?
A library that provides access to the device's network such as its IP address, MAC address, and airplane mode status.
IPアドレス、MACアドレス、機内モードの状態など、デバイスのネットワークへのアクセスを提供するライブラリ。
Expoのプロジェクトを作成する。
bunx create-expo-app expo-wifi -t expo-template-blank-typescript
これを今回はbunで使ってみようと思います。
bun add expo-network
If you are installing this in an existing React Native app, start by installing expo in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
Configuration
On Android, this module requires permissions to access the network and Wi-Fi state. The permissions ACCESS_NETWORK_STATE and ACCESS_WIFI_STATE are added automatically.
既存のReact Nativeアプリにインストールする場合は、プロジェクトにexpoをインストールすることから始めます。その後、ライブラリのREADMEに記載されている「素のReact Nativeプロジェクトへのインストール」セクションの追加指示に従ってください。
構成
Androidでは、このモジュールはネットワークとWi-Fi状態にアクセスするためのパーミッションが必要です。パーミッションACCESS_NETWORK_STATEとACCESS_WIFI_STATEは自動的に追加されます。
自動的に追加か。。。
確かに設定はしてないな笑
example
完成品はこちら
このソースコードだけでwifiと通信できているか確認できるアプリ作れます。
全体のソースコード
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, ScrollView, TouchableOpacity, RefreshControl } from 'react-native';
import { useEffect, useState, useCallback } from 'react';
import * as Network from 'expo-network';
export default function App() {
const [networkState, setNetworkState] = useState<{
isConnected: boolean;
type: string | null;
isInternetReachable: boolean;
details: Network.NetworkState | null;
}>({
isConnected: false,
type: null,
isInternetReachable: false,
details: null,
});
const [refreshing, setRefreshing] = useState(false);
const getNetworkInfo = async () => {
try {
const networkState = await Network.getNetworkStateAsync();
setNetworkState({
isConnected: networkState?.isConnected ?? false,
type: networkState?.type ?? null,
isInternetReachable: networkState?.isInternetReachable ?? false,
details: networkState ?? null,
});
} catch (error) {
console.error('Error fetching network info:', error);
}
};
const onRefresh = useCallback(async () => {
setRefreshing(true);
await getNetworkInfo();
setRefreshing(false);
}, []);
useEffect(() => {
getNetworkInfo();
}, []);
const renderNetworkStatus = () => {
const statusColor = networkState.isConnected ? '#4CAF50' : '#F44336';
return (
<>
<View style={styles.header}>
<Text style={styles.headerText}>WiFi 接続状態</Text>
</View>
<View style={styles.card}>
<View style={styles.statusContainer}>
<View style={[styles.statusDot, { backgroundColor: statusColor }]} />
<Text style={[styles.statusText, { color: statusColor }]}>
{networkState.isConnected ? '接続中' : '未接続'}
</Text>
</View>
<View style={styles.detailRow}>
<Text style={styles.label}>接続タイプ:</Text>
<Text style={styles.value}>
{networkState.type === 'WIFI' ? 'WiFi'
: networkState.type === 'CELLULAR' ? 'モバイル通信'
: networkState.type === 'BLUETOOTH' ? 'Bluetooth'
: networkState.type === 'ETHERNET' ? '有線LAN'
: networkState.type === 'VPN' ? 'VPN'
: networkState.type === 'OTHER' ? 'その他'
: '不明'}
</Text>
</View>
<View style={styles.detailRow}>
<Text style={styles.label}>インターネット:</Text>
<Text style={styles.value}>
{networkState.isInternetReachable ? '利用可能' : '利用不可'}
</Text>
</View>
{!networkState.isConnected && (
<View style={styles.errorMessage}>
<Text style={styles.errorText}>
WiFiに接続されていません。{'\n'}
端末のWiFi設定を確認してください。
</Text>
</View>
)}
</View>
</>
);
};
return (
<ScrollView
style={styles.container}
contentContainerStyle={styles.contentContainer}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
title="更新中..."
tintColor="#2196F3"
/>
}
>
<StatusBar style="light" />
{renderNetworkStatus()}
<TouchableOpacity style={styles.refreshButton} onPress={onRefresh}>
<Text style={styles.refreshButtonText}>接続状態を更新</Text>
</TouchableOpacity>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
contentContainer: {
padding: 16,
},
header: {
backgroundColor: '#2196F3',
padding: 16,
paddingTop: 60,
marginBottom: 16,
marginHorizontal: -16,
},
headerText: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
},
card: {
backgroundColor: 'white',
borderRadius: 12,
padding: 16,
marginBottom: 16,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
statusContainer: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 16,
justifyContent: 'center',
},
statusDot: {
width: 12,
height: 12,
borderRadius: 6,
marginRight: 8,
},
statusText: {
fontSize: 24,
fontWeight: 'bold',
},
detailRow: {
flexDirection: 'row',
marginBottom: 12,
alignItems: 'center',
},
label: {
fontSize: 16,
color: '#666',
width: 120,
},
value: {
fontSize: 16,
color: '#333',
flex: 1,
},
errorMessage: {
backgroundColor: '#FFF3F3',
borderRadius: 8,
padding: 16,
marginTop: 16,
borderWidth: 1,
borderColor: '#FFE0E0',
},
errorText: {
color: '#D32F2F',
fontSize: 16,
textAlign: 'center',
lineHeight: 24,
},
refreshButton: {
backgroundColor: '#2196F3',
padding: 16,
borderRadius: 12,
alignItems: 'center',
},
refreshButtonText: {
color: 'white',
fontSize: 16,
fontWeight: '500',
},
});
動作はこんな感じですね。
手順書も作ってみた参考までに
Expo WiFi Status App
このアプリケーションは、デバイスのWiFi接続状態をリアルタイムで確認できるExpoベースのモバイルアプリケーションです。
機能
- WiFi接続状態のリアルタイム表示
- ネットワークタイプの表示(WiFi、モバイル通信など)
- インターネット接続状態の確認
- プルトゥリフレッシュによる接続状態の更新
必要条件
環境構築
- bunのインストール(まだインストールしていない場合):
curl -fsSL https://bun.sh/install | bash
- プロジェクトのクローンとセットアップ:
# リポジトリをクローン
git clone [your-repository-url]
cd expo-wifi
# 依存関係のインストール
bun install
- アプリケーションの起動:
bun start
使用方法
- Expo Goアプリを起動
- QRコードをスキャン(またはURLを入力)してアプリを開く
- アプリが自動的にデバイスのWiFi接続状態を表示
- 画面を下にプルダウンして接続状態を更新
- 「接続状態を更新」ボタンをタップして手動更新も可能
技術仕様
- Framework: Expo (SDK 52)
- Language: TypeScript
- 主要パッケージ:
- expo-network: WiFiおよびネットワーク情報の取得
- react-native: UIコンポーネント
- expo-status-bar: ステータスバーの制御
WiFi通信の仕組み
このアプリケーションは以下のような方法でWiFi情報を取得しています:
-
expo-network
パッケージを使用して、デバイスのネットワーク状態を取得
const networkState = await Network.getNetworkStateAsync();
- 取得できる情報:
- 接続状態(接続中/未接続)
- ネットワークタイプ(WiFi/モバイル通信など)
- インターネット到達可能性
注意: Expoの制限により、WiFiの詳細な情報(SSID、信号強度など)や、
WiFiスキャン機能は利用できません。これらの機能が必要な場合は、
expo-dev-clientを使用するか、React Native CLIプロジェクトへの移行が必要です。
トラブルシューティング
-
アプリが起動しない場合:
- bunとExpo Goが最新バージョンかを確認
-
bun install
を再実行
-
ネットワーク情報が取得できない場合:
- デバイスの位置情報設定が有効になっているか確認
- アプリのネットワークアクセス権限を確認
-
更新が反映されない場合:
- アプリを完全に終了して再起動
- Expo Goをクリアして再起動
Discussion