총 게시물 919건, 최근 0 건 안내 RSS 글쓰기
이전글  다음글  목록 글쓰기
[안드로이드]

구글 GCM Client/Server 완벽 예제(서버페이지 사용X)스압주의

글쓴이 : 피로리 날짜 : 2012-07-18 (수) 15:07 조회 : 23282
글주소 : http://www.androidside.com/B49_best/5347
GCMServerTutorial.zip (1.2M), Down : 100, 2012-07-18 15:07:57
 
  온라인마케팅 기초 아이보스
온라인마케팅이 어렵고 생소하신가요? 랭키닷컴 1위 아이보스의 마케팅 꿀 Tip
www.i-boss.co.kr
  파일다운프로그램 스마트파일
안전한 웹하드! 검증된 웹하드! 모든 컨텐츠 가격 할인 보장, 자료많은 웹하드.
smart-file.co.kr
  신규웹하드 밥파일
영화, 드라마, 예능, 애니, 무료다운로드, 무료쿠폰, 신규웹하드, 웹툰
www.babfile.kr
신청하기


요번에 C2DM이 GCM으로 정식서비스를 하여서 많은 분들이 혼란을 겪고 있는거 같아
저같은 초보분들 삽질하지 마시라고 가이드를 적어봅니다. (근데 왜 강좌/학습 게시판에 글작성이 안되나요??ㅜㅜ)
몇몇 블로그에 예제들을 보았지만 제가 하려는것과 속성이 틀려서 결국
되지도 않는 영어실력으로 개발자문서를 보며 만들었습니다. ㅜㅜ
저는 웹페이지를 거치지않고 자바단에서만 동작하게 하였습니다(필요시 웹DB 사용)
여기서 사용되는 소스의 주 타겟은 컨텐츠서비스를 하는 어플입니다.
무슨 말이냐하면 유저들 정보를 가지고 있으면 한꺼번에 푸쉬하는거죠(이벤트알림이나 공지사항 등등)
여기선 간단히 설명드리고 자세한건 첨부파일을 받아서 봐주세요.
-------------------- GCMMain.java --------------------
private static final String TAG = "GCM";
 private static final String PASSWORD = "1111";
 //자신의 Project ID 를 넣어주세요
 private static final String SENDER_ID = "자신의 프로젝트 아이디"; 
    private EditText managerPassword;
    private Button managerButton;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        //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);
       }
        setInit();
    }
------------------------------------------------------
GCMMain.java 에서는 위에 SENDER_ID에 자신의 Project ID를 넣어주시면 됩니다.
 
-------------------- GCMIntentService.java --------------------
private static final String TAG = "GCM";
 private static final String INSERT_PAGE = "http://자신의 서버 아이피/insert_registration.php";
 private static final String SENDER_ID = "자신의 프로젝트 아이디";
 private GCMHttpConnect httpConnect = null;
 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);
//   단일전송일때 주석처리
//   insertRegistrationID(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){
  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, 어플이 처음 시작되는 클래스명.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);
 }
 
 public void insertRegistrationID(String id){
  httpConnect = new GCMHttpConnect(INSERT_PAGE + "?regID=" + id, httpRequest);
  httpConnect.start();

 }
-------------------------------------------------------------
GCMIntentService.java 에서는 INSERT_PAGE와 SENDER_ID가 있습니다.
SENDER_ID는 GCMMain.java 와 같이 자신의 Project ID를 넣어주면 됩니다.
INSERT_PAGE에는 메세지를 일괄전송시에 RegID값들을 DB에서 불러오기 위한 서버주소입니다.
서버가 없고 RegID값을 DB가 아닌 어플내에서 관리한다면 필요없는 부분입니다.
 
그 밑에 PendingIntent 에서 주석으로 된 부분에 어플이 시작되는 클래스명을 적어주면
메세지 수신시 인디케이터에 메시지가 뜨면서 클릭시 해당 액티비티를 실행시키는 겁니다.
 
