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

안드로이드 GCM관련 질문 드려요

0 추천
안녕하세요

현재 GCM을 구현하여 테스트 중인데요

어플을 프로세스 강제 종료를 할 경우에는 메시지가 날라오지 않는데 그게 정상인가요?

저는 어플을 강제 종료할 경우라도 메시지를 받을 수 있게 하고 싶은데 혹시 방법이 있는지 문의드려요

 

답변 부탁드려요
삽질개발자 (460 포인트) 님이 2013년 4월 4일 질문

2개의 답변

+1 추천

 


제가 아는 것은 없지만 아는 것을 적어보겠습니다. 100%신용은 금물입니다요;

우선 3.1 버전 이전은 앱이 완전히 종료되도 C2DM or GCM을 받을수 있었습니다.

하지만 3.1이후부터 바뀌게 되었습니다.

Android 3.1 버전부터 system의 package manager가 app의 stoped 상태를 유지 관리한다고 합니다.

app이 종료 되어 있을때 Broadcast의 Intent Flag에 따라 stoped된 어플도 Broadcast를 받을지 안받을지 정해주는 걸로 알고 있습니다.

 -> http://aroundck.tistory.com/684

위를 읽어보면 시스템이 Broadcast intent에 대해서는 기본값으로 FLAG_EXCLUDE_STOPPED_PACAGES를 준다고 합니다. 이를 토대로 생각해보면

GCM도 Broadcast를 이용하고, systme에서 intentFlag에 FLAG_EXCLUDE_STOPPED_PACAGES 로 Broadcast를 하기 때문에 이미 완전히 종료된 app은 GCM을 받을 수 없는 것으로 생각됩니다.

아래는 GCMBroadcastReceiver.java 입니다.

 

public class GCMBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "GCMBroadcastReceiver";
    private static boolean mReceiverSet = false;

    @Override
    public final void onReceive(Context context, Intent intent) {
        Log.v(TAG, "onReceive: " + intent.getAction());
        // do a one-time check if app is using a custom GCMBroadcastReceiver
        if (!mReceiverSet) {
            mReceiverSet = true;
            GCMRegistrar.setRetryReceiverClassName(getClass().getName());
        }
        String className = getGCMIntentServiceClassName(context);
        Log.v(TAG, "GCM IntentService class: " + className);
        // Delegates to the application-specific intent service.
        GCMBaseIntentService.runIntentInService(context, intent, className);
        setResult(Activity.RESULT_OK, null /* data */, null /* extra */);
    }

    /**
     * Gets the class name of the intent service that will handle GCM messages.
     */
    protected String getGCMIntentServiceClassName(Context context) {
        return getDefaultIntentServiceClassName(context);
    }

    /**
     * Gets the default class name of the intent service that will handle GCM
     * messages.
     */
    static final String getDefaultIntentServiceClassName(Context context) {
        String className = context.getPackageName() +
                DEFAULT_INTENT_SERVICE_CLASS_NAME;
        return className;
    }
}

 

위 소스를 보면 onReceive에서 자신의 앱의 패키지 + DEFAULT_INTENT_SERVICE_CLASS_NAME( == .GCMIntentService)로 설정하여 runIntentInService()에서 그 서비스를 실행하고 이후 나머지 로직을

실행하게 됩니다.

테스트를 하여 본 결과, 앱을 강제종료하고 GCM을 보내면, onReceive()의 

Log.v(TAG, "onReceive: " + intent.getAction()); 가 실행이 안되는 것을 알 수 있습니다.

이는 GCMBroadcastReceiver.java 에서 처음에 적은 이유와 같이 'com.google.android.c2dm.intent.RECEIVE' Broadcast를 받지 못하는 것으로 생각할 수 있습니다.

이러한 이유로 강제 종료시에는 GCM을 받을수 없다고 알고 있습니다.

 

아쉽지만 제가 아는 범위에서는 3.1 버전이후 강제로 앱이 종료 되면 GCM을 받을 수 없는 것은 정상입니다. (루팅 된 폰은 예외 일것임)

수고하셔요..

 

 

 

앙드로이등 (850 포인트) 님이 2013년 4월 4일 답변
0 추천
저도 공부해보려고 인터넷에서 예제, 강좌 같은것들보고 GCM구현해서 사용중인데

젤리빈에서 테스트중인데 앱 종료해도 메세지 받아지네요.

저는 받아지는게 정상인줄 알았는데 아닌가보네요?
NullPointerException (1,640 포인트) 님이 2013년 4월 5일 답변
흠.. 그런가요..?
제가 테스트한 상황은
앱을 완전히 종료 즉. 설정 -> 애플리케이션 -> 해당앱 -> 강제 종료.
일때 GCM을 받을 수 없었습니다.
강제종료가아닌 그냥 앱이 STOP 상태일때는 GCM수신은 가능하였습니다.
ㅎㅎ
...