居眠りモードのときに位置情報の更新を取得するための解決策を見つけなければなりません。更新が継続的であるか、5 分以上ごとであるかは問題ではありません。現時点では、LocationListener を含むウェイクロックを取得するフォアグラウンド サービスがあります。アプリもホワイトリストに登録されています。居眠りしているときに私のサービスは強制終了されませんが、GPS 信号は強制終了されます。場所の更新を取得するための解決策が見つかりません。また、AlarmManager.setExactAndAllowWhileIdle を使用してサービスを開始しようとしましたが、サービスは居眠り状態で開始されますが、まだ locationupdates はありません。
ボタンでサービスを開始するMainActivity :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startTrackingServiceButton = (Button) findViewById(R.id.startTrackingServiceButton);
Button stopTrackingServiceButton = (Button) findViewById(R.id.stopTrackingServiceButton);
askForWhitelistingApp();
if (permissionsGranted()) {
startTrackingServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
askForWhitelistingApp();
startTrackUserForegroundService();
//setServiceWithAlarmManager();
}
});
stopTrackingServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopTrackUserForegroundService();
}
});
}else{
ActivityCompat.requestPermissions(this, new String[] {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION },
10);
}
}
private void setServiceWithAlarmManager(){
Intent intent = new Intent(MainActivity.this, TrackUserForegroundService.class);
intent.setAction(TrackUserForegroundService.ACTION_START_FOREGROUND_SERVICE);
PendingIntent pintent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.MINUTE, 40);
calendar.set(Calendar.SECOND, 20);
calendar.set(Calendar.HOUR, 3);
Long time = calendar.getTimeInMillis();
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pintent);
}
private void startTrackUserForegroundService(){
Intent intent = new Intent(MainActivity.this, TrackUserForegroundService.class);
intent.setAction(TrackUserForegroundService.ACTION_START_FOREGROUND_SERVICE);
startService(intent);
}
private void stopTrackUserForegroundService(){
Intent intent = new Intent(MainActivity.this, TrackUserForegroundService.class);
intent.setAction(TrackUserForegroundService.ACTION_STOP_FOREGROUND_SERVICE);
startService(intent);
}
private boolean permissionsGranted() {
return ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED;
}
private void askForWhitelistingApp(){
Intent intent = new Intent();
String packageName = this.getPackageName();
PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
this.startActivity(intent);
}
}
private PowerManager.WakeLock aquireWakelock(){
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock");
return wakeLock;
}
ForegroundService :
@Override
public void onCreate() {
Log.e(TAG, "onCreate");
initializeLocationManager();
try {
mLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "No right permissions", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "Network " + ex.getMessage());
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
Log.i(TAG, "No right permissions", ex);
} catch (IllegalArgumentException ex) {
Log.d(TAG, "Does not have a gps provider" + ex.getMessage());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
String action = intent.getAction();
switch (action){
case ACTION_START_FOREGROUND_SERVICE:
Log.d(TAG, "Start tracking user with foreground service.");
Intent mainActivityIntent = new Intent(this, MainActivity.class);
PendingIntent mainActivityPendingIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel("0", "notification_channel", NotificationManager.IMPORTANCE_DEFAULT);
mChannel.setDescription("Track user service channel");
mChannel.setShowBadge(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(mChannel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "0")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Tracking user")
.setContentText("Track user with foreground")
.setContentInfo("Track user with service")
.setAutoCancel(false)
.setOngoing(true)
.setContentIntent(mainActivityPendingIntent);
Notification notification = builder.build();
startForeground(1, notification);
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock");
wakeLock.acquire();
break;
case ACTION_STOP_FOREGROUND_SERVICE:
wakeLock.release();
stopForeground(true);
break;
}
return START_STICKY;
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
Log.i(TAG, "Exception:", ex);
}
}
}
}
private void stopTrackUserForegroundService()
{
Log.d(TAG, "Stop tracking user with foreground service.");
wakeLock.release();
stopForeground(true);
String hallo = "";
}
TrackUserForegroundService.LocationListener[] mLocationListeners = new TrackUserForegroundService.LocationListener[]{
new TrackUserForegroundService.LocationListener(LocationManager.GPS_PROVIDER),
new TrackUserForegroundService.LocationListener(LocationManager.NETWORK_PROVIDER)
};
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
Log.e(TAG, "LocationListener " + provider);
mLastLocation = new Location(provider);
}
@Override
public void onLocationChanged(Location location) {
Log.e(TAG, "onLocationChanged: " + location);
mLastLocation.set(location);
}
@Override
public void onProviderDisabled(String provider) {
Log.e(TAG, "onProviderDisabled: " + provider);
}
@Override
public void onProviderEnabled(String provider) {
Log.e(TAG, "onProviderEnabled: " + provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.e(TAG, "onStatusChanged: " + provider);
}
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}