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 中很多功能用不了了,很坑,找了很久原因。

解決:
重新註冊一個賬號。

四、參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章