Android

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

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{8e56749 u0 com.teset/.ManageService}
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1945)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7356)
       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:930)


 

Service단에서 포그라운드에 올린 후 Noti를 주었음에도 불구하고 발생하였다. 

[오류 원인]
context.startForegroundService()호출 후 5초이내에 startForeground()호출되어야한다. 
문제는 안드로이드 시스템이 이것을 보장하지 않는다는 것이다.!! 
그래서 결론은 startForeground()를 5초이내에 호출하지 못하여 발생된 오류이다.

코드상 문제는 없다.

개발자가 할 수 있는 일은 무엇을까? 
오류에 대비하여 1분뒤 AlarmManager를 사용하여  한 번 더 호출하였다.

Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
    alarmManagerSetting(gContext);
}
}, 60000); //1분뒤 실행


private void alarmManagerSetting(Context context){
  try {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, ServiceAlarmReceiver.class);
    PendingIntent sender =
        PendingIntent.getBroadcast(context, REQUEST_CODE_SERVICE_ALARM_MANAGER, intent, 0);
    long currentTime = System.currentTimeMillis();
    int interval = 10000 * 6 * 30;//30분 간격으로 체크

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) //api level 23 (Marshmallow 6.0)
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, currentTime + interval, sender);
    }
  }catch (Exception e){
    e.printStackTrace();
    Crashlytics.log(“AlarmManager호출 오류n+ e.getMessage() +n+ e.getStackTrace());
  }
}

public class ServiceAlarmReceiver extends BroadcastReceiver
{
  @Override
  public void onReceive(Context context, Intent intent)
  {
    try
    {
         boolean isRunning = isServiceRunningCheck(context);
         if (!isRunning) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    Intent in = new Intent(context, ManageService.class);
                    context.startForegroundService(in);
             } else {
                    Intent in = new Intent(context, ManageService.class);
                    context.startService(in);
             }
         }
     }
     catch (Exception e)
     {
         e.printStackTrace();
     }
}

public boolean isServiceRunningCheck(Context context) {
try {
   ActivityManager manager = (ActivityManager) context.getSystemService(Activity.ACTIVITY_SERVICE);
   for (ActivityManager.RunningServiceInfo rsi : manager.getRunningServices(Integer.MAX_VALUE)) {
   if (“com.test.ManageService”.equals(rsi.service.getClassName())) {   
      return true;
   }
}
   return false;
}catch (Exception e){
   return false;
}
}

이 코드 역시 보장할 수 없지만 AlarmManager를 사용하여 30분 간격으로 계속 호출하여 백그라운드서비스를 동작하게 하려는 시도이다.
반드시 백그라운드 서비스를 실행해야함으로 
지푸라기라도 잡는 심정으로 한 번 더 호출하였다.

Leave a Reply

error: Content is protected !!