2016. 4. 7. 14:41ㆍmobile/android
************************** GCM 강좌 ****************************************
android GCM 클라이언트, 서버 완벽 구현 1 [ 사전 준비 ]
android GCM 클라이언트, 서버 완벽 구현 2 [ 클라이언트 셋팅, GCM 설정 ]
android GCM 클라이언트, 서버 완벽 구현 3 [ 클라이언트 셋팅, GCM 설정 ]
android GCM 클라이언트, 서버 완벽 구현 4 [ 서버 셋팅, GCM 설정 ]
******************************************************************************
이번에는 서버를 구성해 보겠습니다.
GCM 서버 구축에는 web project가 필요합니다. 이 강좌에서는 jsp 와 tomcat 을 사용합니다.
java jdk, eclipse, tomcat 은 설치되어있어야 합니다.
jdk, eclipse, tomcat 설치 방법은 검색해보면 아주 많이 나와있으니 참고하시기 바랍니다.
web 지식이 부족하신 분들은 jsp hello world 출력하기 강좌를 따라하시고 오셔도 충분합니다.
* web project 생성 방법은 생략합니다
2016.09.26 내용추가 web project 생성에 관련한 포스팅이 추가되어서 여기에도 명시해 드립니다 ^^ Mac 에 Tomcat 설치 / 톰캣 설치 (윈도우에서의 설치는 구글링 : 클릭)
eclipse에서 webproject 생성 / dynamic web project / jsp |
순서 요약입니다.
1. jar 파일 준비
2. GCMUtil.java, GCMVo.java 생성
3. 앱에서 보낸 regId 받기
4. PUSH 호출
선행작업으로 web project 를 생성합니다.
기본적인 Dynamic Web Project 여도 상관없고 spring 프레임이거나 아무거나 상관없습니다.
필자는 기본적인 Dynamic 구조로 설명하겠습니다.
1. jar 파일 준비
다음 jar 파일을 다운받습니다.
그리고 WebContent > WEB-INF > lib 폴더 아래로 복사합니다.
2. GCMUtil.java, GCMVo.java 생성
GCMUtil.java 를 생성합니다. GCMUtil 이 하는 일은 실제 GCM PUSH 를 보내는 역할을 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 |
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Message.Builder;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
/**
* GCM UTIL
*
* gcm-server.jar, json-simple-1.1.1.jar 필요
*
* @author
*
*/
public class GCMUtil {
static final String API_KEY = "서버 API KEY"; // server api key
private static final int MAX_SEND_CNT = 999; // 1회 최대 전송 가능 수
// android 에서 받을 extra key (android app 과 동일해야 함)
static final String TITLE_EXTRA_KEY = "TITLE";
static final String MSG_EXTRA_KEY = "MSG";
static final String TYPE_EXTRA_CODE = "TYPE_CODE";
// android 에서 받을 extras key
List<String> resList = null;
private Sender sender;
private Message message;
public ArrayList<GCMVo> rtnList;
/**
* GCM Util 생성자
* RegistrationId 셋팅, sender 셋팅, message 셋팅
*
* @param reslist : RegistrationId
* @param gcmVo : msg 정보
*/
public GCMUtil(List<String> reslist, GCMVo gcmVo) {
sender = new Sender(API_KEY);
this.resList = reslist;
setMessage(gcmVo);
rtnList = new ArrayList<GCMVo>();
sendGCM();
}
/**
* 메시지 셋팅
* @param gcmVo
*/
private void setMessage(GCMVo gcmVo) {
Builder builder = new Message.Builder();
builder.addData(TITLE_EXTRA_KEY, gcmVo.getTitle());
builder.addData(MSG_EXTRA_KEY, gcmVo.getMsg());
builder.addData(TYPE_EXTRA_CODE, gcmVo.getTypeCode());
message = builder.build();
}
/**
* 메시지 전송
*/
private void sendGCM() {
if (resList.size() > 0) {
if (resList.size() <= MAX_SEND_CNT) { // 한번에 1000건만 보낼 수 있음
sendMultivastResult(resList);
} else {
List<String> resListTemp = new ArrayList<String>();
for (int i = 0; i < resList.size(); i++) {
if ((i + 1) % MAX_SEND_CNT == 0) {
sendMultivastResult(resListTemp);
resListTemp.clear();
}
resListTemp.add(resList.get(i));
}
// 1000건씩 보내고 남은 것 보내기
if(resListTemp.size() != 0){
sendMultivastResult(resListTemp);
}
}
}
}
/**
* 실제 멀티 메시지 전송
*
* @param list
*/
private void sendMultivastResult(List<String> list) {
try {
MulticastResult multiResult = sender.send(message, list, 5); // 발송할 메시지, 발송할 타깃(RegistrationId), Retry 횟수
List<Result> resultList = multiResult.getResults();
for (int i=0; i<resultList.size(); i++){
Result result = resultList.get(i);
// 결과 셋팅
GCMVo rtnGcmVo = new GCMVo();
rtnGcmVo.setRegId(list.get(i));
rtnGcmVo.setMsgId(result.getMessageId());
rtnGcmVo.setErrorMsg(result.getErrorCodeName());
if (result.getMessageId() != null) { // 전송 성공
rtnGcmVo.setPushSuccessOrFailure(true);
} else { // 전송 실패
rtnGcmVo.setPushSuccessOrFailure(false);
}
rtnList.add(rtnGcmVo);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
|
cs |
20# : 메모한 서버 API-KEY 를 넣습니다.
24# ~ 26# : 3번 강좌에 설명해 놓았습니다. android project의 GCMIntentService.java 클래스에 19# ~ 21# 과 동일해야 합니다.
67# : 메시지를 한번에 보낼수 있는 최대 갯수는 1000개입니다. 안전성을 위해 999개씩 보내도록 분기합니다.
GCMVo.java 생성합니다. GCMVo 는 PUSH를 보낼 때 정보를 담는 역할을 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 |
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class GCMVo {
// android 로 보낼 정보
private String title = "제목입니다.";
private String msg = "내용입니다.";
private String typeCode = "코드입니다.";
// push 결과 정보
private String regId; // regId
private boolean pushSuccessOrFailure; // 성공 여부
private String msgId = ""; // 메시지 ID
private String errorMsg = ""; // 에러메시지
public String getTitle() {
return title;
}
public void setTitle(String title) throws UnsupportedEncodingException {
this.title = URLEncoder.encode(title, "UTF-8");
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) throws UnsupportedEncodingException {
this.msg = URLEncoder.encode(msg, "UTF-8");
}
public String getTypeCode() {
return typeCode;
}
public void setTypeCode(String typeCode) {
this.typeCode = typeCode;
}
public boolean getPushSuccessOrFailure() {
return pushSuccessOrFailure;
}
public void setPushSuccessOrFailure(boolean pushSuccessOrFailure) {
this.pushSuccessOrFailure = pushSuccessOrFailure;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public void setRegId(String regId) {
this.regId = regId;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getRegId() {
return regId;
}
}
|
cs |
3. 앱에서 보낸 regId 받기
PUSH를 보내려면 디바이스의 regId 가 있어야 합니다.
android project 에서 로그로 regId 를 출력하고 있어서 복사해서 호출할 때 그냥 사용해도 무방합니다.
하지만 앱실행 > 앱에서 서버로 regId 전송 > 서버에서 regId 수집 및 저장 > 수집된 regId로 PUSH 호출 > 앱에서 PUSH 수신 과 같은 로직이 있어야 사용하기 편하기 때문에 받는 부분을 꼭 구현하시기 바랍니다.
WebContent 폴더 아래에 sendGCMReg.jsp 파일을 생성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 |
<%@page import="java.net.URLEncoder"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/json; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%
System.out.println("*********************************************************");
System.out.println("REG 획득");
System.out.println("KEY : " + request.getParameter("KEY"));
System.out.println("REG : " + request.getParameter("REG"));
System.out.println("*********************************************************");
Map rtnMap = new HashMap();
rtnMap.put("DATA", URLEncoder.encode("등록되었습니다.", "UTF-8"));
rtnMap.put("DATA1", "END1");
out.print(rtnMap.toString());
%> |
cs |
그리고 sendGCMReg.jsp 를 호출하는 주소를 andorid project 의 MainActivity.java 의 SERVER_URL 변수에 셋팅합니다.
대략 http://111.111.111.111:8080/sendGCMReg.jsp 이런 모양이 되겠네요.
이제 앱을 실행합니다. 에뮬레이터 말고 인터넷이 가능한 스마트폰에서 꼭 실행하도록 합니다.
여기서 실행하면 더이상 앱에서는 오류가 발생하지 않습니다.
버튼을 클릭해 봅니다.
그럼 서버의 eclipse 의 console 에 REG 정보가 찍혀있을 것입니다.
여기서 획득한 regId 정보를 메모합니다.
regId 정보를 db에 넣어서 관리할 수 도 있겠죠 ???
4. PUSH 호출
regId 도 획득했으니 이제 regId 를 이용하여 PUSH 를 직접 보내봅시다.
WebContent 폴더 아래에 sendGCM.jsp 파일을 생성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 |
<%@page import="esaving.module.common.pushmobile.GCMUtil"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="esaving.module.common.pushmobile.GCMVo"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%
//전달할 PUSH 내용
String title = "PUSH 제목 입니다.";
String msg = "PUSH 내용입니다 ^^ !!!!";
// GCM 정보 셋팅
GCMVo gcmVo = new GCMVo();
gcmVo.setTitle(title);
gcmVo.setMsg(msg);
gcmVo.setTypeCode("");
// GCM reg id 셋팅
List<String> reslist = new ArrayList<String>();
reslist.add("입력받은 regId를 입력합니다.");
GCMUtil gcmUtil = new GCMUtil(reslist, gcmVo);
for(int i=0; i<gcmUtil.rtnList.size(); i++){
GCMVo rtnGcmVo = gcmUtil.rtnList.get(i);
out.println("regId : " + rtnGcmVo.getRegId());
out.println("성공 여부 : " + rtnGcmVo.getPushSuccessOrFailure());
out.println("메시지ID : " + rtnGcmVo.getMsgId());
out.println("에러메시지 : " + rtnGcmVo.getErrorMsg());
}
%> |
cs |
10# ~ 17# : PUSH 보낼 내용을 셋팅합니다.
21# : 입력받은 regId 를 입력합니다.
30# : 에러메시지가 NotRegistered 이면 앱이 삭제됬다고 판단하면 된다. 비교할 수 있는 상수는 Constants.ERROR_NOT_REGISTERED 입니다.
실제로 앱이 삭제되고 google gcm 서버로 regId 가 삭제하는 메시지를 보내고 적용되는 시간이 조금 걸리니 앱 삭제 후 바로 테스트하는 것은 의미없습니다.
sendGCM.jsp 를 호출 해 주면 PUSH 가 도착하는 것을 볼 수 있습니다.
대략 http://111.111.111.111:8080/sendGCM.jsp 과 같은 주소이겠죠 ?
이상으로 GCM 클라이언트(어플리케이션)와 서버를 완벽하게 구현하는 강좌를 마칩니다.
'mobile > android' 카테고리의 다른 글
android status bar 색상 변경 / 상태바 색상 변경 / 5.0 롤리팝 , 6.0 마시멜로우 까지 적용 / 머티리얼 적용 (0) | 2016.06.13 |
---|---|
android 뒤로가기 두번 눌러서 종료 / 어플 종료 방법 / 두번 눌러서 닫기 (2) | 2016.05.12 |
android 현재 WebView에서 외부 페이지 불러오기 / WebView 새창 띄우지 않기 / WebViewClient (0) | 2016.04.20 |
android webview 에서 카메라 호출 및 사진첩(갤러리) 호출하여 이미지 파일 업로드 하기 (23) | 2016.04.14 |
android html5 스마트폰 카메라와 연결하기, 사진(갤러리) 및 동영상 찍기 예제 ( URL.createObjectURL ) (0) | 2016.04.08 |
android GCM 클라이언트, 서버 완벽 구현 예제 3 [ 클라이언트 셋팅, GCM 설정 ] (5) | 2016.04.07 |
android GCM 클라이언트, 서버 완벽 구현 예제 2 [ 클라이언트 셋팅, GCM 설정 ] (5) | 2016.04.07 |
android GCM 클라이언트, 서버 완벽 구현 예제 1 [ 사전 준비 ] (1) | 2016.04.07 |
Android OCR 한글 및 영문 인식 Tesseract 샘플 프로젝트 테스트 (110) | 2016.04.06 |
android | 꺼진 화면에서 앱 실행하기 / 잠든 화면 깨우기 / 잠금 화면 위로 실행/ (6) | 2016.03.30 |