Skip to content

配置依赖

在开始基于 Entity Service 进行应用开发之前,需要先将 SDK 以依赖的方式引入到工程中。

下面是工程构建文件中的示例配置。请将其中的用户名和密码替换为 Telenav 提供的下载凭证。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
repositories {
    ...    
    maven {
        url "https://telenav.jfrog.io/artifactory/telenav-maven-releases/"
        credentials {
            username '#REPO_USER_NAME#'
            password '#REPO_PASSWD#'
        }
    }
}

dependencies {
    implementation("com.telenav.sdk:telenav-sdk-base:#SDK_BASE_VERSION#")
    implementation("com.telenav.sdk:telenav-entity-cloud:#ENTITY_SDK_VERSION#")
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
repositories {
    ...
    maven {
        url "https://telenav.jfrog.io/artifactory/telenav-maven-releases/"
        credentials {
            username '#REPO_USER_NAME#'
            password '#REPO_PASSWD#'
        }
    }
}

dependencies {
    implementation("com.telenav.sdk:telenav-sdk-base:#SDK_BASE_VERSION#")
    implementation("com.telenav.sdk:telenav-entity-hybrid:#ENTITY_SDK_VERSION#")
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
repositories {
    ...
    maven {
        url "https://telenav.jfrog.io/artifactory/telenav-maven-releases/"
        credentials {
            username '#REPO_USER_NAME#'
            password '#REPO_PASSWD#'
        }
    }
}

dependencies {
    implementation("com.telenav.sdk:telenav-sdk-base:#SDK_BASE_VERSION#")
    implementation("com.telenav.sdk:telenav-entity-onboard:#ENTITY_SDK_VERSION#")
}


说明

  1. 如果使用 Edge SDK 或 Hybrid SDK,请确保下载 Telenav 发布的 SDK 数据包,解压后将其拷贝到 sdkDataDir 所指向的路径下。该路径需要与初始化 SDK 时在 SDKOptions 中设置的路径保持一致。
  2. 请参考 release notes 获取最新的 Entity SDK 版本SDK Base 版本

提示

SDK 依赖了若干开源库(例如 okhttp、okio、common-lang 等)。如果通过 Gradle 或 Maven 下载 SDK,这些依赖会被自动拉取;如果是手动下载 SDK,则需要根据 SDK 的 POM 文件,将这些依赖一并添加到你的工程中。

API 签名

使用 Entity SDK 时,应用需要提供 API Key 和 API Signature。

在请求中通过 api_key 参数指定 Key,通过 api_signature 参数指定 Signature: https://<domain_name>/entity/v4/search/json?query=coffee&location=37.368647,-122.03504&api_key={API Key}&api_signature={API Signature}

每次请求对应的 API Signature 都是唯一的,可按如下方式生成有效签名:
api­key + “:” + timestamp + “:” + MD5 (api­key + “:” + timestamp + “:” + api­secret) 其中 timestamp 为 UTC 秒数,例如 1393379693。

创建 Client

在使用搜索或其他能力之前,需要先初始化 EntityService 并创建一个 EntityClient 实例。initialize() 方法只需要调用一次。

  • Cloud Client 模式只使用云端搜索
  • Hybrid Client 模式会优先使用云端搜索 (需要本地索引文件支持)
  • Edge Client 模式只使用本地搜索(需要本地索引文件支持)

整体调用时序如下图所示:应用层通过 EntityService.initialize(SDKOptions) 完成初始化后,由 EntityClientBeanFactory 根据模式构造对应的实现层实例(Cloud/Embedded/Hybrid),最终通过 getClient() 拿到 EntityClient 用于后续 searchRequest() 等调用。

EntityClient 初始化与搜索时序图

创建 Cloud Client

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
try {
    SDKOptions sdkOptions = SDKOptions.builder()
            .setApiKey("#API_KEY_PROVIDED_BY_TELENAV#")
            .setApiSecret("#API_SECRET_PROVIDED_BY_TELENAV#")
            .setCloudEndPoint("#CLOUD_ENDPOINT_PROVIDED_BY_TELENAV#")
            .setLocale(Locale.EN_US)
            .build();

    EntityService.initialize(sdkOptions);
} catch (EntityException e) {
    // SDK 初始化失败:请检查 API key/secret、cloud endpoint 以及 lib 依赖
}
EntityClient entityClient = EntityService.getClient();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
try {
    val sdkOptions = SDKOptions.builder()
            .setApiKey("#API_KEY_PROVIDED_BY_TELENAV#")
            .setApiSecret("#API_SECRET_PROVIDED_BY_TELENAV#")
            .setCloudEndPoint("#CLOUD_ENDPOINT_PROVIDED_BY_TELENAV#")
            .setLocale(Locale.EN_US)
            .build()
    EntityService.initialize(sdkOptions)
} catch (e: EntityException) {
    // SDK 初始化失败:请检查 API key/secret、cloud endpoint 以及 lib 依赖
}
var entityClient = EntityService.getClient()

创建 Hybrid Client

说明

如果使用下面示例中的 Edge SDK 或 Hybrid SDK,请确保下载 Telenav 发布的 SDK 数据包,解压后拷贝到 sdkDataDir 所指向的路径下。

Hybrid 模式下,HybridApi 会通过线程池并行发起 Cloud 与 Onboard 两路异步请求,由 ResponseCollector 汇总结果并按优先级(云端成功优先)回调到用户 Callback。其内部调用时序如下:

Hybrid Client 并行调用时序图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
try {
    SDKOptions sdkOptions = SDKOptions.builder()
            .setApiKey("#API_KEY_PROVIDED_BY_TELENAV#")
            .setApiSecret("#API_SECRET_PROVIDED_BY_TELENAV#")
            .setCloudEndPoint("#CLOUD_ENDPOINT_PROVIDED_BY_TELENAV#")
            .setSdkDataDir("#SDK_DATA_DIR#")
            .setSdkCacheDataDir("#SDK_CACHE_DATA_DIR#")
            .setLocale(Locale.EN_US)
            .build();

    EntityService.initialize(sdkOptions);
} catch (EntityException e) {
    // SDK 初始化失败:请检查 API key/secret、cloud endpoint 以及 lib 依赖
    // 同时检查本地索引数据是否存在,以及索引/缓存目录是否具有读写权限

}
EntityClient entityClient = EntityService.getClient();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
try {
    val sdkOptions = SDKOptions.builder()
            .setApiKey("#API_KEY_PROVIDED_BY_TELENAV#")
            .setApiSecret("#API_SECRET_PROVIDED_BY_TELENAV#")
            .setCloudEndPoint("#CLOUD_ENDPOINT_PROVIDED_BY_TELENAV#")
            .setSdkDataDir("#SDK_DATA_DIR#")
            .setSdkCacheDataDir("#SDK_CACHE_DATA_DIR#")
            .setLocale(Locale.EN_US)
            .build()
    EntityService.initialize(sdkOptions)
} catch (e: EntityException) {
    // SDK 初始化失败:请检查 API key/secret、cloud endpoint 以及 lib 依赖
    // 同时检查本地索引数据是否存在,以及索引/缓存目录是否具有读写权限
}
var entityClient = EntityService.getClient()

创建 Edge Client

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
try {
    SDKOptions sdkOptions = SDKOptions.builder()
            .setSdkDataDir("#SDK_DATA_DIR#")
            .setSdkCacheDataDir("#SDK_CACHE_DATA_DIR#")
            .setLocale(Locale.EN_US)
            .build();

    EntityService.initialize(sdkOptions);
} catch (EntityException e) {
    // SDK 初始化失败:请检查 lib 依赖、本地索引数据是否存在,以及索引/缓存目录是否具有读写权限
}
EntityClient entityClient = EntityService.getClient();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
try {
    val sdkOptions = SDKOptions.builder()
            .setSdkDataDir("#SDK_DATA_DIR#")
            .setSdkCacheDataDir("#SDK_CACHE_DATA_DIR#")
            .setLocale(Locale.EN_US)
            .build()
    EntityService.initialize(sdkOptions)
} catch (e: EntityException) {
    // SDK 初始化失败:请检查 lib 依赖、本地索引数据是否存在,以及索引/缓存目录是否具有读写权限
}
var entityClient = EntityService.getClient()


至此,SDK 已经可以正常使用了!

获取数据

这是个简单的获取所有POI 分类的代码,调用成功后会返回所有的分类。

例子代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
entityClient.getCategoriesRequest()
    .asyncCall(new Callback<EntityGetCategoriesResponse>() {

        @Override
        public void onSuccess(EntityGetCategoriesResponse response) {
            // log response in JSON format
            LOG.info(EntityJsonConverter.toPrettyJson(response));

            List<Category> categories = response.getResults();
            for(Category category : categories) {
                // iterate through categories and its child categories.
            }
        }

        @Override
        public void onFailure(Throwable t) {
            LOG.error("Get unsuccessful response or throwable happened when executing the request.", t);
        }
    });
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
entityClient.getCategoriesRequest()
    .asyncCall(object : Callback<EntityGetCategoriesResponse> {

        override fun onSuccess(response: EntityGetCategoriesResponse) {
            // log response in JSON format
            Log.i("sdk", EntityJsonConverter.toPrettyJson(response))

            val categories = response.results
            for (category in categories) {
                // iterate through categories and its child categories.
            }
        }

        override fun onFailure(t: Throwable) {
            Log.e("sdk", Get unsuccessful response or throwable happened when executing the request.", t)
        }
    })

超时说明

默认行为

类型 默认值 说明
连接超时(connect) 5 秒 CloudEntityClientDEFAULT_CONNECT_TIMEOUT_SECONDS = 5
读超时(read) 不限制 未调用 readTimeout,使用 OkHttp 默认 0(无限等待)
写超时(write) 不限制 未调用 writeTimeout,同上
Hybrid 模式选择超时 5 秒 Hybrid 会在云端与车机之间做结果收集/仲裁,单次调用在客户端侧有一个「最多等待多久再判定超时」的配置,单位为 毫秒

如何自定义

在构造 CloudEntityClient 时传入的 SDKOptions 中,若 getCallFactory() 非 null,则 SDK 完全使用你提供的 Call.Factory(一般为自建 OkHttpClient)。

建议在自建 OkHttpClient.Builder 上按需设置:
- connectTimeout(...)
- readTimeout(...)
- writeTimeout(...)

 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
35
36
37
38
39
import com.telenav.sdk.core.SDKOptions;
import com.telenav.sdk.entity.api.EntityClient;
import com.telenav.sdk.entity.api.EntityService;
import com.telenav.sdk.entity.api.error.EntityClientImplNotFoundException;
import com.telenav.sdk.entity.api.error.EntityInitializationFailedException;
import okhttp3.Dispatcher;
import okhttp3.OkHttpClient;
import java.util.concurrent.TimeUnit;
// 与 CloudEntityClient 默认并发上限接近(可选)
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(10);
dispatcher.setMaxRequestsPerHost(10);
OkHttpClient httpClient = new OkHttpClient.Builder()
        .dispatcher(dispatcher)
        .connectTimeout(10, TimeUnit.SECONDS)   // 连接超时
        .readTimeout(30, TimeUnit.SECONDS)     // 读超时(首包 + body)
        .writeTimeout(30, TimeUnit.SECONDS)    // 写超时
        .build();
SDKOptions options = SDKOptions.builder()
        .setApiKey("your-api-key")
        .setApiSecret("your-api-secret")
        .setCloudEndPoint("https://your-endpoint.example.com")
        .setCallFactory(httpClient)            // 关键:整库 HTTP 走该客户端
        .build();
EntityService.initialize(options);
EntityClient client = EntityService.getClient();


//Hybrid:全局默认「选结果」等待时间(毫秒)
//在 EntityService.initialize 的第二个参数里配置(需 ≥ 1000 才会在 Hybrid 上下文里作为有效值参与选择逻辑)。

import com.telenav.sdk.entity.api.EntityService;
import com.telenav.sdk.entity.api.EntityServiceSettings;
EntityService.initialize(
        sdkOptions,
        EntityServiceSettings.builder()
                .hybridSelectionTimeout(8000)   // 8 秒,单位 ms
                .build()
);