반응형

이번 강의에서는 안드로이드가 DB와 어떻게 연결되는지를 알아보는것과 전 강의에서 얻어온 등록ID를 DB에 삽입하는것, Third party가 구글로 푸쉬메시지 요청을 보내는것 그리고 푸쉬로 날라온 메시지를 핸들링하는법에 대해 알아보겠습니다.


안드로이드를 개발하면서 DB를 사용하지 않고 개발하는 프로젝트가 몇 없었습니다. 그렇다면 안드로이드가 사용하는 DB는 무었이 있는지 궁금하실텐데 일단 안드로이드가 자체적으로 갖고있는 SQLite가 있으며 외부 데이터베이스는 없습니다. 데이터 베이스의 목적은 여러 디바이스가 공유하여 데이터를 보여주는것에 큰 포커스를 갖고있는데 SQLite는 디바이스 내부에서 처리하는 데이터베이스이기때문에 독립적인 프로젝트라면 활용도가 높겠지만 누구나 동일한 데이터를 공유하는 프로젝트라면 SQLite는 별볼일없는 컴포넌트에 불과하지 않습니다.

그렇다면 외부데이터베이스가 없는데 "어떻게 데이터를 공유하는 프로젝트를 개발하느냐?" 라는 의문이 생기는데 한단계 과정만 더 거친다면 외부데이터베이스를 마음껏 사용할 수 있습니다. 하지만 그러기 위해선 웹 어플리케이션을 구동 할 수 있는 서버가 필요하게됩니다.

안드로이드가 외부데이터베이스에 접근하는 방식은 httpRequest를 하는것이 있고, httpRequest 이후 response된 객체를 json 또는 xml 또는 String 으로 파싱하여 사용하는 방법이 가장 대표적인 방법입니다.

말이 좀 거창한데 이후 진행될 강의를 따라 직접 해보시면 그 원리가 파악되실겁니다.


이 과정에서 기본적으로 알아둬야할것들을 나열해드리겠습니다. 선행학습이 필요하니 해당되는 기본기에 하나라도 부합되지 않으신분들은 해당 과정부터 알고오셔야 강의가 이해됩니다. 주로 웹 어플리케이션 부분입니다.

1. sql을 알고있어야한다.(기본적인 insert , select 까지만)

2. jsp를 활용한 데이터베이스 접속을 모델1 또는 모델2로 설계가 가능해야한다.



그럼 이제 본격적으로 안드로이드가 Third party 쪽에 요청하는 부분을 개발해보도록 하겠습니다. 물론 제가 미리 제작해놓은 클래스를 가져다 쓰셔도되고 독자적으로 개발해도되지만 재활용하는샘치고 제것을 가져다 패키지에 삽입해주시는게 여러모로 빠를겁니다.

ServerRequest.java

위 클래스는의 생성자는 요청url , map으로 구성된 파라미터 , responseHandler , handler 로 구성되어있습니다.

responseHandler와 handler를 추가적으로 준 이유는 요청후에 처리를 하는편이 예외처리에 좀더 도움이 되고, 언제 오류가 날지 모르는 안드로이드로부터 방어적인 프로그래밍을 가능케하려는 목적에 있습니다. 클래스를 패키지에 삽입하셨다면 이제 GCMIntentService 클래스에서 onRegistered 함수에 위 클래스를 인스턴스화하고 responseHandler와 handler를 구성해주시면 됩니다.

예제코드를 보도록 하겠습니다.

package com.example.mygcm;


import java.util.HashMap;


import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.ResponseHandler;

import org.apache.http.util.EntityUtils;


import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.widget.Toast;


import com.google.android.gcm.GCMBaseIntentService;


public class GCMIntentService extends GCMBaseIntentService{

public ServerRequest serverRequest_insert = null;

//GCM에 정상적으로 등록되었을경우 발생하는 메소드

@Override

protected void onRegistered(Context arg0, String arg1) {

// TODO Auto-generated method stub

Log.d("test","등록ID:"+arg1);

HashMap<Object , Object> param = new HashMap<Object , Object>();

param.put("regid", arg1);

serverRequest_insert = new ServerRequest("http://localhost:8080/gcmtest/insert.jsp", param, mResHandler, mHandler);

serverRequest_insert.start();

}

/**

* responseHandler가 mHandler에게 상태메시지를 보냄 해당 메시지를 살펴 토스트로 띄움

*/

private Handler mHandler = new Handler(){

public void handleMessage(Message msg) {

serverRequest_insert.interrupt();

String result = msg.getData().getString("result");

if(result.equals("success")){

Toast.makeText(MainActivity.mContext, "데이터베이스에 regid가 등록되었습니다.", 3000).show();

}else{

Toast.makeText(MainActivity.mContext, "데이터베이스에 regid 등록이 실패하였습니다.", 3000).show();

}

}

};

/**

* 요청후 response에 대한 파싱처리

*/

private ResponseHandler<String> mResHandler = new ResponseHandler<String>(){

public String handleResponse(HttpResponse response) throws org.apache.http.client.ClientProtocolException ,java.io.IOException {

HttpEntity entity = response.getEntity();

Message message = mHandler.obtainMessage();

Bundle bundle = new Bundle();

String result = EntityUtils.toString(entity).trim();

if(result.equals("success")){

bundle.putString("result", "success");

}else{

bundle.putString("result", "fail");

}

message.setData(bundle);

mHandler.sendMessage(message);

return null;

}

};

//GCM에 해지하였을경우 발생하는 메소드

@Override

protected void onUnregistered(Context arg0, String arg1) {

Log.d("test","해지ID:"+arg1);

}

//GCM이 메시지를 보내왔을때 발생하는 메소드

@Override

protected void onMessage(Context arg0, Intent arg1) {

// TODO Auto-generated method stub

}

//오류를 핸들링하는 메소드

@Override

protected void onError(Context arg0, String arg1) {

Log.d("test",arg1);

}

//서비스 생성자

public GCMIntentService() {

super(MainActivity.PROJECT_ID);

Log.d("test","GCM서비스 생성자 실행");

}

}

