Android GNSS 模块分析(三)JNI 层

        接着上篇分析(Android GNSS 模块分析(二)Framework 层),继续往下分析 JNI 层的实现,其实在 JNI 层相对来说就比较简单了,这一层主要就是起到承上启下的过渡作用,那么可以从三点去了解下这一层的实现。

        LocationManagerService 分析 JNI 层实现

        1、JNI 代码的初始化

        2、与 HAL 层的通信

        3、与 Framework 层的通信

分析第一部分:JNI 代码的初始化

GNSS JNI 初始化时调用顺序

        class_init_native

        native_is_supported

        native_is_supported

        native_init_once

        native_init

        native_cleanup

        native_is_gnss_visibility_control_supported

        native_init

        native_supports_psds

        native_set_agps_server

        这是我从开机启动时,在 JNI 层添加日志所打印的开机启动时 JNI 层函数调用的顺序。配合上层 LocationManagerService 服务的初始化,可以分析上层与底层通信的流程。

1.1 class_init_native()

在上层 GnssLocationProvider 初始化的时候,就会调用静态代码块中的 class_init_native() 方法进行 JNI 层初步初始化。

(frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp)

主要工作有两步:调用 android_location_GnssLocationProvider_set_gps_service_handle();缓存 JNI 方法和类对象。

android_location_GnssLocationProvider_set_gps_service_handle() 主要就是去初始化 gnssHal,连接底层的Hal 对象。

1.2 native_init_once(true)

在 GnssLocationProvider 的初始化过程中,初始化 JNI 的方法集中在 handleInitialize() 中。先调用 native_init_once(true) 完成 JNI 层的初始化。内容较多,逐步分析

1.2.1 重新调用 android_location_GnssLocationProvider_set_gps_service_handle() 方法,再去获取一次 gnssHal 服务。

1.2.2 调用 linkToDeath() 给 gnssHal 服务注册释放监听。通过 GnssDeathRecipient 回调。最终会调用 method_reportGnssServiceDied 方法通知到上层,底层服务已经挂了

1.2.3 通过 gnssHal->getExtensionXtra() 获取 Hal 层的 IGnssXtra 实现对象,IGnssXtra 是 Hal 层实现的 Hidl 服务端。是否实现取决于底层是否支持 psds 服务。保存到 gnssXtraIface 变量中。

1.2.4 通过 gnssHal->getExtensionAGnssRil() 获取 Hal 层的 IAGnssRil_V1_0 / IAGnssRil_V2_0 实现对象。Hal 层是否实现取决于底层是否支持 agps_ril 服务。保存到 agnssRilIface 变量中。

1.2.5 通过 gnssHal->getExtensionAGnss() 获取 Hal 层的 IAGnss_V1_0 / IAGnss_V2_0 实现对象。获取的是 Hal 层实现 IAGnss.hal 的服务端。 保存到 agnssIface 变量中。

1.2.6 通过 gnssHal->getExtensionGnssNavigationMessage() 获取 Hal 层 IGnssNavigationMessage 实现对象。是 Hal 层实现 IGnssNavigationMessage.hal 的服务端。保存到 gnssNavigationMessageIface 变量中。

1.2.7 通过 gnssHal->getExtensionGnssMeasurement() 获取到 Hal 层 IGnssMeasurement_V1_0 / IGnssMeasurement_V1_1 / IGnssMeasurement_V2_0 实现对象。是 Hal 层实现 IGnssMeasurement.hal 的服务端。保存到 gnssMeasurementIface 变量中

1.2.8 通过 gnssHal_V2_0->getExtensionMeasurementCorrections() 获取到 Hal 层 IMeasurementCorrections 实现对象。是 Hal 层实现 IMeasurementCorrections.hal 的服务端。保存到 gnssCorrectionsIface 变量中。此 hidl 接口是框架中独立的接口,属于 android.hardware.gnss.measurement_corrections@1.0 中的接口。这个库在 android.hardware.gnss@2.0 中使用,其他的 hidl 版本没有使用。

1.2.9 通过 gnssHal->getExtensionGnssDebug() 获取到 Hal 层 IGnssDebug 实现对象。是 Hal 层实现 IGnssDebug.hal 的服务端。保存到 gnssDebugIface 变量中。

1.2.10 通过 gnssHal->getExtensionGnssNi() 获取到 Hal 层 IGnssNi 实现对象。是 Hal 层实现 IGnssNi.hal 的服务端。保存到 gnssNiIface 变量中。

1.2.11 通过 gnssHal->getExtensionGnssConfiguration() 获取到 Hal 层 IGnssConfiguration 实现对象。是 Hal 层实现 IGnssConfiguration.hal 的服务端。保存到 gnssConfigurationIface 变量中。

