This article will introduce Huawei game services, and explain how to use game services to achieve account login and authentication functions in MVVM mobile game APP.

What is a game service?

Game Service is a service provided by Huawei for mobile developers to meet various mobile game development needs. With Game Services, you can easily implement leaderboards, events, achievements, save and other functions in your game. Game Services simplifies the game development process, allowing you to create game projects with a short, orderly code structure.

Huawei Game Services provides you with the following development capabilities to help you develop games more efficiently:

· Account login

· Game addiction prevention

Buoy,

Achievement,

The event,

List,

· Game Archive

· Player statistics

· Obtaining basic information of the game

Software and hardware requirements

· Android Studio 3.x and above

· JDK 1.8 and above

· Your application should meet the following conditions:

– minSdkVersion: 17

– targetSdkVersion: 29

– compileSdkVersion: 29

The development process

Integration of 1.

First, you need to register as a Huawei developer and integrate HMS Core into your project. You can access material about this step from the link below.

https://medium.com/huawei-dev…

2. Add dependencies

After integrating the HMS Core into the project and starting the Game Service in the AGC console, add the required dependent libraries to the build.gradle file in the app directory, as shown below:

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. Create Application class

When your Application starts, the game service is triggered by the Application class. The game service is started in this class, and this class is started with the project. After creating the BaseApplication class, you need to define it in the Manifest file.

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. Design the landing page

After all the permissions and libraries have been added to the project, you can start developing the login page for your game. This is where Huawei certification services are used. Authentication services allow you to view all users of a game from the console. In addition, the authentication service provides multiple login methods: including Facebook, Twitter, Google, email, phone number, or Huawei ID. I’m going to share a common landing page design. Here is an example of using Huawei ID to log in.

You can view the documentation of the authentication service at the following link:

https://developer.huawei.com/…

<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>

5. Create LoginViewModel class

The LoginViewModel class receives, processes, and sends processed data from the View class to the View class. All login operations will be done in the LoginViewModel class.

First, create the client in the HUAWeiidAuthService object.

private lateinit var mClient: HuaweiIdAuthService

Next is the development account logout. The purpose of this is to end an open session in the application. Once logged off, we need to create the login method. First, call the logout method. Then add the StartactivityForResult method and override it in the View class.

The LoginViewModel class looks like this:

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()
    }
}

Create LoginViewModelFactory class

Create the LoginViewModelFactory class and set the context as a parameter. This class returns the ViewModel class.

class LoginViewModelFactory(private val context: Context): ViewModelProvider.NewInstanceFactory(){ override fun <T : ViewModel? > create(modelClass: Class<T>): T { return LoginViewModel(context) as T } }

7. Create LoginFragment

Add a ViewModel dependency to the XML file and use it as a binding object. You need to open the XML file again, add the variable “ViewModel”, and add Type as the ViewModel class directory.

<data>
    <variable
        name="viewmodel"
        type="com.xxx.xxx.viewmodel.LoginViewModel"/>
</data>

Return to LoginFragment and add factory class, ViewModel class, and bind.

private lateinit var binding: FragmentLoginBinding
private lateinit var viewModel: LoginViewModel
private lateinit var viewModelFactory: LoginViewModelFactory

Define these objects on the onCreateView method.

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 }

Create a login button click event listener and call the login method in the ViewModel class.

var gameLoginButton = binding.id16.findViewById<View>(R.id.id_16)
gameLoginButton.setOnClickListener {
    showProgressDialog()
    viewModel.login(this)
}

Finally, create the onActivityResult method to see the login result. If the login is successful, you can see some user information, such as user name, ID, country/region, age, and so on. Authentication service provides a wealth of user information, you can use authentication service in the 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 {Toad.Maketext (context, R.String.s, PENDGNINError, Toast.LENGTH_SHORT).show() Log.e(Constants.LOGIN_FRAGMENT_TAG,"sign in failed : " + (signInHuaweiIdTask.exception as ApiException).statusCode) dismisProgressDialog() } } }

conclusion

Now you can log in to the game App. You can also choose to use the authentication service as I did, because it provides you with a variety of user information, and you can view all users in the AGC console.

In the next article, I’ll look at “building achievements” (configuring achievements for your players to customize (up to 200) to increase the player’s sense of freshness and accomplishment, and to encourage continued engagement), and provide an example. Pay attention to the second article to develop your game application with a clean structure.

reference

Game Service Documentation

Authentication service document

For more details on HMS Core, please refer to: Huawei Developer Union official website to get development guidance documents and participate in developer discussions. Please download demos and sample code from CSDN or Reddit

The original link: https://developer.huawei.com/… Author: Pepper