위 코드는 일단 서버로 요청을한뒤 서버에서 response하는 객체를 읽어 토스트로 표시만 할 뿐입니다. 그러나 서버측에서 어떻게 처리하느냐에 따라 표현하는 토스트도 달리지므로 의미없는 코드는 아닙니다. 또한 추가적으로 예외를 처리할 부분이 많으나 그러려면 여러가지 경우를 추가적으로 처리하고 체크박스에 대한 상태까지도 고려해야하므로 일단은 무시하고 이렇게 가도록 하겠습니다.


Third party에 요청하는 코드를 만들었으니 이제 Third party가 이를 어떻게 받아들여 처리하는지 아래 코드로 확인해보시면 되겠습니다. Third party는 jsp 웹어플리케이션 부분이 되겠습니다 .안드로이드가 아닙니다.

insert.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@ page import="java.sql.*" %>

<%

String regid = request.getParameter("regid");

try {

String driverName = "oracle.jdbc.driver.OracleDriver";

String url = "jdbc:oracle:thin:@localhost:1521:XE";

ResultSet rs = null;

Class.forName(driverName);

Connection con = DriverManager.getConnection(url,"gcmtest","gcm123");

Statement stmt = con.createStatement();

String sql = "insert into gcm (regid) values ('" + regid + "')";

rs = stmt.executeQuery(sql);

out.print("success");

con.close();

}catch (Exception e) {

out.print("fail");

}

%>

매우 간결한 코드입니다. 단순히 등록ID를 데이터베이스에 저장만 하는 기능입니다. 이런식으로 디바이스별 등록ID를 데이터베이스에 누적 할 수 있습니다.

위 코드들의 흐름을 보면 아래 그림과 같다고 볼 수있습니다.



insert.jsp 파일은 디비접속및 질의 실행후 그 결과를 페이지로 반환하는데 저는 간단하게 success 또는 fail을 적어 반환시켜보았습니다. 이렇게 할경우 안드로이드쪽에서는 요청한 결과 페이지를 response객체로 반환하는데 이때 이 객체를 간단히 파싱해서 조건 처리를 해보았습니다. 물론 json이나 xml등으로 페이지를 구성해서 반환한다면 저렇게 간단한 파싱은 되지 않지만 어디까지나 기본적인 사항들만을 표현하기 위해 이렇게 만들었습니다.


이제 데이터베이스에 등록ID를 누적하는것을 완성했으니 해당 등록ID와 일치하는 디바이스에 메시지를 날려보는 처리를 구현해보겠습니다. 이번엔 안드로이드가 아니라 서버측에서 구현을 하고 안드로이드측에서 메시지를 받아 핸들하는 처리순서대로 코드를 구성해보겠습니다.

시작하기전에, 라이브러리라는것이 정말 좋은게 막 가져다 조립을 하면 돌아간다는점에서, 안드로이드건 jsp건 둘다 java를 베이스로 둔 점이 정말 마음에 듭니다. 이런 얘기를 하는 이유는 바로 가이드1에서 내려받은 GCM 라이브러리가 jsp에서도 사용된다는 점입니다. 정말 세심하게 코딩하려면 구지 GCM라이브러리를 사용하지 않아도 되지만 저는 라이브러리를 사용한 전송을 구현하겠습니다.

일단 라이브러리의 위치를 찾기 귀찮으시다면 아래 파일을 받아서 라이브러리를 등록해주세요.

json-simple-1.1.1.jar

gcm-server.jar


라이브러리를 등록하셨다면 이제 푸쉬를 보내는 jsp페이지 코딩의 예제를 보여드리겠습니다.

push.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@ page import="java.sql.*" %>

<%@ page import="java.util.ArrayList" %>

<%@ page import="com.google.android.gcm.server.*" %>

<%

ArrayList<String> regid = new ArrayList<String>(); //메시지를 보낼 대상들

String MESSAGE_ID = String.valueOf(Math.random() % 100 + 1); //메시지 고유 ID

boolean SHOW_ON_IDLE = true; //기기가 활성화 상태일때 보여줄것인지

int LIVE_TIME = 1; //기기가 비활성화 상태일때 GCM가 메시지를 유효화하는 시간

int RETRY = 2; //메시지 전송실패시 재시도 횟수

String simpleApiKey = "AIzaSyCvu6Ka-rb5zm8EvZkwt6mkXhlerxxe2Qk2s"; //가이드 1때 받은 키

String gcmURL = "https://android.googleapis.com/gcm/send"; //푸쉬를 요청할 구글 주소

try {

String driverName = "oracle.jdbc.driver.OracleDriver";

String url = "jdbc:oracle:thin:@localhost:1521:XE";

ResultSet rs = null;

Class.forName(driverName);

Connection con = DriverManager.getConnection(url,"gcmtest","gcm123");

Statement stmt = con.createStatement();

String sql = "select * from gcm";

rs = stmt.executeQuery(sql);

//모든 등록ID를 리스트로 묶음

while(rs.next()){

regid.add(rs.getString("regid"));

}

con.close();

Sender sender = new Sender(simpleApiKey);

Message message = new Message.Builder()

.collapseKey(MESSAGE_ID)

.delayWhileIdle(SHOW_ON_IDLE)

.timeToLive(LIVE_TIME)

.addData("test","PUSH!!!!")

.build();

MulticastResult result = sender.send(message,regid,RETRY);

}catch (Exception e) {

}

%>

위 코드를 보면서 몇가지 상수와 이전에 얻어둔 simpleApiKey가 보일것입니다. 적당히 코드를 살펴본후 자기것에 맞춰 수정하면 되겠습니다. 중요한건 제가 여려명에게 푸쉬를 보내기위해 Multicast방식을 이용했습니다만, 단 한명이게 보내고자할때는 그냥 sender 방식을 사용해도되겠습니다.

