Android 服务未更新位置

and*_*dXP 1 java service android location android-fusedlocation

我需要每 1 分钟和每 5 米位移更新一次融合位置(我知道这是不好的做法,但为了测试和显示在 Log 中),我通过按钮开始服务按下按钮后立即按下我在 logcat 中找到位置但是只有一次。根据服务类onLocationChanged应每 1 分钟调用一次,但即使我的 GPS 几乎每分钟打开一次,然后在一段时间后关闭,它也不会再次调用,但 Logcat 中仍然没有位置更新。我需要服务类来保持更新位置而不影响UI 或主线程

这是 logcat 只显示一次位置更新

09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service onConnected Calling
09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Start Location Update is Calling
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service OnLocationChanged Calling
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Here is Updated Locations: Latitude 28.5XXXXX Longitude 77.2XXXXX
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Sending Location Starting  Accuracy is: 37.5
Run Code Online (Sandbox Code Playgroud)

这是我的服务类

public class Location_Service_background extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    public static final String TAG = "===Location Service===";
    GoogleApiClient apiClient;
    Location mCurrentLocation;
    LocationRequest locationRequest;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        GoogleApiSetup();
        RequestLocationUpdates();
        Log.d(TAG,"OnStartCommand Is Calling ");
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }



    @Override
    public void onCreate() {
        super.onCreate();

    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        if (apiClient.isConnected()){
            Log.d(TAG,"Service On Destroy Calling and apiClient is Connected");
            StopLocationUpdates();
            apiClient.disconnect();
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d(TAG,"Service onConnected Calling");
        if (mCurrentLocation != null) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
             mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient);

        }
        else {
            Log.d(TAG,"Start Location Update is Calling");
            StartLocationUpdate();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG,"Service OnConnectionSuspended Calling");
        apiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG,"Service OnLocationChanged Calling");
        mCurrentLocation=location;
        Log.d(TAG,"Here is Updated Locations: Latitude "+mCurrentLocation.getLatitude()+"Longitude "+mCurrentLocation.getLongitude());
        String Latitude= String.valueOf(mCurrentLocation.getLatitude());
        String Longitude=String.valueOf(mCurrentLocation.getLongitude());
        String Accuracy=String.valueOf(mCurrentLocation.getAccuracy());
        Log.d(TAG,"Sending Location Starting"+" "+" Accuracy is: "+mCurrentLocation.getAccuracy());


    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d(TAG,"Connection Failed Called "+connectionResult);
    }



    private synchronized  void GoogleApiSetup() {
        apiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        apiClient.connect();
    }

    private void RequestLocationUpdates() {
        locationRequest = new LocationRequest();
        //1 Min = 60 seconds AND 1000 milliseconds in 1 second
        locationRequest.setInterval(60 * 1000);//5 Min 300 x 1000=300000
        locationRequest.setFastestInterval(60 * 1000);//2 Min
        locationRequest.setSmallestDisplacement(5);
        locationRequest.setMaxWaitTime(60*1000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    private void StopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this);
    }

    private void StartLocationUpdate() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            return;
        }
        if (apiClient.isConnected()) {
            LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this);
        }
        else {
            Log.d(TAG,"GoogleApiClient is not connected yet.Please Try Again");
            apiClient.connect();
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

RH2*_*201 6

希望这有助于避免我在这个问题上遇到的挫折。我正在使用 FusedLocationAPI 来请求位置更新和 GoogleApiClient。我也从服务中做到这一点。

您不会在定时间隔内获得任何位置更新,因为 setSmallestDisplacement() 绝对优先于其他参数。所以即使你有

locationRequestTimeInterval = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setInterval(1)    
    .setFastestInterval(1)    
    .setMaxWaitTime(1)    
    .setSmallestDisplacement(5);
Run Code Online (Sandbox Code Playgroud)

在满足smallestDisplacement 参数之前,这永远不会被触发。

对此的解决方案是创建两个单独的 LocationRequests...一个只与距离有关,一个只与时间有关,并使用您的单个 GoogleApiClient 创建 2 个 requestLocationUpdates 命令,一个使用 Time LocationRequest,以及其他使用距离位置请求。

所以你的 2 LocationRequests 看起来像这样:

locationRequestDistanceInterval = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setFastestInterval(0) // This MUST be set, otherwise no updates
            .setSmallestDisplacement(LOCATION_REQUEST_MIN_DISTNACE);

locationRequestTimeInterval = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL)
            .setFastestInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL);
Run Code Online (Sandbox Code Playgroud)
  • 请注意,必须在距离请求上设置 setFastestInterval() 值,否则将不会触发距离请求。它不必为 0,但必须设置此字段。

然后在您的 GoogleApiClients onConnected() 中,您可以添加两个 requestLocationUpdates() 调用。

LocationServices.FusedLocationApi.requestLocationUpdates(
    mLocationClient, 
    locationRequestDistanceInterval, 
    new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            // Handle your Distance based updates
        }
    }
);

LocationServices.FusedLocationApi.requestLocationUpdates(
    mLocationClient, 
    locationRequestTimeInterval, 
    new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            // Handle your Time based updates
        }
    }
);  
Run Code Online (Sandbox Code Playgroud)

您可以使用相同或不同的 LocationListeners 来处理每个请求的响应。希望这可以帮助。