我想运行Foreground Service
,无论应用是关闭还是打开10秒。经过10秒钟后,Foreground Service
应该被销毁,并在5分钟后再次调用。我找到的Foreground Service
找到了用户的位置,然后将其保存到SQLite
数据库中。因此,基本上我想每5分钟存储一次新坐标,以便可以减少电池消耗。
我的服务等级:
public class LocationService extends Service{
private final static int UPDATE_TIME = 10000;
private final static int UPDATE_DISTANCE = 0;
private LocationListener locationListener;
private LocationManager locationManager;
private PowerManager.WakeLock mWakeLock;
private String latitude, longitude;
private DatabaseHelper myDb;
@Override
public void onCreate() {
super.onCreate();
myDb = new DatabaseHelper(this);
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
createWakeLock(); //Creates a wakelock
createNotification(); //Creates a notification if SDK version is > 26
}
@SuppressLint("MissingPermission")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mWakeLock.acquire(10*60*500L /*5 minutes*/);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.d("Location", "Updated");
getCoordinates(location); //Gets coordinates
insertCoordinates(latitude, longitude); //Sends coordinates to SQLite database
sendDataToMainActivity(latitude, longitude); //Sends coordinates to MainActivity
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, UPDATE_TIME, UPDATE_DISTANCE, locationListener);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "Destroyed");
if(locationManager != null)
locationManager.removeUpdates(locationListener);
mWakeLock.release();
}
private void createWakeLock() {
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
if(pm != null)
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "myApp:myWakeLock");
}
private void createNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Service")
.setContentText("Coordinates Location Running")
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
}
private void getCoordinates(Location location) {
this.latitude = String.valueOf(location.getLatitude());
this.longitude = String.valueOf(location.getLongitude());
}
private void insertCoordinates(String latitude, String longitude) {
boolean inserted = myDb.insertData(latitude, longitude); //Insert coordinates
//Check if insertion is completed
if(inserted)
Toast.makeText(LocationService.this, "Coordinates Inserted", Toast.LENGTH_SHORT).show();
else
Toast.makeText(LocationService.this, "Coordinates Not Inserted", Toast.LENGTH_SHORT).show();
}
private void sendDataToMainActivity(String latitude, String longitude) {
Intent i = new Intent("location_update");
i.putExtra("latitude", latitude);
i.putExtra("longitude",longitude);
sendBroadcast(i);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
答案 0 :(得分:1)
使用融合位置Api请求位置更新,这将在指定的重复间隔(给定5分钟)内触发待处理的意图(假设启动了一个意图服务)。因此融合位置Api每5分钟读取一次位置并将其发送一次到意向服务,从那里您可以进行处理。
有关更多详细信息,请参阅this。
答案 1 :(得分:0)
您可以使用警报管理器设置确切的警报,在警报的接收功能中启动服务,比设置下一个警报运行前台服务5分钟
答案 2 :(得分:0)
由于电源管理限制,“融合位置Api”可能无法在后台运行。 您应该使用警报管理器,但最新的android版本中有一些limitations。有关DOZE here
的更多信息 AlarmManager alarm =
(AlarmManager)getSystemService(Context.ALARM_SERVICE);
if (alarm == null) return; // for instant apps
Intent intent = new Intent(this, MyBroadcastReceiver.class)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerInMillis,
PendingIntent.getBroadcast(this, intent, PendingIntent.FLAG_UPDATE_CURRENT));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AlarmManager.AlarmClockInfo ac=
new AlarmManager.AlarmClockInfo(triggerInMillis, null);
alarm.setAlarmClock(ac, PendingIntent.getBroadcast(this, intent, PendingIntent.FLAG_UPDATE_CURRENT));
} else {
alarm.setExact(AlarmManager.RTC_WAKEUP, triggerInMillis,
PendingIntent.getBroadcast(this, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}