1.2.12 通过 gnssHal->getExtensionGnssGeofencing() 获取到 Hal 层 IGnssGeofencing 实现对象。是 Hal 层实现 IGnssGeofencing.hal 的服务端。保存到 gnssGeofencingIface 变量中。

1.2.13 通过 gnssHal->getExtensionGnssBatching() 获取到 Hal 层 IGnssBatching 实现对象。是 Hal 层实现 IGnssBatching.hal 的服务端。保存到 gnssBatchingIface 变量中。

1.2.14 通过 gnssHal->getExtensionVisibilityControl() 获取 Hal 层 IGnssVisibilityControl 实现对象。是 Hal 层实现 IGnssVisibilityControl.hal 的服务端。保存到 gnssVisibilityControlIface 变量中。IGnssVisibilityControl.hal hidl 接口是框架中独立的接口,属于 android.hardware.gnss.visibility_control@1.0 中的接口。这个库是在 android.hardware.gnss@2.0 中使用,其他 hidl 版本没有使用。

native_init_once() 这里获取底层服务的同时,其实也是初始化获取底层是否支持这类服务。后续会给这些服务添加 callback 回调对象。用于完成提供服务。

下表先简单描述下 HAL 接口层的功能,以提供的 HAL 封装文件展开

Hal 服务功能关联类(callback、数据封装类)接口版本hidl 库
IGnss.hal标准的GNSS(全球卫星导航系统)接口,实现基本的 GNSS 服务功能封装IGnssCallback.hal1.0 \ 1.1 \ 2.0android.hardware.gnss@1.0 \ android.hardware.gnss@1.1 \ android.hardware.gnss@2.0
IGnssXtra.halXTRA 服务。高通 gpsOneXTRA 的援助技术在公司的改进中扩展了 gps 芯片组,允许通过互联网连接下载辅助 gps。芯片组为更精确的位置发现提供了更高的灵敏度,尤其是在通常难以找到 GPS 信号的位置。gpsOneXTRA 帮助提供了独立的性能,并简化了 GNSS 的帮助交付 GNSS 引擎,可以使第一次定位时间TTFF提高18到30秒。但是 gpsOneXTRA 需要每天或几天更新一次数据。该数据可以通过网络从 XTRA 服务器上获取。(3条消息) 【驱动】GNSS驱动:gpsOneXTRA 援助技术郭老二的博客-CSDN博客gpsonextraIGnssXtraCallback.hal1.0android.hardware.gnss@1.0
IAGnssRil.halAGNSS RIL 支持的扩展接口。2.0 继承 1.0 的 hal 服务IAGnssRilCallback.hal1.0 \ 2.0android.hardware.gnss@1.0 \ android.hardware.gnss@2.0
IAGnss.halAGNSS 支持的扩展接口IAGnssCallback.hal1.0 \ 2.0android.hardware.gnss@1.0 \ android.hardware.gnss@2.0
IGnssNavigationMessage.hal支持GNSS导航消息报告的扩展接口。上层注册回调之后,底层就会通过回调上报信息,无需请求。提供 close() 关闭接口IGnssNavigationMessageCallback.hal1.0android.hardware.gnss@1.0
IGnssMeasurement.halGNSS测量支持的扩展接口。上层注册回调之后,底层就会通过回调上报信息,无需请求。提供 close() 关闭接口IGnssMeasurementCallback.hal1.0 \ 1.1 \ 2.0android.hardware.gnss@1.0 \ android.hardware.gnss@1.1 \ android.hardware.gnss@2.0
IMeasurementCorrections.hal支持测量修正的 hidl 接口IMeasurementCorrectionsCallback.hal其他hidl 接口android.hardware.gnss.measurement_corrections@1.0
IGnssDebug.hal支持 Debug 的扩展接口1.0 \ 2.0android.hardware.gnss@1.0 \ android.hardware.gnss@2.0
IGnssNi.hal网络初始化(NI)支持的扩展接口。结果会通过回调提供到上层IGnssNiCallback.hal1.0android.hardware.gnss@1.0
IGnssConfiguration.hal将GNSS配置信息从平台传递到HAL的接口1.0 \ 1.1 \ 2.0android.hardware.gnss@1.0 \ android.hardware.gnss@1.1 \ android.hardware.gnss@2.0
IGnssGeofencing.halGNSS geofence支持的扩展接口IGnssGeofenceCallback.hal1.0android.hardware.gnss@1.0
IGnssBatching.halGNSS批处理支持的扩展接口。IGnssBatchingCallback.hal1.0 \ 2.0
IGnssVisibilityControl.halGNSS位置报告权限和通知接口IGnssVisibilityControlCallback.halandroid.hardware.gnss.visibility_control@1.0

