|
本文将介绍华为游戏服务,并讲解如何在MVVM架构的移动游戏App中使用游戏服务实现账号登录及认证功能。
游戏服务是华为为移动开发者提供的用于满足各种移动游戏开发需求的服务。使用游戏服务,您可以轻松地在游戏中实现排行榜、事件、成就、存档等功能。游戏服务有效简化游戏的开发过程,让您可以使用简短有序的代码结构创建游戏项目。
华为游戏服务,为您提供以下开发能力,帮助您更高效地开发游戏:
· 帐号登录
· 游戏防沉迷
· 浮标
· 成就
· 事件
· 排行榜
· 游戏存档
· 玩家数据统计
· 游戏基本信息获取
· Android Studio 3.X 及以上版本
· JDK 1.8 及以上版本
· 您的应用应满足以下条件:
— minSdkVersion: 17
— targetSdkVersion: 29
— compileSdkVersion: 29
1.** 集成**
首先,您要先注册成为华为开发者,并将HMS Core集成到项目中。 您可以从下面的链接访问有关该步骤的材料。
https://medium.com/huawei-developers/android-integrating-your-apps-with-huawei-hms-core-1f1e2a090e98
2. 添加依赖
集成HMS Core到项目中并在AGC控制台开启游戏服务之后,将所需依赖的库添加到app目录下的build.gradle文件中,如下所示:
dependencies {implementation 'com.huawei.agconnect:agconnect-auth:1.5.1.300'implementation 'com.huawei.hms:base: 5.0.5.300'implementation 'com.huawei.hms:hwid: 5.2.0.300'implementation 'com.huawei.hms:iap:5.0.1.300'implementation 'com.huawei.hms:game: 5.0.4.302'}
当您的应用启动时,游戏服务由Application类触发启动。游戏服务是在这个类中启动的,而此类和项目一同启动。创建BaseApplication类后,您需要在Manifest文件中定义它。
class BaseApplication : Application(){ companion object{ lateinit var instance: BaseApplication private set } override fun onCreate() { super.onCreate() instance = this HuaweiMobileServicesUtil.setApplication(this) HwAds.init(this) }}
在所有权限和库都添加到项目中后,您可以开始为您的游戏开发登录页面。此时就用到了华为认证服务。认证服务使您可以在控制台上查看游戏的所有用户。此外,认证服务还提供了多种登录方式:包含Facebook、Twitter、Google、邮箱、电话号码或华为ID。我将分享一个通用的登录页面设计。以下是一个使用华为ID登录的示例。
您可以在以下链接查看认证服务的文档:
https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agc-auth-introduction-0000001053732605?ha_source=hms1
<androidx.constraintlayout.motion.widget.MotionLayout 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" app:layoutDescription="@xml/motion_scene_splash" android:id="@+id/id_09" android:layout_height="match_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:src="@drawable/background" android:alpha="0.7" android:id="@+id/id_11"/> <ImageView android:id="@+id/imgView_logo" android:layout_width="130dp" android:layout_height="130dp" android:layout_marginTop="80dp" android:scaleType="centerInside" android:src="@drawable/vs_logo" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/imgView_logo_rays" android:layout_width="130dp" android:layout_height="130dp" android:layout_marginTop="80dp" android:scaleType="centerInside" android:src="@drawable/vs_logo" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/imgView_cloudLeft" android:layout_width="130dp" android:layout_height="130dp" android:layout_marginTop="16dp" android:scaleType="centerInside" android:src="@drawable/cloud" android:translationX="-20dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:tint="#9E9E9E" /> <ImageView android:id="@+id/imgView_cloudRight" android:layout_width="130dp" android:layout_height="130dp" android:layout_marginTop="120dp" android:scaleType="centerInside" android:src="@drawable/cloud" android:translationX="20dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:tint="#607D8B" /> <LinearLayout android:id="@+id/linlay_inputs" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="30dp" android:alpha="1" android:layout_marginLeft="30dp" android:layout_marginEnd="30dp" android:layout_marginRight="30dp" android:gravity="center" android:layout_marginTop="10dp" android:orientation="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imgView_cloudRight"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/muli_regular" android:text="Welcome Back" android:textColor="#000000" android:textSize="20sp" android:id="@+id/id_12" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@font/muli_regular" android:text="Sign in to continue" android:textColor="#000000" android:textSize="14sp" android:id="@+id/id_13" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@drawable/et_background" android:drawableStart="@drawable/ic_baseline_email_24" android:drawableLeft="@drawable/ic_baseline_email_24" android:drawablePadding="16dp" android:hint="Email" android:inputType="textEmailAddress" android:padding="16dp" android:textSize="14sp" android:textColor="#000000" android:fontFamily="@font/muli_regular" android:id="@+id/id_14"/> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="@drawable/et_background" android:drawableStart="@drawable/ic_baseline_lock_24" android:drawableLeft="@drawable/ic_baseline_lock_24" android:drawableEnd="@drawable/ic_baseline_visibility_24" android:drawableRight="@drawable/ic_baseline_visibility_24" android:drawablePadding="16dp" android:hint="Password" android:inputType="textPassword" android:padding="16dp" android:textSize="14sp" android:textColor="#000000" android:fontFamily="@font/muli_regular" android:id="@+id/id_15"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:background="@drawable/button_one" android:text="@string/signInButton" android:textAllCaps="false" android:fontFamily="@font/muli_regular" android:textColor="#7E675E" android:id="@+id/id_16"/> </LinearLayout> <TextView android:id="@+id/tv_forgotPassword" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginEnd="30dp" android:alpha="1" android:layout_marginRight="30dp" android:text="Forgot Password?" android:textColor="#7E675E" android:textSize="13sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/linlay_inputs" /> <ImageView android:id="@+id/safads" android:layout_width="wrap_content" android:layout_height="100dp" android:src="@drawable/color_logo" app:tint="#9E9E9E" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/linlay_inputs" android:visibility="invisible"/> </androidx.constraintlayout.motion.widget.MotionLayout>
LoginViewModel类将从View类接收、处理数据并将处理过的数据发送到View类。所有的登录操作都将在LoginViewModel类中完成。
首先,在HuaweiIdAuthService对象中创建客户端。
private lateinit var mClient: HuaweiIdAuthService
接下来是开发帐户注销。这样做的目的是结束应用中打开的会话。注销后,我们需要创建login方法。首先,调用logout方法。然后添加startActivityForResult方法,并将其在View类重写。
LoginViewModel类如下所示:
class LoginViewModel(private val context: Context): ViewModel(){ private lateinit var mClient: HuaweiIdAuthService fun login(fragment: Fragment){ logout() val huaweiIdAuthParamsHelper =HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM) val scopeList: MutableList<Scope> = ArrayList() scopeList.add(Scope(HwIDConstant.SCOPE.ACCOUNT_BASEPROFILE)) huaweiIdAuthParamsHelper.setScopeList(scopeList) val authParams = huaweiIdAuthParamsHelper.setAccessToken().createParams() mClient = HuaweiIdAuthManager.getService(context, authParams) fragment.startActivityForResult(mClient.signInIntent, 1002) } fun logout(){ Log.i(Constants.LOGIN_VIEWMODEL_TAG, "In LogOut Fun.") val auth = AGConnectAuth.getInstance() auth.signOut() }}创建LoginViewModelFactory类,并将上下文设置为参数。此类将返回ViewModel类。class LoginViewModelFactory(private val context: Context): ViewModelProvider.NewInstanceFactory(){ override fun <T : ViewModel?> create(modelClass: Class<T>): T { return LoginViewModel(context) as T }}
在XML文件上添加ViewModel依赖,并将它作为绑定对象。你需要再次打开XML文件,添加变量“viewmodel”,将type添加为ViewModel类目录。
<data> <variable name="viewmodel" type="com.xxx.xxx.viewmodel.LoginViewModel"/></data>
返回LoginFragment并添加工厂类、viewmodel类,并进行绑定。
private lateinit var binding: FragmentLoginBindingprivate lateinit var viewModel: LoginViewModelprivate lateinit var viewModelFactory: LoginViewModelFactory
在onCreateView方法上定义这些对象。
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { binding = DataBindingUtil.inflate(inflater, R.layout.activity_splash_login, container,false) as ActivitySplashLoginBinding viewModelFactory =LoginViewModelFactory(requireContext() ) viewModel = ViewModelProviders.of(this, viewModelFactory).get(LoginViewModel::class.java) return binding.root }
创建登录按钮点击事件监听,并在ViewModel类中调用login方法。
var gameLoginButton = binding.id16.findViewById<View>(R.id.id_16)gameLoginButton.setOnClickListener { showProgressDialog() viewModel.login(this)}
最后,创建onActivityResult方法,查看登录结果。如果登录成功,您可以看到一些用户信息,比如用户名、ID、国家/地区、年龄等。认证服务提供了丰富的用户信息,您可以在App中使用认证服务。
override fun onActivityResult( requestCode: Int, resultCode: Int, @Nullable data: Intent? ) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == 1002) { val signInHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data) if (signInHuaweiIdTask.isSuccessful) { val huaweiAccount = signInHuaweiIdTask.result val accessToken = huaweiAccount.accessToken Log.w(Constants.LOGIN_FRAGMENT_TAG, "accessToken: $accessToken") val credential = HwIdAuthProvider.credentialWithToken(accessToken) val provider_now = credential.provider Log.w(Constants.LOGIN_FRAGMENT_TAG, "provider_now: $provider_now") AGConnectAuth.getInstance().signIn(credential) .addOnSuccessListener { signInResult -> val user = AGConnectAuth.getInstance().currentUser Log.w(Constants.LOGIN_FRAGMENT_TAG, "Login Success. User Display Name : " + user.displayName) userName = user.displayName //Start another fragment here. (activity as MainActivity?)!!.setSelectedTab(Constants.TAB_LOGIN,Constants.TAB_HOME,false) dismisProgressDialog() }.addOnFailureListener { e: Exception -> Toast.makeText(context, R.string.authenticationError, Toast.LENGTH_SHORT).show() Log.w(Constants.LOGIN_FRAGMENT_TAG, "sign in for agc failed: " + e.message) dismisProgressDialog() } } else { Toast.makeText(context, R.string.sgnInError, Toast.LENGTH_SHORT).show() Log.e(Constants.LOGIN_FRAGMENT_TAG,"sign in failed : " + (signInHuaweiIdTask.exception as ApiException).statusCode) dismisProgressDialog() } } }
结论
现在您可以在游戏App上实现登录功能啦。您也可以跟我一样选择使用认证服务,因为它可以为您提供多种用户信息,您可以在AGC控制台中查看所有用户。
在下一篇文章中,我将介绍“构建成就”(为游戏玩家自定义配置成就(最高200个),增加玩家的新鲜感和成就感,鼓励玩家持续参与),并提供一个示例。请关注第二篇文章,以简洁的结构开发您的游戏应用。
参考
游戏服务文档
认证服务文档
欲了解HMS Core更多详情,请参阅: >>华为开发者联盟官网[quote]
获取开发指导文档 >>参与开发者讨论请到CSDN社区或者Reddit社区 >>下载demo和示例代码请到Github或者Gitee >>解决集成问题请到Stack Overflow [/quote]
原文链接:https://developer.huawei.com/consumer/cn/forum/topic/0201550888629240197?fid=18
原作者:胡椒 |
|