HEROJOON 블로그(히로블)

Android [Service took too long to process intent: com.google.android.c2dm.intent.RECEIVE App may get closed.]해결하기 본문

Backend

Android [Service took too long to process intent: com.google.android.c2dm.intent.RECEIVE App may get closed.]해결하기

herojoon 2020. 3. 17. 01:47
반응형

목표

여러 Push가 전송될 때 Android 앱에서 메시지 받을 수 있도록 코드를 수정하는 것입니다.

 

FCM에서 발송된 여러 Push메시지를 받을 때 Android에서 첫번째 Push는 잘 받지만 나머지 Push에서는 처리가 오래 걸린다는 메시지와 함께 메시지를 띄우지 못한 이슈가 있었습니다.

 

<Android Console Message>

Service took too long to process intent: com.google.android.c2dm.intent.RECEIVE App may get closed.

 

이 부분은 이전에 만들었던 예제에서 발생하므로 발생하는 예제인

2020/02/28 - [Backend] - Android 앱 프로젝트에 FCM설정 및 코드작성 코드를 수정하겠습니다.

 

(참고 Docs : https://firebase.google.com/docs/cloud-messaging/android/receive?hl=ko)

 

Android 앱에서 메시지 수신  |  Firebase

Firebase 알림의 동작은 수신하는 앱의 포그라운드/백그라운드 상태에 따라 달라집니다. 포그라운드 상태인 앱에서 알림 메시지 또는 데이터 메시지를 수신하려면 onMessageReceived 콜백을 처리하는 코드를 작성해야 합니다. 알림과 데이터 메시지의 차이점에 대한 설명은 메시지 유형을 참조하세요. 메시지 처리 메시지를 수신하려면 FirebaseMessagingService를 확장하는 서비스를 사용합니다. 서비스에서 onMessageReceived

firebase.google.com

 

app수준의 build.gradle에 의존Library 추가

dependencies {
    implementation 'androidx.work:work-runtime:2.3.3'
}

 

코드 추가 (Worker.java)

package com.herojoon.fcmtestapp;

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

public class MyWorker extends Worker {

    private static final String TAG = "MyWorker";

    public MyWorker(@NonNull Context appContext, @NonNull WorkerParameters workerParams) {
        super(appContext, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        Log.d(TAG, "Performing long running task in scheduled job");
        // TODO(developer): add long running task here.
        return Result.success();
    }
}

 

코드 수정 (MyFirebaseMessagingService.java)

package com.herojoon.fcmtestapp;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;

import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FCMService";

    /**
     * 메시지 수신받는 메소드
     * @param msg
     */
    @Override
    public void onMessageReceived(RemoteMessage msg) {
        Log.i("### msg : ", msg.toString());

        if (msg.getData().size() > 0) {
            Log.i("### data : ", msg.getData().toString());
            sendTopNotification(msg.getData().get("title"), msg.getData().get("content"));
            if (true) {
                scheduleJob();
            } else {
                handleNow();
            }
        }

        if (msg.getNotification() != null) {
            Log.i("### notification : ", msg.getNotification().getBody());
            sendTopNotification(msg.getNotification().getTitle(), msg.getNotification().getBody());
        }
    }

    /**
     * Schedule async work using WorkManager.
     */
    private void scheduleJob() {
        OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(MyWorker.class)
                .build();
        WorkManager.getInstance().beginWith(work).enqueue();
    }

    /**
     * Handle time allotted to BroadcastReceivers.
     */
    private void handleNow() {
        Log.d(TAG, "Short lived task is done.");
    }

    private void sendTopNotification(String title, String content) {
        final String CHANNEL_DEFAULT_IMPORTANCE = "channel_id";
        final int ONGOING_NOTIFICATION_ID = 1;
        Intent notificationIntent = new Intent(this, MyFirebaseMessagingService.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        Notification notification =
                new Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE)
                        .setContentTitle(title)
                        .setContentText(content)
                        .setSmallIcon(R.drawable.common_full_open_on_phone)
                        .setContentIntent(pendingIntent)
                        .build();

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_DEFAULT_IMPORTANCE,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        notificationManager.notify(ONGOING_NOTIFICATION_ID, notification);
    }
}

 

에러 수정

 

app수준의 build.gradle에서 minSdkVersion을 올려줌. -> Sync Now

 

결과

폰 상단 상태표시줄에 발송된 메시지의 아이콘이 표시되었습니다.

아래로 드래그하면 발송된 메시지의 내용을 볼 수 있습니다.

반응형
Comments