막무가내 삽질 블로그
안드로이드 fcm push notification, send fcm device to device 본문
728x90
A유저가 B유저의 프로필에서 친구추가를 누르면 B유저의 핸드폰에 알림이 울려야 한다.
FCM 을 활용하여 테스트 해보았다.
https://firebase.google.com/docs/android/setup?hl=ko
안드로이드 프로젝트에 파이어베이스를 추가 시킨다
마지막 단계 sync now를 누른 후 이 화면이 계속 되는 사람들은 에뮬레이터를 한번 실행시키면 넘어 갈 수 있다.
토큰은 사람으로 치면 주민등록번호라고 생각한다.
사람이 태어나면 주민번호를 등록하고 사망하면 주민번호가 삭제되는 것 처럼 앱이 실행되면 토큰이 발급되면서 해당 토큰으로 알림을 받을 수 있다.
테스트 파일의 흐름은
A핸드폰의 토큰을 발급받고 보관해 두었다가 B핸드폰을 실행하여 A핸드폰의 토큰으로 알림을 보낸다.
MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, instanceIdResult -> {
String token = instanceIdResult.getToken();
Log.d(TAG, "토큰 : " + token);
});
앱을 실행시키면 토큰이 발급된다. 토큰을 다른곳에 적어 두었다가 B핸드폰을 실행전에
sendNotificationToUser("토큰번호"); 를 삽입해서 넣어주고 다시 실행 시키면 A핸드폰에 알림이 울린다.
private void sendNotificationToUser(String token) {
Model model = new Model(token, new NotificationModel(add, content));
Api apiService = ApiClient.getClient().create(Api.class);
retrofit2.Call<ResponseBody> responseBodyCall = apiService.sendNotification(model);
responseBodyCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
Log.d(TAG,"성공");
}
@Override
public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {
Log.d(TAG, "실패");
}
});
}
Api Interface, 서버키는 아래 사진에
public interface Api {
@Headers({"Authorization: key=" + "SERVER KEY를 넣으세요", "Content-Type:application/json"})
@POST("fcm/send")
Call<ResponseBody> sendNotification(
@Body Model root);
}
ApiClient
public class ApiClient {
private static final String BASE_URL = "https://fcm.googleapis.com/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Model
public class Model {
@SerializedName("to") // "to" changed to token
private String token;
@SerializedName("notification")
private NotificationModel notification;
public Model(String token, NotificationModel notification) {
this.token = token;
this.notification = notification;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public NotificationModel getNotification() {
return notification;
}
public void setNotification(NotificationModel notification) {
this.notification = notification;
}
}
NotificationModel
public class NotificationModel {
private String title;
private String body;
public NotificationModel(String title, String body) {
this.title = title;
this.body = body;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
FirebaseMessaging
public class FirebaseMessaging extends FirebaseMessagingService {
private static final String TAG = "FirebaseMessage";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "onMessageReceived: ");
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "onMessageReceived: 1");
sendNotification(remoteMessage.getNotification().getBody(), remoteMessage.getNotification().getTitle());
} else if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "onMessageReceived: 2");
String tittle = remoteMessage.getData().get("tittle");
String text = remoteMessage.getData().get("text");
sendNotification(tittle, text);
}
}
public void sendNotification(String tittle, String text) {
Log.d(TAG, "sendNotification: ");
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);
String channelId = getString(R.string.default_notification_channel_id);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(tittle)
.setContentText(text)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_VIBRATE)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
manifest application 안에 추가
<service
android:name=".FirebaseMessaging"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
알림이 올 때 포그라운드, 백그라운드 다 울릴 수 있도록 수정했다.
'Android' 카테고리의 다른 글
안드로이드 opencv 이미지 얼굴 판별 o,x (0) | 2020.01.26 |
---|---|
android glide image size (0) | 2020.01.21 |
android infinite/endless scroll (0) | 2019.12.25 |
java.lang.IndexOutOfBoundsException: 에러 난 이유 (0) | 2019.12.17 |
android null object reference (0) | 2019.12.15 |
Comments