跳转至

第三方应用跳转入口

最后更新:

入口协议 1,稳定接口。从包含本功能的 EVCC 3.3.1 更新包起提供。早期同版本 APK 可能没有这些 入口,请以 Intent 能否解析为准,不要只比较 versionName。这些入口不要求接入 EVCC SDK 或绑定 Binder。

地址与参数

用途 Scheme URL 等价 Intent Action
应用商店详情与更新 evcc://store/app?package=com.example.app com.kooo.evcc.action.OPEN_STORE_APP
Android 权限管理 evcc://permissions/app?package=com.example.app com.kooo.evcc.action.OPEN_APP_PERMISSIONS
EVCC 开放 API 应用授权 evcc://api/authorize?package=com.example.app com.kooo.evcc.action.OPEN_API_AUTHORIZATION

Intent Action 使用字符串 Extra package_name。Scheme URL 使用查询参数 package。目标包名必填, 建议传调用应用自己的 context.packageName;EVCC 根据目标应用的真实名称和包名显示页面,不接受外部 指定的应用名称、权限列表、下载地址或执行命令。

包名须为点分隔的 Android 应用包名,每段以英文字母开头、后续为字母、数字或下划线,最长 255 字符。 Scheme 的 host、路径和参数名使用表中的小写形式;仅接受表中的路径,不接受重复的 package 参数、 额外查询参数、端口、用户信息或 fragment。Intent Action 不附带 URI。入口目前不支持回调结果。

商店入口的行为

EVCC 切到下载站的应用商店,在用户当前选择的商店站点中跨分类、跨分页按完整包名精确匹配, 找到后打开应用详情。EVCC 自身的版本条目遵循用户选择的更新通道。

同一包名有多个可用条目时,优先选择 Android versionCode 最高的条目,版本代码相同时选择更新时间 较新的条目,避免因分类顺序打开旧版本。

详情页沿用现有的版本比较、更新按钮、安装引导与授权流程。用户须点击更新或安装,跳转本身不会 下载或安装 APK,也不会绕过应用的安装授权。应用不必已安装,商店仍可显示安装详情。

如果应用未在当前站点上架、已下架或没有可用版本,EVCC 会显示“当前商店站点未找到应用”,用户可 切换站点后重新发起跳转。网络或商店服务失败会显示错误,不会打开其他包名或同名应用。

Android 权限入口的行为

EVCC 切到应用管理,检查当前 Android 用户是否已安装目标应用,再打开该应用的权限管理窗口。 窗口显示真实应用名称及包名,用户可逐项操作或点击现有的“一键授予”。仅声明特殊权限或服务的 应用也可以打开此窗口。

跳转不会自动授予、撤销权限或启用无障碍服务。实际可授予的权限取决于车机系统、应用声明和 EVCC 运行服务的 UID/权限;连接成功不代表所有权限都能授予。目标应用未安装、运行服务未连接或页面不可用时, EVCC 会显示原因。这里管理的是 Android 系统权限。

车辆属性、变量、音乐等 EVCC 开放 API 权限使用下一节的按应用授权入口。两套权限相互独立。

EVCC 开放 API 按应用授权

evcc://api/authorize?package=com.example.app 直接打开该已安装应用的开放 API 权限窗口,跳过应用列表。 已有授权时显示当前保存的权限,新授权仍默认选择 STANDARD。用户可以选择包括 ALL 在内的预设, 逐项调整并保存。新增敏感权限需确认风险,系统写入仍需逐次在车机端确认。

入口只接收包名,不接受 preset、permissions 或自动保存参数;第三方应用不能借跳转预选全部权限、 扩大现有授权或跳过确认。应用未安装或开放 API 功能不可用时会显示原因。返回第三方应用后,重新 连接开放 API 并读取真实 grantedPermissions,参见权限与应用授权。

当前源码 SDK 提供 client.openAuthorization(),不要求先绑定或获得授权。没有该方法的已发布 SDK 可直接使用表中的 Intent Action。旧版可回退到 com.kooo.evcc.evccapi.OPEN_SETTINGS 或 client.openSettings(),打开控制台后手动选择应用。OPEN_SETTINGS 在新版本也接受可选 package_name Extra;未传时仍打开原来的控制台。