그리고 insertRegistrationID(String id)부분은 마찬가지로 웹서버에서 DB데이터를 뽑아오는
함수입니다. "?regID=" 부분은 파라메터 인자값이고요. 역시 서버가 없다면 주석처리 하시면 됩니다.
 
-------------------- GCMSendMessage.java --------------------
private Sender    gcmSender;    //GCM Sender
 private Message    gcmMessage;   //GCM Message
 private Result     gcmResult;    //GCM Result(단일 전송)
 private MulticastResult  gcmMultiResult;  //GCM Multi Result(일괄 전송)
 
 //일괄전송에 필요한 List 변수
 private List<String> registrationIds = new ArrayList<String>();
 //단일전송에 필요한 변수
 private String     registrationId = "이곳에 RegId를 입력하세요";
 //DB에서 RegID를 가져오기 위해 만들어진 서버 페이지 주소
 private static final String SELECT_PAGE = "http://자신의 서버 아이피/select_registration.php";
 //파싱하기 위해 데이터를 담을 변수
 private static String JSON = null;
 //개발자 콘솔에서 발급받은 API Key
 private static String   API_KEY = "자신이 발급받은 API KEY를 입력하세요";
 //메세지의 고유 ID(?)정도로 생각하면 됩니다. 메세지의 중복수신을 막기 위해 랜덤값을 지정합니다
 private static String   COLLAPSE_KEY = String.valueOf(Math.random() % 100 + 1);
 //기기가 활성화 상태일 때 보여줄 것인지.
 private static boolean  DELAY_WHILE_IDLE = true;
 //기기가 비활성화 상태일 때 GCM Storage에 보관되는 시간
 private static int   TIME_TO_LIVE = 3;
 //메세지 전송 실패시 재시도할 횟수
 private static int    RETRY = 3;
 
 private EditText pushTicker;
 private EditText pushTitle;
 private EditText pushMessage;
 private TextView pushLength;
 
 private Button pushShow;
 private Button pushTrans;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.send_message);
    
     setLayout();
//     단일전송시에는 주석처리
//     getJson(SELECT_PAGE);
//     단일전송시에는 주석처리
//     getToken();     
 }
 
 public void setMessage(){
  gcmSender = new Sender(API_KEY);
  gcmMessage = new Message.Builder()
     .collapseKey(COLLAPSE_KEY)
     .delayWhileIdle(DELAY_WHILE_IDLE)
     .timeToLive(TIME_TO_LIVE)
     .addData("ticker", pushTicker.getText().toString())
     .addData("title", pushTitle.getText().toString())
     .addData("msg", pushMessage.getText().toString())
     .build();
 }
 
 public void sendMessage(){
  //일괄전송시에 사용
//  try {
//   gcmMultiResult = gcmSender.send(gcmMessage, registrationIds, RETRY);
//  } catch (IOException e) {
//   Log.w(TAG, "IOException " + e.getMessage());
//  }
//  Log.w(TAG, "getCanonicalIds : " + gcmMultiResult.getCanonicalIds() + "\n" +
//    "getSuccess : " + gcmMultiResult.getSuccess() + "\n" +
//    "getTotal : " + gcmMultiResult.getTotal() + "\n" +
//    "getMulticastId : " + gcmMultiResult.getMulticastId());
  
  //단일전송시에 사용
  try {
   gcmResult = gcmSender.send(gcmMessage, registrationId, RETRY);
  } catch(IOException e) {
   Log.w(TAG, "IOException " + e.getMessage());
  }
  Log.w(TAG, "getCanonicalIds : " + gcmResult.getCanonicalRegistrationId() + "\n" +
    "getMessageId : " + gcmResult.getMessageId());
 }