중요시 봐야할점은 데이터를 어떻게 삽입하느냐가 관건인데 message 객체의 함수들은 모두 체이닝형식으로 this를 반환하도록 구현되어있나봅니다. 그래서 저렇게 체이닝의 메소드를 연결하고 build() 메소드가 들어기가 이전에 addData(String , String)의 메소드로 데이터를 삽입해주시면 되겠습니다. key / value의 쌍으로 파라미터를 추가하게 되어있으며 이 데이터는 후에 안드로이드 intent 로 넘어오게됩니다. 안드로이드는 intent에서 key를 갖고 value를 추적할 수 있는데 그래서 key이름을 잊지않도록 합니다.


혹시나 궁금해하시는 분들을 위해 Third party 쪽의 스크린샷을 담아봤습니다.

모델1로 개발한것이며 라이브러리3개와 페이지 2개가 전부입니다. 아 물론 데이터베이스가 같은 서버내에서 구동되는점도 있습니다.


이제 심심하니 푸쉬를 잠깐 날려보도록 하겠습니다. 아직 안드로이드쪽에서 푸쉬를 받는 처리를 하지않았지만 페이지의 요청만으로도 푸쉬가 날라갈 수 있다는점이 있습니다. 후에 푸쉬를 요청하는 방법은 개발자들이 알아서 표현해주시고 저는 일단 아무런 보안없이 푸쉬를 날려보도록 하겠습니다. 저같은경우는 이 주소를 입력하면 푸쉬가 날라갑니다.

http://localhost:8080/gcmtest/push.jsp

라고 주소창에 날리면 푸쉬가 날아갑니다. 물론 날아갔다고 표현하지 않았으니 페이지는 아무것도 뜨지않습니다. 그럼 이제 안드로이드쪽에서 푸쉬로 날라온 메시지를 어떻게 처리하는지 보겠습니다.

이전에 푸쉬로 날라온 메시지를 처리하는 부분은 GCMIntentService 클래스에서 onMessage 함수라고 말씀드렸습니다. 그러니 그쪽부분을 잠시 손봐주면 되겟지만 아쉽게도 이벤터처리메스도들에게는 뷰를 핸들할 권한이 없기때문에 따로 스레드를 포함한 핸들러를 돌려주셔야만 화면에서 받은 메시지를 표현할 수 있습니다.

아래 코드를 보면서 수정해주시면 되겠습니다.

package com.example.mygcm;


import java.util.HashMap;


import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.ResponseHandler;

import org.apache.http.util.EntityUtils;


import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.widget.Toast;


import com.google.android.gcm.GCMBaseIntentService;


public class GCMIntentService extends GCMBaseIntentService {

String gcm_msg = null;

public ServerRequest serverRequest_insert = null;


// GCM에 정상적으로 등록되었을경우 발생하는 메소드

@Override

protected void onRegistered(Context arg0, String arg1) {

// TODO Auto-generated method stub

Log.d("test", "등록ID:" + arg1);

HashMap<Object, Object> param = new HashMap<Object, Object>();

param.put("regid", arg1);

serverRequest_insert = new ServerRequest(

"http://localhost:8080/gcmtest/insert.jsp", param,

mResHandler, mHandler);

serverRequest_insert.start();

}


/**

* 요청후 핸들러에의해 리스트뷰 구성

*/

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

serverRequest_insert.interrupt();

String result = msg.getData().getString("result");

if (result.equals("success")) {

Toast.makeText(MainActivity.mContext,

"데이터베이스에 regid가 등록되었습니다.", 3000).show();

} else {

Toast.makeText(MainActivity.mContext,

"데이터베이스에 regid 등록이 실패하였습니다.", 3000).show();

}

}

};


/**

* 요청후 response에 대한 파싱처리

*/

private ResponseHandler<String> mResHandler = new ResponseHandler<String>() {

public String handleResponse(HttpResponse response)

throws org.apache.http.client.ClientProtocolException,

java.io.IOException {

HttpEntity entity = response.getEntity();

Message message = mHandler.obtainMessage();

Bundle bundle = new Bundle();

String result = EntityUtils.toString(entity).trim();

if (result.equals("success")) {

bundle.putString("result", "success");

} else {

bundle.putString("result", "fail");

}

message.setData(bundle);

mHandler.sendMessage(message);

return null;

}

};


// GCM에 해지하였을경우 발생하는 메소드

@Override

protected void onUnregistered(Context arg0, String arg1) {

Log.d("test", "해지ID:" + arg1);

}


// GCM이 메시지를 보내왔을때 발생하는 메소드

@Override

protected void onMessage(Context arg0, Intent arg1) {

// TODO Auto-generated method stub

Log.d("test", "메시지가 왔습니다 : " + arg1.getExtras().getString("test"));

gcm_msg = arg1.getExtras().getString("test");

showMessage();

}


// 오류를 핸들링하는 메소드

@Override

protected void onError(Context arg0, String arg1) {

Log.d("test", arg1);

}


// 서비스 생성자

public GCMIntentService() {

super(MainActivity.PROJECT_ID);

Log.d("test", "GCM서비스 생성자 실행");

}


public void showMessage() {

Thread thread = new Thread(new Runnable() {

public void run() {

handler.sendEmptyMessage(0);

}

});

thread.start();

}


private Handler handler = new Handler() {

public void handleMessage(Message msg) {

Toast.makeText(MainActivity.mContext, "수신 메시지 : "+gcm_msg, 3000).show();

}

};

}


이것으로 안드로이드 GCM 가이드를 마치겠습니다. 결국 레이아웃에 textView 하나는 안쓴채로 진행됬는데요; 사실 토스트말고 textView에 표현해도 상관없는거였지만 잊고있어서^^;