1.3 native_init()

上层调用 native_init_once() 后,会调用 native_init() 函数。native_init() 函数 对应 JNI 层的 android_location_GnssLocationProvider_init() 方法。这个函数实际上完成的是对之前拿到的底层的 Hal 功能对象添加 callback 回调。

1.4 native_cleanup()

这里进行回调注册成功之后,会调用 native_cleanup() 将 GNSS 底层服务的注册给清除,这里走一次注册的流程,确保后续 GNSS 提供服务时流程能够正常

1.5 native_is_gnss_visibility_control_supported()

判断底层是否支持 IGnssVisibilityControl 的 Hal 服务。这里是返回的 true,标识在初始化的时候是有赋值的。

1.6 native_init()

流程走到 handleInitialize() 的最后,会调用 updateEnabled() 函数,判断当前用户是否打开了 GNSS 功能设置,从而调用 handleEnable() 去开启 GNSS 服务。流程中会先调用 native_init() 去进行 Hal 层回调接口的初始化。

1.7 native_supports_psds()

初始化 Hal 层回调接口之后,会去调用 native_supports_psds() 判断下底层是否支持 PSDS IGnssXtra 的 Hal 服务。这里返回的是 true,说明底层在初始化的时候是成功赋值的

1.8 native_set_agps_server()

这里的调用是给底层 AGnss.hal 服务设置一个 Server 服务端,这个服务端可以是 SUPL,也可以是 C2K 服务。底层是支持 AGNSS Hal 服务的。SUPL(安全用户面定位)采用用户平面的数据承载来传输定位辅助信息,并在移动终端和网络之间携带定位技术相关的协议。SUPL的目的是代替或补充移动网络中的现有定位标准——基于控制平面信令定位

这些就是 GNSS 初始化过程中与底层通信的流程

分析第二部分 HAL 层的通信

        * 获取 Hal 对象以及获取 Hal 层所支持的服务对象

        * 设置 Hal 回调对象

2.1  获取 Hal 对象

(frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp)

        GnssLocationProvider 开始加载到内存的时候,就加载了 JNI 层的流程,在 class_init_native() 中调用了上面的函数去获取 Hal 服务。由于 Hal 是 在 init 阶段通过 rc 文件拉起的,Hal 服务已经准备就绪,如果支持的话,这里能直接拿到 Hal 服务对象。

2.2 获取 Hal 层所支持的服务对象

        通过 Google 原生定义的 GNSS 模块的 hidl 文件(hardware/interfaces/gnss)可以发现,HIDL 接口定义的服务有很多,在 Hal 层中实现。那么在 JNI 层会通过 Hal 对象去拿到对应的底层服务对象。这部分在上一节 1.2 中有描述。拿到对象后,Framework 层下发数据时,直接通过对应的服务类对象,调用到底层。这部分调用在

2.3 设置 Hal 回调对象

        上面拿到 Hal 层具体的服务对象后,还需要给这些不同的服务对象设置回调,用于 Hal 层的消息返回。

        Hal 服务对象回调的注册是在 android_location_GnssLocationProvider_init() 完成的,这个函数对应上层的 native_init(),通过之前的分析可知,上层每一次调用 requestLocationUpdates() 函数请求位置信息调用时,都会触发这个回调注册。

