private static final String PASSWORD = "1111";
//자신의 Project ID 를 넣어주세요
private static final String SENDER_ID = "자신의 프로젝트 아이디";
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();
}
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);
}
protected void onMessage(Context context, Intent intent) {
if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
showMessage(context, intent);
}
}
protected void onError(Context context, String msg) {
// TODO Auto-generated method stub
Log.w(TAG, "onError!! " + msg);
}
protected void onRegistered(Context context, String regID) {
// TODO Auto-generated method stub
if(!regID.equals("") || regID != null){
Log.w(TAG, "onRegistered!! " + regID);
// 단일전송일때 주석처리
// insertRegistrationID(regID);
}
}
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();
}
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());
}
대단하시네요.. 몇가지 여쭈어 보아도 될까요? 컴파일해보니 로그켓에 regid 값이 'APA91bHWao7uxLdL4uvCMYDMA6ZAGORIwm6yzCCYet0484Jq_............................쭉쭉더길게' 이런식으로 나오 던데 이값을 registrationId = ""; << 여기에 넣는것이 맞나요?
그리고 php문서에서 만약 제 DB의 regid값을 저장해놓는 열(row)의 이름을 'reg_id' 라고 해놓았을때 밑의 코드들의 올바르게 작성된건가요? 그리고 밑줄 쳐놓은 regID는 안드로이드 프로젝트에서 선언된 regID 변수인지...(같다고 생각하고 작성하였습니다 ㅜㅜ 혹시 안드로이드 프로젝트에 데이터베이스에 쓰인 변수가 사용되였나요?,,)
----------
네. APA91bHW..... 이런식으로 나오는게 맞구요. 정상적으로 등록되었다는겁니다.
단일 전송시에는 registrationId 에 넣어서 사용하면 되구요.
서버가 있으신듯하니까 List에 넣어서 사용하시겠네요.
소스에 regID는 "insert_registration.php?regID=" <-파라미터로 쓴거말곤 없습니다.
혹시 서버가 다르신거 아닌가요? 몇가지 예상되는걸 적어볼게요.
1.서버환경이 다를경우 (참고로 저는 리눅스서버에 DB는 MySQL입니다)
2. DB 테이블구조 "insert into adt(reg_id) values('$regID')"; adt는 테이블명이 되야하고, reg_id가 필드명이 되는게 맞아요
3. 파싱문제 DB에서 select할 때 JSON형태로 파싱하는데 키값이 맞나 확인해보세요.
send하기전에 로그에 변수찍어봐서 값이 제대로 들어왔나 확인해보세요.
그래도 안되시면 해당에러 로그를 남겨주시면 답변드릴게요~
좋은 자료 감사합니다!!
올려주신 프로젝트 import해서 설정도 다 해줬고 apikey값과 reg_id값도 다 넣어서 실행했는데
입력하고 전송 버튼을 누르면 프로그램이 중지되었습니다 라고 뜨고 종료됩니다 ㅠㅠ
왜 안되는 걸까요??
regId 값을 못찾겠어서 Toast메세지로 regId값을 띄우려했는데 regId값이 없는것처럼 나오네요.
regId값은 어떻게 알 수 있나요?
Log창에서도 찾지 못하고 있어서 질문드립니다.
에러도 안나고,
07-31 16:34:40.202: D/GCM(3497): gcmMessage :: Message(collapseKey=1.2773615554621158, timeToLive=3, delayWhileIdle=true, data: {ticker=sdt,title=xfhh,msg=dfhuu})
07-31 16:34:40.202: D/GCM(3497): registrationId :: APA91bGpgjlYOPH_s6j7gzPXZ87fQv5MhWTHaGv_fOlCGKPKGcsc3tgj2sSMm67M8Z_XZAZQaam0uaH80-2RQ0qKwMqD7jUBvzmoTPK_UWQr2cxy7rpI0dl5xwxL_oawm_e9JBifRD027__rirKLYWRiEfigcSFNow
07-31 16:34:40.202: D/GCM(3497): RETRY :: 3
07-31 16:34:41.253: D/GCM(3497): gcmResult :: [ messageId=0:1343720083388948%6f98f80d89d212f7 ]
07-31 16:34:41.253: D/GCM(3497): getCanonicalIds : null <==================================값이 없음.
07-31 16:34:41.253: D/GCM(3497): getMessageId : 0:1343720083388948%6f98f80d89d212f7
아이스크림에서 돌리니까 이번에는 아래와 같은 에러를 보이네요.
08-01 11:44:08.140: E/AndroidRuntime(22112): FATAL EXCEPTION: main
08-01 11:44:08.140: E/AndroidRuntime(22112): java.lang.IllegalStateException: Could not execute method of the activity
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.view.View$1.onClick(View.java:3098)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.view.View.performClick(View.java:3620)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.view.View$PerformClick.run(View.java:14292)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.os.Handler.handleCallback(Handler.java:605)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.os.Handler.dispatchMessage(Handler.java:92)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.os.Looper.loop(Looper.java:137)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.app.ActivityThread.main(ActivityThread.java:4512)
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.lang.reflect.Method.invokeNative(Native Method)
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.lang.reflect.Method.invoke(Method.java:511)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
08-01 11:44:08.140: E/AndroidRuntime(22112): at dalvik.system.NativeStart.main(Native Method)
08-01 11:44:08.140: E/AndroidRuntime(22112): Caused by: java.lang.reflect.InvocationTargetException
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.lang.reflect.Method.invokeNative(Native Method)
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.lang.reflect.Method.invoke(Method.java:511)
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.view.View$1.onClick(View.java:3093)
08-01 11:44:08.140: E/AndroidRuntime(22112): ... 11 more
08-01 11:44:08.140: E/AndroidRuntime(22112): Caused by: android.os.NetworkOnMainThreadException
08-01 11:44:08.140: E/AndroidRuntime(22112): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
08-01 11:44:08.140: E/AndroidRuntime(22112): at java.net.InetAddress.getAllByName(InetAddress.java:220)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:460)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188)
08-01 11:44:08.140: E/AndroidRuntime(22112): at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:280)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.google.android.gcm.server.Sender.post(Sender.java:468)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.google.android.gcm.server.Sender.post(Sender.java:447)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.google.android.gcm.server.Sender.sendNoRetry(Sender.java:170)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.google.android.gcm.server.Sender.send(Sender.java:121)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.example.gcmmanager.GCMSendMessage.sendMessage(GCMSendMessage.java:117)
08-01 11:44:08.140: E/AndroidRuntime(22112): at com.example.gcmmanager.GCMSendMessage.onClickButton(GCMSendMessage.java:172)
08-01 11:44:08.140: E/AndroidRuntime(22112): ... 14 more
얼마전에 가입해서 댓글이 매우 늦어져서..혹시 볼사람이 있을까 해서 올려봅니다ㅎㅎ
setMessage()후에
sendMessage()를 실행시키는 부분을 스레드 하나 만들어서 돌리면 되더라구요..
예를들면
class NetworkThread extends Thread{
public void run(){
sendMessage();
}
}
요런식으로 스레드 하나 만들어서
sendMessage()있던 부분에서 start해주면 오류없이 지나가더라고요..
회사일 때문에 배우면서 하는 중이라..혹 더 좋은 방법있으시면 알려주세요~~ㅎ
꽤 전의 글인데 답변이 달릴지는 잘 모르겠네요...
심각: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
at com.snapThinking.GCM.push.server.GCMPush.sendPush(GCMPush.java:45)
at org.apache.jsp.pushServer_jsp._jspService(pushServer_jsp.java:112)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:620)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:745)
이런식의 에러가 발생하는데 어디서 문제가 생긴건지 잘 모르겠습니다.
json-simple-1.1.1.jar을 lib에 넣고 build path로 지정까지 했는데 에러가 발생하네요
감사감사 훌륭하십니다 ^^