푸쉬를 보내는 방법은 위에서 설명했듯이 페이지 요청으로 보내보았습니다. 하지만 푸쉬가 날라와야할 시점은 개발하는 목적에 따라 다르기때문에 "어느 한 시점에 꼭 푸쉬가 날라와야 정상이다" 라고 단정짓기 어렵습니다.

 

 

반응형



Posted by 궁극의 java개발자
,





반응형

2부 가이드를 시작하겠습니다. 2부에서는 안드로이드(이하 클라이언트) 코딩에 대하여 설명드리겠습니다. 일단 코딩에 앞서GCM이 구성되는 원리부터 설명드리겠습니다. 그래야만 개발하면서 왜 이렇게 구성해야하는지 이해가 가실겁니다.


GCM의 구성 원리

GCM을 구성하는것은 크게 클라이언트와 GCM 두가지가 있습니다. 하지만 여기에 Third party가 꼽사리를 껴서 구성해도 상관은 없습니다. 클라이언트는 안드로이드 디바이스가 되겠고 GCM은 구글이 지원하는 클라우드 메시징을 전담하는 어떤 실체가 되겠습니다. 그러면 이 두가지가 어떤식으로 동작하는지 설명드리겠습니다.

 


먼저 안드로이드 디바이스는 각각의 고유 id를 갖고있습니다. 디바이스가 GCM에 등록을 한다고 구글에 요청을 보내면 구글에서는 해당 id를 갖고 어떤 고유 등록id를 생성하여 등록을 요청한 안드로이드 디바이스에 보내고 ,또 구글에서는 등록id를 저장해둡니다.


왜 구글에서 이 id를 저장하고 또 디바이스에 id를 보내는지는 편지를 보내는 시스템과 비교해보시면 아주 간단하게 이해하실겁니다. 실제로 우리는 우편을 보낼때도 상대방의 주소를 모르면 보내지 못하는게 정상입니다. 이렇듯 구글에서도 푸쉬를 넣을 주소(등록id)를 알지못하면 해당 디바이스에 어떤 메시지도 보낼수가 없습니다.












또 디바비스에 등록id를 보내주는 이유는 이후 주기적인 등록id 재요청없이 자신의 등록id를 Third party에 보내 데이터베이스에 저장후 앞으로 이 데이터베이스에서 푸쉬메세지를 보내고자하는 디바이스 등록id를 찾아 메시지를 보내기 위함입니다.



등록 ID를 발급받은것만으로 푸쉬메시지를 보내고 받는것의 반은 한겁니다. 이제 푸쉬를 하는방법과 구글이 푸쉬한 메시지를 받는법에 대하여 설명드리겠습니다.

푸쉬를 하기위해서는 이전 강의에서 받은 PROJECT ID와 simple api key와 등록 ID(위에서 설명한) 가 필요합니다. 이렇게해서 푸쉬메시지를 보내는 개발자를 알아내고 푸쉬메시지를 받는 디바이스를 알아내어 메시지가 전송되는겁니다. 푸쉬메시지를 수신하기위해서는 디바이스 내부에 몇가지 퍼미션과 서비스를 등록하여 구글에서 날라오는 메시지를 핸들만 해주면 손쉽게 메시지를 가져올 수 있습니다.



GCM의 구성원리는 이정도로 하고 이제 안드로이드 프로젝트 생성하고 서비스를 등록하여 GCM을 위한 등록ID 요청및 푸쉬메시지 핸들링에 대하여 보도록 하겠습니다.

GCM은 안드로이드 2.2버젼부터 사용가능한 것이므로 최소 api는 8로 설정하여 프로젝트를 생성해주세요. 그리고 1부 강좌에서 내려받은 GCM 라이브러리를 안드로이드 프로젝트에 libs 폴더내부에 복사해주세요. libs 폴더가 없는경우 생성해주시면 되겠습니다.

저의 경우는 gcm 라이브러리가 D:\dev\android_sdk\extras\google\gcm\gcm-client\dist 이 위치에 들어있습니다.

<위 사진은 2.3 api를 이용한것으로 2.2로 해도 상관없습니다.>

gcm.jar

<요청에 의해 라이브러리파일을 올려드립니다 ㅋ>

libs 폴더내부에 gcm.jar 라이브러리를 복사한후 라이브러리를 사용하겠다고 빌드패스에 등록합니다.



안드로이드 프로젝트에서 저는 시작부터 뷰를 구성하는 버릇이 있기때문에 일단 레이아웃부터 구성해봅시다. 레이아웃은 등록ID와 푸쉬된 메시지를 간단하게 표현하고 푸쉬 받기/받지않기 를 설정하는 체크박스 정도로 구성해보도록 하겠습니다.

레이아웃은 어떤 모양이든 상관없습니다. 다만 서드파티를 사용하는 강의이므로 푸쉬받기/푸쉬받지않기 루틴에 대해 DB를 한번 조사하는 요청이 필요하지만 지금 강의에서는 그냥 체크에 따른 푸쉬 설정/해지만을 다루도록 하겠습니다. DB조사요청을 알고싶으시면 댓글을 달아주시면 루틴을 설명드리겠습니다.

 

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:id="@+id/LinearLayout1"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >



<CheckBox

android:id="@+id/checkBox1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="푸쉬 받기 설정" />


<TextView

android:id="@+id/textView1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="TextView" />

</LinearLayout>

레이아웃은 이정도가 되겠습니다.


이제 퍼미션과 리시버를 받기위해 AndroidManifest.xml 파일 설정을 해보도록 하겠습니다.

추가해야할 퍼미션은

<uses-permission android:name="com.example.mygcm.permission.C2D_MESSAGE"/>

<permission android:name="com.example.mygcm.permission.C2D_MESSAGE" android:protectionLevel="signature" />

<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

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

위 두 퍼미션은 안드로이드 4.1부터는 필요없다고 하네요. 그리고 퍼미션을 추가할때 패키지이름을 정확히 적어주셔야만 메시지를 핸들할수 있으니 실수없이 적으셔야합니다. 그다음 receiver와 service를 등록해야합니다.

