Android 实现 Alexa App-to-App Account Linking

前言

Alexa 的 App-to-App Account Linking 指的是将你的 App 账号与 Alexa App 账号进行 “链接”,“链接” 的作用是为了通过 Amazon Echo 系列音箱来语音控制支持 Alexa 的设备。App-to-App Account Linking 有两种方式,分别 ”从您的应用开始“ 和 ”从 Alexa 应用开始“,这篇文章讲的是第一种。

对于没有实现过的小伙伴,第一次实现可能会无从下手,因为 Google 或者百度搜索几乎找不到相关接入的博客,而且 Alexa 的英文文档也是比较难理解的,最重要的是在实现的过程中还会遇到很多坑,所以这里记录一下。

一、“链接” 流程

1.1 界面交互流程

分成是否安装 Alexa App。

  • 已安装 Alexa App:打开 Alexa App,跳转到一个是否同意 “链接” 的页面,点击 “链接” 则返回到你的 App。


  • 未安装 Alexa App:打开浏览器加载 Alexa 登录页面,登录后加载一个是否同意 “链接” 的页面,点击 “链接” 则返回到你的 App。


1.2 底层交互流程

这里贴一张文档中的流程图:


从流程图上可以看到步骤是这样的:
(1)如果用户没有登录那么需要先登录,因为后面后端与 Alxea 交互的时候是需要通过 token 唯一识别某一个用户的。
(2)客户端请求后端获取 Alexa app URL 和 LWA fallback URL。

(3)后端返回对应的 URL。
(4)在页面上点击绑定 Alexa 的时候,如果已安装 Alexa App,则打开 Alexa App,跳转到一个是否同意 “链接” 的页面。点击“链接” 后 Alexa App 会通过 Alexa app URL 中的 redirect_uri 打开你的 App 中指定的页面,并且返回亚马逊授权码;点击取消也是通过 redirect_uri 打开你的 App 中指定的页面。
(5)未安装 Alexa App,则打开浏览器加载 Alexa 登录页面,登录后加载一个是否同意 “链接” 的页面。点击 “链接” 后 Alexa App 会通过 LWA fallback URL 中的 redirect_uri 打开你的 App 中指定的页面,并且返回亚马逊授权码;点击取消也是通过 redirect_uri 打开你的 App 中指定的页面。
(6)客户端拿着亚马逊授权码请求后端,后端去请求亚马逊后端启用技能并 “链接” 账户。
(7)后端返回账户 “链接” 状态,也就是最终绑定成功还是失败。

二、实现

2.1 配置应用链接

Alexa App 打开你的 App 的时候需要通过应用链接跳转回来,所以这里需要先配置应用链接。

(1)添加 Intent 过滤器:

<activity 
    android:name=".xxx.LinkMiddleAppActivity">
    <intent-filter android:autoVerify="true"
        tools:targetApi="m">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="https"
            android:host="www.example.com" />
    </intent-filter>
</activity>
  • android:autoVerify="true":在 Android 6.0 及更高版本的设备上安装应用,系统会去验证应用中的 host,如果与后面配置的 https://xxx/.well-known/assetlinks.json 中的 xxx 匹配,那么系统就会将你的应用指定为处理该 host 的默认程序。
  • scheme+host:组成应用链接 https://www.example.com,打开指定 Activity 的时候就是通过这两个来标记的。

(2)配置 assetlinks.json
通过在线网站 生成 assetlinks.json 内容:

  • Hosting site domain:存放 assetlinks.json 文件的域名,需要与 Intent 过滤器中设置的 host 保持一致,这个域名让后端提供即可。
  • App package name:App 的包名。
  • App package fingerprint (SHA256):App 的 SHA256。

填写完成后点击 “Generate statement” 按钮即可生成 assetlinks.json 内容。

或者手动生成,如下,更改 package_name、sha256_cert_fingerprints 即可:

[{
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
        "namespace": "android_app",
        "package_name": "com.example.app",
        "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
    }
}]

然后创建 assetlinks.json 文件,将上面的内容复制进去,将 assetlinks.json 文件发给后端同事,让他上传到 www.example.com 域名的 .well-known 目录下,然后打开 https://www.example.com/.well-known/assetlinks.json 可以看到配置的内容即可。

最后点击在线网站的 “Test statement” 按钮,如果返回 success 那么就表示 assetlinks.json 文件配置成功了。

(3)测试应用链接
首先将应用安装到手机上,等待 20s 以上,让系统完成异步验证流程。然后在终端执行如下命令:

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "https://www.example.com"

如果可以打开你的应用,那么应用链接配置成功;如果弹框让你选择是使用应用打开还是浏览器打开,或者不弹框直接用浏览器打开,那么应用链接配置失败,需要回去检查上面的配置是否有误。

