2017-11-10 12 views
0

私は場所を頻繁に、1分または2分ごとに送信する必要があるAndroidアプリをやっています。このために、私はJobSchedulerServiceを使用します。私はすでにAndroid N versionのデバイスで15分ごとに1回以上実行するように管理しましたが、.setPeriodic().setMinimumLatency()に置き換えています。実際には、最初は確立された時間に定期的に実行されますが、しばらくしてから約7〜9分ごとに実行されます。停止するまでに1分ごとにJobschedulerまたはServiceを実行するにはどうすればよいですか?

私は既にバッテリー節約ホワイトリストにアプリケーションを含めましたが、動作しませんでした。制限なしで毎分またはそれに類するサービスを実行する方法はありますか?アプリがどれくらいのバッテリーを費やしているかは関係ありません。

EDIT

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); 

} 
} 

また、あなたのBroadcastReceiver

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

あなた Manifest.xmlファイル内 register()方法は2つのことを行い登録してください。

の1-問題WakefulBroadcastReceiverでキャッチし、必要な

2- Serviceが殺害されたかどうかを確認するために呼び出される次のアラームを設定した場合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'は2つの異なるクラスです、そうですか? – 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をごBroadcastReceiverを登録することを忘れないでください:WakefulBroadcastReceiverは、APIレベル26.1.0で廃止されました。 JobSchedulerServiceは仕事をします