在打盹模式下,我必须找到一种解决方案来获取位置更新。更新是连续的还是每 5 分钟或更长时间都没有关系。目前我有一个前台服务,它获取一个带有 LocationListener 的唤醒锁。该应用程序也被列入白名单。我的服务在打瞌睡时不会被杀死,但 gps 信号会。我找不到获取位置更新的解决方案。我还尝试使用 AlarmManager.setExactAndAllowWhileIdle 启动服务,服务以打瞌睡状态启动,但仍然没有位置更新。
使用按钮启动服务的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;
}
前台服务:
@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);
}
}