2.2 配置技能

即在 Alexa 开发者控制台配置技能的相关参数,例如 Alexa app URL、LWA fallback URL 中的一些参数就是在这里配置的,实际上这一步一般都是后端去完成,但是有些后端也没配置过,会导致客户端使用 Alexa app URL、LWA fallback URL 的时候各种报错,所以客户端还是要了解一些主要参数的配置,出现错误的时候才知道是哪里错了并提醒后端改过来。

(1)登录 Alexa Skills Kit 开发者控制台
(2)在技能列表中找到需要配置的技能,选择编辑。
(3)点击左侧栏的 “TOOLS”,然后再点击 “Account linking”。
(4)打开 ”Allow users to link their account to your skill from within your application or website“ 开关,”authorization grant type“ 选择 Auth Code Grant。如下图:

(5)Your Android App Authorization URI 填写 assetlinks.json 文件的地址 https://www.example.com/.well-known/assetlinks.json
(6)Your Redirect URLs 填写应用链接 https://www.example.com
(7)记住这里的 ”Your Client ID“ 和 ”Alexa Client Id“,后端返回的 Alexa app URL 和 LWA fallback URL 中的 client_id 使用的是后者,如果弄错了需要告诉后端改回来,否则打开 Alxea App 会报错。

2.3 获取用户的亚马逊授权码去启用技能并 “链接” 账户

(1)请求后端获取 Alexa app URL 和 LWA fallback URL。
(2)判断 Alexa App 是否安装,已安装打开 Alexa App,未安装打开浏览器加载 Alexa 登录页面(由于浏览器无法通过应用链接跳转回 App,所以这里通过应用内的 WebView 加载)。如下:

private void openAlexaAppToAppUrl() {
    boolean isAlexaInstalled = AppUtils.isAppInstalled("com.amazon.dee.app");
    if (isAlexaInstalled) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(alexaAppUrl));
        startActivity(intent);
    } else {
        CommonWebActivity.start(this, lwaFallbackUrl);
    }
}

com.amazon.dee.app 需要在清单文件中声明,否则在 targetSdkVersion 30 及以上 AppUtils#isAppInstalled() 无效。

<queries>
    <package android:name="com.amazon.dee.app" />
</queries>

如果是打开 Alexa App,用户同意 “链接” 后会通过 Alexa app URL 中的 redirect_uri 打开你的 App 中指定的页面,也就是上面配置了应用链接的 LinkMiddleAppActivity 页面,在该页面获取亚马逊授权码:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Uri uri = getIntent().getData();
    String code = uri.getQueryParameter(”code“);
}

如果是打开 Web 页面,用户同意 “链接” 后会加载一个 Url,亚马逊授权码就在这个 Url 中,在 CommonWebActivity 页面获取到 Url 后将亚马逊授权码取出来即可:

private WebViewClient mWebViewClient = new WebViewClient() {
    ...
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        if (url.contains("code")) {
            Uri uri = Uri.parse(url);
            String code = uri.getQueryParameter(”code“);
        }
    }
    ...
};

(3)拿着亚马逊授权码请求后端,后端去请求亚马逊后端启用技能并 “链接” 账户。然后后端返回账户 “链接” 状态,也就是最终绑定成功还是失败。

三、遇到的一些坑

3.1 无法在 Google Play 搜索到 Alexa App 进行下载

问题:
无法在 Google Play 搜索到 Alexa App。

原因:
在大陆地区下载 Alexa App 需要使用国外的应用市场账号。

解决:

  • 使用国外的应用市场账号进行下载。
  • 在电脑上下载再安装到手机上。

3.2 国内登录 Alexa App 报错

问题:
登录填写验证码的时候提示验证码不正确,或者登录成功后弹框报错:

原因:
国内使用应该是被限制了,Alexa App 判断地区是国内就不给使用。

解决:
更改手机系统地区为美国。

如果上面改了后还不行可以尝试以下操作:

  • 更改系统语言为英文。
  • 翻墙。
  • 关闭定位。
  • 拔掉 SIM 卡。

3.3 Unable to link account with Alexa

问题:
跳转到 Alexa App 后显示 Unable to link account with Alexa,如下:

原因:
后端返回的 Alexa app URL 中的 skill_stage 设置错了。

解决:
技能发布之前 stage 需要设置成 development,发布之后设置成 live。

3.4 跳转到 Alexa app 后不显示提示文字

问题:
跳转到 Alexa app 后不显示提示文字,如图:

原因:
账号被限制了,可能是手机号注册的原因,也可能是识别到是国内登录的原因,总之后面这个账号虽然能登录,但是 Alexa App 中很多功能用不了了,很坑,找了很久原因。

解决:
重新注册一个账号。

四、参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容