一文教你整合通知系統的多種HMS Core服務,實現資料安全和真實使用者驗證
1、介紹
Overview
雲資料庫是AppGallery Connect提供的服務之一,實現雲端資料的同步,提供統一的資料模型和豐富的資料管理介面。在保證資料的可用性、可靠性、一致性,以及安全等特性基礎上,能夠實現資料在客戶端和雲端之間的無縫同步,併為應用提供離線支援,以幫助開發者快速構建端雲、多端協同的應用。
您將建立什麼
在本次codelab中,您將建立一個MVVM架構的安卓專案,實現Video Calling應用的雲資料庫和WebRTC功能,整合通知系統的推送服務、分析服務、機器學習服務、安全檢測服務以及崩潰服務,實現資料安全和真實使用者驗證。
您將會學到什麼
-
整合AppGallery Connect的華為帳號登入認證服務。
-
整合AppGallery Connect的崩潰服務。
-
整合AppGallery Connect的雲資料庫。
-
使用雲資料庫和WebRTC開發應用。
-
通過Safety Detect檢查執行應用的裝置是否安全。
-
使用推送服務和分析服務實現給受眾傳送通知。
-
使用機器學習服務活體檢測特性驗證使用者帳號。
2、您需要什麼
硬體需求
-
安裝Android Studio並已連網的電腦
-
華為或安卓手機(帶USB線),用於調測和執行
軟體需求
-
JDK版本:1.8.211或以上
-
Android API 21或以上
-
HMS Core (APK) 6.0.0.300或以上
-
Android Studio版本:3.6.1或以上
-
華為手機:EMUI 5.0版本或以上;非華為手機:Android 5.0或以上
3、能力接入準備
如果您需要正式釋出一款整合音訊編輯服務的應用,請參閱HUAWEI HMS Core整合準備做好相關準備工作。本codelab提供的樣例已為您完成準備工作。如您使用示例程式碼,忽略本步驟。
準備整合HMS Core前,在華為開發者聯盟上註冊成為開發者並完成實名認證,具體方法可參考帳號註冊認證。
4、配置開發環境
-
登入AppGallery Connect,點選“我的專案”。
-
在專案列表中找到您的專案,在專案下的應用列表中選擇您需要整合SDK的應用。
-
在“專案設定”頁面選擇“常規”頁籤。點選“應用”區域裡的“agconnect-services.json”下載配置檔案。
-
把agconnect-services.json檔案複製到專案裡。
配置HMS Core SDK的Maven倉地址
Android Studio的Maven倉地址配置方式在Gradle外掛7.0以下版本、7.0版本和7.1及以上版本有所不同。
Maven倉地址無法直接在瀏覽器中開啟訪問,只能在IDE中配置。如需新增多個Maven程式碼庫,請將華為公司的Maven倉地址配置在最後。
以7.1及以上版本為例。
-
開啟Android Studio專案根路徑下的build.gradle檔案。
-
如agconnect-services.json檔案已新增到應用中,選擇buildscript > dependencies新增AppGallery Connect和Android Gradle外掛配置。
buildscript { dependencies { ... //新增Android Gradle外掛配置。將{version}替換為真實的Gradle外掛版本,例如,7.1.1。 classpath 'com.android.tools.build:gradle:{version}' //新增AppGallery Connect外掛配置。 classpath 'com.huawei.agconnect:agcp:1.6.0.300' } }
-
開啟專案及settings.gradle檔案,為HMS Core SDK配置Maven倉地址。
pluginManagement { repositories { gradlePluginPortal() google() mavenCentral() //為HMS Core SDK配置Maven倉地址。 maven { url 'https://developer.huawei.com/repo/' } } } dependencyResolutionManagement { ... repositories { google() mavenCentral() //為HMS Core SDK配置Maven倉地址。 maven { url 'https://developer.huawei.com/repo/' } } }
5、啟用服務
整合雲資料庫SDK前,請啟用雲資料庫服務。步驟如下:
-
登入AppGallery Connect,點選“我的專案”。
-
在專案列表中選擇您需要開通雲資料庫服務的專案。
-
在導航樹上點選“構建 > 雲資料庫”。在雲資料庫服務介面,點選“立即開通”。
-
在引導介面選擇“資料處理位置”。
-
啟用認證服務,機器學習服務,推送服務,安全檢測服務和華為分析。
6、設計UI
本codelab將設計app主頁,聯絡人頁面,以及攜帶使用者資料頁面。在主頁中,您可以輸入會議ID進入會議。
7、整合認證服務 – 華為賬號登入
示例程式碼使用華為帳號登入模式,所以您需要在AppGallery Connect中啟用認證服務的華為帳號認證模式。否則,登入將會失敗。
-
登入AppGallery Connect,點選“我的專案”。
-
在專案列表中選擇您的專案。
-
點選“構建 > 認證服務”,進入認證服務的頁面。如果首次使用認證服務,請點選“立即開通”開通服務。
-
進入“認證服務”介面後,選擇“認證方式”頁籤,點選“華為帳號”對應“操作”列的“啟用”。
-
在專案裡呼叫認證服務相關方法。使用雲資料庫函式前,確保您已使用華為賬號登入應用。
示例程式碼:
authParams = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM) .setAccessToken() .createParams() private fun signInHuaweiId(){ val signInIntent = service.signInIntent startActivityForResult(signInIntent, HUAWEI_ID_SIGN_IN) }
8、整合崩潰服務
啟用華為分析服務
崩潰服務使用華為分析能力實現崩潰事件上報,因此您在整合崩潰SDK前需要啟用華為分析。
-
將編譯依賴項新增到“dependencies”中。
dependencies { implementation 'com.huawei.hms:hianalytics:5.2.0.301' implementation 'com.huawei.agconnect:agconnect-crash:1.5.1.300' }
-
在左側導航欄選擇“質量 > 崩潰”。如果首次使用崩潰服務,請點選“立即開通”開通服務。
buildscript { repositories { google() jcenter() //為HMS Core SDK配置Maven倉地址。 maven {url 'https://developer.huawei.com/repo/'} } dependencies { ... //新增AppGallery Connect外掛配置。 classpath 'com.huawei.agconnect:agcp:1.6.0.300' } } allprojects { repositories { google() jcenter() //為HMS Core SDK配置Maven倉地址。 maven {url 'https://developer.huawei.com/repo/'} } }
9、新增和匯出物件型別
-
登入AppGallery Connect,點選“我的專案”。
-
在專案列表中選擇您的專案。
-
在導航樹上點選“構建 > 雲資料庫”。
-
單擊“新增”,進入建立物件型別頁面。
-
輸入“物件型別名”為“CallsSdp”後,單擊“下一步”。
-
單擊“新增欄位”,新增如下欄位後,單擊“下一步”。
欄位名稱
型別
主鍵
非空
加密
預設值
meetingID
String
√
√
–
–
sdp
Text
–
–
–
–
callType
String
–
–
–
–
-
設定索引,單擊“下一步”。
-
設定所需的角色和許可權。
-
單擊“確定”。建立完成後返回物件型別列表中,可以檢視已建立的物件型別。
-
單擊“匯出”。
-
選擇匯出檔案格式,選擇“java格式”。
-
單擊“確定”。匯出的JAVA檔案包含該版本中所有的物件型別資訊。在接下來的步驟中,該檔案將被新增到本地開發環境中。
10、新增儲存區
-
登入AppGallery Connect,選擇“我的專案”。
-
在專案列表頁面中選擇專案。
-
在導航樹上點選“構建 > 雲資料庫”。
-
單擊“儲存區”頁籤。
-
單擊“新增”,進入建立儲存區頁面。
-
設定“儲存區名稱”為“QuickLine”。
-
單擊“確定”。
11、新增物件型別檔案
將匯出的JAVA格式檔案新增至本地開發環境。如已存在,請覆蓋原檔案。為保證整合成功,請勿修改匯出的JAVA檔案。
12、初始化雲資料庫
在新增物件型別檔案後,您可以使用雲資料庫開發應用。開發應用前,需要初始化AGConnectCloudDB,然後建立Cloud DB zone和物件型別。示例程式碼已在各步驟中列出,方便您檢視。
-
在application類中初始化雲資料庫。您需在CloudDbWrapper.kt中建立initialize方法來初始化AGConnectCloudDB。
AGConnectCloudDB.initialize(context)
-
為雲資料庫建立RoutePolicy、Instance、和ObjectTypes。
instance = AGConnectInstance.buildInstance(AGConnectOptionsBuilder() .setRoutePolicy(AGCRoutePolicy.GERMANY) .build(context)) cloudDB = AGConnectCloudDB.getInstance( AGConnectInstance.getInstance(), AGConnectAuth.getInstance()) cloudDB?.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())
-
建立儲存區配置物件並開啟該儲存區。
config = CloudDBZoneConfig( Constants.CloudDbZoneName, CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE, CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC ) config?.persistenceEnabled = true val task = cloudDB?.openCloudDBZone2(config!!, true) task?.addOnSuccessListener { cloudDBZone = it cloudDbInitializeResponse(true) }?.addOnFailureListener { Log.e(TAG, "Open cloudDBZone failed for " + it.message) cloudDbInitializeResponse(false) }
13、寫入資料
本節主要介紹如何使用雲資料庫服務在應用中寫入資料。本例使用executeUpsert方法寫入資料。如下程式碼通過方法呼叫將SDP示例程式碼寫入資料庫中。
fun call() {
Log.d(TAG, "contacts: called")
peerConnection?.createOffer(
SdpObserverImpl(
onCreateSuccessCallback = { sdp ->
Log.d(TAG, "contacts: onCreateSuccessCallback called")
peerConnection?.setLocalDescription(SdpObserverImpl(
onSetSuccessCallback = {
Log.d(TAG, "contacts: onSetSuccess called")
val offerSdp = CallsSdp()
offerSdp.meetingID = meetingID
offerSdp.sdp = Text(sdp.description)
offerSdp.callType = sdp.type.name
val upsertTask = cloudDBZone?.executeUpsert(offerSdp)
upsertTask?.addOnSuccessListener { cloudDBZoneResult ->
Log.i(TAG, "Calls Sdp Upsert success: $cloudDBZoneResult")
}?.addOnFailureListener {
Log.e(TAG, "Calls Sdp Upsert failed: ${it.message}")
}
Log.e(TAG, "onSetSuccess")
}
), sdp)
}
), _mediaConstraints
)
}
14、檢視資料
不同場景下需要檢視的資料不同,例如,檢視註冊使用者列表。我們使用executeQuery方法實現這個功能。如您定義查詢和策略引數後收到成功訊息,您可以通過收到的截圖訪問資料並新增到使用者列表中。
Sample code:
fun queryUsers(userList: (ArrayList<Users>) -> Unit) {
val queryUsers = CloudDBZoneQuery.where(Users::class.java)
val queryTask = cloudDBZone?.executeQuery(
queryUsers,
CloudDBZoneQuery.CloudDBZoneQueryPolicy.POLICY_QUERY_FROM_CLOUD_ONLY
)
queryTask?.addOnSuccessListener { snapshot ->
val usersList = arrayListOf<Users>()
try {
while (snapshot.snapshotObjects.hasNext()) {
val user = snapshot.snapshotObjects.next()
usersList.add(user)
}
} catch (e: AGConnectCloudDBException) {
Log.e(TAG, "processQueryResultExc: " + e.message)
} finally {
userList(usersList)
snapshot.release()
}
}?.addOnFailureListener {
Log.e(TAG, "Fail processQueryResult: " + it.message)
}
}
15、使用安全檢測服務提高裝置安全性
安全檢測服務提供強健的安全能力。本專案使用SysIntegrity來檢查執行應用的裝置是否安全,例如,檢查裝置是否被root過。
-
將編譯依賴項新增到“dependencies”中。
dependencies { implementation 'com.huawei.hms:safetydetect:5.0.5.302' }
-
新增SysIntegrity程式碼塊。
private fun invokeSysIntegrity() { val nonce = ByteArray(24) try { val random: SecureRandom = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { SecureRandom.getInstanceStrong() } else { SecureRandom.getInstance("SHA1PRNG") } random.nextBytes(nonce) } catch (e: NoSuchAlgorithmException) { Log.e("NoSuchAlgorithmException", e.message!!) } SafetyDetect.getClient(this) .sysIntegrity(nonce, "YOUR_APPID") .addOnSuccessListener { response -> val jwsStr = response.result val jwsSplit = jwsStr.split(".").toTypedArray() val jwsPayloadStr = jwsSplit[1] val payloadDetail = String( Base64.decode( jwsPayloadStr.toByteArray(StandardCharsets.UTF_8), Base64.URL_SAFE ), StandardCharsets.UTF_8 ) try { val jsonObject = JSONObject(payloadDetail) val basicIntegrity = jsonObject.getBoolean("basicIntegrity") val isBasicIntegrity = basicIntegrity.toString() val basicIntegrityResult = "Basic Integrity: $isBasicIntegrity" Log.i("Basic Integrity", basicIntegrityResult) showToastLong(this, "The device is secure") if (!basicIntegrity) { Log.i("Advice", jsonObject.getString("advice")) } } catch (e: JSONException) { val errorMsg = e.message Log.e("JsonException", errorMsg ?: "unknown error") } } .addOnFailureListener { e -> val errorMsg: String? = if (e is ApiException) { SafetyDetectStatusCodes.getStatusCodeString(e.statusCode) + ": " + e.message } else { e.message } Log.e("TAG", errorMsg.orEmpty()) errorMsg?.let { showToastShort(this, it) } }
16、使用推送服務和分析服務實現面向受眾的推送
推送服務實現訊息傳送。分析服務提供使用者資料,推送服務能更精準地把訊息推送給目標使用者。
-
將編譯依賴項新增到“dependencies”中。
dependencies { implementation 'com.huawei.hms:push:6.5.0.300' implementation 'om.huawei.hms:hianalytics:6.5.0.300' }
-
在Activity或Fragment中啟用華為分析服務。
HiAnalyticsTools.enableLog() HiAnalytics.getInstance(this)
-
Generate a user's token.
fun getPushToken(context: Context) { coroutineScope.launch { async(dispatcher) { val tokenScope = "HCM" val token = HmsInstanceId.getInstance(context).getToken("YOUR_APP_ID", tokenScope) Log.i("PushNotificationTAG", "get token:$token") userPushTokenLiveData.postValue(token) } } }
-
在AppGallery Connect推送服務頁面傳送通知。
17、真實使用者驗證
靜態活體檢測服務實時捕捉人臉,無需使用者另外操作即可檢測是否為真實人臉還是虛假人臉(例如,捕捉的人臉圖片、視訊截圖、面具等)
-
將編譯依賴項新增到“dependencies”中。
dependencies { implementation 'com.huawei.hms:ml-computer-vision-livenessdetection:2.2.0.300302'}
-
在AndroidManifest.xml檔案中新增許可權,確保活體檢測服務能訪問攝像機。
<uses-permission android:name="android.permission.CAMERA" />
-
新增必要條件並獲得使用者同意後,新增驗證使用者是否真實的程式碼。
private fun livenessDetection() { //獲取活體檢測配置並設定面具和太陽鏡檢測。 val captureConfig: MLLivenessCaptureConfig = MLLivenessCaptureConfig.Builder().setOptions( MLLivenessCaptureConfig.DETECT_MASK ).build() //獲取活體檢測外掛實體。 val capture: MLLivenessCapture = MLLivenessCapture.getInstance() capture.setConfig(captureConfig) capture.startDetect(requireActivity(), this.callback) }
18、測試和驗證
完成必要步驟後,將手機和電腦連線,啟用USB調測模式。在Android Studio頁面,點選執行
您建立的專案,生成APK包。在手機上安裝APK包。-
安裝完成後,開啟應用。
-
使用華為賬號登入。
-
如您沒有會議ID,輸入一個ID並點選“CREATE”按鈕生成會議。然後您可以把會議ID分享給好友,開始視訊會議。
-
如需呼叫聯絡人,在“Contacts”頁面點選
。
注意:如對方在忙,呼叫將失敗。
19、恭喜您
祝賀您,您已經成功完成了本codelab並學到了:
-
如何整合Cloud DB和WebRTC。
-
如何整合機器學習服務和真實使用者驗證。
-
如何使用推送服務和分析服務實現面向受眾的提醒。
-
如何使用Kotlin和MVVM架構。
20、參考檔案
華為認證服務
華為崩潰服務
華為雲資料庫
華為安全檢測服務
華為推送服務
華為分析服務
華為機器學習服務
WebRTC
您可以下載原始碼。
欲瞭解更多更全技術文章,歡迎訪問https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh