일단 구글 개발자 사이트에서 GCM Service 를 등록했으면, 이제 앱에서 사용자 폰을 GCM Service 에 등록하고 ID 를 받아야 한다.
이클립스에서 일단 구글 서비스 패키지가 설치가 되어 있어야 하니...
"Android SDK Manager" 를 실행해서...
"Google Play service" 가 설치되어 있어야 한다.
이게 설치되어 있으면...
{안드로이드 SDK 설치된폴더}/sdk/extras/android/support/v4/android-support-v4.jar
에 있는 "android-support-v4.jar" 를 lib 폴더에 복사해 준다.
이 때, "gcm.jar" 파일도 필요한데... 이건 뭐... 인터넷에서 검색해 넣자... 많이 나온다.
이게 원래는 "Android SDK Manager" 에서 "Google Cloud Messaging for Android Library" 설치하면 나오는 파일인데, 이게 어떨때는 설치항목에 나오고 어떤때는 안나오고 막 그렇다.
파일만 있으면 해당 패키지가 설치되어 있지 않더라도 상관없으니, 그냥 다운 받아 넣어도 된다.
이렇게 라이브러리를 등록하고... 앱을 만들면...
대충 이런 형태가 된다.
MainActivity.java 는 그냥 최초 로딩 되는 폼일 뿐이고,
GCMHttpConnect.java 와 GCMIntentService.java 가 실제 동작하는 클래스다.
소스를 살펴보면...
[AndroidManifest.xml]
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="kr.blogspot.son10001" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> <permission android:name="kr.blogspot.son10001.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="kr.blogspot.son10001.permission.C2D_MESSAGE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.VIBRATE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="kr.blogspot.son10001" /> </intent-filter> </receiver> <service android:name=".GCMIntentService" /> </application> </manifest>
[MainActivity.java]
package kr.blogspot.son10001; import android.app.Activity; import android.os.Bundle; import android.util.Log; import com.google.android.gcm.GCMRegistrar; public class MainActivity extends Activity { private static final String TAG = "GCM"; private static final String SENDER_ID = "529212329497"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); registerGcm(); } public void registerGcm() { GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); //GCM 등록여부 final String regId = GCMRegistrar.getRegistrationId(this); //등록된 ID가 없으면 ID값을 얻어옵니다 if (regId.equals("") || regId == null) { GCMRegistrar.register(this, SENDER_ID); }else{ Log.w(TAG, "Already Registered : " + regId); } } }
[GCMHttpConnect.java]
package kr.blogspot.son10001; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import android.os.Handler; import android.os.Message; import android.util.Log; public class GCMHttpConnect extends Thread{ private static final String TAG = "HTTP"; private Request mRequest; private String mString; public GCMHttpConnect(String url, Request request) { mString = url; mRequest = request; } @Override public void run() { download(mString); Message msg = new Message(); msg.what = 0; mHandler.sendMessage(msg); } Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub if (mRequest != null) { mRequest.OnComplete(); } } }; public static interface Request { public void OnComplete(); } public void download(String address) { StringBuilder jsonHtml = new StringBuilder(); try{ //연결 url 설정 URL url = new URL(address); //컨넥션 객체 생성 HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setDefaultUseCaches(false); conn.setDoInput(true); // 서버에서 읽기 모드 지정 conn.setDoOutput(false); // 서버로 쓰기 모드 지정 conn.setRequestMethod("POST"); // 전송 방식은 POST //연결되었다 if(conn != null){ conn.setConnectTimeout(10000); conn.setUseCaches(false); //연결확인 코드가 리턴되었을 때 if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){ BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); for(;;){ String line = br.readLine(); if(line == null) break; jsonHtml.append(line); } br.close(); } conn.disconnect(); } }catch(Exception e){ Log.w(TAG, e.getMessage()); } } }
[GCMIntentService.java]
package kr.blogspot.son10001; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.util.Log; import android.widget.Toast; import com.google.android.gcm.GCMBaseIntentService; public class GCMIntentService extends GCMBaseIntentService { private static final String TAG = "GCM"; private static final String SENDER_ID = "529212329497"; private GCMHttpConnect.Request httpRequest = new GCMHttpConnect.Request() { @Override public void OnComplete() { // TODO Auto-generated method stub showToast(); } }; public GCMIntentService() { super(SENDER_ID); } @Override protected void onMessage(Context context, Intent intent) { if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { showMessage(context, intent); } } @Override protected void onError(Context context, String msg) { // TODO Auto-generated method stub Log.w(TAG, "onError!! " + msg); } @Override protected void onRegistered(Context context, String regID) { // TODO Auto-generated method stub if(!regID.equals("") || regID != null){ Log.w(TAG, "onRegistered!! " + regID); } } @Override protected void onUnregistered(Context context, String regID) { // TODO Auto-generated method stub Log.w(TAG, "onUnregistered!! " + regID); } public void showToast(){ Toast.makeText(this, "RegID 등록 완료", Toast.LENGTH_LONG).show(); } private void showMessage(Context context, Intent intent){ Log.w(TAG, "onShowMessage!! "); String title = intent.getStringExtra("title"); String msg = intent.getStringExtra("msg"); String ticker = intent.getStringExtra("ticker"); NotificationManager notificationManager = (NotificationManager)context.getSystemService(Activity.NOTIFICATION_SERVICE); //행하는 이벤트를 하고싶을 때 아래 주석을 풀어주세요 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0); // PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(), 0); Notification notification = new Notification(); notification.icon = R.drawable.ic_launcher; notification.tickerText = ticker; notification.when = System.currentTimeMillis(); notification.vibrate = new long[] { 500, 100, 500, 100 }; notification.sound = Uri.parse("/system/media/audio/notifications/20_Cloud.ogg"); notification.flags = Notification.FLAG_AUTO_CANCEL; notification.setLatestEventInfo(context, title, msg, pendingIntent); notificationManager.notify(0, notification); } }
대강 이렇다.
중요한 것은...
AndroidManifest 에 있는 "service" 항목에 있는 클래스가 실제 GCM 을 컨트롤 하는 함수라는것을 알고 있으면, 어떻게든 분석이 가능 할 것이다.
이렇게 하고 앱을 실행 해 보면...
저렇게 GCM service 등록 ID 를 알아 낼수 있는데, 이걸 이용해서 서버에서 특정 사용자에게 Push 메시지를 보낼 수 있다.
일반적으로는 앱을 실행 할때 등록 ID 을 생성해서 서버에다 전송해 등록해 놓고, 필요 할 때, 저 ID 를 이용해 메시지를 보내면, 해당 폰에서 메시지를 받아 볼 수 있게 된다.
이제 저 ID 를 이용해 Push 서버에 메시지를 보내기만 하면 된다.