使用Android提供的模拟任意地理位置的接口,执行如下方法时,会报异常:
- Location localLocation = getLoc(LocationManager.GPS_PROVIDER);
- mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER,
- localLocation);
- 12-10 14:54:24.497: W/System.err(27548): java.lang.IllegalArgumentException: Incomplete location object, missing timestamp or accuracy? Location[gps 22.546054,114.025974 acc=0 et=?!? alt=0.0 vel=0.0 bear=0.0]
- 12-10 14:54:24.497: W/System.err(27548): at android.location.LocationManager.setTestProviderLocation(LocationManager.java:1218)
- 12-10 14:54:24.497: W/System.err(27548): at com.zhao3546.MockLocationServicePro$1.run(MockLocationServicePro.java:55)
- 12-10 14:54:24.497: W/System.err(27548): at android.os.Handler.handleCallback(Handler.java:725)
- 12-10 14:54:24.497: W/System.err(27548): at android.os.Handler.dispatchMessage(Handler.java:92)
- 12-10 14:54:24.497: W/System.err(27548): at android.os.Looper.loop(Looper.java:137)
- 12-10 14:54:24.497: W/System.err(27548): at android.app.ActivityThread.main(ActivityThread.java:5106)
- 12-10 14:54:24.497: W/System.err(27548): at java.lang.reflect.Method.invokeNative(Native Method)
- 12-10 14:54:24.497: W/System.err(27548): at java.lang.reflect.Method.invoke(Method.java:511)
- 12-10 14:54:24.497: W/System.err(27548): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
- 12-10 14:54:24.500: W/System.err(27548): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
- 12-10 14:54:24.500: W/System.err(27548): at dalvik.system.NativeStart.main(Native Method)
这个问题可以通过两个方法解决。
方法一:
主要是这句,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;
- }
方法二,加上下面的反射调用:
- try
- {
- Method method = Location.class.getMethod("makeComplete");
- if (method != null)
- {
- method.invoke(localLocation);
- }
- }
- catch (NoSuchMethodException e)
- {
- e.printStackTrace();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
第二个方法调用的 makeComplete() 方法在Android源码中的实现如下,其实和第一个方法异曲同工,还是第一个方法更优。
- /**
- * Helper to fill incomplete fields.
- *
- * <p>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();
- }
- /**
- * Helper to fill incomplete fields.
- *
- * <p>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();
- }