본문 바로가기

Development/Android Studio

(Android Studio) Chapter18. Check Network state

1. 배경

네트워크가 연결이 됐는지 여부에 따라 일부 기능이 작동하지 않을 수 있기 때문에 해당 여부에 대해서 체크하고 상태를 알리는 기능을 추가

 

2. 기본 동작 프로세스

  1) 인터넷 권한, 네트워크 상태 받아올 수 있는 권한 요청

  2) BroadcastReceiver 클래스 작성

  3) BroadcastReceiver 등록

  4) 해제

 

3. 빌드 프로세스

  1) Manifest에 권한 요청 코드 작성

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

  2) BroadcastReceiver를 확장하여 상태값을 받아오고 상태에 따라 출력할 메시지를 수정

public class NetworkReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 네트워크 상태값 받아오기
        if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
            NetworkInfo info = (NetworkInfo)  intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            NetworkInfo.DetailedState state = info.getDetailedState();
            if(state == NetworkInfo.DetailedState.CONNECTED) { //네트워크 연결 상태이면..\
              MainActivity.tv_state.setText("네트워크 연결 완료");
            } else if (state == NetworkInfo.DetailedState.DISCONNECTED) { // 네트워크 연결 해제이면....
              MainActivity.tv_state.setText("네트워크 연결 해제");
            }
        }
    }
}

  3) MainActivity에서 Receiver를 등록하고 Intent를 통해 상태를 받아와서 엑션을 취하게 하고 다시 등록한 리시버를 해제

public class MainActivity extends AppCompatActivity {

    public static TextView tv_state;
    private NetworkReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv_state = findViewById(R.id.tv_state);

        // 브로드캐스트 리시버 등록
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        receiver = new NetworkReceiver();
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        registerReceiver(receiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 등록한 리시버 해제
        unregisterReceiver(receiver);
    }
}

 

4. 현재 방식

  1) 차이점

    - 30버전 부터는 BroadcastReceiver를 사용하지 않고 ConnectivityManager.NetworkCallback을 통해 상태를 체크함.

    - 네트워크의 연결 여부가 아니라 사용 가능 여부 체크, 따라서 와이파이인지 셀룰러인지의 문제가 중요하지않게 됨

    - 권한 요청은 전과 같음

 

  2) 수정 코드 

    - ConnectivityManager.NetworkCallback 확장하여 class 정의

public class NetworkReceiver extends ConnectivityManager.NetworkCallback {
    private TextView tv_state;

    public NetworkReceiver(TextView tv_state) {
        this.tv_state = tv_state;
    }

    @Override
    public void onAvailable(@NonNull Network network) {
        super.onAvailable(network);
        tv_state.setText("네트워크 연결 완료");
    }

    @Override
    public void onLost(@NonNull Network network) {
        super.onLost(network);
        tv_state.setText("네트워크 연결 해제");
    }
}

    - MainActivity에서 action 수행


public class MainActivity extends AppCompatActivity {
    private NetworkReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv_state = findViewById(R.id.tv_state);
        receiver = new NetworkReceiver(tv_state);

        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkRequest.Builder builder = new NetworkRequest.Builder();
        connectivityManager.registerNetworkCallback(builder.build(), receiver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 등록한 리시버 해제
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        connectivityManager.unregisterNetworkCallback(receiver);
    }
}