Android 奥利奥:如何从后台捕捉位置更新?

Android 奥利奥:如何从后台捕捉位置更新?,android,android-service,android-location,android-8.0-oreo,android-fusedlocation,Android,Android Service,Android Location,Android 8.0 Oreo,Android Fusedlocation,我将我的应用程序迁移到oreo(正如google play now所要求的那样),现在启动手机时出现了一个错误: 不允许启动服务意图 我的应用程序正在后台监听任何位置更新,并定期将抓取的位置发送到服务器。为此,我愿意: 在AndroidManifest.xml <receiver android:name="com.myapp.StartServiceBroadcastReceiver"> <intent-filter> <actio

我将我的应用程序迁移到oreo(正如google play now所要求的那样),现在启动手机时出现了一个错误:

不允许启动服务意图

我的应用程序正在后台监听任何位置更新,并定期将抓取的位置发送到服务器。为此,我愿意:

AndroidManifest.xml

  <receiver android:name="com.myapp.StartServiceBroadcastReceiver">  
    <intent-filter>  
      <action android:name="android.intent.action.BOOT_COMPLETED" />  
    </intent-filter>  
  </receiver> 
而LocationService基本上可以做到:

public void onCreate() {

  mLocationServices.setListener(this);
  mLocationServices.startLocationUpdates(true, // startWithLastKnownLocation,

                                         150000, // interval => 2.5 min  // Set the desired interval for active location updates, in milliseconds.
                                                                         // The location client will actively try to obtain location updates for your
                                                                         // application at this interval, so it has a direct influence on the amount
                                                                         // of power used by your application. Choose your interval wisely.

                                         30000, // fastestInterval => 30 s  // Explicitly set the fastest interval for location updates, in milliseconds.
                                                                            // This controls the fastest rate at which your application will receive location updates, which might be faster than setInterval(long)
                                                                            // in some situations (for example, if other applications are triggering location updates).
                                                                            // This allows your application to passively acquire locations at a rate faster than it actively acquires locations, saving power.

                                         900000, // maxWaitTime => 15 min  // Sets the maximum wait time in milliseconds for location updates.
                                                                           // If you pass a value at least 2x larger than the interval specified with setInterval(long), then location
                                                                           // delivery may be delayed and multiple locations can be delivered at once. Locations are determined at
                                                                           // the setInterval(long) rate, but can be delivered in batch after the interval you set in this method.
                                                                           // This can consume less battery and give more accurate locations, depending on the device's hardware
                                                                           // capabilities. You should set this value to be as large as possible for your needs if you don't
                                                                           // need immediate location delivery.

                                         LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, // priority => Block level accuracy is considered to be about 100 meter accuracy.
                                                                                           //             Using a coarse accuracy such as this often consumes less power.

                                         25); // smallestDisplacement => 25 meters // Set the minimum displacement between location updates in meters  


}

@Override
public void onLocationChanged(Location location) {
   ....
}

在oreo之前一切都很好,但现在在oreo+上失败了。我能做些什么来让我的服务运行?

从Android Oreo开始,你不能简单地

您可以像这样作为前台服务启动服务(Kotlin,但在Java中类似):

在您的服务中,请确保您尽快致电。这还将发出通知,以便用户知道您的应用程序在后台处于活动状态

正如在评论中指出的那样,您可能也会受到影响


有一个关于Oreo的背景解释限制的问题。

从Android Oreo开始,你不能简单地

您可以像这样作为前台服务启动服务(Kotlin,但在Java中类似):

在您的服务中,请确保您尽快致电。这还将发出通知,以便用户知道您的应用程序在后台处于活动状态

正如在评论中指出的那样,您可能也会受到影响



关于Oreo的后台执行限制有很多问题。

您是否尝试过
startForegroundService()
使用前台服务就是其中之一solution@NileshRathodstartForegroundService和startService到底有什么区别?@Redman同样的问题,使用前台服务意味着什么?可能重复:您是否尝试过使用前台服务solution@NileshRathodstartForegroundService和startService之间到底有什么区别?@Redman同样的问题,使用前台服务意味着什么?可能重复:谢谢markus,但在前台启动服务真正意味着什么呢?后台服务之间的区别是什么?@loki,基本上它意味着用户可以注意到该服务(它显示一个通知),并且即使用户没有积极使用该应用程序,该服务也可以运行。另请参见。@MarkusPenguin。。不,不可能全天向用户显示通知:(他们还有其他方法吗?@loki从Android Oreo开始需要这样做。你不可能让你的应用程序在后台永久运行而不被用户注意。如果你不想有一个持久的通知,你可以-但这当然取决于你的使用情况。@MarkusPenguin-这样其他应用程序如何抓取位置更新?正如我所看到的,它们都没有持久性通知…谢谢markus,但在前台启动服务的真正含义是什么?后台服务之间的区别是什么?@loki,基本上这意味着用户可以注意到该服务(它显示一个通知)即使用户未积极使用该应用程序,它也可以运行。另请参见。@MarkusPenguin..no不可能在全天向用户显示通知:(他们还有其他方法吗?@loki从Android Oreo开始需要这样做。你不可能让你的应用程序在后台永久运行而不被用户注意。如果你不想有一个持久的通知,你可以-但这当然取决于你的使用情况。@MarkusPenguin-这样其他应用程序如何抓取位置更新?没有一个像我看到的那样有持久通知。。。
public void onCreate() {

  mLocationServices.setListener(this);
  mLocationServices.startLocationUpdates(true, // startWithLastKnownLocation,

                                         150000, // interval => 2.5 min  // Set the desired interval for active location updates, in milliseconds.
                                                                         // The location client will actively try to obtain location updates for your
                                                                         // application at this interval, so it has a direct influence on the amount
                                                                         // of power used by your application. Choose your interval wisely.

                                         30000, // fastestInterval => 30 s  // Explicitly set the fastest interval for location updates, in milliseconds.
                                                                            // This controls the fastest rate at which your application will receive location updates, which might be faster than setInterval(long)
                                                                            // in some situations (for example, if other applications are triggering location updates).
                                                                            // This allows your application to passively acquire locations at a rate faster than it actively acquires locations, saving power.

                                         900000, // maxWaitTime => 15 min  // Sets the maximum wait time in milliseconds for location updates.
                                                                           // If you pass a value at least 2x larger than the interval specified with setInterval(long), then location
                                                                           // delivery may be delayed and multiple locations can be delivered at once. Locations are determined at
                                                                           // the setInterval(long) rate, but can be delivered in batch after the interval you set in this method.
                                                                           // This can consume less battery and give more accurate locations, depending on the device's hardware
                                                                           // capabilities. You should set this value to be as large as possible for your needs if you don't
                                                                           // need immediate location delivery.

                                         LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, // priority => Block level accuracy is considered to be about 100 meter accuracy.
                                                                                           //             Using a coarse accuracy such as this often consumes less power.

                                         25); // smallestDisplacement => 25 meters // Set the minimum displacement between location updates in meters  


}

@Override
public void onLocationChanged(Location location) {
   ....
}
val serviceIntent = Intent(context, LocationService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(serviceIntent)
} else {
    context.startService(serviceIntent)
}