gps冷启动,温启动和热启动源码分析

  1. GpsLocationProvider.java 在全局定义了一个通往底层的方法,这个就是关联到flags是什么,通常做底层会封装好改接口,然后告诉你传递什么值对应着以什么方式启动,比如传入参数:冷启动:0XFFFF 暖启动:0X0001 热启动:0X0001
private native void native_delete_aiding_data(int flags);
  1. 看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. 继续看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. 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 NullPointerException to remain compatible with previous implementation
            throw new NullPointerException();
        }
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
                provider);

        // and check for ACCESS_LOCATION_EXTRA_COMMANDS
        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. 再从调用方出发出发,看LocationManagerService(也就是父类ILocationManager)中的sendExtraCommand方法何时被调用:
LocationManager mLm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//冷启动
Bundle bundle = null;
mLm.sendExtraCommand("gps", "force_xtra_injection", bundle); //command
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); //command
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); //command
mLm.sendExtraCommand("gps", "force_time_injection", bundleHot);
boolean b3 = mLm.sendExtraCommand("gps", "delete_aiding_data", bundleHot);
  1. 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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值