추가할 xml 구문은

<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="com.example.mygcm" />

</intent-filter>

</receiver>

<service android:name=".GCMIntentService"></service>

intent-filter 내부에 category란에 패키지명을 정확히 적어주셔야 리시버가 제대로 동작됩니다.

최종적인 AndroidManifest.xml


AndroidManifest.xml 설정이 완료되었으면 이제 MainActivity 를 손봐줄차례입니다.

MainActivity 에서는 체크박스를 통해 푸쉬메시지를 받는지 받지않는지를 설정하는데 이것은 gcm.jar 라이브러리를 통해 구성합니다.

GCMRegister 라는 클래스 내부 스태틱 메소드들을 활용하여 GCM을 등록/해지하는데 다음 코드를 보면 금방 이해하실겁니다.

 

package com.example.mygcm;


import android.app.Activity;

import android.content.Context;

import android.os.Bundle;

import android.util.Log;

import android.view.Menu;

import android.widget.CheckBox;

import android.widget.CompoundButton;

import android.widget.CompoundButton.OnCheckedChangeListener;

import android.widget.TextView;


import com.google.android.gcm.GCMRegistrar;


public class MainActivity extends Activity {

public static Context mContext = null;

//푸쉬를 받기/받지 않기를 설정하기 위한 체크박스

public CheckBox cb_setting = null;

//푸쉬로 받은 메시지를 표현하기 위한 텍스트뷰

public static TextView tv_msg = null;


public static String PROJECT_ID = "2891710653";

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mContext = this;

setContentView(R.layout.activity_main);

tv_msg = (TextView)findViewById(R.id.textView1);

cb_setting = (CheckBox)findViewById(R.id.checkBox1);

cb_setting.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override

public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

// TODO Auto-generated method stub

//푸쉬 받기

if(isChecked){

Log.d("test","푸쉬 메시지를 받습니다.");

GCMRegistrar.checkDevice(mContext);

GCMRegistrar.checkManifest(mContext);

if(GCMRegistrar.getRegistrationId(mContext).equals("")){

GCMRegistrar.register(mContext, PROJECT_ID);

}else{

//이미 GCM 을 상요하기위해 등록ID를 구해왔음

GCMRegistrar.unregister(mContext);

GCMRegistrar.register(mContext, PROJECT_ID);

}

}

//푸쉬 받지않기

else{

Log.d("test","푸쉬 메시지를 받지 않습니다.");

GCMRegistrar.unregister(mContext);

}

}

});

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.activity_main, menu);

return true;

}

}

 


MainActivity 코딩이 완료되면 이제 직접적인 등록/해지/오류/메시지 핸들을 담당하는 서비스 클래스를 작성해야합니다.

아까 AndroidManifest.xml 에서 <service android:name=".GCMIntentService"></service> 부분에 GCMIntentService 라고 이름을 적었는데 이 이름과 동일한 클래스를 패키지 내부에 만들어주세요.


위 사진과 같이 4개의 메소드를 오버라이딩 해주시고 추가적으로 서비스가 잘 동작하는지에 대한 생성자를 구성해주세요. 메소드들은 모두 오버라이딩되어 사용되는데 이때 메소드 이름앞에 모두 on이 붙는 이유는 바로 이벤트가 발생할때 처리하려는 목적으로 만들어진 함수들이기 떄문입니다. 그래서 등록을 하거나 해지 또는 메시지를 수신받을때 모두 그에 해당되는 함수가 호출되어 저기서 처리가 가능하게끔하는것입니다.

<브로드캐스터내부에서 뷰를 제어 할 수 없으므로 일단은 로그만 찍어보았습니다.>

아래 코드는 GCMIntentService 클래스의 코드입니다.

package com.example.mygcm;


import android.content.Context;

import android.content.Intent;

import android.os.Handler;

import android.util.Log;

import android.widget.Toast;


import com.google.android.gcm.GCMBaseIntentService;


public class GCMIntentService extends GCMBaseIntentService{

//GCM에 정상적으로 등록되었을경우 발생하는 메소드

@Override

protected void onRegistered(Context arg0, String arg1) {

// TODO Auto-generated method stub

Log.d("test","등록ID:"+arg1);

}

//GCM에 해지하였을경우 발생하는 메소드

@Override

protected void onUnregistered(Context arg0, String arg1) {

Log.d("test","해지ID:"+arg1);

}

//GCM이 메시지를 보내왔을때 발생하는 메소드

@Override

protected void onMessage(Context arg0, Intent arg1) {

// TODO Auto-generated method stub

}

//오류를 핸들링하는 메소드

@Override

protected void onError(Context arg0, String arg1) {

Log.d("test",arg1);

}

//서비스 생성자

public GCMIntentService() {

super(MainActivity.PROJECT_ID);

Log.d("test","GCM서비스 생성자 실행");

}

}


이것으로 2부 가이드를 마치겠습니다. 이번 강의에서는 GCM의 구성원리를 파악하는것에 중점을 두고 써내려갔는데 얼마나 이해될런지 모르겠습니다. 아직 안드로이드쪽의 개발이 완료된것은 아닙니다. 메시지 핸들링처리나 등록ID를 DB에 저장하는 요청도 하지 않았기때문인데, 다음 강의에서 등록ID를 DB에 누적하는 요청과 안드로이드가 어떻게 데이터베이스에 접근하는지에 대하여 강의하도록 하겠습니다.

 

반응형



Posted by 궁극의 java개발자
,





반응형

구글에서는 이제 더이상 C2DM의 서비스를 제공하지 않습니다. 다만 GCM(Google Cloud Messaging)이라는 새로운 명칭의 서비스를 제공하는데 최근 작업해본 결과 안드로이드쪽에서나 서드파티쪽에서나 C2DM보다 훨신 간결한 코드로 모든 익셉션처리가 매우 편하도록 구현된점이 놀라웠습니다.

