GpsLocationProvider.java 在全局定义了一个通往底层的方法,这个就是关联到flags是什么,通常做底层会封装好改接口,然后告诉你传递什么值对应着以什么方式启动,比如传入参数:冷启动:0XFFFF 暖启动:0X0001 热启动:0X0001
private native void native_delete_aiding_data (int flags);
看native_delete_aiding_data该方法被调用时,先判断传递的Bundle对象是否为空;a.为空对应着冷启动;b.创建Bundle对象时,bundle.putBoolean(“ephemeris”, true)时对应着温启动;c.同样创建Bundle对象,传入bundle.putBoolean(“almanac”, true);详细见5
private static final int GPS_DELETE_ALL = 0xFFFF ;
private static final int GPS_DELETE_EPHEMERIS = 0x0001 ;
private static final int GPS_DELETE_ALMANAC = 0x0002 ;
...
private boolean deleteAidingData (Bundle extras) {
int flags;
if (extras == null ) {
flags = GPS_DELETE_ALL;
} else {
flags = 0 ;
if (extras.getBoolean("ephemeris" )) flags |= GPS_DELETE_EPHEMERIS;
if (extras.getBoolean("almanac" )) flags |= GPS_DELETE_ALMANAC;
if (extras.getBoolean("position" )) flags |= GPS_DELETE_POSITION;
if (extras.getBoolean("time" )) flags |= GPS_DELETE_TIME;
if (extras.getBoolean("iono" )) flags |= GPS_DELETE_IONO;
if (extras.getBoolean("utc" )) flags |= GPS_DELETE_UTC;
if (extras.getBoolean("health" )) flags |= GPS_DELETE_HEALTH;
if (extras.getBoolean("svdir" )) flags |= GPS_DELETE_SVDIR;
if (extras.getBoolean("svsteer" )) flags |= GPS_DELETE_SVSTEER;
if (extras.getBoolean("sadata" )) flags |= GPS_DELETE_SADATA;
if (extras.getBoolean("rti" )) flags |= GPS_DELETE_RTI;
if (extras.getBoolean("celldb-info" )) flags |= GPS_DELETE_CELLDB_INFO;
if (extras.getBoolean("all" )) flags |= GPS_DELETE_ALL;
}
if (flags != 0 ) {
native_delete_aiding_data(flags);
return true ;
}
return false ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
继续看deleteAidingData方法:sendExtraCommand是在LocationProviderInterface里定义的,需要传递进去delete_aiding_data值和上面2中需要的Bundle对象
@Override
public boolean sendExtraCommand (String command, Bundle extras) {
long identity = Binder.clearCallingIdentity();
boolean result = false ;
if ("delete_aiding_data" .equals(command)) {
result = deleteAidingData(extras);
} else if ("force_time_injection" .equals(command)) {
sendMessage(INJECT_NTP_TIME, 0 , null );
result = true ;
} else if ("force_xtra_injection" .equals(command)) {
if (mSupportsXtra) {
xtraDownloadRequest();
result = true ;
}
} else {
Log.w(TAG, "sendExtraCommand: unknown command " + command);
}
Binder.restoreCallingIdentity(identity);
return result;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
LocationManagerService.java服务,是如何LocationProviderInterface里的sendExtraCommand:可以看出来要调用p.sendExtraCommand(command, extras)则要在远程中实现,使用ILocationManager对象调用sendExtraCommand()方法
public class LocationManagerService extends ILocationManager .Stub {
...
@Override
public boolean sendExtraCommand (String provider, String command, Bundle extras) {
if (provider == null ) {
throw new NullPointerException();
}
checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
provider);
if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS)
!= PackageManager.PERMISSION_GRANTED)) {
throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission" );
}
synchronized (mLock) {
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null ) return false ;
return p.sendExtraCommand(command, extras);
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
再从调用方出发出发,看LocationManagerService(也就是父类ILocationManager)中的sendExtraCommand方法何时被调用:
LocationManager mLm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Bundle bundle = null ;
mLm.sendExtraCommand("gps" , "force_xtra_injection" , bundle);
mLm.sendExtraCommand("gps" , "force_time_injection" , bundle);
boolean b1 = mLm.sendExtraCommand("gps" , "delete_aiding_data" , bundle);
Bundle bundleWarm = new Bundle();
bundleWarm.putBoolean("ephemeris" , true );
mLm.sendExtraCommand("gps" , "force_xtra_injection" , bundleWarm);
mLm.sendExtraCommand("gps" , "force_time_injection" , bundleWarm);
boolean b2 = mLm.sendExtraCommand("gps" , "delete_aiding_data" , bundleWarm);
Bundle bundleHot = new Bundle();
bundleHot.putBoolean("almanac" , true );
mLm.sendExtraCommand("gps" , "force_xtra_injection" , bundleHot);
mLm.sendExtraCommand("gps" , "force_time_injection" , bundleHot);
boolean b3 = mLm.sendExtraCommand("gps" , "delete_aiding_data" , bundleHot);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
LocationManager.java中的sendExtraCommand,这里的provider要求的其实就是”gps”字符串,其中mService就是4中的ILocationManager,所以4中的sendExtraCommand方法就在这里执行了。
private final ILocationManager mService;
...
/**
* Sends additional commands to a location provider.
* Can be used to support provider specific extensions to the Location Manager API
*
* @param provider name of the location provider.
* @param command name of the command to send to the provider.
* @param extras optional arguments for the command (or null).
* The provider may optionally fill the extras Bundle with results from the command.
*
* @return true if the command succeeds.
*/
public boolean sendExtraCommand (String provider, String command, Bundle extras) {
try {
return mService.sendExtraCommand(provider, command, extras);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20