基於MVVM架構的遊戲App如何整合華為遊戲服務(一)——登入認證
本文將介紹華為遊戲服務,並講解如何在 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' }
3 . 建立 Application類
當您的應用啟動時,遊戲服務由 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) } }
4. 設計登入頁面
在所有許可權和庫都新增到專案中後,您可以開始為您的遊戲開發登入頁面。此時就用到了華為認證服務。認證服務使您可以在控制檯上檢視遊戲的所有使用者。此外,認證服務還提供了多種登入方式:包含 Facebook、 Twitter、 Google、郵箱、電話號碼或華為 ID。我將分享一個通用的登入頁面設計。以下是一個使用華為 ID登入的示例。
您可以在以下連結檢視認證服務的文件:
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android=" xmlns:app=" xmlns: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>
5. 建立 LoginViewModel類
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() } }
6. 建立 LoginViewModelFactory類
建立 LoginViewModelFactory類,並將上下文設定為引數。此類將返回 ViewModel類。
class LoginViewModelFactory(private val context: Context): ViewModelProvider.NewInstanceFactory(){ override fun <T : ViewModel?> create(modelClass: Class<T>): T { return LoginViewModel(context) as T } }
7. 建立 LoginFragment
在 XML檔案上新增 ViewModel依賴,並將它作為繫結物件。你需要再次開啟 XML檔案,新增變數 “viewmodel”,將 type新增為 ViewModel類目錄。
<data> <variable name="viewmodel" type="com.xxx.xxx.viewmodel.LoginViewModel"/> </data>
返回 LoginFragment 並新增工廠類、 viewmodel 類,並進行繫結。
private lateinit var binding: FragmentLoginBinding private lateinit var viewModel: LoginViewModel private 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.sıgnInError, Toast.LENGTH_SHORT).show() Log.e(Constants.LOGIN_FRAGMENT_TAG,"sign in failed : " + (signInHuaweiIdTask.exception as ApiException).statusCode) dismisProgressDialog() } } }
結論
現在您可以在遊戲 App上實現登入功能啦。您也可以跟我一樣選擇使用認證服務,因為它可以為您提供多種使用者資訊,您可以在 AGC控制檯中檢視所有使用者。
在下一篇文章中,我將介紹“構建成就”( 為遊戲玩家自定義配置成就(最高 200個),增加玩家的新鮮感和成就感,鼓勵玩家持續參與 ),並提供一個示例。請關注第二篇文章,以簡潔的結構開發您的遊戲應用。
參考
欲瞭解
HMS Core
更多詳情,請參閱:
>>
華為開發者聯盟官網
>>
獲取開發指導文件
>>
參與開發者討論請到
CSDN社群
或者
Reddit
社群
>>
下載
demo
和示例程式碼請到
Github
或者
Gitee
>>
解決整合問題請到
Stack Overflow
原文連結: https://developer.huawei.com/consumer/cn/forum/topic/0201550888629240197?fid=18
原作者:胡椒
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69970551/viewspace-2782022/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於滴滴雲的棋牌遊戲服務端架構設計遊戲服務端架構
- 如何在Flutter中整合華為認證服務Flutter
- 華為遊戲登入校驗異常遊戲
- 遊戲架構 遊戲架構設計(8)遊戲架構
- iOS平臺 | 快速整合華為AGC認證服務iOSGC
- 華納娛樂遊戲登入-19188190807遊戲
- 使用unity完成華為遊戲的初始化和華為帳號登入Unity遊戲
- 華為遊戲登入多次重複提醒更新HMS Core遊戲
- Go遊戲服務端框架從零搭建(一)— 架構設計Go遊戲服務端框架架構
- 【Serverless】Unity快速整合認證服務實現郵件登入ServerUnity
- 遊戲引擎Cocos接入HMS Core,華為推送服務擁抱遊戲開發者!遊戲引擎遊戲開發
- 整合spring cloud雲架構 - SSO單點登入之OAuth2.0登入認證SpringCloud架構OAuth
- 華為遊戲登入驗籤失敗can not find publicKey of the cp遊戲
- 重新認識Java微服務架構-認證服務Java微服務架構
- 如何在遊戲陪玩app原始碼中實現簡訊驗證碼登入?遊戲APP原始碼
- 整合spring cloud雲架構 - SSO單點登入之OAuth2.0登入認證(1)SpringCloud架構OAuth
- 微服務架構 | 7.1 基於 OAuth2 的安全認證微服務架構OAuth
- 遊戲登陸主機的認證測試該怎麼做?遊戲
- 華為聯運遊戲或應用稽核駁回:點選登入進入遊戲,未顯示歡迎欄遊戲
- 如何避免遊戲炸服——遊戲上線的RoadMap遊戲
- 【程式設計師的遊戲開發之路】 遊戲架構程式設計師遊戲開發架構
- 華為遊戲中心花瓣遊戲開發者服務持續升級,賦能高效研運遊戲開發
- 遊戲陪玩原始碼的登入方式,簡訊驗證碼登入的實現遊戲原始碼
- 如何認識遊戲“節奏”遊戲
- 遊戲伺服器的常用架構遊戲伺服器架構
- 遊戲為什麼老愛讓玩家滾服? 遊戲滾服的前世今生遊戲
- 遊戲伺服器 遠端登入遊戲伺服器工具遊戲伺服器
- 如何在steam上架一款遊戲遊戲
- 信不信?各種紅包App最後都會整合遊戲!App+遊戲的變現模式分析APP遊戲模式
- 遊戲即服務的五條建議,提升遊戲變現能力遊戲
- 遊戲伺服器架構概要遊戲伺服器架構
- 2.基於CAS SSO單點登入服務端環境搭建架構原始碼服務端架構原始碼
- 2.基於CAS SSO單點登入服務端環境搭建+架構原始碼服務端架構原始碼
- 蘋果新規:禁止新冠疫情為主題的娛樂和遊戲App !已有遊戲被下架蘋果遊戲APP
- jwt 如何實現一個服務認證了另一個服務也可以認證JWT
- EMQX 登入認證,通過外部自建HTTP服務控制MQHTTP
- 華為遊戲試玩不生效遊戲
- TGA“遊戲嘉年華”公佈,13款遊戲限時Demo上架遊戲