마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

전화 벨이 울리는 동안의 이벤트를 캐치 하고 싶은데 잘 안되네요

0 추천
public class CallReceiver extends BroadcastReceiver {

    @RequiresApi(api = Build.VERSION_CODES.S)
    @Override
    public void onReceive(Context context, Intent intent) {
        registerCustomTelephonyCallback(context);
    }

    @RequiresApi(Build.VERSION_CODES.S)
    class CustomTelephonyCallback extends TelephonyCallback implements TelephonyCallback.CallStateListener {
        private CallBack mCallBack;
        public CustomTelephonyCallback(CallBack callBack) {
            mCallBack = callBack;
        }

        @Override
        public void onCallStateChanged(int state) {
            mCallBack.callStateChanged(state);
        }
    }
    @RequiresApi(Build.VERSION_CODES.S)
    public void registerCustomTelephonyCallback(Context context) {
        TelephonyManager telephony = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);

        telephony.registerTelephonyCallback(context.getMainExecutor(), new CustomTelephonyCallback(new CallBack() {
            @Override
            public void callStateChanged(int state) {

                int myState = state;
                if( myState == TelephonyManager.CALL_STATE_RINGING) {
                    Log.e("MyPhoneStateListener", "RINGING");
                }
            }
        }));
    }

    interface CallBack {
        void callStateChanged(int state);
    }
}
여기 저기서 소스 가져와서 저렇게 구성했는데 도대체 
Log.e... 부분에 브레이크가 걸리질 안네요. 에뮬레이터에서 가상으로 전화하는 방식으로 테스트 했습니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent intent = new Intent(getApplicationContext(), CallReceiver.class); // 실행시키고픈 서비스클래스 이름
    // intent.putExtra("", ""); 필요시 인텐트에 필요한 데이터를 담아준다

    startService(intent); // 서비스 실행!
}
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<receiver
    android:name=".CallReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE"/>
    </intent-filter>
</receiver>
ㅇㅇㅇㅇ (180 포인트) 님이 2022년 11월 13일 질문

1개의 답변

0 추천

좀 이상한 부분이 AndroidManifest.xml에 CallReceiver를 등록한 건 맞아 보이는데, 아래 권한에 대한 처리가 필요해 보이는데 하고 계신지 궁금하구요.

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

그리고, CallReceiver는 BroadCastReceiver인데, startService를 하는 부분도 이상합니다. 제가 알기로 BroadCastReceiver는 register/unregisterReceiver메소드를 사용해야 하는 걸로 알고 있고요, AndroidManifest.xml에 BroadCastReceiver가 등록이 되어 있다면 시스템에서 자동으로 등록해주므로, register/unregister할 필요가 없습니다.

 

CallReceiver의 registerCustomEelephonyCallback 메소드 안에 있는

context.getMainExecutotr()

는 실행해 보면 에러입니다. 왜냐하면 BroadCastReciver의 context는 ReceiverRestrictedContext 인데, 이게 안드로이드 내부 클래스로 접근이 불가능하네요. 그리고 getMainExecutor라는 메소드를 찾을 수 없는 것으로 나옵니다.

다른 방법으로는 TelephonyManager를 사용할 수도 있습니다.

spark (227,530 포인트) 님이 2022년 11월 13일 답변
...