融合位置提供商似乎没有使用GPS接收器

cja*_*cja 39 gps android geolocation google-play-services

适用于Moto G的Android 4.3,适用于Nexus 7的Android 4.4.2,适用于Nexus 5的Android 4.4.2.Android Studio 0.4.

我不想接收定期的位置更新,我只想在用户按下按钮时获得准确的位置.

我已经按照这个例子:https://developer.android.com/training/location/retrieve-current.html

在清单文件中:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Run Code Online (Sandbox Code Playgroud)

我使用GooglePlayServicesUtil.isGooglePlayServicesAvailable检查Play服务是否可用

在主要活动中:

//in activity onCreate method
mLocationClient = new LocationClient(this, this, this);

@Override
protected void onStart() {
    mLocationClient.connect();
    super.onStart();
}

@Override
protected void onStop() {
    mLocationClient.disconnect();
    super.onStop();
}

//in button onclick method    
mCurrentLocation = mLocationClient.getLastLocation();
Run Code Online (Sandbox Code Playgroud)

我没有SIM卡.如果我启用Wifi,有时我会得到一个准确的位置.其他时候mCurrentLocation为null.

如果我禁用Wifi,则mCurrentLocation始终为null.

我正在几个地方的外面进行测试,总能清楚地看到天空.我在每个地方等了三分钟.

我从未在屏幕顶部的Android通知栏上看到GPS图标.

我有这些位置设置: 在此输入图像描述

GPS测试应用程序设法在同一设备上成功使用GPS,并禁用Wi-Fi,因此GPS正在工作: 在此输入图像描述

注册位置更新,如https://developer.android.com/training/location/receive-location-updates.html,也不起作用.注册方法从未调用.

我究竟做错了什么?

cja*_*cja 16

我解决了 问题是"让Google应用访问您的位置"已关闭: 在此输入图像描述

当我打开它时,我得到GPS读数,当它关闭时,我没有.

我把它关掉了有两个原因:

  1. 我正在开发一个应用程序,用于公司的许多设备,我想要最少的手动配置

  2. 屏幕上显示"此设置仅影响Google应用".我知道Play Services是谷歌软件,但我认为谷歌不希望最终用户理解这一点.

然后我获得了Android 4.4.2更新,并且位置设置页面已更改.看来我可以关闭谷歌位置报告,并仍然从融合的位置提供商获得GPS读数: 在此输入图像描述

因此,也许谷歌意识到这种设置令人困惑并改进了它.无论哪种方式,如果我几天前得到4.4.2,我会节省很多时间.


Sar*_*ran 15

问题在于getLastLocation()因为它使用了缓存的位置.我遇到了同样的问题,我也尝试使用这种简单的方法.因为,我已经切换到收听更新(并在第一次成功更新后自动停止).

这是我的代码有效.

首先,检查应用程序中的可用性(不是必需的,可以在Activity中而不保留结果):

public class MainApp extends Application {
  public static enum PlayServices {
    NOT_CHECKED, AVAILABLE, UNAVAILABLE
  };
  public static PlayServices mPlayServices = PlayServices.NOT_CHECKED;

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

    if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
      MainApp.mPlayServices = MainApp.PlayServices.AVAILABLE;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,进入活动:

public class MainActivity extends SherlockFragmentActivity implements
  GooglePlayServicesClient.ConnectionCallbacks,
  GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {
Run Code Online (Sandbox Code Playgroud)

在其中onCreate():

if (MainApp.mPlayServices != MainApp.PlayServices.UNAVAILABLE) {
  mLocationClient = new LocationClient(this, this, this);

  mLocationRequest = LocationRequest.create();
  mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  mLocationRequest.setInterval(5000);
  mLocationRequest.setNumUpdates(1);
  mLocationRequest.setFastestInterval(1000);

  mUpdatesRequested = false;
  MainApp.prefs.edit().putBoolean(MainApp.KEY_LOCATION_UPDATES_REQUESTED, mUpdatesRequested)
      .commit();
}
Run Code Online (Sandbox Code Playgroud)

MainActivity课程的其余部分:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  Log.d(this.getClass().getSimpleName(), "onActivityResult(" + requestCode + ", " + resultCode
      + ")");
  // Decide what to do based on the original request code
  switch (requestCode) {
    case MainApp.PLAY_CONNECTION_FAILURE_RESOLUTION_REQUEST:
      /*
       * If the result code is Activity.RESULT_OK, try
       * to connect again
       */
      switch (resultCode) {
        case Activity.RESULT_OK:
          // here we want to initiate location requests!
          mLocationClient = new LocationClient(this, this, this);

          break;
      }
      break;
  }
}

@Override
public void onConnected(Bundle dataBundle) {
  Log.d(this.getClass().getSimpleName(), "onConnected()");

  Log.d(this.getClass().getSimpleName(), "Google Play Services are available.");
  MainApp.mPlayServices = MainApp.PlayServices.AVAILABLE;

  if (!mUpdatesRequested) {

    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    boolean gps_enabled = false;
    try {
      gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
    }

    boolean network_enabled = false;
    try {
      network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
    }

    // don't start listeners if no provider is enabled
    MainApp.locEnabled = gps_enabled || network_enabled;

    if (!MainApp.locEnabled) {
      // we have access to PlayServices, but user has disabled location visibility --> alert him
      alertLocationOff();
    } else {
      mLocationClient.requestLocationUpdates(mLocationRequest, this);
      mUpdatesRequested = true;
    }
  }
}

@Override
public void onDisconnected() {
  Log.d(this.getClass().getSimpleName(), "onDisconnected()");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
  Log.d(this.getClass().getSimpleName(), "onConnectionFailed()");

  Log.d(this.getClass().getSimpleName(), "Google Play Services not available.");
  MainApp.mPlayServices = MainApp.PlayServices.UNAVAILABLE;

  /*
   * Google Play services can resolve some errors it detects.
   * If the error has a resolution, try sending an Intent to
   * start a Google Play services activity that can resolve
   * error.
   */
  if (connectionResult.hasResolution()) {
    try {
      // Start an Activity that tries to resolve the error
      connectionResult.startResolutionForResult(this,
          MainApp.PLAY_CONNECTION_FAILURE_RESOLUTION_REQUEST);
      /*
       * Thrown if Google Play services canceled the original
       * PendingIntent
       */
    } catch (IntentSender.SendIntentException e) {
      // Log the error
      e.printStackTrace();
    }
  } else {
    /*
     * If no resolution is available, display a dialog to the
     * user with the error.
     */
    GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show();
  }
}

@SuppressLint("NewApi")
@Override
public void onLocationChanged(Location location) {
  Log.d(this.getClass().getSimpleName(), "onLocationChanged(), location=" + location);

  if (location != null) {
    boolean present = true;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
      present = Geocoder.isPresent();
    }

    if (present) {
      (new ExtractLocationTask(this)).execute(location);
    } else {
      Log.e(this.getClass().getSimpleName(), "Geocoder not present");
      MainApp.mPlayServices = MainApp.PlayServices.UNAVAILABLE;
    }
  }
}