-----------------------------------------------------------------
메세지를 보내는 GCMSendMessage.java 부분입니다.
String registrationId 는 단일전송시에 직접 입력하는 부분입니다. 등록시 얻은 RegID를 적어주시면 됩니다.
List<String> registrationIds 는 일괄전송시에 사용되는 변수로 onCreate에서
데이터를 얻어오고 그 수만큼 add하고 있습니다.
SELECT_PAGE는 DB에서 RegID들을 얻어오기 위한 서버페이지입니다.
역시 서버가 없다면 무시해도 됩니다.
API_KEY는 Api Console 센터에서 발급받은 Key입니다. 뭐 Project ID와 API_KEY 는 전부 아시리라 믿습니다.
 
 
---------- 정리 ------------
- 단일전송일 경우(한명에게 보내고자 할 경우 or 테스트용)
위에서 말한 API_KEY, SENDER_ID, RegID 변수에 자신의 값들을 넣어주시고 테스트하시면 됩니다.
 
- 일괄전송일 경우
(개인 서버가 있는경우)
위 소스에 있는 주석들을 풀어준 후 자신의 서버주소를 적어주시면 됩니다.
(개인 서버가 없는경우)
RegID 값들을 알 수 있다면 List에 직접 add하여 주시거나
SharedPreferences를 이용하여 데이터를 불러와 add하셔도 됩니다.
혹시 서버페이지를 만드시려고 하는분이 있으시면 참고되시라고 같이 올렸습니다.
---------------------------
 
--------- 필수로 해야할것들 ---------
이 소스를 이용하여 자신의 프로젝트에 적용시킬 때 주의하실점이 있습니다.
- Manifest GCM관련 퍼미션등록 여부와 리시버 등록 여부 확인 (첨부된 프로젝트와 비교하세요)
- 각종 퍼미션 (WAKE_LOCK, INTERNET, GET_ACCOUNTS, VIBRATE) <- 요거안해주면 고생많이 합니다.
- !!!GCM라이브러리 추가!!!(gcm.jar  gcm-server.jar   json_simple-1.1.jar)
제일 중요합니다. 꼭 libs폴더에 넣어서 빌드패스에 추가하셔야합니다.
특히 json_simple-1.1.jar 요놈 없으면 NodefClassException이라는 상큼한 에러가 나옵니다.
라이브러리는 다음과 같은 경로에 있습니다.(개발환경마다 경로가 다를 수 있습니다)
SDK/android-sdk/extras/google/gcm/gcm-client/dlist/gcm.jar
SDK/android-sdk/extras/google/gcm/gcm-server/dlist/gcm-server.jar
SDK/android-sdk/extras/google/gcm/gcm-server/lib/json_simple1.1.jar
-----------------------------------
 
이상으로 글을 마칩니다. 모르시는 부분이 있으면 코드 조금만 분석해보시면
금방 알 수 있을거에요. ㅎㅎ 워낙 허접한 코드라서..
 
저같은 초보분들에게 바칩니다. 해보시고 잘되시면 칭찬한번씩만 해주세요.
회사에서 하라는 일은 안하고 이런짓하고 있어요.




질문답변 게시판에서 궁금한 사항을 해결하셨다면, 애써 답변해주신 분께 잘 되었다고 따뜻한 댓글 한마디 남겨주세요.
그리고 답변해주신 분의 글을 '추천' 해주세요.
추천받으신 분에게 1포인트가, 추천하신 분에게도 1포인트가 적립됩니다. ^^

피로리 2012-07-18 (수) 17:20 추천추천 1 반대 0
보통 서버에 있는 웹페이지를 통하여 메세지를 날리게 됩니다.(asp, jsp 등등)
그니까 자신의 웹서버를 한번 거쳐가는거죠
A단말기 -> 웹서버 ->GCM 서버 ->B단말기 이런과정을 거치죠
 
근데 이건 웹페이지없이도 어플자체에서 보낼수있게 했어요.
A단말기 -> GCM 서버 -> B단말기 이렇게요.
php페이지는 DB를 따로 사용하는경우 쓰면 되고요
DB가 없고 사용자의 RegID값을 알면 registrationId 에 넣어서
send하면 됩니다.
바람돌2 2012-07-18 (수) 15:18
 감동입니다 ㅠㅠㅠㅠ
 
