본문 바로가기
Flutter

[Flutter] 플러터 - 네트워크 상태 감지 connectivity_plus

by s_hoonee 2024. 7. 8.
반응형

https://pub.dev/packages/connectivity_plus/versions/3.0.6

 

connectivity_plus 3.0.6 | Flutter package

Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS.

pub.dev

앱 실행시 네트워크 상태 확인하기 

 

1. 네트워크 상태 감지를 할 메소드를 생성

import 'package:connectivity/connectivity.dart';
import 'package:dio/dio.dart';
import '../common/data/index/index.dart';

final appServicesProvider = Provider.autoDispose<AppServices>((ref) {
  return AppServices();
});

class AppServices {
  static final AppServices _instance = AppServices._internal();

  factory AppServices() {
    return _instance;
  }

  AppServices._internal();

  final String url = baseServerUrl;
  final ExceptionDio exceptionDio = ExceptionDio();
  final Dio dio = Dio();
  final Connectivity connectivity = Connectivity();

  /// 네트워크 연결 상태 확인 메소드
  Future<bool> isConnected() async {
    var connectivityResult = await connectivity.checkConnectivity();
    return connectivityResult != ConnectivityResult.none;
  }
}
enum ConnectivityResult {
  /// WiFi: Device connected via Wi-Fi
  wifi,

  /// Mobile: Device connected to cellular network
  mobile,

  /// None: Device not connected to any network
  none
}

클래스를 뜯어보니 none이면 데이터나 와이파이 꺼져있다고 판단! 

나는 네이티브 스플래쉬 패키지가 끝나면 router에 init이 splashScreen이다. 여기서 로그인 여부를 따지는데 먼저 네트워크 체크를 해준다. 이후 네트워크가 돌아오면 로그인 여부 체크 후 로직에 맞게 진입시킨다 

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../global/common/data/index/index.dart';
import '../../global/common/data/storage/secure_storage.dart';
import '../../global/components/icon_svg_png/custom_png_icon.dart';
import '../../global/config/router/main_router.dart';

class SplashScreen extends ConsumerStatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);

  @override
  SplashScreenState createState() => SplashScreenState();
}

class SplashScreenState extends ConsumerState<SplashScreen> {
  @override
  void initState() {
    super.initState();
    _checkConnection();
  }

  Future<void> _checkConnection() async {
    final appServices = ref.read(appServicesProvider);
    bool isConnected = await appServices.isConnected();
    
    if (!isConnected) {
      _showNoConnectionDialog();
    } else {
      await checkLoginStatus();
    }
  }

  Future<void> checkLoginStatus() async {
    await Future.delayed(const Duration(seconds: 2));
    bool isLoggedIn = await getLoginStatus();

    if (isLoggedIn) {
      debugPrint('🙆‍ 로그인 성공');
      router.go('/');
    } else {
      debugPrint('🙅‍️로그인 실패 refreshToken이 없습니다.');
      router.go('/welcome');
    }
  }

  Future<bool> getLoginStatus() async {
    final bool isLoggedIn = await secureStorage
        .read(key: 'refreshToken')
        .then((value) => value != null);

    return isLoggedIn;
  }

  void _showNoConnectionDialog() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text('네트워크 오류', style: TextStyle(fontSize: 25.sp)),
        content: Text('인터넷 연결이 없습니다. 연결을 확인하고 다시 시도하세요.', style: TextStyle(fontSize: 15.sp)),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.of(context).pop();
              _checkConnection(); // 다시 시도
            },
            child: const Text('다시 시도'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColor.white,
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              CustomPngIcon(
                fileDirectory: 'splash',
                fileName: 'splash',
                color: AppColor.primary,
                width: 220.w,
                height: 130.h,
              ),
              SpinKitThreeBounce(
                color: AppColor.primary,
                size: 25.w,
              ),
              SizedBox(height: 40.h),
            ],
          ),
        ),
      ),
    );
  }
}