private class ExtractLocationTask extends AsyncTask<Location, Void, Boolean> {
  Context mContext;

  public ExtractLocationTask(Context context) {
    super();
    mContext = context;
  }

  @Override
  protected Boolean doInBackground(Location... params) {
    Log.d(getClass().getSimpleName(), "ExtractLocationTask.onPreExecute()");

    boolean found = false;
    try {
      Geocoder geoCoder_local = new Geocoder(mContext, Locale.getDefault());
      Geocoder geoCoder_en = new Geocoder(mContext, Locale.ENGLISH);

      List<Address> addresses_local = geoCoder_local.getFromLocation(params[0].getLatitude(),
          params[0].getLongitude(), 10);
      List<Address> addresses_en = geoCoder_en.getFromLocation(params[0].getLatitude(),
          params[0].getLongitude(), 10);

      if (addresses_local != null && addresses_local.size() > 0) {

        // do what you want with location info here

        // based on mLocationRequest.setNumUpdates(1), no need to call
        // removeLocationUpdates()

        MainApp.locEnabled = true;

        mUpdatesRequested = false;
        MainApp.prefs.edit()
            .putBoolean(MainApp.KEY_LOCATION_UPDATES_REQUESTED, mUpdatesRequested).commit();

        found = true;
      }
    } catch (IOException e) {
      Log.e(this.getClass().getSimpleName(), "Exception: ", e);
    }

    return found;
  }

  @Override
  protected void onPostExecute(Boolean found) {
    Log.d(getClass().getSimpleName(), "ExtractLocationTask.onPostExecute()");

    if (found) {
      // update UI etc.
    } else if (!mUpdatesReRequested) {
      mLocationClient.requestLocationUpdates(mLocationRequest, (LocationListener) mContext);
      mUpdatesRequested = true;
      mUpdatesReRequested = true;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望这能帮助你实现它!

  • 顺便说一句.来自**FusedLocation源代码**(https://android.googlesource.com/platform/frameworks/base/+/6fa9ad4afcd762aea519ff61811386c23d18ddb2/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java)你可以看到他们以相同的方式使用LocationManager(使用`isProviderEnabled()`)来检查GPS和网络的可用性. (7认同)
  • LocationManager.isProviderEnabled是否与融合位置提供程序一起使用? (3认同)
  • Google Play位置服务仍然存在很多问题.有时它不会检测到位置并且需要很长时间.但是,旧技术为您提供比Google Play定位服务API更快的位置.如果有人想要遇到此问题,只需观察每当您的MAP应用程序同时显示"等待位置"时,使用旧的定位技术运行您的示例应用程序.旧的一个返回非常快的结果播放位置服务. (3认同)
  • 感谢您确认LocationManager用法 (2认同)

And*_*rew 5

位置提供商不会唤醒 GPS,直到某些客户端请求(订阅)高精度位置(如其他用户给出的示例中所述)。GPS 测试应用程序不使用位置提供程序,而是使用旧的“直接”方式获取位置。

还有过期机制,如果认为最后位置已过时,它会在一段时间后删除有关最后位置的信息。

综上所述,LP(位置提供商)确实有可能没有什么可以给你的。