Starting from Android 8.0, in order to reduce power consumption, the system has restricted the frequency of backend applications to obtain user location information. Only a few updates are allowed per hour. For details, please refer to the official description. According to official guidelines, if you want to increase the frequency of location updates, the backend application needs to provide a front-end service notification.
Therefore, the original location simply using locationManager cannot be used in the background. So I plan to use a foreground service, and can also get the current location when the app is in the background.
I checked several blogs and said that the front-end service needs to call startForeground(int, Notification) in the onStartCommand method of the service to enable the foreground service.
However, onStartCommand needs to go through the life cycle of startservice() before it will be called.
I used bindservice() instead, which just needs activity and service interaction. Of course, the two startup methods can be mixed. But it is not necessary.
All I need is the service bound to the control and I don't want to handle the end of the service.
1. Activity/fragment call bind service
Intent serviceIntent = new Intent(this, ); bindService(serviceIntent, conn, Service.BIND_AUTO_CREATE); // When binding a service, you need to pass an object of the ServiceConnection implementation class.// When binding a service, the onBind method of the service will be triggered. This method will return an Ibinder object to the onServiceConnected() of activity/fragment. Through this object, you can access the methods in the service ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { } };
2. I called startForeground(int, Notification) in the onBind() method
The first parameter is a positive integer that is not 0, which represents the id of the notification, and the second parameter represents the notification that needs to be displayed.
The notification build needs to be adapted to 8.0, otherwise your notification will not be displayed (I thought it was OnePlus that blocked the notification when it was called for the first time)
3. At this time, the front-end service should have been implemented, and the location information obtained by the service needs to be passed to the activity. (You can get it by calling the locationmanager directly, and the location is hidden here)
public class MyBinder extends Binder { public ForegroundLocationService getService(){ return ; } } //Implement communication between the caller client and Service through binder private MyBinder binder = new MyBinder(); //Return the MyBinder object we instantiated through the service onBind() method, which can obtain the current Service @Override public IBinder onBind(Intent arg0) { NotificationUtils notificationUtils = new NotificationUtils(this); startForeground(111, ("Notice", "Continuous positioning",null)); return binder; }
4. Then, the controls and services need to interact, and here are divided into three methods.
- When the service is obtained, the act actively calls the data
- Set a callback in the service, and the service actively passes data to the act
- Pass data through broadcast.
ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //This method can get the service instance, and the callback can be continuously updated ForegroundLocationService foregroundLocationService = (() service).getService(); (new () { @Override public void onLocation(Location location) { } }); } };
Write the interface in the service and call it in the callback method that gets the location.
public interface LocationCallback { /** * Current location */ void onLocation(Location location); } private LocationCallback mLocationCallback; private class LocationListener implements { public LocationListener(String provider) { (TAG, "LocationListener " + provider); } @Override public void onLocationChanged(Location location) { ("location", "onLocationChanged: " + "Current coordinates:" + () + " : " + ()); if(mLocationCallback!=null){ (location); } } }
Service sends messages to Activity, and can use broadcasting. Of course, Activity needs to register the corresponding receiver. For example, if the Service wants to send the same message to multiple activities, it would be even better to use this method, and it will be omitted here. For details, please refer to the article below.
Reference article:https:///article/
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.