도전11과 비슷하다.

 

액티비티에 글자 입력 -> 서비스로 데이터 전송 -> 서비스에서 브로드캐스트 수신자로 데이터 전송 -> 액티비티에 글자 출력

 

activity_main.xml은 동일하다.

 

1. MainActivity.java

package com.example.doitmission12;

public class MainActivity extends AppCompatActivity {

    EditText inputText;
    TextView outputText;

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

        // 브로드캐스트 수신자 등록
        IntentFilter filter = new IntentFilter("com.example.CUSTOM_BROADCAST");
        registerReceiver(myReceiver, filter);

        inputText = findViewById(R.id.editTextText);
        outputText = findViewById(R.id.textView2);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            // 서비스로 데이터 전송
                Intent serviceIntent = new Intent(getApplicationContext(), MyService.class);
                serviceIntent.putExtra("key",inputText.getText().toString());
                startService(serviceIntent);
            }
        });
    }

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

        // 브로드캐스트 수신자 해제
        unregisterReceiver(myReceiver);
    }

    // BroadcastReceiver 객체 생성하기
    private BroadcastReceiver myReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            if ("com.example.CUSTOM_BROADCAST".equals(intent.getAction())) {
                // 브로드캐스트 수신 시 처리
                String text = intent.getStringExtra("key");
                outputText.setText(text+"(Broadcast)");
            }
        }
    };
}

 

액티비티 안에 브로드캐스트 수신자 등록하기

        IntentFilter filter = new IntentFilter("com.example.CUSTOM_BROADCAST");
        registerReceiver(myReceiver, filter);

 

[ 브로드캐스트 객체 생성 : 잘못 작성한 코드 ]

더보기

오답. BroadcastReceiver를 extends하여 새로운 class로 만드는게 아니라 BroadcastReceiver 객체로 만들면 된다.

뭐.. 아래같이 만든 다음 MyReceiver myReceiver = new MyReceiver() 이렇게 만들 수도 있겠다만~

BroadcastReceiver에서 재정의를 해서 새로운 메서드를 추가하고 이럴 것이 아니기 때문에 그냥 BroadcastReceiver 객체를 만들어주면 되는 거다.

    /*
    public static class MyReciever extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent broadcastIntent = new Intent(context, MainActivity.class);
            String text = intent.getStringExtra("key");
            // 확인용
            if(text!=null)
                Log.d("broadcast",text!=null?text:"null");
            broadcastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|
                    Intent.FLAG_ACTIVITY_CLEAR_TOP);
            broadcastIntent.putExtra("key",text+"(Broadcast)");
            context.getApplicationContext().startActivity(broadcastIntent);
        }
    }*/

2. MyService.java

package com.example.doitmission12;

public class MyService extends Service {
    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(intent==null)
            return Service.START_STICKY;
        else
            processCommand(intent);
        return super.onStartCommand(intent, flags, startId);
    }

    private void processCommand(Intent intent){
        String text = intent.getStringExtra("key");
        // 확인용
        Log.d("service",text!=null?text:"null");
        Intent activityIntent = new Intent("com.example.CUSTOM_BROADCAST");
        activityIntent.putExtra("key",text+"(service)");
        sendBroadcast(activityIntent);
    }
}

 

[ 확인용 로그 ]

더보기

만약 그냥 Log.d("TAG", text) 이렇게 작성해버린다면, text가 null일 때 에러가 발생한다. 왜냐면 log에 null 값이 들어가면 안되기 때문이다. 그러므로, null이 들어간다면 다른 값을 출력하도록 만들어줘야한다. 아래의 경우 null 값이 들어갔으면 "null"을 출력하도록 설정해주었다.

// 확인용
Log.d("service",text!=null?text:"null");

 

[ 서비스 -> 브로드캐스트로 데이터 전송 ]

Intent activityIntent = new Intent("com.example.CUSTOM_BROADCAST");
activityIntent.putExtra("key",text+"(service)");
sendBroadcast(activityIntent);

인텐트 객체를 만들 때, 메인엑티비티에서 설정해주었던 인텐트 필터를 설정해준다.

그리고 sendBroadcast() 에서드에 만든 인텐트를 넣어준다.

 

3. 실행결과

 

이번엔 도전11 문제랑 차이점을 두었다. 서비스를 거치면 "(service)", 브로드캐스트를 거치면 "(Broadcast)"가 텍스트에 추가되도록 했다.

출력이 잘 된 것을 확인할 수 있다.