専門家:クーリエアプリMVVM Jetpack(HMSアカウントとAuthService)Kotlinを使用しているアンドロイド-パート1
24207 ワード
概要
この記事では、私はHMSのアカウントとAuthServiceキットなどのHMSコアキットを統合するKotlinを使用してクーリエAndroidアプリケーションを作成します.
アプリケーションは、DataBinding、AndroidViewModel、オブザーバー、LiveDataなどのJetpackのコンポーネントを使用してAndroid MVVMのクリーンなアーキテクチャを使用するようになります.
本稿では,観測可能なパターンを用いたデータベース化を実装する.
Huawei IDサービス紹介
Huawei IDログインシンプルかつ安全な、迅速なサインインと認証機能を提供します.代わりにアカウントとパスワードを入力し、認証を待っているだけで、ユーザーはすぐにHuawei IDボタンを使用してHuawei IDを使用してアプリケーションに迅速かつ安全にサインをタップすることができます.
前提条件
Huawei電話エミュ3.0以降.
非Huawei電話アンドロイド4.4以降(APIレベル19以上).
HMSコアAPK
アンドロイド
アカウントアカウント
ログインして、AppGallery Connectポータルのプロジェクトを作成または選択します.
プロジェクトの設定に移動し、設定ファイルをダウンロードします.
一般的な情報に移動し、データストレージの場所を提供します.
アプリ開発
必要な依存関係を追加します.
Androidのスタジオを起動し、新しいプロジェクトを作成します.プロジェクトが完了したら.
Gradleスクリプトフォルダに移動し、ビルドを開きます.Gradle (モジュール: app ).
次のパッケージモデル、イベント、ViewModelを作成しました.
モデル:プライマリフォルダで新しいパッケージを作成し、モデル名を指定します.次に、ユーザーを作成します.このパッケージのKTファイル.
LoginViewModel.KT
UIにデータバインディングを含めるには、すべてのコンテンツをエンクロージャします.
表示されるように、セクションのレイアウトにViewModelが導入されます.タイプ値が必要なViewModelを持つ特定のフォルダーにポイントしていることを確認します.
メインアクティビティ.KT : Huawei IDログイン用に実装.
「パッケージコム.HMSコルリエレープ
アンドロイド.os束
アンドロイド.ウィジェット.トースト
輸入アンドロイド.appcompatアプリ.appcompatactivity
輸入アンドロイド.データベース化.データグラム
輸入アンドロイド.ライフサイクル.観測者
輸入アンドロイド.ライフサイクル.ビューモデラー
インポートCOM.HMSコルリアーナップ.データベース化.アクティブ結合
インポートCOM.HMSコルリアーナップ.ViewModelOrderViewModel
インポートCOM.HMSコルリアーナップ.ViewModel(株)
クラスの動作
**
アプリケーションのビルド結果
ヒントとトリック
アイデンティティキットは、最初にHuawei ID登録またはサインをページに表示します.ユーザーは、登録されたHuawei IDを使用して署名した後のみIDキットによって提供される機能を使用することができます.
結論
この記事では、AndroidアプリケーションでHuawei IDを統合する方法を学びました.完全にこの記事を読んだ後、ユーザーは簡単にKotlinを使用してクーリエAndroidアプリケーションでHuawei IDを実装することができます.
この記事を読んでくれてありがとう.あなたがそれが役に立つとわかるならば、この記事に好きで、コメントしてください.それは私にたくさん意味します.
参考文献
HMSドキュメント
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050048870
アカウントキットトレーニングビデオ
https://developer.huawei.com/consumer/en/training/course/video/101603872818951100
この記事では、私はHMSのアカウントとAuthServiceキットなどのHMSコアキットを統合するKotlinを使用してクーリエAndroidアプリケーションを作成します.
アプリケーションは、DataBinding、AndroidViewModel、オブザーバー、LiveDataなどのJetpackのコンポーネントを使用してAndroid MVVMのクリーンなアーキテクチャを使用するようになります.
本稿では,観測可能なパターンを用いたデータベース化を実装する.
Huawei IDサービス紹介
Huawei IDログインシンプルかつ安全な、迅速なサインインと認証機能を提供します.代わりにアカウントとパスワードを入力し、認証を待っているだけで、ユーザーはすぐにHuawei IDボタンを使用してHuawei IDを使用してアプリケーションに迅速かつ安全にサインをタップすることができます.
前提条件
Huawei電話エミュ3.0以降.
非Huawei電話アンドロイド4.4以降(APIレベル19以上).
HMSコアAPK
アンドロイド
アカウントアカウント
アプリケーションギャラリー統合プロセス
ログインして、AppGallery Connectポータルのプロジェクトを作成または選択します.
プロジェクトの設定に移動し、設定ファイルをダウンロードします.
一般的な情報に移動し、データストレージの場所を提供します.
アプリ開発
必要な依存関係を追加します.
Androidのスタジオを起動し、新しいプロジェクトを作成します.プロジェクトが完了したら.
Gradleスクリプトフォルダに移動し、ビルドを開きます.Gradle (モジュール: app ).
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.huawei.agconnect'
android {
compileSdkVersion 30
buildToolsVersion "29.0.3"
buildFeatures {
dataBinding = true
viewBinding = true
}
同じビルドで.Gradleファイルで、ライフサイクルライブラリを依存関係に追加します.このライブラリは、UIをViewModelとLiveDataに接続するのに役立ちます.dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDependency
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.annotation:annotation:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1'
次の依存関係を追加する //HMS Kits
implementation 'com.huawei.agconnect:agconnect-core:1.5.0.300'
implementation 'com.huawei.hms:hwid:5.3.0.302'
Gradleスクリプトフォルダに移動し、ビルドを開きます.Gradleプロジェクト.classpath 'com.huawei.agconnect:agcp:1.4.2.300'
maven {url 'https://developer.huawei.com/repo/'}
コード実装次のパッケージモデル、イベント、ViewModelを作成しました.
モデル:プライマリフォルダで新しいパッケージを作成し、モデル名を指定します.次に、ユーザーを作成します.このパッケージのKTファイル.
data class User(
var from: String,
var to: String
)
ViewModel : ViewModelはUIのデータ変更を簡単に更新できます.ViewModelという名前のパッケージをメインフォルダに作成します.次に、新しいファイルを作成し、LoginViewModelという名前を付けます.KT,OrderViewModelそれらのファクタyviewModelProviderと一緒のKT.LoginViewModel.KT
package com.hms.corrieraap.viewmodel
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.databinding.Observable
import androidx.lifecycle.AndroidViewModel
import com.hms.corrieraap.OrderActivity
import com.hms.corrieraap.event.ActivityNavigation
import com.hms.corrieraap.event.LiveMessageEvent
import com.huawei.hmf.tasks.Task
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
const val HMS_SIGN_IN: Int = 9001
class LoginViewModel(application: Application) : AndroidViewModel(application), Observable {
private var mAuthManager: AccountAuthService? = null
private var mAuthParam: AccountAuthParams? = null
val startActivityForResultEvent = LiveMessageEvent<ActivityNavigation>()
fun login() {
mAuthParam = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.createParams()
mAuthManager = AccountAuthManager.getService(Activity(), mAuthParam)
startActivityForResultEvent.sendEvent {
startActivityForResult(
mAuthManager?.signInIntent,
HMS_SIGN_IN
)
}
}
fun onResultFromActivity(context: Context, requestCode: Int, data: Intent?) {
when (requestCode) {
HMS_SIGN_IN -> {
val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
onCompleteLogin(context, authAccountTask)
}
}
}
private fun onCompleteLogin(context: Context, doneTask: Task<AuthAccount>) {
if (doneTask.isSuccessful) {
val authAccount = doneTask.result
Log.d("LoginViewModel", "SigIn Success")
context.startActivity(Intent(context, OrderActivity::class.java))
} else {
Log.d("LoginViewModel", "SigIn Error")
}
}
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
}
LoginViewModelFactoryKTpackage com.hms.corrieraap.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class LoginViewModelFactory : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(LoginViewModel::class.java)){
return LoginViewModel() as T
}
throw IllegalArgumentException ("UnknownViewModel")
}
}
OrderViewModel.KT
package com.hms.corrieraap.viewmodel
import androidx.databinding.Bindable
import androidx.databinding.Observable
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.hms.corrieraap.model.User
class OrderViewModel : ViewModel(), Observable {
@Bindable
val from = MutableLiveData<String>()
@Bindable
val to = MutableLiveData<String>()
var data = MutableLiveData<User>()
fun onDataChanged() {
val from = from.value!!
val to = to.value!!
val user = User(from, to)
data.value = user
}
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
TODO("Not yet implemented")
}
override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
TODO("Not yet implemented")
}
}
OrderViewModelファクトリKTpackage com.hms.corrieraap.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import java.lang.IllegalArgumentException
class OrderViewModelFactory : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(OrderViewModel::class.java)){
return OrderViewModel() as T
}
throw IllegalArgumentException("UnknownViewModel")
}
}
XMLレイアウトデータベースUIにデータバインディングを含めるには、すべてのコンテンツをエンクロージャします.
表示されるように、セクションのレイアウトにViewModelが導入されます.タイプ値が必要なViewModelを持つ特定のフォルダーにポイントしていることを確認します.
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="LoginViewModel"
type="com.hms.corrieraap.viewmodel.LoginViewModel" />
</data>
主な活動.XML :<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="LoginViewModel"
type="com.hms.corrieraap.viewmodel.LoginViewModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<com.google.android.material.appbar.AppBarLayout
style="@style/AppTheme.AppBarOverlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
style="@style/AppTheme.PopupOverlay"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="@color/colorPrimaryDark" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="SigIn / SignUp "
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="34sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn_sign"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"
android:background="@color/colorPrimaryDark"
android:text="Login With Huawei Id"
android:onClick="@{()->LoginViewModel.login()}"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</layout>
アクティブな順序.XML :<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="orderViewModel"
type="com.hms.corrieraap.viewmodel.OrderViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
style="@style/AppTheme.AppBarOverlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
style="@style/AppTheme.PopupOverlay"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="@color/colorPrimaryDark" />
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:orientation="horizontal">
<TextView
android:id="@+id/heading_from_text_view"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:text="@string/heading_from"
android:textAllCaps="true"
android:textSize="20sp" />
<FrameLayout
android:id="@+id/place_autocomplete_frame"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_weight="1">
<TextView
android:id="@+id/place_autocomplete_from"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/hint_address"
android:text="@={orderViewModel.from}"
android:textSize="20sp" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:orientation="horizontal">
<TextView
android:id="@+id/heading_to_text_view"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:text="@string/heading_to"
android:textAllCaps="true"
android:textSize="20sp" />
<FrameLayout
android:id="@+id/place_autocomplete_frame2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_weight="1">
<TextView
android:id="@+id/place_autocomplete_to"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/hint_address"
android:text="@={orderViewModel.to}"
android:textSize="20sp" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:weightSum="1.0">
<Button
android:id="@+id/neworder_button_calculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginEnd="0dp"
android:layout_marginRight="0dp"
android:layout_weight="0.4"
android:text="@string/heading_calculate" />
<Button
android:id="@+id/neworder_button_additional"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="0.4"
android:text="@string/neworder_alert_additional" />
<Button
android:id="@+id/neworder_button_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:onClick="@{()->orderViewModel.onDataChanged()}"
android:layout_weight="0.4"
android:text="@string/heading_call" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal">
<TextView
android:id="@+id/neworder_textview_summary"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:layout_marginBottom="@dimen/activity_vertical_margin"
android:layout_weight="0.2"
android:gravity="center_horizontal"
android:textAlignment="center"
android:textAllCaps="true" />
</LinearLayout>
</LinearLayout>
</layout>
LiveMessageEvent : lifeemessageeventsを実装して、ライフキャストを提供するpackage com.hms.corrieraap.event
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
class LiveMessageEvent<T> : SingleLiveEvent<(T.() -> Unit)?>() {
fun setEventReceiver(owner: LifecycleOwner, receiver: T) {
observe(owner, Observer { event ->
if (event != null) {
receiver.event()
}
})
}
fun sendEvent(event: (T.() -> Unit)?) {
value = event
}
}
SingleEvent:LifefeycleObserverのための実装singleliveEventpackage com.hms.corrieraap.event
import android.util.Log
import androidx.annotation.MainThread
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import java.util.concurrent.atomic.AtomicBoolean
open class SingleLiveEvent<T> : MutableLiveData<T>() {
private val mPending = AtomicBoolean(false)
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
super.observe(owner, Observer { t ->
if (mPending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}
@MainThread
override fun setValue(t: T?) {
mPending.set(true)
super.setValue(t)
}
@MainThread
fun call() {
value = null
}
companion object {
private val TAG = "SingleLiveEvent"
}
}
アクティブナビゲーション.KT:アクティビティ遷移のための実装インタフェイスpackage com.hms.corrieraap.event
import android.content.Intent
interface ActivityNavigation {
fun startActivityForResult(intent: Intent?, requestCode: Int)
}
メインアクティビティ.KT : Huawei IDログイン用に実装.
package com.hms.corrieraap
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProviders
import com.hms.corrieraap.databinding.ActivityMainBinding
import com.hms.corrieraap.event.ActivityNavigation
import com.hms.corrieraap.viewmodel.LoginViewModel
import com.hms.corrieraap.viewmodel.LoginViewModelFactory
class MainActivity : AppCompatActivity(), ActivityNavigation {
private lateinit var viewModel: LoginViewModel
private lateinit var dataBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val factory = LoginViewModelFactory()
viewModel = ViewModelProviders.of(this, factory).get(LoginViewModel::class.java)
dataBinding.loginViewModel = viewModel
dataBinding.lifecycleOwner=this
viewModel.startActivityForResultEvent.setEventReceiver(this, this)
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
viewModel.onResultFromActivity(requestCode, data)
super.onActivityResult(requestCode, resultCode, data)
}
}
OrderactivityKT :注文新しい宅配便のために実装.「パッケージコム.HMSコルリエレープ
アンドロイド.os束
アンドロイド.ウィジェット.トースト
輸入アンドロイド.appcompatアプリ.appcompatactivity
輸入アンドロイド.データベース化.データグラム
輸入アンドロイド.ライフサイクル.観測者
輸入アンドロイド.ライフサイクル.ビューモデラー
インポートCOM.HMSコルリアーナップ.データベース化.アクティブ結合
インポートCOM.HMSコルリアーナップ.ViewModelOrderViewModel
インポートCOM.HMSコルリアーナップ.ViewModel(株)
クラスの動作
private lateinit var activityOrderBinding: ActivityOrderBinding
private lateinit var orderViewModel: OrderViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityOrderBinding = DataBindingUtil.setContentView(this, R.layout.activity_order)
val factory = OrderViewModelFactory()
orderViewModel = ViewModelProviders.of(this, factory).get(OrderViewModel::class.java)
activityOrderBinding.lifecycleOwner = this
orderViewModel.data.observe(this, Observer {
Toast.makeText(this, "Placed Order", Toast.LENGTH_SHORT).show();
})
}
」
**
アプリケーションのビルド結果
ヒントとトリック
アイデンティティキットは、最初にHuawei ID登録またはサインをページに表示します.ユーザーは、登録されたHuawei IDを使用して署名した後のみIDキットによって提供される機能を使用することができます.
結論
この記事では、AndroidアプリケーションでHuawei IDを統合する方法を学びました.完全にこの記事を読んだ後、ユーザーは簡単にKotlinを使用してクーリエAndroidアプリケーションでHuawei IDを実装することができます.
この記事を読んでくれてありがとう.あなたがそれが役に立つとわかるならば、この記事に好きで、コメントしてください.それは私にたくさん意味します.
参考文献
HMSドキュメント
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050048870
アカウントキットトレーニングビデオ
https://developer.huawei.com/consumer/en/training/course/video/101603872818951100
Reference
この問題について(専門家:クーリエアプリMVVM Jetpack(HMSアカウントとAuthService)Kotlinを使用しているアンドロイド-パート1), 我々は、より多くの情報をここで見つけました https://dev.to/hmscommunity/expert-courier-app-mvvm-jetpack-hms-account-and-authservice-in-android-using-kotlin-part-1-18i8テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol