강의는 구 버전인 GCM 이나
블로그는 FCM 으로 작성 하였다.
소켓으로 연결방식으로 사용 하는 것이 아니라 구글에서 연결 단말을 이용하는 방식이다.
단말을 등록된 사람만 메시가 전송된다.
[안드로이드(22)] - GCM보다 더 간편하게 FCM으로 푸시알림 구현하기 Part1
[안드로이드 - FCM(Firebase Cloud Messaging)으로 푸시서비스 구현]
안드로이드 스튜디오를 열어서 일단 기본설정으로 프로젝트를 하나 만들자. 여기서 알아 둬야 할것은 패키지 이름이다. 이 패키지 이름을 FCM에서 앱추가하면서 등록해 줘야 하기 때문이다. 다시 firebase 콘솔 페이지에 들어가자.
Firebase consol에서 새로운 프로젝트 만들기
https://console.firebase.google.com/
생성된 나의 프로젝트
https://console.firebase.google.com/project/juhofcm/overview
firebase.설정
https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko
AndroidMainfest.xml
잡서비스 추가
https://github.com/firebase/firebase-jobdispatcher-android
FCM을 이용해 안드로이드 앱으로 메시지 전송 (1)
[Android] 안드로이드 FCM(FireBase Cloud Messaging) 푸시알림 구현하기 (2)
출처: http://codersdict.com/20 [코딕트]
class MainActivity
package kr.co.braverokmc.fcmpushexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
public class MainActivity extends AppCompatActivity {
/* TextView textView;
String getMessage;*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* textView =(TextView)findViewById(R.id.text1);*/
//추가한 라인
FirebaseMessaging.getInstance().subscribeToTopic("news");
String message=FirebaseInstanceId.getInstance().getToken();
/*
아래 코드 실행 안됨
Intent intent=getIntent();
if(intent!=null){
getMessage=intent.getStringExtra("message");
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(getMessage);
}
});
}*/
//FirebaseMessaging.getInstance().
/* 앱을 어떻게 만들지에 따라 얼마든지 다르게 구현 하면 된다. 이 예제에서는 단순히 news라는
토픽에 등록하는 과정을 구현했을 뿐이다. 버튼을 만들어서 버튼을 클릭했을때 수행되게 할 수도 있다.
이 예제는 앱이 실행되면 자동으로 news라는 토픽을 구독한다는 의미다.
FirebaseMessaging.getInstance().subscribeToTopic("news");
FirebaseInstanceId.getInstance().getToken();
토픽(주제)에 등록되면 나중에 관리자가 메세지를 보낼때 주제별로 선택해서 보낼
수 있게 해주는 것이다.기존 토픽에 추가로 등록하거나 없으면 새로운 토픽을 생성할 수도 있다.
위 샘플은 news라는 토픽에 구독등록을 한다는 의미이다. 자신이 원하는 토픽을 만들어 주면 된다.
한가지 유의해야 할것은 토픽이 즉시 적용되지 않는다. 생성되는데 몇시간 길게는 하루가 걸리기도 한다고 한다.
추가) 혹시 토픽을 추가하면 에러가 발생하면 gradle에서 firebase-messaging을 가장 최신 버전으로
수정해 준다. 최근 다시 해보니 에러가 발생해서 최신버전으로 변경하니 정상적으로 동작했음!*/
}
}
class MyFirebaseMessagingService
package kr.co.braverokmc.fcmpushexample;
/**
* Created by choi on 2017-04-19.
*/
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
import com.firebase.jobdispatcher.GooglePlayDriver;
import com.firebase.jobdispatcher.Job;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {
private static final String TAG = "FirebaseMsgService";
// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//추가한것
sendNotification(remoteMessage.getData().get("message"));
// TODO(developer): Handle FCM messages here.
// Not getting messages here? See why this may be: https://goo.gl/39bRNJ
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
//여기에서 메시지가 전달 받는다.
/*
아래 코드 실행 안됨
String message=remoteMessage.getNotification().getBody();
Intent intent =new Intent(this, MainActivity.class);
intent.putExtra("message", message);*/
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
/**
* Schedule a job using FirebaseJobDispatcher.
*/
private void scheduleJob() {
// [START dispatch_job]
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
Job myJob = dispatcher.newJobBuilder()
.setService(MyJobService.class)
.setTag("my-job-tag")
.build();
dispatcher.schedule(myJob);
// [END dispatch_job]
/*
위에코드는 간략하게 아래는 전체
Bundle myExtrasBundle = new Bundle();
myExtrasBundle.putString("some_key", "some_value");
Job myJob = dispatcher.newJobBuilder()
// the JobService that will be called
.setService(MyJobService.class)
// uniquely identifies the job
.setTag("my-unique-tag")
// one-off job
.setRecurring(false)
// don't persist past a device reboot
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
// start between 0 and 60 seconds from now
.setTrigger(Trigger.executionWindow(0, 60))
// don't overwrite an existing job with the same tag
.setReplaceCurrent(false)
// retry with exponential backoff
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
// constraints that need to be satisfied for the job to run
.setConstraints(
// only run on an unmetered network
Constraint.ON_UNMETERED_NETWORK,
// only run when the device is charging
Constraint.DEVICE_CHARGING
)
.setExtras(myExtrasBundle)
.build();
dispatcher.mustSchedule(myJob);*/
}
/**
* Handle time allotted to BroadcastReceivers.
*/
private void handleNow() {
Log.d(TAG, "Short lived task is done.");
}
private void sendNotification(String messageBody) {
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);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("FCM Push Test")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
class MyFirebaseInstanceIDService
package kr.co.braverokmc.fcmpushexample;
/**
* Created by choi on 2017-04-19.
*/
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
// [START refresh_token]
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String token = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + token);
// 생성등록된 토큰을 개인 앱서버에 보내 저장해 두었다가 추가 뭔가를 하고 싶으면 할 수 있도록 한다.
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("Token", token)
.build();
//토큰을 실어서 보낼 자신의 서버주소를 적어 준다.
//request
Request request = new Request.Builder()
.url("http://서버주소/fcm/register.php")
.post(body)
.build();
try {
client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class MyJobService
package kr.co.braverokmc.fcmpushexample;
/**
* Created by choi on 2017-04-19.
*/
import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;
public class MyJobService extends JobService {
@Override
public boolean onStartJob(JobParameters job) {
// Do some work here
return false; // Answers the question: "Is there still work going on?"
}
@Override
public boolean onStopJob(JobParameters job) {
return false; // Answers the question: "Should this job be retried?"
}
}
R.layout.activity_main
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="kr.co.braverokmc.fcmpushexample.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/text1"
/>
</RelativeLayout>
AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kr.co.braverokmc.fcmpushexample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- [START fcm_default_icon] -->
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/a5" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
<!-- [END fcm_default_icon] -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- [START firebase_service] -->
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<!-- [END firebase_service] -->
<!-- [START firebase_iid_service] -->
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<!-- [END firebase_iid_service] -->
<service
android:exported="false"
android:name=".MyJobService">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
</intent-filter>
</service>
</application>
</manifest>
app1
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.google.gms:google-services:3.0.0'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
app2
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "kr.co.braverokmc.fcmpushexample"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//추가한 라인(계속 업그레이드 되고 있다.)
compile 'com.google.firebase:firebase-messaging:10.0.1'
//서버로 데이터를 보낼때 okhttp를 사용한다면 추가
compile 'com.squareup.okhttp3:okhttp:3.2.0'
//잡스서비스 추가
compile 'com.firebase:firebase-jobdispatcher:0.6.0'
}
apply plugin: 'com.google.gms.google-services'
131강
132강
댓글 ( 4)
댓글 남기기