Kotlin:推荐使用 Intent Action

使用指定 EVCC 包名的隐式 Intent,可以避免其他应用接管相同 scheme。旧版 EVCC 没有注册 Action 时, 调用会失败,应用应给出更新 EVCC 或手动操作的提示,不要循环拉起页面。

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent

fun openEvccPage(context: Context, action: String): Boolean {
    val intent = Intent(action)
        .setPackage("com.kooo.evcc")
        .putExtra("package_name", context.packageName)
        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    return try {
        context.startActivity(intent)
        true
    } catch (_: ActivityNotFoundException) {
        false // EVCC 未安装,或当前版本没有这个入口
    } catch (_: SecurityException) {
        false // 系统不允许启动该页面
    }
}

// “前往更新”按钮
openEvccPage(context, "com.kooo.evcc.action.OPEN_STORE_APP")

// “前往授予权限”按钮
openEvccPage(context, "com.kooo.evcc.action.OPEN_APP_PERMISSIONS")

// “前往开放 API 授权”按钮
openEvccPage(context, "com.kooo.evcc.action.OPEN_API_AUTHORIZATION")

返回 true 只表示系统接受了启动请求,不表示商店找到应用、用户完成安装或权限已经授予。 第三方应用返回前台后应重新检查自己的版本或所需权限;开放 API 客户端应按其会话重连流程重新检查授权。

Kotlin:使用 Scheme URL

import android.net.Uri

val uri = Uri.Builder()
    .scheme("evcc")
    .authority("permissions") // 商店为 "store";开放 API 为 "api"
    .path("/app") // 开放 API 使用 "/authorize"
    .appendQueryParameter("package", context.packageName)
    .build()

val intent = Intent(Intent.ACTION_VIEW, uri)
    .setPackage("com.kooo.evcc")
    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
// 与上例一样,捕获 ActivityNotFoundException 和 SecurityException。
context.startActivity(intent)

网页中的链接也可使用这些 scheme,但能否拉起取决于浏览器及车机系统。Android 应用优先使用 指定包名的 Intent Action;不要通过显式指定 MainActivity 检测支持,否则旧版可能只打开首页。

Java 示例

public static boolean openEvccPermissions(android.content.Context context) {
    android.content.Intent intent = new android.content.Intent(
        "com.kooo.evcc.action.OPEN_APP_PERMISSIONS")
        .setPackage("com.kooo.evcc")
        .putExtra("package_name", context.getPackageName())
        .addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
    try {
        context.startActivity(intent);
        return true;
    } catch (android.content.ActivityNotFoundException | SecurityException error) {
        return false;
    }
}

商店入口将 Action 换成 com.kooo.evcc.action.OPEN_STORE_APP,其余相同。

支持检测与 Android 11 包可见性

若应用需要提前调用 resolveActivity() 检测入口,在 Manifest 中声明:

<queries>
    <package android:name="com.kooo.evcc" />
</queries>

再对与调用示例相同的 Intent 执行 intent.resolveActivity(context.packageManager) != null。 即使检测成功,启动时仍应捕获异常。启动请求成功也不代表 EVCC 已激活或页面功能可用。

页面保护与调试

冷启动与 EVCC 已打开时使用相同入口。EVCC 的激活、版本功能授权、维护状态和安全密码检查继续生效; 受保护的主页或目标页要求用户解锁,取消解锁不会打开权限窗口。连续发起跳转时,新的有效请求替换 尚未完成的请求;EVCC 退到后台时会取消未完成的页面加载,回到前台后重新处理仍有效的请求。

以下命令仅打开页面。请将示例包名替换为自己的包名:

adb shell am start -a android.intent.action.VIEW -d 'evcc://store/app?package=com.example.app' -p com.kooo.evcc
adb shell am start -a com.kooo.evcc.action.OPEN_APP_PERMISSIONS -p com.kooo.evcc --es package_name com.example.app
adb shell am start -a com.kooo.evcc.action.OPEN_API_AUTHORIZATION -p com.kooo.evcc --es package_name com.example.app

建议在目标车机验证冷启动、已打开、返回应用、未安装应用、未上架应用、无网络、受保护页面和连续跳转。 页面显示或单元测试通过不能代替实际更新、权限授予与车型兼容验收。