안녕하세요 알통몬입니다. 공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
이번 포스팅에서는 jsp + FCM을 사용해 jsp 에서 android로 Notification을 보내는 방법에 대해 알아보겠습니다.
먼저 안드로이드진영부터 보겠습니다.
두개의 클래스와 manifest.xml, build.gradle(Module:app)에 코드를 추가해야 합니다.
1. FirebaseInstanceIDService
import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; import yeogiyo.jumo.MainActivity; public class FirebaseInstanceIDService extends FirebaseInstanceIdService { private static final String TAG = "FirebaseIIDService"; private MainActivity mainActivity = MainActivity.activity; String email, rest_id, position, isLogout; @Override public void onTokenRefresh() { String token = FirebaseInstanceId.getInstance().getToken(); Log.d(TAG, "Refreshed token: " + token); // 각자 핸드폰 토큰값을 핸드폰으로 전송합니다 } } |
2. FirebaseMessagingService
import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.BitmapFactory; import android.media.RingtoneManager; import android.net.Uri; import android.support.v4.app.NotificationCompat; import com.google.firebase.messaging.RemoteMessage; import yeogiyo.jumo.MainActivity; import yeogiyo.jumo.R; public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService { private static final String TAG = "FirebaseMsgService"; @Override public void onMessageReceived(RemoteMessage remoteMessage) { String message = remoteMessage.getData().get("message"); String title = remoteMessage.getData().get("title"); sendNotification(message, title); } private void sendNotification(String messageBody, String title) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); Resources resources = getResources(); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_notifications_active_white_24dp) .setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.logo)) .setContentTitle(title) .setContentText(messageBody) .setAutoCancel(true) .setSound(defaultSoundUri) .setWhen(System.currentTimeMillis()) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } } |
3. manifest.xml
위에서 만든 두 개의 클래스를 토대로 service를 추가합니다.
<application> ...... <service android:name=".firebase.FirebaseMessagingService" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name=".firebase.FirebaseInstanceIDService" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service> ...... </application> |
4. build.gradle(Module:app)
dependencies { .... compile 'com.google.firebase:firebase-messaging:10.2.4' } |
그리고 MainActivity의 onCreate() 에 아래와 같이 mysql token을 저장할 수 있도록 jsp 데이터를 보내는
코드를 작성합니다.
FirebaseMessaging.getInstance().subscribeToTopic("news"); String tokens = FirebaseInstanceId.getInstance().getToken(); try { /*String tokenss = autoLogin.getString("tokens", null); SharedPreferences.Editor editor = autoLogin.edit(); editor.putString("tokens", tokens); editor.apply();*/ String result = new TaskMethod("jsp 주소", "token=" + tokens, "UTF-8").execute().get(); Log.d("resultssssss", result + ":"); } catch (Exception e) { e.printStackTrace(); } 위의 TaskMethod 클래스는 AsyncTask 클래스를 상속받는 클래스로 제가 커스텀한 클래스입니다. |
jsp 와 안드로이드, mysql 을 연동하는 작업에 대한 포스팅은 아래 url에서 확인하실 수 있습니다
2017/03/11 - [안드로이드] - 안드로이드 jsp mysql 연동 회원가입과 로그인 최종 정리
mysql에 토큰이 정상적으로 저장된다고 가정하고 진행하겠씁니다.
이번엔 jsp 입니다.
메시지를 보낼 수 있도록 만든 페이지입니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>FCM Example</title> </head> <body> <h2>Notification 보낼 내용 입력</h2>
<form action="pushPushBaebe.jsp" method="post"> <textarea name="message" rows="4" cols="50" placeholder="메세지를 입력하세요"></textarea><br> <input type="submit" name="submit" value="Send" id="submitButton"> </form> </body> </html>
|
위 msg.jsp에서 받은 메시지를 토대로 토큰을 확인해 메시지를 전달하는 jsp입니다.
PushPpushBaebe.jsp
<%@page import="java.net.URLEncoder"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%> <%@ page import="java.util.*"%> <%@ page import="com.google.android.gcm.server.*"%>
<% ArrayList<String> token = new ArrayList<String>(); //token값을 ArrayList에 저장 String MESSAGE_ID = String.valueOf(Math.random() % 100 + 1); //메시지 고유 ID boolean SHOW_ON_IDLE = false; //옙 활성화 상태일때 보여줄것인지 int LIVE_TIME = 1; //옙 비활성화 상태일때 FCM가 메시지를 유효화하는 시간입니다. int RETRY = 2; //메시지 전송에 실패할 시 재시도 횟수입니다.
String simpleApiKey = "apiKey"; String gcmURL = "https://android.googleapis.com/fcm/send"; Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { String jdbcUrl = "jdbc:mysql://localhost:3306/"'database이름'"; // MySQL 계정 String dbId = "userId"; // MySQL 계정 String dbPw = "userPwd"; // 비밀번호 String sql = "sql문"; // 등록된 token을 찾아오도록 하는 sql문
Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(jdbcUrl, dbId, dbPw); stmt = conn.prepareStatement(sql); rs = stmt.executeQuery();
//모든 등록ID를 리스트로 묶음 while(rs.next()){ token.add(rs.getString("token")); 저장된 토큰을 가져와 ArrayList에 저장합니다. } conn.close(); request.setCharacterEncoding("utf-8"); String title = new String("Notification 타이틀".getBytes("UTF-8"),"UTF-8"); String msg = new String(request.getParameter("message").getBytes("UTF-8"), "UTF-8"); //메시지 한글깨짐 처리 // msg.jsp 에서 전달받은 메시지 out.print(msg); Sender sender = new Sender(simpleApiKey); Message message = new Message.Builder() .collapseKey(MESSAGE_ID) .delayWhileIdle(SHOW_ON_IDLE) .timeToLive(LIVE_TIME) .addData("message",msg) .addData("title",title) .build(); 위의 addData의 키 값인 "message" 와 "title" 안드로이드의 FirebaseMessagingService 에서 받은 message , title과 일치해야 합니다. @Override public void onMessageReceived(RemoteMessage remoteMessage) { String message = remoteMessage.getData().get("message"); String title = remoteMessage.getData().get("title"); sendNotification(message, title); } MulticastResult result1 = sender.send(message,token,RETRY); if (result1 != null) { List<Result> resultList = result1.getResults(); for (Result result : resultList) { System.out.println(result.getErrorCodeName()); } } }catch (Exception e) { e.printStackTrace(); } %> |
위에서 simpleApiKey는 아래 사진 보여지는 곳에서 확인할 수 있습니다.
여기까지 따라오셨다면
클라우드 메시지를 성공적으로 보내실 수 있습니다.
이상입니다.
궁금하신 부분들은 댓글달아주시면 최대한 아는 지식 선에서 답변 드리겠습니다.
한가지 주의하실 점은 MainActivity 에서 token은 딱 한번만 생성합니다.
그리고 앱을 지웠다 다시 깔거나 핸드폰 자체 설정에서 앱의 데이터들을 지웠다가 다시 실행하면
token을 다시 생성하고 다시 보냅니다.
이상입니다.