Unity3D Android GCM Integration - 2. Sender ID 등록 및 Push 메세지 핸들링 후 알림 띄우기

 유니티3D 안드로이드 푸시 처리를 위한 GCM 연동 준비작업을 정리했었습니다. 이번에는 안드로이드 디바이스에서 GCM 푸시를 받을 수 있게 Sender ID를 등록하고 푸시 메세지 핸들링을 처리할 GCMBaseIntentService를 상속받는 GCMIntentService 클래스 클라이언트쪽 작업을 정리해보겠습니다.

  • 자체 서버(JSP든 PHP든) + DB + 운영툴(공지 메세지 보내기)
 보통은 GCM 푸시하려면 위와 같은 구조로 서버 구성을 하겠죠. 제가 정리할 내용은 아래와 같은 구조입니다.

  • 자체 서버 없음. 앱 하나에서 GCM Push Send까지 다 함.
  • DB 없음. 등록된 디바이스는 오직 한개라고 정의하고 간단히 멤버변수에 때려박음.
  • 운영툴 없음. GUI TextFiled로 입력받은 스트링을 GCM에 보냄.

 한마디로 with out Server 구조입니다. 즉, Client -> GCM -> 동일 Client 이런식이 되는거죠. 혼자 북치고 장구치고 다 하는 튜토리얼입니다. 일반적으론 각자 구현한 Server -> GCM -> Clients 이렇게 되겠죠. 제가 서버 개발자가 아니라서 일단 이렇게 하는데요, 서버와의 연동부분이 필요한 부분은 소스구현없이 따로 살짝 언급하고 진행하도록 하겠습니다.


1. 안드로이드

public class MainActivity extends UnityPlayerActivity {
private final String LOG_TAG = "UNITY_GCM_TEST";
private final String GCM_SENDER_ID = "1111111111111";
private String strRegId = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
this.strRegId = GCMRegistrar.getRegistrationId(this);
if (this.strRegId == null || this.strRegId.equals("")) {
GCMRegistrar.register(this, GCM_SENDER_ID);
Log.d(LOG_TAG, "Sender Id Regist");
} else {
Log.d(LOG_TAG, "Registered Sender Id " + this.strRegId);
}

}
}

 앱이 시작되면 구글 GCM 서버에 Sender ID가 등록 안 되어 있다면 등록해서 디바이스의 고유한 등록 ID를 받아야 합니다. 이때 넘겨주는 Sender ID는 구글 API Project 사이트에서 등록했던 Project Number 값을 기입합니다.

 결과로 받는 RegID는 각 디바이스별 고유 ID값입니다. 서버에서는 이 아이디를 참고해서 푸시를 보내는 것이죠. 현재 샘플에서는 자기 자신에게 보낼 것이기에 직접 멤버 변수로 RegID 를 가지고 있습니다. 서버에서는 DB에 저장을 해야겠죠. 참고로 앱을 삭제 후 다시 설치해 등록을 다시해도 RegID는 고유합니다.

 이제 연동 준비작업에서 AndroidManifest.xml에 추가했던 GCMIntentService 클래스를 보겠습니다.

 AndroidManifest.xml에만 추가되었기 때문에 실제로 클래스를 위와같이 하나 만들어줍니다. Superclass는 com.google.android.gcm.GCMBaseIntentService입니다. 그리고 아래와 같이 작업합니다.

