2017-11-10 10 views
0

나는 1 분 또는 2 분 간격으로 위치를 자주 전송해야하는 Android 앱을 만들고 있습니다. 이를 위해 JobSchedulerService을 사용합니다. 저는 Android N version으로 .setPeriodic().setMinimumLatency()으로 대체하여 15 분마다 한 번 이상 실행되도록했습니다. 사실 그것은 처음에는 정해진 시간에 주기적으로 실행되지만 잠시 후 약 7 ~ 9 분마다 실행됩니다.멈추지 않을 때마다 Jobscheduler 또는 서비스를 실행하는 방법은 무엇입니까?

배터리 절약 화이트리스트에는 이미 애플리케이션이 포함되어 있지만 작동하지 않았습니다. 아무런 제한없이 매분 또는 유사한 서비스를 실행할 수있는 방법이 있습니까? 앱에서 소비하는 배터리 양은 중요하지 않습니다.

편집는 :

이것은 내가 무엇을 시도했다입니다 :

ReceiverService :

public class ReceiverService extends WakefulBroadcastReceiver { 

@Override 
public void onReceive(Context ctx, Intent intent) { 

    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { 
     if (!isMyServiceRunning(ServiceBackground.class, ctx)) 
      startWakefulService(ctx, new Intent(ctx, ServiceBackground.class)); 

     new ServiceAlarmManager(ctx).register(); 
    } 

} 

private boolean isMyServiceRunning(Class<?> serviceClass,Context context) { 
    ActivityManager manager = (ActivityManager)context. getSystemService(Context.ACTIVITY_SERVICE); 
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
     if (serviceClass.getName().equals(service.service.getClassName())) { 
      Log.i("Service already","running"); 
      return true; 
     } 
    } 
    Log.i("Service not","running"); 
    return false; 
} 

}

ServiceAlarmManager는 @madking 말했듯이 정확히 동일합니다.

+0

이것은 실제로 끔찍한 실행입니다. 기기를 잠자 게 해주세요. – Vyacheslav

+0

당신이 원하는 것은 불가능합니다 –

+0

장치가 충전되기 때문에 그것은 불가능할 수 없습니다. 나는 배터리가 아니라 매분마다 위치를 전송하는 것이 우선입니다. – smartgg

답변

0

당신은 Service에 위치를 전송 코드를 넣어 주기적으로 Service가 실행 중인지 확인하고 Service이 OS에 의해 살해 된 경우 다시 시작합니다 AlarmManager을 구현할 수 있습니다. WakefulBroadcastReceiver을 사용하여 AlarmManager을 구현해야합니다.

ReceiverService.java

public class ReceiverService extends WakefulBroadcastReceiver { 

@Override 
public void onReceive(Context ctx, Intent intent) { 

    if (!YourService.isRunning()) { 
     startWakefulService(ctx, new Intent(ctx, YourService.class)); 
    } 

    new ServiceAlarmManager(ctx).register(); 
} 
} 

ServiceAlarmManager.java

public class ServiceAlarmManager { 

private Context ctx; 
private static final int TIME_INTERVAL = 300 * 1000; 

public ServiceAlarmManager(Context context) { 
    ctx = context; 
} 

public void register() { 

    Intent serviceRestarter = new Intent(); 
    serviceRestarter.setAction("someString"); 

    PendingIntent pendingIntentServiceRestarter = PendingIntent.getBroadcast(ctx, 0, serviceRestarter, 0); 
    AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(ctx.ALARM_SERVICE); 
    Date now = new Date(); 
     alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, now.getTime() + TIME_INTERVAL, pendingIntentServiceRestarter); 

} 
} 

는 또한 등록하여 귀하의 Manifest.xml 파일

<receiver android:name=".ReceiverService"> 
     <intent-filter> 
      <action android:name="someString" /> 
     </intent-filter> 
    </receiver> 

register() 방법은 두 가지 일을에서 BroadcastReceiver.

1 문제 WakefulBroadcastReceiver에 의해 체포하고 다시 시작하는 브로드 캐스팅 Service 필요한

2 다음 알람이 Service 살해되었는지 확인하기 위해 호출 수를 설정합니다.

이렇게하면 OS가 정보를 삭제하더라도 서비스가 계속 실행되므로 주기적으로 위치 업데이트를 보낼 수 있습니다.

참고 : 응용 프로그램에서 배터리를 더 많이 사용하지만 비즈니스 요구 사항에 따라 선택하지 않아도 상관하지 않으므로이 방법은 권장되지 않습니다.

+0

당신의 대답에 감사드립니다! 귀하의 코드를 구현하려고하는데,'.isRunning()'에 대해 모르겠다.'MyService.class' 내부의 Getter입니까? – smartgg

+0

@smartgg 아니요.이 질문의 첫 번째 대답에서 이와 같이 구현해야합니다. https://stackoverflow.com/questions/17588910/check-if-service-is-running-on-android – madking

+0

'Location'과'ServiceAlarmManager'를 검사하는'Service'는 두 개의 다른 클래스입니다, 맞습니까? – smartgg

0

나는 이것을 시도했다 : 당신의 활동의 onCreate()에서 매분 (setAlarm) 동안 알람을 스케쥴한다.매번 경보가 WakefulBroadcastReceiver이라고합니다, 트리거, 그리고 우리가 우리의 서비스 (들) 시작 어디된다

private static long INTERVAL_ALARM = 1 * 60 * 1000; 

public static void setAlarm(Context context) { 
    long current_time = Calendar.getInstance().getTimeInMillis(); 
    Intent myAlarm = new Intent(context.getApplicationContext(), AlarmReceiver.class); 
    PendingIntent recurringAlarm = PendingIntent.getBroadcast(context.getApplicationContext(), 0, myAlarm, PendingIntent.FLAG_CANCEL_CURRENT); 
    AlarmManager alarms = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
    alarms.setRepeating(AlarmManager.RTC_WAKEUP, current_time, INTERVAL_ALARM, recurringAlarm); 
} 

을 그리고 수신기 :

public class AlarmReceiver extends WakefulBroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
     Intent myService = new Intent(context, MyService.class); 
     context.startService(myService); 
    } 

} 서비스에

, 당신 치료가 끝나면 StopSeflf()를해야합니다.

은 Manifest.xml 파일에

NB 당신의 브로드 캐스트 리시버를 등록하는 것을 잊지 마세요 : WakefulBroadcastReceiver는 API 레벨 26.1.0에서 더 이상 사용되지 않습니다. JobSchedulerService가 작업을 수행합니다.