static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
    ALOGD("--test-- id = %ld, native_init",debug_test++);
    /*
     * This must be set before calling into the HAL library.
     */
    if (!mCallbacksObj)
        mCallbacksObj = env->NewGlobalRef(obj);

    /*
     * Fail if the main interface fails to initialize
     */
    if (gnssHal == nullptr) {
        ALOGE("Unable to initialize GNSS HAL.");
        return JNI_FALSE;
    }

    Return<bool> result = false;

    // Set top level IGnss.hal callback.
    sp<IGnssCallback> gnssCbIface = new GnssCallback();
    if (gnssHal_V2_0 != nullptr) {
        result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
    } else if (gnssHal_V1_1 != nullptr) {
        result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
    } else {
        result = gnssHal->setCallback(gnssCbIface);
    }

    if (!result.isOk() || !result) {
        ALOGE("SetCallback for IGnss interface failed.");
        return JNI_FALSE;
    }

    // Set IGnssXtra.hal callback.
    if (gnssXtraIface == nullptr) {
        ALOGI("Unable to initialize IGnssXtra interface.");
    } else {
        sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
        result = gnssXtraIface->setCallback(gnssXtraCbIface);
        if (!result.isOk() || !result) {
            gnssXtraIface = nullptr;
            ALOGI("SetCallback for IGnssXtra interface failed.");
        }
    }

    // Set IAGnss.hal callback.
    Return<void> agnssStatus;
    if (agnssIface_V2_0 != nullptr) {
        sp<IAGnssCallback_V2_0> aGnssCbIface = new AGnssCallback_V2_0();
        agnssStatus = agnssIface_V2_0->setCallback(aGnssCbIface);
    } else if (agnssIface != nullptr) {
        sp<IAGnssCallback_V1_0> aGnssCbIface = new AGnssCallback_V1_0();
        agnssStatus = agnssIface->setCallback(aGnssCbIface);
    } else {
        ALOGI("Unable to initialize IAGnss interface.");
    }

    if (!agnssStatus.isOk()) {
        ALOGI("SetCallback for IAGnss interface failed.");
    }

    // Set IGnssGeofencing.hal callback.
    sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
    if (gnssGeofencingIface != nullptr) {
        auto status = gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
        if (!status.isOk()) {
            ALOGI("SetCallback for IGnssGeofencing interface failed.");
        }
    } else {
        ALOGI("Unable to initialize IGnssGeofencing interface.");
    }

    // Set IGnssNi.hal callback.
    sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
    if (gnssNiIface != nullptr) {
        auto status = gnssNiIface->setCallback(gnssNiCbIface);
        if (!status.isOk()) {
            ALOGI("SetCallback for IGnssNi interface failed.");
        }
    } else {
        ALOGI("Unable to initialize IGnssNi interface.");
    }

    // Set IAGnssRil.hal callback.
    sp<IAGnssRilCallback> aGnssRilCbIface = new AGnssRilCallback();
    if (agnssRilIface != nullptr) {
        auto status = agnssRilIface->setCallback(aGnssRilCbIface);
        if (!status.isOk()) {
            ALOGI("SetCallback for IAGnssRil interface failed.");
        }
    } else {
        ALOGI("Unable to initialize IAGnssRil interface.");
    }

    // Set IGnssVisibilityControl.hal callback.
    if (gnssVisibilityControlIface != nullptr) {
        sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
                new GnssVisibilityControlCallback();
        result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
        if (!result.isOk() || !result) {
            ALOGI("SetCallback for IGnssVisibilityControl interface failed.");
        }
    }

    // Set IMeasurementCorrections.hal callback.
    if (gnssCorrectionsIface != nullptr) {
        sp<IMeasurementCorrectionsCallback> gnssCorrectionsIfaceCbIface =
                new MeasurementCorrectionsCallback();
        result = gnssCorrectionsIface->setCallback(gnssCorrectionsIfaceCbIface);
        if (!result.isOk() || !result) {
            ALOGI("SetCallback for IMeasurementCorrections interface failed.");
        }
    }

    return JNI_TRUE;
}

分析第三部分 Framework 层的通信

3.1 HAL 层通过 JNI 层注册的回调对象,将数据信息回调到 JNI 层,然后再由 JNI 层与 Framework 层函数的绑定通知到上层。

        Hal 层的数据通过回调到 JNI 层时,JNI 层需要将数据通知到上层,那么需要绑定 HAL 回调信息与 Framework 层的对应函数,这部分早在初始化的 android_location_GnssLocationProvider_class_init_native() 完成。