public class GCMIntentService extends GCMBaseIntentService {
private final String LOG_TAG = "UNITY_GCM_TEST";
private final static String GCM_SENDER_ID = "111111111111";
public GCMIntentService() {
super(GCM_SENDER_ID);
}

@Override
protected void onError(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.d(LOG_TAG, "onError : " + arg1);
}

@Override
protected void onMessage(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
String strTitle = arg1.getStringExtra("Title");
String strMsg = arg1.getStringExtra("Msg");
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(arg0, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(arg0, 0 , notificationIntent, 0);

Notification notification = new Notification();
Resources res = getResources();
notification.icon = res.getIdentifier("com.test.gcm:drawable/app_icon", null, null);

notification.defaults = Notification.DEFAULT_ALL;
//notification.vibrate = new long[]{100, 50, 100, 50};
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.tickerText = "Ticker Text Test.";
notification.setLatestEventInfo(arg0, strTitle, strMsg, pendingIntent);
notificationManager.notify(0, notification);
}

@Override
protected void onRegistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.d(LOG_TAG, "onRegistered : " + arg1);

// TODO : 서버가 있다면 RegID를 전송해서 DB에 등록한다.
}

@Override
protected void onUnregistered(Context arg0, String arg1) {
// TODO Auto-generated method stub
Log.d(LOG_TAG, "onUnregistered : " + arg1);

// TODO : 역시나 서버가 있다면 삭제요청을 보낸다.
}

}

 GCM으로부터 푸시를 받으면 알림을 띄우고 알림을 클릭하면 해당 앱(Activity)을 실행하는 부분입니다. 붉은색 Sender ID는 마찬가지로 Project Number입니다. 중요한 함수는 onRegistered와 on Message입니다.

 onRegistered의 경우 현재는 서버 연동 없이 진행하는 튜토리얼이라 RegID 로그만 출력하고 있지만 저 부분에서 각자의 서버와 연동을 해줘야합니다. 즉, 구현한 서버에 디바이스의 고유 ID를 보내주고 서버에서 DB로 관리를 해야하는 것이죠.

 두번째로 onMessage에서는 GCM서버에서 날라온 푸시를 Notification 처리하는 부분입니다. 이 부분을 처리하면서 간단하게는 진동 이슈가 있었고 R.java와의 연동 이슈문제알림을 클릭해 이미 실행중인 Activity를 활성화 하는 부분의 이슈가 있었습니다. R.java때문에 생긴 R drawable 이슈는 지금처럼 유니티 엔진베이스가 아닌 순수 안드로이드 게임이나 어플이라면 생기지 않을 이슈죠.


2. 유니티3D

using UnityEngine;

public class GCMManager : MonoBehaviour 
{
static GCMManager _instance;
private AndroidJavaObject curActivity;
public static GCMManager GetInstance()
{
if( _instance == null )
{
_instance = new GameObject("GCMManager").AddComponent<GCMManager>();
}
return _instance;
}
void Awake()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
curActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");
}

}

 간단한 GCMManager 싱글톤 컴포넌트입니다. 아직은 유니티3D에서 위와 같이 자바와 연결 작업만하고 추가적인 작업은 없습니다.

using UnityEngine;

public class TestGUI : MonoBehaviour 
{
void Start()
{
}
// Update is called once per frame
void Update () 
{
if (Application.platform == RuntimePlatform.Android)
        {

            if (Input.GetKey(KeyCode.Escape))
            {
                Application.Quit();
                return;
            }
}
}

void OnGUI()
{
float fYpos = 0;
GUI.Label(new Rect(0, fYpos, 400, 100), "Unity3D Android GCM Test");
}
}


 TestGUI 컴포넌트도 마찬가지입니다. GUI Label하나 출력하는 것말고는 없죠.

 GCM 푸시를 받아서 알림을 띄우는 처리까지 정리해봤습니다. 다음에는 언급한데로 실제 서버는 아니지만 안드로이드 자바에서 GCM에 메세지를 Send 처리하는 것을 정리해보겠습니다.

댓글

이 블로그의 인기 게시물

'xxx.exe' 프로그램을 시작할 수 없습니다. 지정된 파일을 찾을 수 없습니다.

goorm IDE에서 node.js 프로젝트로 Hello World Simple Server 만들어 띄워보기

애드센스 수익을 웨스턴 유니온으로 수표대신 현금으로 지급 받아보자.