android - 即使 GPS 关闭,如何使用融合位置 API 获取位置更新?

标签 android gps google-play-services fusedlocationproviderapi

这个问题可能被问了很多次,但我找不到任何解决方案。 我需要在后台获取用户位置 15 分钟。

当 GPS 打开时,它工作正常,但当 GPS 关闭时,应用程序无法获取位置更新。我需要它至少获取网络位置或 WiFi 位置。

如何使用融合位置 API 实现此目的?

位置管理器具有此功能,但位于融合位置。因为 Google 建议开发人员使用播放服务 API 中的位置,所以我不想使用位置管理器。 我怎样才能实现这一目标,所以让我发布我迄今为止尝试过的内容:

import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

/**
 * Created by 4264 on 14-10-2016.
 */

public class Locationlistener implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener  {


    private Location mlocation; // location
    private double latitude; // latitude
    private double longitude; // longitude
    private GoogleApiClient mGAC;
    private Context mContext;
    public static final String TAG = "GPSresource";
    private FusedLocationProviderApi fusedLocationProviderApi;
    private LocationRequest locationRequest;

    public Locationlistener(Context c)
    {
        mContext = c;
        try {
            buildGoogleApiClient();
            mGAC.connect();
        }
        catch(Exception e)
        {
            Log.d(TAG,e.toString());
        }
    }

    protected synchronized void buildGoogleApiClient() {
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
        locationRequest.setInterval(1);
        locationRequest.setFastestInterval(1);
        mGAC = new GoogleApiClient.Builder(mContext)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
       }


    public double getLatitude(){
        if(mlocation != null){
            latitude = mlocation.getLatitude();
        }

        // return latitude
        return latitude;
    }

    /**
     * Function to get longitude
     * */
    public double getLongitude() {
        if (mlocation != null) {
            longitude = mlocation.getLongitude();
        }

        // return longitude
        return longitude;
    }

    public Location GetLocationBlocking() throws InterruptedException {



        //      String lat=String.valueOf(moCurrentLocation.getLatitude());
        //    String longt=String.valueOf(moCurrentLocation.getLongitude());
//        Toast.makeText(oContext,"Lat"+lat+"long"+longt,Toast.LENGTH_SHORT).show();
        return mlocation;

    }


    @Override
    public void onConnected(Bundle bundle) {
            Location oLocation = LocationServices.FusedLocationApi.getLastLocation(mGAC);
            if (mGAC != null) {

                mlocation = oLocation;
            getLatitude();
            getLongitude();
            if (oLocation != null){
              Log.d("lat",String.valueOf(mlocation.getLatitude()));
            Log.d("long",String.valueOf(mlocation.getLongitude()));
            }
            else{
                LocationServices.FusedLocationApi.requestLocationUpdates(mGAC, locationRequest, this);
        }   }}


    @Override
    public void onConnectionSuspended(int i) {

    }




    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {
        mlocation=location;
    }
}

最佳答案

我不明白你说你不想使用位置管理器和 GPS...看看这个 Location Strategies ...基于此文档,我们有 3 种访问位置的策略:

  1. 全局定位系统
  2. 网络位置提供商
  3. 或同时使用

但对于您的位置问题,这是我的报价: 在 Activity 中,输入以下内容以连接并开始接收位置更新:

private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;

private long UPDATE_INTERVAL = 10 * 1000;  /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Create the location client to start receiving updates
    mGoogleApiClient = new GoogleApiClient.Builder(this)
                          .addApi(LocationServices.API)
                          .addConnectionCallbacks(this)
                          .addOnConnectionFailedListener(this).build();
}

protected void onStart() {
    super.onStart();
    // Connect the client.
    mGoogleApiClient.connect();
}

protected void onStop() {
    // Disconnecting the client invalidates it.
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

    // only stop if it's connected, otherwise we crash
    if (mGoogleApiClient != null) {
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

public void onConnected(Bundle dataBundle) {
    // Get last known recent location. 
    Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    // Note that this can be NULL if last location isn't already known.
    if (mCurrentLocation != null) {
      // Print current location if not null
      Log.d("DEBUG", "current location: " + mCurrentLocation.toString());
      LatLng latLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
    }
    // Begin polling for new location updates.
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {
    if (i == CAUSE_SERVICE_DISCONNECTED) {
      Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
    } else if (i == CAUSE_NETWORK_LOST) {
      Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
    }
}

// Trigger new location updates at interval
protected void startLocationUpdates() {
    // Create the location request
    mLocationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setInterval(UPDATE_INTERVAL)
        .setFastestInterval(FASTEST_INTERVAL);
    // Request location updates
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
        mLocationRequest, this);
}

然后使用 onLocationChanged 注册位置更新:

public void onLocationChanged(Location location) {
    // New location has now been determined
    String msg = "Updated Location: " +
        Double.toString(location.getLatitude()) + "," +
        Double.toString(location.getLongitude());
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    // You can now create a LatLng Object for use with maps
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}

有关 Fused Location API 的更多信息,请参阅 Make ypur app Location Aware 位置更新问题排查

位置更新应始终使用 GoogleApiClient 利用 LocationServices.API 完成,如上所示。不要使用较旧的位置 API,它们的可靠性要差得多。即使使用正确的 FusedLocationApi,也有很多事情可能会出错。考虑以下潜在问题:

  • 您是否添加了必要的权限?确保您的应用拥有 INTERNETACCESS_COARSE_LOCATION 权限,以确保 可以按照上面指南中的说明访问位置。
  • 调用时是否返回 null LocationServices.FusedLocationApi.getLastLocation 这是正常现象 因为此方法仅在已有位置时返回 最近被另一个应用程序检索到。如果返回 null,则此 意味着您需要开始接收位置更新 LocationServices.FusedLocationApi.requestLocationUpdates 之前 接收如上所示的位置。
  • 您是否尝试获取 genymotion 模拟器的位置?确保 您已启用 GPS 并正确配置了纬度/经度。尝试重新启动 如果需要,模拟器并重新启用 GPS 或尝试设备(或 官方模拟器)来排除 genymotion 特定问题。

关于android - 即使 GPS 关闭,如何使用融合位置 API 获取位置更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40055001/

相关文章:

android - 如何将另一个 View 膨胀到 LinearLayout 中?

Android多个屏幕尺寸具有相同的密度

android - 伪造/模拟 Google Play 服务

android - libGDX Google Play 游戏服务 - Android

c# - 从 USB-GPS-Receiver 读取数据

android - 如何正确调用 Service 中的 startIntentSenderForResult?

android - 如何为android打包sapui5应用程序?

android - Android Firebase 的每个 Activity 是否都需要添加一个 AuthStateListener?

ios - CLLocation altitude 属性在飞行中的有效性

Android 运行时 GPS 位置 - 黑莓设备 - 不工作