android自带gps定位功能相信大家都不会太陌生了,都有所涉及。简单的写了一个示例程序,获取经纬度还有其它相关数据的代码,还有其他相关的知识,比如直接跳转到打开系统gps设置的界面。还有一个bug的处理,异常信息:Incomplete location object, missing timestamp or accuracy
1、获取location 示例程序
package com.example.locationexample; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.util.Log; import android.widget.TextView; import android.annotation.TargetApi; import android.app.Activity; import android.content.Context; public class MainActivity extends Activity { LocationManager mLocationManager; Location mlocation; TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView)findViewById(R.id.textView1); getLocation(); // mlocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); // mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation); } public Location getLocation(){ mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); mlocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (mlocation == null) { mlocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, mLocationListener); return mlocation; } LocationListener mLocationListener = new LocationListener() { @TargetApi(17) @Override public void onLocationChanged(Location mlocal) { if(mlocal == null) return; String strResult = "getAccuracy:" + mlocal.getAccuracy() + "\r\n" + "getAltitude:" + mlocal.getAltitude() + "\r\n" + "getBearing:" + mlocal.getBearing() + "\r\n" + "getElapsedRealtimeNanos:" + String.valueOf(mlocal.getElapsedRealtimeNanos()) + "\r\n" + "getLatitude:" + mlocal.getLatitude() + "\r\n" + "getLongitude:" + mlocal.getLongitude() + "\r\n" + "getProvider:" + mlocal.getProvider()+ "\r\n" + "getSpeed:" + mlocal.getSpeed() + "\r\n" + "getTime:" + mlocal.getTime() + "\r\n"; Log.i("Show", strResult); if (mTextView != null) { mTextView.setText(strResult); } } @Override public void onProviderDisabled(String arg0) { } @Override public void onProviderEnabled(String arg0) { } @Override public void onStatusChanged(String provider, int event, Bundle extras) { } }; }
在这里提醒一下,最好activity销毁时候onDestroy(),移除mLocationManager这个变量。
权限如下:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
还有重点看这行代码参数mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0, mLocationListener);
LocationManager.GPS_PROVIDER是gps提供,100是时间,多久刷新一次,0是距离,如果你不动的话,测试最好写0
mLocationListener是接口啦,数据就是那里来的。
2、异常
如果你使用mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation);这行代码报出下面的堆栈错误信息
java.lang.IllegalArgumentException: Incomplete location object, missing timestamp or accuracy? Location[gps 23.126704,113.365648 acc=1 et=?!? alt=-7.422 vel=0.008333334 bear=237.76]
解决办法:
方法一:
主要是这句,location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());,其实加上这句就可以了。
例如:
@SuppressLint("NewApi") private Location getLoc(String provider) { Location location = new Location(provider); location.setLatitude(lat); location.setLongitude(lng); location.setAltitude(altitude); location.setBearing(bearing); location.setSpeed(speed); location.setAccuracy(accuracy); location.setTime(System.currentTimeMillis()); location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); return location; }主要是这句,location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());,其实加上这句就可以了。如下
mlocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation);
方法二,加上下面的反射调用:
try { Method method = Location.class.getMethod("makeComplete"); if (method != null) { method.invoke(localLocation); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }
方法二使用,是借鉴android系统源码的反射作用
源码如下:
/** * Helper to fill incomplete fields. * * Used to assist in backwards compatibility with * Location objects received from applications. * * @see #isComplete * @hide */ public void makeComplete() { if (mProvider == null) mProvider = "?"; if (!mHasAccuracy) { mHasAccuracy = true; mAccuracy = 100.0f; } if (mTime == 0) mTime = System.currentTimeMillis(); if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos(); }
建议使用第一个方法。
3、是否已打开自身GPS
//获取是否已打开自身GPS public boolean isGpsEnable() { String providers = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); if (providers.contains(LocationManager.GPS_PROVIDER)) { return true; } else { return false; } }
4、直接跳转到系统设置gps界面
Intent callGPSSettingIntent = new Intent( android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); this.startActivity(callGPSSettingIntent);
作者:qq_16064871 发表于2016/8/24 19:52:40 原文链接
阅读:19 评论:0 查看评论