Android使用HMS Toolkit接入HMS

1,189 阅读4分钟

前言

华为移动服务(Huawei Mobile Services,缩写HMS)是华为云服务开放能力的合集

华为移动服务核心(HMS Core)指的是华为终端云服务开放能力合集

使用HMS和HMS Core可以让用户在开发项目中快速对接HMS提供的各类服务(账号登录、支付、地图、人脸等)

Android studio 利用HMS Toolkit工具开发集成HMS

新建一个项目

推荐JDK1.8及以上、Android SDK21及以上

下载插件HMS Toolkit

在顶部工具栏中File->Settings->Plugins中查找HMS Toolkit

image.png 点击Install安装成功之后,重启AS,便可

重启之后,在顶部栏会生成HMS工具菜单

image.png

在使用之前需要进入华为开发者联盟进行注册,具体注册详情参考注册帐号

注册之后,点击Sign in进行登录

点击Configiration Wizard进行环境集成,会显示如下界面

image.png 点击Link

会进入项目管理界面

点击添加项目,输入项目名称

点击添加应用

image.png 注意应用包名需要与项目包名一致,点击确认之后回到AS,点击Link下面的Retry

image.png 出现这个就可以正常进入下一步

点击Add Kits选择服务,这边便选择一个账号服务进行测试

image.png

Confirm之后

image.png 会需要让你选择签名文件,这边有两种方式

  1. 新建一个签名文件
  2. 选择一个创建好的签名文件

方法一可以参考

Android Studio如何创建密钥库及密钥 - alxe_yu - 博客园 (cnblogs.com)

创建好之后,输入密匙密码,Alias,点击Generate生成SHA256指纹,Next下一步

image.png

等待创建好,就可以愉快的使用他的HMS服务啦

调试账号服务

image.png

基于上一步点击Go之后会弹出对应教程,这边是调试就不一步步跟着敲了把对应代码复制进项目

点击华为账号服务或进入官网查看教程

移动与智慧屏应用快速接入华为帐号-场景化开发-Android-华为帐号服务 (huawei.com) 将静默登录代码编写好之后

image.png

选择如图点击,可以使用官方云调试机进行调试

image.png 点击按钮出现登录界面代表接入服务成功

image.png

最后贴上源代码

package com.huawei.hmstestdome1

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import com.huawei.hms.common.ApiException
import com.huawei.hms.support.account.AccountAuthManager
import com.huawei.hms.support.account.request.AccountAuthParams
import com.huawei.hms.support.account.request.AccountAuthParamsHelper
import com.huawei.hms.support.account.result.AuthAccount
import com.huawei.hms.support.account.service.AccountAuthService
import com.huawei.hms.support.api.entity.common.CommonConstant

class MainActivity : AppCompatActivity() {

    // 华为帐号登录授权服务,提供静默登录接口silentSignIn,获取前台登录视图getSignInIntent,登出signOut等接口
    private var mAuthService: AccountAuthService? = null

    // 华为帐号登录授权参数
    private var mAuthParam: AccountAuthParams? = null

    // 用户自定义signInIntent请求码
    private val REQUEST_CODE_SIGN_IN = 1000

    // 用户自定义日志标记
    private val TAG = "Account"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<View>(R.id.HuaweiIdAuthButton).setOnClickListener { silentSignInByHwId() }
    }

    /**
     * 静默登录,如果设备上的华为帐号系统帐号已经登录,并且用户已经授权过,无需再拉起登录页面和授权页面,
     * 将直接静默登录成功,在成功监听器中,返回帐号信息;
     * 如果华为帐号系统帐号未登录或者用户没有授权,静默登录会失败,需要显式拉起前台登录授权视图。
     */
    private fun silentSignInByHwId() {
        // 1、配置登录请求参数AccountAuthParams,包括请求用户id(openid、unionid)、email、profile(昵称、头像)等。
        // 2、DEFAULT_AUTH_REQUEST_PARAM默认包含了id和profile(昵称、头像)的请求。
        // 3、如需要请求获取用户邮箱,需要setEmail();
        mAuthParam = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
            .setEmail()
            .createParams()

        // 使用请求参数构造华为帐号登录授权服务AccountAuthService
        mAuthService = AccountAuthManager.getService(this, mAuthParam)

        // 使用静默登录进行华为帐号登录
        val task = mAuthService!!.silentSignIn()
        task.addOnSuccessListener { authAccount -> // 静默登录成功,处理返回的帐号对象AuthAccount,获取帐号信息
            dealWithResultOfSignIn(authAccount)
        }
        task.addOnFailureListener { e -> // 静默登录失败,使用getSignInIntent()方法进行前台显式登录
            if (e is ApiException) {
                val apiException = e
                val signInIntent = mAuthService!!.getSignInIntent()
                // 如果应用是全屏显示,即顶部无状态栏的应用,需要在Intent中添加如下参数:
                // intent.putExtra(CommonConstant.RequestParams.IS_FULL_SCREEN, true)
                // 具体详情可以参见应用调用登录接口的时候是全屏页面,为什么在拉起登录页面的过程中顶部的状态栏会闪一下?应该如何解决?
                signInIntent.putExtra(CommonConstant.RequestParams.KEY_SIGN_IN_PARAMS, true)
                startActivityForResult(signInIntent, REQUEST_CODE_SIGN_IN)
            }
        }
    }

    /**
     * 处理返回的AuthAccount,获取帐号信息
     *
     * @param authAccount AuthAccount对象,用于记录帐号信息
     */
    private fun dealWithResultOfSignIn(authAccount: AuthAccount) {
        // 获取帐号信息
        Log.i(TAG, "display name:" + authAccount.getDisplayName())
        Log.i(TAG, "photo uri string:" + authAccount.avatarUriString)
        Log.i(TAG, "photo uri:" + authAccount.avatarUri)
        Log.i(TAG, "email:" + authAccount.getEmail())
        Log.i(TAG, "openid:" + authAccount.getOpenId())
        Log.i(TAG, "unionid:" + authAccount.getUnionId())
        // TODO 获取用户信息后业务逻辑
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE_SIGN_IN) {
            Log.i(TAG, "onActivitResult of sigInInIntent, request code: " + REQUEST_CODE_SIGN_IN)
            val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
            if (authAccountTask.isSuccessful) {
                // 登录成功,获取到登录帐号信息对象authAccount
                val authAccount = authAccountTask.result
                dealWithResultOfSignIn(authAccount)
                Log.i(TAG, "onActivitResult of sigInInIntent, request code: " + REQUEST_CODE_SIGN_IN)
            } else {
                // 登录失败,status code标识了失败的原因,请参见API参考中的错误码了解详细错误原因
                Log.e(TAG, "sign in failed : " + (authAccountTask.exception as ApiException).statusCode)
            }
        }
    }
}


布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- Define an ID for the button control. -->
    <com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton
        android:id="@+id/HuaweiIdAuthButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

其他服务,后后续慢慢更新。