Android

[안드로이드 백그라운드서비스] RemoteServiceException이 발생하는 이유는 무엇이며 나는 해결책을 찾고 싶다.android.app.ActivityThread$H.handleMessage

백그라운드 서비스의 경우 구글 안드로이드 운영체제가 새롭게 나올때 마다 처리방법이 달라졌다. 특히 오레오 버전부터 확 달라졌고, 그 때 부터 앱 사용자들로부터 RemoteServiceException오류가 대거 발생하기 시작했다. 해겨할 수 있는 방법이 없을까?? 나와 같은 오류를 경험한 개발자들이 많다. 하지만 그 누구도 해결책을 모르는 것일까? 아무리 구글링해도 좋은 해결책을 찾지 못했다.


백그라운드 관련 서비스 오류

 

첫번째 오류

가장 흔하게 몇 년 간 나를 괴롭히며 발생한 오류로 Bad notification for startForeground 오류

Fatal Exception: android.app.RemoteServiceException: Bad notification for startForeground
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2228)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:246)
       at android.app.ActivityThread.main(ActivityThread.java:8443)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:596)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)


 

두번째 오류

첫번째 오류와 마찬가지로 몇 년간 나를 괴롭힌 Context.startForegroundService() did not then call Service.startForeground() 오류

Fatal Exception: android.app.RemoteServiceException: 
Context.startForegroundService() did not then call Service.startForeground(): 
ServiceRecord{206579e u0 com.test/.BGMService}
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1970)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7386)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)


세번째 오류

가장 최근에 새롭게 발생된 오류이다. 대부분 중국 폰에서 문제가 발생한다.

Fatal Exception: android.app.RemoteServiceException: 
Bad notification(tag=null, id=7324) 
posted from package com.test, crashing app(uid=10345, pid=20049):
Couldn't inflate contentViewsjava.lang.NullPointerException:
Attempt to invoke virtual method
'android.app.Notification$MessagingStyle 
android.app.Notification$MessagingStyle.setConversationType(int)' on a null object reference
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:236)
       at android.app.ActivityThread.main(ActivityThread.java:7876)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)


 

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Intent intent = new Intent(MainActivity.this, BGMService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
	startForegroundService(intent);
} else {
	startService(intent);
}
public class BGMService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //G_NOTIFICATION_ID = (int) (System.currentTimeMillis()%10000);
            displayNotification(getApplicationContext(), 0, 0, 0);
        }

    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            displayNotification(getApplicationContext(), 0, 0, 0);
        }

        this.regisiterReceiver();   
        
        return Service.START_STICKY;        
    }
    
    
	public void displayNotification(Context context, int level, double temperrature, double volt) {
        try {
            SharedPreferences sp = context.getSharedPreferences(MY_PM_PREF, Activity.MODE_PRIVATE);
            myNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

            //디자인 설정
            getChooseDesignForStatusBar(sp, context);

            //노티영역 클릭시 이동할 activity 설정
            Intent newIntent = new Intent(context, MainActivity.class);
            newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); //Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP  //FLAG_ACTIVITY_BROUGHT_TO_FRONT
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

                //ULog.d("FROCS", "========================= G_NOTIFICATION_ID : " + G_NOTIFICATION_ID);
                //int NOTIFICATION_ID = 2020;
                String CHANNEL_ID = "channel_bar_2020";  //여기 수정시 NotiActivity.class에서도 변경해줘야한다.
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                        context.getResources().getString(R.string.content_txt_43),
                        NotificationManager.IMPORTANCE_LOW);//.IMPORTANCE_HIGH);//IMPORTANCE_LOW);

                channel.setDescription(context.getResources().getString(R.string.cont_44));  // 노티 하단에 정보로 제공된다.
                //channel.setAllowBubbles(false);

//                channel.enableLights(true);
//                channel.setLightColor(Color.RED);
                channel.setShowBadge(false); //추가 : notification의 setContentTitle 안보이게 처리하기
//                channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);

//                잠금화면 알림 설정 (VISIBILITY)
//
//                VISIBILITY_SECRET : 잠금화면 알림을 사용하지 않음
//                VISIBILITY_PRIVATE : 잠금화면 알림은 표시되나, 내용은 표시되지 않음
//                VISIBILITY_PUBLIC : 전체 내용을 잠금화면에 표시
                //channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
                ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

                Notification notification = new androidx.core.app.NotificationCompat.Builder(this, CHANNEL_ID)
                        //.setContentTitle("") //자동표기됨
                        .setContentTitle(context.getResources().getString(R.string.content_txt_45)) //추가
                        .setAutoCancel(false)
                        //.setWhen(System.currentTimeMillis())
                        .setShowWhen(false)
                        //.setLargeIcon(null)
                        .setSmallIcon(getPngImage(level))
                        .setContentIntent(pendingIntent)
                        .setContent(remoteViews)
                        .build();

                notification.flags |= Notification.FLAG_NO_CLEAR; // 지우기 버튼 눌렀을때 지워지지 않게

                startForeground(G_NOTIFICATION_ID, notification);
            }else {
                Notification notification = new Notification.Builder(context)
                        .setAutoCancel(false)
                        //.setTicker(context.getResources().getString(R.string.info_contents_txt_5))
//                .setContentTitle("My notification")
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(getPngImage(level))
                        .setContentIntent(pendingIntent)
                        //.setPriority(Notification.PRIORITY_MAX)  상단위치값인듯,, 제일 앞으로 오게하기
                        .setContent(remoteViews)
                        .build();
                notification.flags |= Notification.FLAG_NO_CLEAR; // 지우기 버튼 눌렀을때 지워지지 않게
                myNotificationManager.notify(NOTI_ENABLE, notification);
            }

        }catch(Exception e){
            //Toast.makeText(getApplicationContext(), R.string.content_txt_100, Toast.LENGTH_LONG).show();
        }

    }    
    
    
}

 

백그라운드 서비스 관련 구글문서

백그라운드 실행제한 : developer.android.com/about/versions/oreo/background

developer.android.com/reference/android/app/Service#startForeground(int,%20android.app.Notification)

 

도움이 되려나?

forum.developer.samsung.com/t/fatal-exception-android-app-remoteserviceexception-context-startforegroundservice-did-not-then-call-service-startforeground/3376

 

Fatal Exception: android.app.RemoteServiceException Context.startForegroundService() did not then call Service.startForeground()

We recently implemented foreground service and on Android 9 (Samsung devices only) some users experience some recurring crashes and we don’t know what’s causing this. Fatal Exception: android.app.RemoteServiceException Context.startForegroundService()

forum.developer.samsung.com

proandroiddev.com/pitfalls-of-a-foreground-service-lifecycle-59f014c6a125

 

Pitfalls of a foreground Service lifecycle

As part of Google Play’s target API level requirement existing apps need to target at least Android 8.0. One of the migration steps is…

proandroiddev.com

stackoverflow.com/questions/20857120/what-is-the-proper-way-to-stop-a-service-running-as-foreground

stackoverflow.com/questions/44425584/context-startforegroundservice-did-not-then-call-service-startforeground

 

나에게 해결책을 달라!!!!4달라!!!

Leave a Reply

error: Content is protected !!