GCM을 이용하기위해서는 C2DM을 알고 있건 GCM의 푸쉬기능을 활용하기위해 이 글을 처음보건 상관없이 매우 간편하게 코드를 구성하고 디버깅 할 수 있으니 어렵게 생각하지 않으셔도 됩니다. 그럼 1부 가이드를 시작하겠습니다.

GCM을 구성하기위해서는 단순히 안드로이드 단말기 하나만으로 자기 자신에게 푸쉬를 주는 방법과 서드파티(서버)를 통해 다른 디바이스들에게 푸쉬를 주는방법이 있으며 또 다르게 사용하는 방법등 여러가지가 있습니다. 근데 흔히 자기 자신에게 푸쉬를 주는건 내부적으로 서비스를 돌리는것이 더 효율적이며 보통은 후좌쪽의 목적으로인해 GCM을 많이 사용하곤합니다. 그래서 저도 후좌쪽(내가 타인에게 GCM 서비스를 이용한 메시지를 날린다)으로 코드를 구현하려합니다.

기본적으로 GCM을 하기위해서는 PROJECT ID와 API Key가 필요합니다. 일단 이 두가지를 구글에서 얻어야합니다.

https://code.google.com/apis/console/b/0

위 주소로가서

Services -> Google Cloud Messaging for Android의 서비스를 ON 시켜줍니다.


Overview를 클릭하시면 DashBoard에 Service란에 GCM이 등록된 상태가 보입니다. 저렇게 등록디 되어야만 GCM서비스를 이용 할 수 있습니다. 이제 PROJECT ID와 API Key를 얻어야하는데 일단 PROJECT ID는 url 주소에 나와있습니다.


파랑색으로 블록친곳의 숫자가 자기 자신의 고유 PROJECT ID가 되겠습니다. 이것을 따로 복사해주세요.


API Key 는 아래 화면과 같이 하면 얻을 수 있습니다.


API Access -> Create new Browser key를 누르고 Create를 해주시면 생성이 됩니다. 이때 생성된 API Key를 따로 복사해주세요.


이제 필요한 스트링키들은 모두 구했고 GCM을 활용하기위한 API를 받아야할 차례입니다. 이클립스를 켜서 Android SDK Manager를 활성화해봅니다. Extras에 Google Cloud Messaging for Android Library를 체크하고 다운로드해주세요.

만일 Extra에 위 라이브러리가 없을경우 ADT와 SDK Tool버젼을 업데이트 해주셔야합니다.




이상으로 1부 가이드를 마치겠습니다. 1부때는 코딩하기 이전의 리소스를 확보하는것으로하고 2부때는 안드로이드쪽 코딩에 들어가겠습니다. 기본적인 안드로이드 지식이 필요하며 아마 중급자에 해당되는 내용(전공자는 초급이라고 생갈할지도...) 으로 안드로이드의 서비스 파트에대한 지식을 요망하는 부분입니다.

 

반응형



Posted by 궁극의 java개발자
,





반응형

아이폰 APNS와 같이 Android 도 Push 사용을 위해서는 방화벽을 열어야 한다.~

 

 

GCM 방화벽 포트는

 

- DNS

android.googleapis.com 443, 5228,5229,5230

 

 

깔끔하지 근데 도메인 오픈이 안된다고 한다면?

X되는거지~ 그럼 IP목록 줄테니 열어줘~ 하고 다음 목록을 던저 주면 된다.

 

 

- IP

대상 IP

Description

1.0.0.0/24

Research prefix for APNIC Labs Australia

1.1.1.0/24

Research prefix for APNIC Labs Australia

1.2.3.0/24

APNIC Debogon Project Australia

8.8.4.0/24

Google Inc. United States

8.8.8.0/24

Google Inc. United States

8.34.208.0/21

Google Inc. United States

8.34.216.0/21

Google Inc. United States

8.35.192.0/21

Google Inc. United States

8.35.200.0/21

Google Inc. United States

23.236.48.0/20

Google Inc. United States

23.251.128.0/19

Google Inc. United States

64.233.160.0/19

Google Inc. United States

64.233.160.0/24

Google Inc. United States

64.233.161.0/24

Google Inc. United States

64.233.162.0/24

Google Inc. United States

64.233.163.0/24

Google Inc. United States

64.233.164.0/24

Google Inc. United States

64.233.165.0/24

Google Inc. United States

64.233.166.0/24

Google Inc. United States

64.233.167.0/24

Google Inc. United States

64.233.168.0/24

Google Inc. United States

64.233.169.0/24

Google Inc. United States

64.233.171.0/24

Google Inc. United States

64.233.176.0/24

Google Inc. United States

64.233.177.0/24

Google Inc. United States

64.233.178.0/24

Google Inc. United States

64.233.179.0/24

Google Inc. United States

64.233.180.0/24

Google Inc. United States

64.233.181.0/24

Google Inc. United States

64.233.182.0/24

Google Inc. United States

64.233.183.0/24

Google Inc. United States

64.233.184.0/24

Google Inc. United States

64.233.185.0/24

Google Inc. United States

64.233.186.0/24

Google Inc. United States

64.233.187.0/24

Google Inc. United States

64.233.188.0/24

Google Inc. United States

64.233.189.0/24

Google Inc. United States

64.233.190.0/24

Google Inc. United States

64.233.191.0/24

Google Inc. United States

66.102.0.0/20

Google Inc. United States

66.102.1.0/24

Google Inc. United States

66.102.2.0/24

Google Inc. United States

66.102.3.0/24

Google Inc. United States

66.102.4.0/24

Google Inc. United States

66.102.12.0/24

Google Inc. United States

66.249.64.0/19

Google Inc. United States

66.249.68.0/24

Google Inc. United States

66.249.69.0/24

Google Inc. United States

66.249.70.0/24

Google Inc. United States