안드래도 푸쉬가 어려워서 고생하고 있었는데..
 
여기는 '퍼가요~♥' 이런거 없나요? ㅎㅎ
댓글주소 추천 0 반대 0
바람돌2 2012-07-18 (수) 15:21
개념이 좀 안 잡히는 데 서버가 없을 경우는 만일 제가 만든 어플에서 사용들에게 푸쉬를 어떻게 날릴수 있죠?(예: 카톡)
댓글주소 추천 0 반대 0
     
     
피로리 2012-07-18 (수) 17:20
베플로 선택된 게시물입니다.
보통 서버에 있는 웹페이지를 통하여 메세지를 날리게 됩니다.(asp, jsp 등등)
그니까 자신의 웹서버를 한번 거쳐가는거죠
A단말기 -> 웹서버 ->GCM 서버 ->B단말기 이런과정을 거치죠
 
근데 이건 웹페이지없이도 어플자체에서 보낼수있게 했어요.
A단말기 -> GCM 서버 -> B단말기 이렇게요.
php페이지는 DB를 따로 사용하는경우 쓰면 되고요
DB가 없고 사용자의 RegID값을 알면 registrationId 에 넣어서
send하면 됩니다.
댓글주소 추천 1 반대 0
안드플 2012-07-20 (금) 11:22
좋은 자료 감사합니다.
구글이 좀더 좋게 변하는건 좋지만 자주 바뀌니 익히면 또 익혀야 하고
좀 피곤하네요 ㅎㅎㅎ
좋은글 넘 감사감사
댓글주소 추천 0 반대 0
굼바 2012-07-20 (금) 20:04
이게 메시지 전송해주는 서버쪽 소스인가요?
아니면 통합되있는 소스인가요?
초보인지라 이 소스 말고 다른소스로 해봐도
regID까지는 어떻게 따왔는데 그 이후가 안되네요 ㅠ
댓글주소 추천 0 반대 0
포스원 2012-07-23 (월) 09:58
안그래도 관련 정보 찾느라 이곳저곳 뒤지는 중이었는데
jsp 라서 약간 변경을 해야겠지만 많은 도움이 될것 같습니다.
감사합니다.
댓글주소 추천 0 반대 0
토르웰 2012-07-30 (월) 00:24
정말 감사합니다...
댓글주소 추천 0 반대 0
안드로22드 2012-07-30 (월) 09:09
감사합니다
댓글주소 추천 0 반대 0
알레알레 2012-09-03 (월) 15:20
감사합니다.
댓글주소 추천 0 반대 0
프로세스 2012-11-13 (화) 14:56
감사합니다. 선 추천 후 읽어보렵니다~
댓글주소 추천 0 반대 0
관스틴 2012-12-11 (화) 21:26
완전 최고이십니다.
댓글주소 추천 0 반대 0
관스틴 2012-12-11 (화) 21:49
이곳에 RegId를 입력하세요 
이 부분에는 무엇을 적어줘야하는건가요 ?
어플을 빌드 했는데, Ticker 타이틀 메세지...그 부분도 ㅠ 설명 좀 해주세요

댓글주소 추천 0 반대 0
오로도로동 2013-01-14 (월) 18:54
감사합니다~^^
댓글주소 추천 0 반대 0
겨우리1212 2016-01-22 (금) 13:34

네.감사합니다.

댓글주소 추천 0 반대 0
이전글  다음글  목록 글쓰기

 


Copyright ⓒ www.androidside.com. All rights reserved.
채팅 권한: 글쓰기 1개
2레벨 이상만 대화 가능
공개 채팅: 평일 !(9시 ~ 17시),토,일
안사2 변경사항 보러가기 챗방이 잘 안보이면 크롬에서 접속해주세요
챗방 숨기기 |  챗방 보이기