달달한 스토리

728x90
반응형

 

오늘로 세 번째 글이다.

 

아까 올렸던 ConnectivityManager이다

 

이것을 이제는 extends로 이용해보자.

 

우선

 

Service를 이용해야 하는데, 나는 아직 Service에 대해서 깊게 이해하지는 않았다.

 

대충 알고 있는 어느 정도 개념은, 눈에 보이지 않은,

 

디바이스의 백그라운드에서 실행할 수 있다고 들었다.

 

우선 메인 액티비티에서 Intent로 서비스에게 요청하면,

 

서비스는 네트워크 콜백 클래스에서 값을 받아서

 

화면에 값을 출력하는 정도로만 알고 있고,

 

오늘 예제에도 그 정도만 써보고자 한다.

 

lcw126.tistory.com/278

 

안드로이드 NetworkCallback(실시간 네트워크 체크)

NetworkCallback에 자세한 사항은 아래 안드로이드 개발자 사이트를 참고 바랍니다. https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback ConnectivityManager.NetworkCall..

lcw126.tistory.com

여기 블로그를 참고했습니다.

 

우선 매니페스트에

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

퍼미션을 추가해준다.

 

와이파이나 네트워크(데이터)가 연결이 되어있는지 확인하는 권한이다.

 

그런 다음 MainActivity를 다음과 같이 작성한다.

 

public class MainActivity extends AppCompatActivity {

    public static TextView textView;



    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) throws IllegalStateException{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = findViewById(R.id.textView);

        Intent intent = new Intent(this,MyService.class);
        startService(intent);

        textView.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                String Hi = textView.getText().toString();
                if(Hi.equals("안녕2")) {
                    Toast.makeText(getApplicationContext(), "성공3", Toast.LENGTH_SHORT).show();
                }
            }
        });

    }

}// MainActivity Class..

중간에 넣은 TextWatcher은 아까 배운 것에 응용하기 위해 넣은 것이다.

 

중요한 건 

 

Intent intent = new Intent(this,MyService.class);
        startService(intent);

이 부분이다. 인텐트를 통해서 서비스로 이동하는 부분이다.

직접 액티비티가 아닌 데이터만(호출한다) 전달이 되는 상황이다.

 

public class MyService extends Service {

    NetworkConnectionCheck networkConnectionCheck;
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {    //  LOLLIPOP Version 이상..
            if(networkConnectionCheck==null){
                networkConnectionCheck=new NetworkConnectionCheck(getApplicationContext());
                networkConnectionCheck.register();
            }
        }
        return START_STICKY;    // START_STICKY : 시스템에 의해 종료 되어도 다시 생성 시켜주는 것
    }// onStartCommand() ..

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {     //  LOLLIPOP Version 이상..
            if(networkConnectionCheck!=null) networkConnectionCheck.unregister();
        }
    }// onDestroy()..
}

그러고 나서 MyService부분을 작성해준다.

 

아직 초보라 이 부분에 대해서는 조금 침묵하겠다. 헤헤..

 

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    //LOLLIPOP 버전 이상에서 동작
public class NetworkConnectionCheck extends ConnectivityManager.NetworkCallback {   // 네트워크 변경에 대한 알림에 사용되는 Callback Class

    private Context context;
    private NetworkRequest networkRequest;
    private ConnectivityManager connectivityManager;
    public static Thread timeThread = null;

    public NetworkConnectionCheck(Context context){
        this.context=context;
        networkRequest =
                new NetworkRequest.Builder()                                        // addTransportType : 주어진 전송 요구 사항을 빌더에 추가
                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)   // TRANSPORT_CELLULAR : 이 네트워크가 셀룰러 전송을 사용함을 나타냅니다.
                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)       // TRANSPORT_WIFI : 이 네트워크가 Wi-Fi 전송을 사용함을 나타냅니다.
                        .build();
        this.connectivityManager = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE); // CONNECTIVITY_SERVICE : 네트워크 연결 관리 처리를 검색
    }

    public void register() { this.connectivityManager.registerNetworkCallback(networkRequest, this);}

    public void unregister() {
        this.connectivityManager.unregisterNetworkCallback(this);
    }

    @Override
    public void onAvailable(@NonNull Network network) {
        super.onAvailable(network);
        // 네트워크가 연결되었을 때 할 동작
        Toast.makeText(this.context, "network available", Toast.LENGTH_SHORT).show();
        timeThread = new Thread(new timeThread());
        timeThread.start(); //쓰레드실행

    }

    @Override
    public void onLost(@NonNull Network network) {
        super.onLost(network);

        // 네트워크 연결이 끊겼을 때 할 동작
        Toast.makeText(this.context, "network lost", Toast.LENGTH_SHORT).show();

    }

    Handler handler = new Handler(Looper.myLooper()) { //실시간 날짜를 출력해주는 핸들러
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();
            String dateTime = bundle.getString("dateTime");
            MainActivity.textView.setText(dateTime);
        }
    };

내가 건드린 부분은 오늘 이 곳이다.

 

onAvailable, onLost 이 부분이 중요한다.

 

각각 인터넷이 연결되었을 때, 연결이 되지 않을 때,

 

액션을 넣을 수 있다. 그런데 막상 해보니까

 

데이터 전달을 할 수 있는 방법이 (내가 아는 선에서는)

 

없더라... 소켓통신이라도 이용해 보려 했는데,

 

생성자로도 해보려 했는데, 잘 되지 않았다.

 

그래서 ui를 건드릴 수 있는 스레드를 이용했다.

 

그랬더니 성공적으로, 메인 액티비티에 textView를

 

가져와서 사용할 수 있었다.

 

이렇게 해서 완성된 영상이다.

 

 

 

 

들어가자마자, 돌고 돌아,

 

안녕 2라는 글자를 쓰게 만들었다.

 

그리고, 와이파이를 끄고 켤 때마다

 

각각 연결되었다. 연결이 되지 않았다라고 써져있다고 나온다.!!

 

이것으로 잘 활용해서 쓰면 되겠다.

 

나머지 자료는 깃 헙에 올리겠다.

 

 

728x90
반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading