我正在尝试了解Android位置在网络上发现了很多代码,它们看起来都不同,他们以不同的方式与库混淆,这让我感到困惑。我无法找到常用的方法。
基本上我需要使用GPS获取位置,如果使用GPS在90秒内未成功检索到位置,则获取网络提供的位置。最简单的方法是什么?
我测试了以下片段,但设备上的结果不健壮有时不清楚如何确保getLastKnownLocation()没有得到一个不是最新的旧存储位置。谢谢!
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
gps_latitude = location.getLatitude();
gps_longitude = location.getLongitude();
gps_timestamp = location.getTime();
gps_accuracy = location.getAccuracy();
gps_provider = location.getProvider();
gps_speed = location.getSpeed();
}
答案 0 :(得分:3)
尝试使用LocationCLient获取可用的最佳已知位置。此课程使用GPS,WiFi和传感器的混合来自动检测当前位置。因此,无需再在GPS或网络之间做出决定。
以下是guide如何使用它。
编辑:您必须使用与API 8兼容的Google Play Services库。
答案 1 :(得分:1)
派对有点拖延,但认为在2016年(或之后)发布阅读此内容的人员更新是值得的。
正如其他答案所示,现在最好的方法是使用 Google Play服务位置API 。 除非您真的需要对位置提供商进行细粒度控制,否则Google API必须在更短的时间内为您提供更好的位置估算,仅使用每个实际需要的资源(GPS,WiFi,Cell Tower,蓝牙)用户的设备。
不幸的是,订阅位置更新仍然很麻烦(正如Matthias指出的那样,API有点复杂)。您需要执行以下部分或全部操作:
我努力在几个不同的项目中设置位置更新,并决定编写一个实用程序类来完成大部分工作:
LocationAssistant - Hassle-free location updates on Android
我还写了一篇关于在各种Android版本上设置Android位置的详细博客文章,您可以read here。
因此,要解决您的原始问题(尽快获得GPS准确度的最新位置):
public class MyActivity extends Activity implements LocationAssistant.Listener {
private LocationAssistant assistant;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// You can specify a different accuracy and interval here, depending on the needs of your app
assistant = new LocationAssistant(this, this, LocationAssistant.Accuracy.HIGH, 5000, true);
}
@Override
protected void onResume() {
super.onResume();
assistant.start();
}
@Override
protected void onPause() {
assistant.stop();
super.onPause();
}
@Override
public void onNewLocationAvailable(Location location) {
// Do something with the location
}
...
}
只要第一个有效位置可用,就会调用 onNewLocationAvailable()
。您需要实现一些更多的侦听器方法来处理未授予权限或关闭位置提供程序的情况。但基本上就是这样。
LocationAssistant 还允许您可靠地拒绝模拟位置(如果您的应用需要)。
答案 2 :(得分:0)
您确定需要优先考虑GPS位置吗?对GPS提供商提出严格要求有几个缺点:
您必须使用最旧的API,因为这是您唯一可以明确强制使用哪种"类型"修复你检索。 (' LocationManager')
从用户体验的角度来看,这通常会更糟糕,因为需要更长时间才能获得GPS修复,它不会在室内工作等。
新的API有很多漂亮的逻辑,可以衡量电池寿命,速度,准确度等等。
我对你的课程申请一无所知,只是想让你考虑你真正的要求是什么。
"新"还有其他好处。 api' s,我在大约18个月前切换到我们的应用程序时发现了第一手资料:
更快更可靠。 它不那么多了。例如,在旧的API中,我们有时会得到一个旧的"修复新的时间戳。这种情况再也不会发生了。还有更多,但这将是一个更长的帖子。 它肯定会消耗更少的电池。例如,当您打开地图视图时,GPS会一直运行,并且GPS图标可见。新的情况并非如此。这让用户想知道发生了什么。这不再是一个大问题。 因此,当涉及到位置输出和工作时,一切都会更好。但是有一些缺点:
您必须安装Google Play服务,这意味着它不适用于任何非谷歌批准的"手机型号,在某些情况下,您必须告诉用户他们需要安装它。
API本身是更复杂的IMO,部分原因在于第1点。除了#34;常规"回调即等待位置修复等。您现在有一个流程可以在您开始之前参与,您必须检查播放服务是否可用,以及" connect" locationclient。这是额外的代码,有点复杂。在代码中也要考虑更多错误的条件(如果你可能会被打扰......)
Google Play服务本身至少需要2.2,因此它不适用于旧设备。我们不得不告诉一些客户他们必须升级......
希望这有帮助!
答案 3 :(得分:0)
使用以下代码。它对我来说很好。 它为我提供了gps和网络上的位置
package com.fudiyo.LocationTracker;
import android.app.Dialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import com.fudiyo.R;
public class GPSLocationNetwork extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
public LocationManager locationManager;
public GPSLocationNetwork(Context context) {
this.mContext = context;
getLocation();
}
@SuppressWarnings("static-access")
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(mContext.LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
//
if (!isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
this.canGetLocation = true;
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener Calling this function will stop using GPS in your
* app
* */
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSLocationNetwork.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
*
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog On pressing Settings button will
* lauch Settings Options
* */
public void showSettingsAlert() {
final Dialog gpsDialog = new Dialog(mContext);
gpsDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
gpsDialog.setContentView(R.layout.gps_enable_dialog);
gpsDialog.setCancelable(true);
Button gpsSettingBtn = (Button) gpsDialog
.findViewById(R.id.btn_setting_gps_dialog);
Button gpsCancelBtn = (Button) gpsDialog
.findViewById(R.id.btn_cancel_gps_dialog);
gpsSettingBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gpsDialog.dismiss();
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
gpsCancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gpsDialog.dismiss();
}
});
gpsDialog.show();
}
@Override
public void onLocationChanged(Location location) {
this.location = location;
getLatitude();
getLongitude();
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}