获取到位置服务后,同时请求网络和GPS定位更新。在没有GPS信号的时候,使用网络定位的位置信息(网络定位信息中无高程值)。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="纬度:"/>
<TextView
android:id="@+id/tv_latitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="经度:"/>
<TextView
android:id="@+id/tv_longitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="服务商:"/>
<TextView
android:id="@+id/tv_provider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="准确性:"/>
<TextView
android:id="@+id/tv_accuracy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="高度:"/>
<TextView
android:id="@+id/tv_altitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="方向角:"/>
<TextView
android:id="@+id/tv_bearing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="速度:"/>
<TextView
android:id="@+id/tv_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="上次上报时间:"/>
<TextView
android:id="@+id/tv_last_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"
android:text="最新上报时间:"/>
<TextView
android:id="@+id/tv_new_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>
</LinearLayout>
MainActivity.java
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import java.text.SimpleDateFormat;
public class MainActivity extends Activity {
private LocationManager locationManager;
/**
* 前一次位置
*/
private Location lastLocation;
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
private TextView tvLatitude;
private TextView tvLongitude;
private TextView tvProvider;
private TextView tvAccuracy;
private TextView tvAltitude;
private TextView tvBearing;
private TextView tvSpeed;
private TextView tvLastTime;
private TextView tvNewTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvLatitude = (TextView) findViewById(R.id.tv_latitude);
tvLongitude = (TextView) findViewById(R.id.tv_longitude);
tvProvider = (TextView) findViewById(R.id.tv_provider);
tvAccuracy = (TextView) findViewById(R.id.tv_accuracy);
tvAltitude = (TextView) findViewById(R.id.tv_altitude);
tvBearing = (TextView) findViewById(R.id.tv_bearing);
tvSpeed = (TextView) findViewById(R.id.tv_speed);
tvLastTime = (TextView) findViewById(R.id.tv_last_time);
tvNewTime = (TextView) findViewById(R.id.tv_new_time);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
}
@Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(listener);
}
private LocationListener listener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
updateLocation(location);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
updateLocation();
}
@Override
public void onProviderEnabled(String s) {
updateLocation();
}
@Override
public void onProviderDisabled(String s) {
}
};
private void updateLocation() {
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
updateLocation(location);
}
private void updateLocation(Location location) {
if (location == null) {
return;
}
//判断新的位置是否可替换当前位置
if (isBetterLocation(location, lastLocation)) {
updateUI(location);
lastLocation = location;
}
}
/**
* 更新UI
* @param location
*/
private void updateUI(final Location location) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvLatitude.setText(location.getLatitude() + "");
tvLongitude.setText(location.getLongitude() + "");
tvProvider.setText(location.getProvider());
tvAccuracy.setText(location.getAccuracy() + "");
tvAltitude.setText(location.getAltitude() + " 米");
tvBearing.setText(location.getBearing() + "");
tvSpeed.setText(location.getSpeed() + " 米/秒");
tvNewTime.setText(dateFormat.format(location.getTime()));
if (lastLocation != null) {
tvLastTime.setText(dateFormat.format(lastLocation.getTime()));
}
}
});
}
/**
* 判断位置信息是否比当前的位置信息好
* @param location 新的位置
* @param currentBestLocation 当前的位置
*/
protected boolean isBetterLocation(Location location,
Location currentBestLocation) {
if (currentBestLocation == null) {
return true;
}
// 检测GPS时间
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > 2000;
boolean isSignificantlyOlder = timeDelta < -2000;
boolean isNewer = timeDelta > 0;//较新
// If it's been more than two minutes since the current location, use
// the new location
// because the user has likely moved
if (isSignificantlyNewer)
{
return true;
}
else if (isSignificantlyOlder)
{
return false;
}
// 检测GPS精度
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// 检测提供者
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and
// accuracy
if (isMoreAccurate)
{
return true;
}
else if (isNewer && !isLessAccurate)
{
return true;
}
else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider)
{
return true;
}
return false;
}
/**
* 判断是否为同一个提供者
* @param provider1
* @param provider2
* @return
*/
private boolean isSameProvider(String provider1, String provider2)
{
if (provider1 == null)
{
return provider2 == null;
}
return provider1.equals(provider2);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>