66.249.72.0/24

Google Inc. United States

66.249.78.0/24

Google Inc. United States

70.32.128.0/19

Google Inc. United States

70.32.132.0/23

Google Inc. United States

70.32.144.0/24

Google Inc. United States

70.32.148.0/23

Google Inc. United States

72.14.192.0/18

Google Inc. United States

72.14.244.0/23

Google Inc. United States

74.125.0.0/16

Google Inc. United States

74.125.0.0/18

Google Inc. United States

74.125.6.0/24

Google Inc. United States

74.125.18.0/24

Google Inc. United States

74.125.20.0/24

Google Inc. United States

74.125.21.0/24

Google Inc. United States

74.125.22.0/24

Google Inc. United States

74.125.23.0/24

Google Inc. United States

74.125.24.0/24

Google Inc. United States

74.125.25.0/24

Google Inc. United States

74.125.26.0/24

Google Inc. United States

74.125.27.0/24

Google Inc. United States

74.125.28.0/24

Google Inc. United States

74.125.29.0/24

Google Inc. United States

74.125.30.0/24

Google Inc. United States

74.125.36.0/24

Google Inc. United States

74.125.41.0/24

Google Inc. United States

74.125.42.0/24

Google Inc. United States

74.125.44.0/24

Google Inc. United States

74.125.45.0/24

Google Inc. United States

74.125.46.0/24

Google Inc. United States

74.125.47.0/24

Google Inc. United States

74.125.53.0/24

Google Inc. United States

74.125.54.0/23

Google Inc. United States

74.125.58.0/24

Google Incorporated United States

74.125.68.0/24

Google Inc. United States

74.125.69.0/24

Google Inc. United States

74.125.70.0/24

Google Inc. United States

74.125.71.0/24

Google Inc. United States

74.125.72.0/24

Google Inc. United States

74.125.73.0/24

Google Inc. United States

74.125.74.0/24

Google Inc. United States

74.125.75.0/24

Google Inc. United States

74.125.80.0/24

Google Inc. United States

74.125.88.0/23

Google Inc. United States

74.125.90.0/23

Google Inc. United States

74.125.117.0/24

Google Incorporated United States

74.125.118.0/24

Google Incorporated United States

74.125.119.0/24

Google Incorporated United States

74.125.127.0/24

Google Inc. United States

74.125.128.0/24

Google Inc. United States

74.125.129.0/24

Google Inc. United States

74.125.130.0/24

Google Inc. United States

74.125.133.0/24

Google Inc. United States

74.125.134.0/24

Google Inc. United States

74.125.135.0/24

Google Inc. United States

74.125.136.0/24

Google Inc. United States

74.125.139.0/24

Google Inc. United States

74.125.140.0/24

Google Inc. United States

74.125.141.0/24

Google Inc. United States

74.125.142.0/24

Google Inc. United States

74.125.143.0/24

Google Inc. United States

74.125.144.0/24

Google Inc. United States

74.125.176.0/24

Google Inc. United States

74.125.177.0/24

Google Inc. United States

74.125.181.0/24

Google Inc. United States

74.125.183.0/24

Google Inc. United States

74.125.186.0/24

Google Inc. United States

74.125.187.0/24

Google Inc. United States

74.125.190.0/24

Google Inc. United States

74.125.193.0/24

Google Inc. United States

74.125.194.0/24

Google Inc. United States

74.125.195.0/24

Google Inc. United States

74.125.196.0/24

Google Inc. United States

74.125.198.0/24

Google Inc. United States

74.125.200.0/24

Google Inc. United States

74.125.201.0/24

Google Inc. United States

74.125.202.0/24

Google Inc. United States

74.125.203.0/24

Google Inc. United States

74.125.204.0/24

Google Inc. United States

74.125.205.0/24

Google Inc. United States

74.125.206.0/24

Google Inc. United States

74.125.207.0/24

Google Inc. United States

74.125.224.0/24

Google Inc. United States

74.125.225.0/24

Google Inc. United States

74.125.226.0/24

Google Inc. United States

74.125.227.0/24

Google Inc. United States

74.125.228.0/24

Google Inc. United States

74.125.229.0/24

Google Inc. United States

74.125.230.0/24

Google Inc. United States

74.125.231.0/24

Google Inc. United States

74.125.232.0/24

Google Inc. United States

74.125.233.0/24

Google Inc. United States

74.125.234.0/24

Google Inc. United States

74.125.235.0/24

Google Inc. United States

74.125.236.0/24

Google Inc. United States

74.125.237.0/24

Google Inc. United States

74.125.238.0/24

Google Inc. United States

74.125.239.0/24

Google Inc. United States

104.135.128.0/18

Google Incorporated United States

104.154.0.0/15

Google Inc. United States

104.196.0.0/14

Google Inc. United States

107.167.160.0/19

Google Inc. United States

107.178.192.0/18

Google Inc. United States

108.59.80.0/20

Google Inc. United States

108.170.192.0/18

Google Inc. United States

108.177.0.0/17

Google Inc. United States

108.177.2.0/24

Google Inc. United States

108.177.4.0/23

Google Inc. United States

108.177.11.0/24

Google Inc. United States

108.177.12.0/24

Google Inc. United States

108.177.13.0/24

Google Inc. United States

130.211.0.0/16

Google Inc. United States

142.250.0.0/15

Google Inc. United States

146.148.0.0/17

Google Inc. United States

162.216.148.0/22

Google Inc. United States

162.222.176.0/21

Google Inc. United States

172.102.8.0/21

Google Inc. United States

172.102.8.0/24

Google Inc. United States

172.102.9.0/24

Google Inc. United States

172.102.10.0/24

Google Inc. United States

172.102.12.0/24

Google Inc. United States

172.102.13.0/24

Google Inc. United States

172.102.14.0/24

Google Inc. United States

172.102.15.0/24

Google Inc. United States

172.110.32.0/21