static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
    ALOGD("--test-- id = %ld, class_init_native",debug_test++);
    // Initialize the top level gnss HAL handle.
    android_location_GnssLocationProvider_set_gps_service_handle();

    // Cache methodIDs and class IDs.
    method_reportLocation = env->GetMethodID(clazz, "reportLocation",
            "(ZLandroid/location/Location;)V");
    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F)V");
    method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
    method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
    method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");
    method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
    method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
            "(Ljava/lang/String;)V");
    method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "()V");
    method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
            "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
    method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
    method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
    method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
    method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
    method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
            "(ILandroid/location/Location;IJ)V");
    method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
            "(ILandroid/location/Location;)V");
    method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
            "(II)V");
    method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
            "(II)V");
    method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
            "(II)V");
    method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
            "(II)V");
    method_reportMeasurementData = env->GetMethodID(
            clazz,
            "reportMeasurementData",
            "(Landroid/location/GnssMeasurementsEvent;)V");
    method_reportNavigationMessages = env->GetMethodID(
            clazz,
            "reportNavigationMessage",
            "(Landroid/location/GnssNavigationMessage;)V");
    method_reportLocationBatch = env->GetMethodID(
            clazz,
            "reportLocationBatch",
            "([Landroid/location/Location;)V");
    method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
    method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
            "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
    method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");

    method_setSubHalMeasurementCorrectionsCapabilities = env->GetMethodID(clazz,
            "setSubHalMeasurementCorrectionsCapabilities", "(I)V");

    jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
    method_correctionsGetLatitudeDegrees = env->GetMethodID(
            measCorrClass,"getLatitudeDegrees", "()D");
    method_correctionsGetLongitudeDegrees = env->GetMethodID(
            measCorrClass, "getLongitudeDegrees", "()D");
    method_correctionsGetAltitudeMeters = env->GetMethodID(
            measCorrClass, "getAltitudeMeters", "()D");
    method_correctionsGetHorPosUncMeters = env->GetMethodID(
            measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
    method_correctionsGetVerPosUncMeters = env->GetMethodID(
            measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
    method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
            measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");

    method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
            measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava/util/List;");

    jclass corrListClass = env->FindClass("java/util/List");
    method_listSize = env->GetMethodID(corrListClass, "size", "()I");
    method_correctionListGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;");

    jclass singleSatCorrClass = env->FindClass("android/location/GnssSingleSatCorrection");
    method_correctionSatFlags = env->GetMethodID(
            singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
    method_correctionSatConstType = env->GetMethodID(
            singleSatCorrClass, "getConstellationType", "()I");
    method_correctionSatId= env->GetMethodID(
            singleSatCorrClass, "getSatelliteId", "()I");
    method_correctionSatCarrierFreq = env->GetMethodID(
            singleSatCorrClass, "getCarrierFrequencyHz", "()F");
    method_correctionSatIsLosProb = env->GetMethodID(
            singleSatCorrClass,"getProbabilityLineOfSight", "()F");
    method_correctionSatEpl = env->GetMethodID(
            singleSatCorrClass, "getExcessPathLengthMeters", "()F");
    method_correctionSatEplUnc = env->GetMethodID(
            singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
    method_correctionSatRefPlane = env->GetMethodID(
            singleSatCorrClass, "getReflectingPlane", "()Landroid/location/GnssReflectingPlane;");

    jclass refPlaneClass = env->FindClass("android/location/GnssReflectingPlane");
    method_correctionPlaneLatDeg = env->GetMethodID(refPlaneClass, "getLatitudeDegrees", "()D");
    method_correctionPlaneLngDeg = env->GetMethodID(refPlaneClass, "getLongitudeDegrees", "()D");
    method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D");
    method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D");

    jclass gnssMeasurementsEventClass = env->FindClass("android/location/GnssMeasurementsEvent");
    class_gnssMeasurementsEvent= (jclass) env->NewGlobalRef(gnssMeasurementsEventClass);
    method_gnssMeasurementsEventCtor = env->GetMethodID(
                    class_gnssMeasurementsEvent,
                    "<init>",
                    "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");

    jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
    class_gnssMeasurement = (jclass) env->NewGlobalRef(gnssMeasurementClass);
    method_gnssMeasurementCtor = env->GetMethodID(class_gnssMeasurement, "<init>", "()V");

    jclass locationClass = env->FindClass("android/location/Location");
    class_location = (jclass) env->NewGlobalRef(locationClass);
    method_locationCtor = env->GetMethodID(class_location, "<init>", "(Ljava/lang/String;)V");

    jclass gnssNavigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
    class_gnssNavigationMessage = (jclass) env->NewGlobalRef(gnssNavigationMessageClass);
    method_gnssNavigationMessageCtor = env->GetMethodID(class_gnssNavigationMessage, "<init>", "()V");

    jclass gnssClockClass = env->FindClass("android/location/GnssClock");
    class_gnssClock = (jclass) env->NewGlobalRef(gnssClockClass);
    method_gnssClockCtor = env->GetMethodID(class_gnssClock, "<init>", "()V");

    jclass gnssConfiguration_halInterfaceVersionClass =
            env->FindClass("com/android/server/location/GnssConfiguration$HalInterfaceVersion");
    class_gnssConfiguration_halInterfaceVersion =
            (jclass) env->NewGlobalRef(gnssConfiguration_halInterfaceVersionClass);
    method_halInterfaceVersionCtor =
            env->GetMethodID(class_gnssConfiguration_halInterfaceVersion, "<init>", "(II)V");
}

        以上基本就是 JNI 层所完成的事情了。

如果文中有错,烦请告知作者,必当有则改之,无则加勉。在此,小弟先行告谢!

联系作者:

上一篇:Android GNSS 模块分析(二)FrameWork 层

下一篇:Android GNSS 模块分析(四)HAL 层

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值