728x90

안드로이드폰에서 전화수신시 앱에서 수신전화의 상태를 감지하여 전화수신 팝업을 띄우기 위한 기본 코드라고 보면 된다.

전화벨이 울리면 메시지가 2번씩 수신된다. 전화에 대한 정보를 2번씩 보내주나 보다.

그래서 팝업창 구현 등을 하려면 1번만 메시지가 수신되어야 하므로 1번만 띄우도록 처리하는 로직이 포함되었다.


--- AndroidManifest.xml 파일 추가할 사항 ---

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

<receiver
    android:name=".CallStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE"/>
    </intent-filter>
</receiver>

 --- CallStateReceiver.java ---

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class CallStateReceiver extends BroadcastReceiver {
    static String mLastState;
    static final String TAG = "CallStateListner";
    
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "CallStateReceiver >>>>>>> 전화 수신");
        
        // 전화 수신 체크
        CallReceivedChk(context, intent);
    }
    
    private void CallReceivedChk(Context context, Intent intent) {
        TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(new PhoneStateListener(){
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                String mState = String.valueOf(state);
                if (mState.equals(mLastState)) { // 두번 호출되는 문제 해결 목적
                    return;
                } else {
                    mLastState = mState;
                }
                
                switch(state) {
                    case TelephonyManager.CALL_STATE_IDLE:
                        Log.d(TAG,"전화 수신 상태가 아닙니다 : CALL_IDLE");
                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        Log.d(TAG, "전화를 받았습니다 : CALL_OFFHOOK");
                        break;
                    case TelephonyManager.CALL_STATE_RINGING:
                        Log.d(TAG, "CALL_RINGING, 수신 전화번호 : " + PhoneNumberUtils.formatNumber(incomingNumber));
                        // 처리하고자 하는 코드 추가하면 된다.
                        break;            
                }
            }    
        }, PhoneStateListener.LISTEN_CALL_STATE);
    }

}


위 코드를 가지고 활용을 해서 팝업창을 띄우는 코드를 새롭게 만들거나

http://gun0912.tistory.com/46 에 있는 코드를 활용하면 팝업창을 띄울 수 있다.

위 코드를 그대로 사용하면 앱이 죽는 증상이 있다.
코드가 100% 완벽하게 동작되도록 하려면 개발자 본인이 수정 보완해야 한다.

코드에 대한 완벽한 분석과 기초지식이 있어야 가능하더라.


스마트폰 스크린이 잠겨있는 OFF 상태에서 전화가 수신되면 수신 팝업창을 ON 상태로 바꿔 사용자에게 메시지를 알려주려면 어떻게 해야 할까?


안드로이드 시스템에서는 장비가 휴면모드로 들어가게 되면 배터리 소모를 최소화하기 위하여 불필요한 CPU나 와이파이를 포함한 모든 기능들은 정지시키려고 한다.
Service 가 지속적으로 실행이 되고 있는 것을 확실하게 보장하기 위해서 "WAKE Locks"를 사용해야 한다. Wake Lock는 앱에서 특정 기능들을 계속 활성화 시켜놓아야 한다는 것을 시스템에 알려주는 역할을 하는 것이다.


private static PowerManager.WakeLock wakeLock;
private void WakeLock(Context context, Intent intent) {
    // 잠든 화면 깨우기
    if (wakeLock != null) {
        return;
    }

    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
            | PowerManager.ON_AFTER_RELEASE, "hi");
    wakeLock.acquire();  
}


이 메소드를 BroadcastReceiver 에 추가한다.


START_STICKY : 재생성과 on StartCommand() 호출(with null intent)
START_NOT_STICKY : 서비스 재 실행하지 않음
START_REDELIVER_INTENT : 재생성과 on StartCommand() 호출(with same intent)
 


읽어볼만한 자료

배터리를 잡아먹는 주원인 WakeLock : http://widzard.tistory.com/36

블로그 이미지

Link2Me

,