YouTube, LLC United States

172.217.0.0/16

Google Inc. United States

172.253.0.0/16

Google Inc. United States

173.194.0.0/16

Google Inc. United States

173.194.7.0/24

Google Inc. United States

173.194.32.0/24

Google Inc. United States

173.194.33.0/24

Google Inc. United States

173.194.34.0/24

Google Inc. United States

173.194.35.0/24

Google Inc. United States

173.194.36.0/24

Google Inc. United States

173.194.37.0/24

Google Inc. United States

173.194.38.0/24

Google Inc. United States

173.194.39.0/24

Google Inc. United States

173.194.40.0/24

Google Inc. United States

173.194.41.0/24

Google Inc. United States

173.194.42.0/24

Google Inc. United States

173.194.43.0/24

Google Inc. United States

173.194.44.0/24

Google Inc. United States

173.194.45.0/24

Google Inc. United States

173.194.46.0/24

Google Inc. United States

173.194.47.0/24

Google Inc. United States

173.194.53.0/24

Google Inc. United States

173.194.63.0/24

Google Inc. United States

173.194.64.0/24

Google Inc. United States

173.194.65.0/24

Google Inc. United States

173.194.67.0/24

Google Inc. United States

173.194.70.0/24

Google Inc. United States

173.194.71.0/24

Google Inc. United States

173.194.72.0/24

Google Inc. United States

173.194.74.0/24

Google Inc. United States

173.194.75.0/24

Google Inc. United States

173.194.77.0/24

Google Inc. United States

173.194.79.0/24

Google Inc. United States

173.194.90.0/24

Google Inc. United States

173.194.93.0/24

Google Inc. United States

173.194.99.0/24

Google Inc. United States

173.194.112.0/24

Google Inc. United States

173.194.113.0/24

Google Inc. United States

173.194.117.0/24

Google Inc. United States

173.194.118.0/24

Google Inc. United States

173.194.119.0/24

Google Inc. United States

173.194.120.0/24

Google Inc. United States

173.194.121.0/24

Google Inc. United States

173.194.124.0/24

Google Inc. United States

173.194.125.0/24

Google Inc. United States

173.194.126.0/24

Google Inc. United States

173.194.127.0/24

Google Inc. United States

173.194.132.0/24

Google Inc. United States

173.194.136.0/24

Google Inc. United States

173.194.140.0/24

Google Inc. United States

173.194.141.0/24

Google Inc. United States

173.194.142.0/24

Google Inc. United States

173.194.192.0/24

Google Inc. United States

173.194.193.0/24

Google Inc. United States

173.194.194.0/24

Google Inc. United States

173.194.195.0/24

Google Inc. United States

173.194.196.0/24

Google Inc. United States

173.194.197.0/24

Google Inc. United States

173.194.199.0/24

Google Inc. United States

173.194.200.0/24

Google Inc. United States

173.194.201.0/24

Google Inc. United States

173.194.202.0/24

Google Inc. United States

173.194.203.0/24

Google Inc. United States

173.194.204.0/24

Google Inc. United States

173.194.205.0/24

Google Inc. United States

173.194.206.0/24

Google Inc. United States

173.194.207.0/24

Google Inc. United States

173.194.208.0/24

Google Inc. United States

173.194.209.0/24

Google Inc. United States

173.194.210.0/24

Google Inc. United States

173.194.211.0/24

Google Inc. United States

173.194.212.0/24

Google Inc. United States

173.194.213.0/24

Google Inc. United States

173.194.214.0/24

Google Inc. United States

173.194.215.0/24

Google Inc. United States

173.194.216.0/24

Google Inc. United States

173.194.217.0/24

Google Inc. United States

173.194.218.0/24

Google Inc. United States

173.194.219.0/24

Google Inc. United States

173.194.220.0/24

Google Inc. United States

173.194.222.0/24

Google Inc. United States

173.194.223.0/24

Google Inc. United States

173.255.112.0/20

Google Inc. United States

185.25.28.0/22

Google Switzerland GmbH Switzerland

192.104.160.0/23

Google Inc. United States

192.158.28.0/22

Google Inc. United States

192.178.0.0/15

Google Inc. United States

199.192.112.0/22

Google Inc. United States

199.223.232.0/21

Google Inc. United States

207.223.160.0/20

Google Inc. United States

209.85.128.0/17

Google Inc. United States

209.85.145.0/24

Google Inc. United States

209.85.146.0/24

Google Inc. United States

209.85.147.0/24

Google Inc. United States

216.58.192.0/19

Google Inc. United States

216.58.208.0/24

Google Inc. United States

216.58.209.0/24

Google Inc. United States

216.58.210.0/24

Google Inc. United States

216.58.211.0/24

Google Inc. United States

216.58.212.0/24

Google Inc. United States

216.58.213.0/24

Google Inc. United States

216.58.214.0/24

Google Inc. United States

216.58.215.0/24

Google Inc. United States

216.58.216.0/24

Google Inc. United States

216.58.217.0/24

Google Inc. United States

216.58.218.0/24

Google Inc. United States

216.58.219.0/24

Google Inc. United States

216.58.220.0/24

Google Inc. United States

216.58.221.0/24

Google Inc. United States

216.58.222.0/24

Google Inc. United States

216.58.223.0/24

Google Inc. United States

216.239.32.0/19

Google Inc. United States

216.239.32.0/24

Google Inc. United States

216.239.33.0/24

Google Incorporated United States

216.239.34.0/24

Google Inc. United States

216.239.35.0/24

Google Incorporated United States

216.239.36.0/24

Google Inc. United States

216.239.38.0/24

Google Inc. United States

216.239.39.0/24

Google Incorporated United States

216.252.220.0/22

Google Inc. United States

216.252.220.0/24

Google Inc. United States

216.252.221.0/24

Google Inc. United States

216.252.222.0/24

Google Inc.

반응형



Posted by 궁극의 java개발자
,