本文是學習過程記錄,這一篇主要包含HMS的配置、AppGallery連接和廣告服務、機器學習服務等內容。
幾個小技巧
對于紅色警告的單詞,鼠標放到單詞字母中間,然后Alt+Enter一般可以自動導入。
對于數字參數,可以選中它,然后Ctrl+Shift+C,會把它變為一個大寫的變量。
要把哪個Activ作為啟動頁,只要打開AndroidManifest.xml文件,把其中的<intent-filter>...部分剪切到目標Activity內即可,例如:
<activity android:name=".TextActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
準備工作
HMS,即Huawei Mobile Service華為移動服務,是和谷歌的GMS(google Mobile Service)對標的另外一套安卓服務框架。
安卓是開源的,但其上的服務框架GMS則是完全的谷歌產品。HMS是華為搭建自有終端軟件生態系統的關鍵產品,也是未來鴻蒙系統生態的重要前提。
要在安卓APP開發中使用HMS的各種強大功能,首先需要注冊成為火花紋開發者聯盟開發者,并完成用戶身份認證,推薦使用銀行卡自動認證,基本上可以實時完成。
華為開發者聯盟傳送門

創建在線項目和應用
在開發APP之前,應該先在華為開發者聯盟網站的【管理中心】創建一個項目,并在項目內創建APP應用。
華為開發者管理中心傳送門
華為的應用商店叫做AppGallery,所以我們進入【AppGallery Connect(AGC)】來管理項目和應用。

進入【我的項目】,添加項目,名稱任意。然后【添加應用】,如下圖所示。注意應用包名建議用.huawei,如果遇到包名已經被占用,建議包名結合用戶名類似user.demo.huawei或demo.user.huawei。

然后我們回到【我的項目】首頁,進入這個新建的項目,可以看到這里有開發者ID(Developer ID)和APP ID、API Key等信息。
進入【API管理】可以設定這個項目能夠使用哪些HMS的服務功能。下面是一些常用服務的簡介。
服務 | 說明
-|-|-
Analytics Kit | 分析服務,幫助開發者分析用戶使用數據。
Auth Service | 第三方身份認證服務,比如蘋果賬號、微信賬號、QQ賬號等。
Remote Configuration | 遠程配置服務,利用云端配置自動更改APP行為或外觀。
App Linking | 跨應用的連接跳轉,也幫助開發者跟蹤用戶連接點擊行為。
APMS | 應用性能管理和監控。
App Messaging | 用于內信息,各種彈窗和提示。
Cloud Hosting | 云主機服務。
Cloud Storage | 云存儲服務。
In-App Purchases | 應用內購買付費服務。
Account Kit | 華為賬號服務,用華為賬號登陸APP。
Game Service | 游戲服務,玩家成就、排行榜和存檔。
Push Kit | 消息推送服務,向用戶推送通知。
Wallet Kit | 錢包服務,卡、證、券、票、鑰匙等各類憑證電子化。
Map Kit | 地圖服務。
Drive Kit | 云空間服務。
ML Kit | 機器學習服務,涉及文字識別、圖像識別、語音識別、人臉識別等。
Safety Detect | 安全檢測服務,防病毒和惡意程序。
Site kit | 位置服務,基于地理定位的服務。
Nearby Service | 近距離通信服務,與附加的手機傳數據。
FIDO | 線上快速身份驗證服務,生物特征認證和快速線上身份驗證。
Awareness Kit | 情景感知服務,包括位置、天氣、用戶狀態、環境光等。
如果搞不清這個些服務的狀況,那么可以先都打開。
配置開發項目
打開AndroidStudio新建項目。注意包名Package name要和在線的一致,如下圖所示,注意不要有多余的空格,否則無法下一步。建議Minimum最小SDK不要故意選太低,建議20以上。

1. agc配置文件
從網站【我的項目】找到對應項目,下載應用對應的agconnect-services.json文件,將AndroidStudio文件列表切換到Project模式,把這個json文件拖拽到app文件夾下,與src文件夾同一級別,彈窗move提示直接OK。

然后在網站項目頁面點擊【添加SDK】,根據下面提示進行配置。
2. 項目級構建設置
然后再切換Project回到Android,找到【Gradle Scripts/build.gradle(Project…)】項目級構建配置,編輯添加兩個maven倉庫和一個classpath路徑,完成后類似如下所示:
buildscript {
repositories { google() jcenter() maven {url 'https://developer.huawei.com/repo/'}
} dependencies { classpath "com.android.tools.build:gradle:4.0.1"
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
}}allprojects { repositories { google() jcenter() maven {url 'https://developer.huawei.com/repo/'}
}}task clean(type: Delete) {
delete rootProject.buildDir
}
修改之后點擊頂部彈出的Sync Now更新設置。也可以點擊Sync with Gradle Files按鈕,如下圖所示。

3. 模塊級構建設置
然后找到找到【Gradle Scripts/build.gradle(Module…)】模塊級構建配置,頂部添加一個app plugin插件,dependencies中添加一個implementation依賴,代碼如下所示:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig { ... } buildTypes { ... }}dependencies { ... implementation 'com.huawei.agconnect:agconnect-core:1.3.1.300'
}
修改之后點擊頂部彈出的Sync Now更新設置。
添加廣告服務
華為廣告服務HUAWEI Ads可以讓我們直接在APP頁面內放入一個廣告條,這個廣告條內容是華為提供的,如果APP用戶大量觀看這個廣告,華為就會向開發者支付一定的廣告酬勞。
幾乎所有的應用或游戲都可以放入廣告條,廣告條形式有很多種,常用的有banner廣告位和應用啟動畫面廣告位(開屏廣告)。
華為廣告服務首頁
從廣告服務首頁點【查看文檔】進入文檔頁面。然后左側瀏覽到【廣告服務/流量變現服務/應用開發/集成HMS Core SDK】,參照下面提示進行配置。
1. Project模式添加json配置
參見上面內容,在project模式下,確保agconnect-services.json文件被放到了src同級目錄。
2 項目級build添加2個倉庫和1個路徑
參見上面內容,在【Gradle Scripts/build.gradle(Project…)】中:
- 檢查兩處倉庫maven {url 'https://developer.huawei.com/repo/'}是否有添加(jcenter()下面)。
- 檢查classpath 'com.huawei.agconnect:agcp:1.3.1.300'是否正確添加。
3. 模塊級build添加2個實現和1個插件
參見上面內容,在【Gradle Scripts/build.gradle(Module…)】中:
- 檢查dependencies中是否添加implementation 'com.huawei.agconnect:agconnect-core:1.3.1.300'
- 添加新的implementation 'com.huawei.hms:ads-lite:13.4.33.300'
- 檢查是否添加apply plugin: 'com.huawei.agconnect'
4. 創建AdSampleApplication類
在應用目錄上右擊,創建JAVA類class,命名為AdSampleApplication。

然后編輯內容為下面內容,注意第一行應該不同。
package hms.demo02.zhyuzh;
import android.app.Application;
import com.huawei.hms.ads.HwAds;
public class AdSampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
HwAds.init(this);
}}
同時修改目錄文件【mainifests/AndroidManifests.xml】,向<application...>中添加以下兩行:
<application
android:usesCleartextTraffic="true"
android:name=".AdSampleApplication"
...
>
...</application>
Banner廣告
我們要在MainActivity界面上顯示一個華為廣告圖片。
1. 修改activity_main.xml
改為LinearLayout,添加一個BannerView,代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_height="match_parent"
xmlns:hwads="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<com.huawei.hms.ads.banner.BannerView
android:id="@+id/hw_banner_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
hwads:adId="testw6vs28auh3"
hwads:bannerSize="BANNER_SIZE_360_144"/>
</LinearLayout>
注意上面LinearLayout中新增的xmlns:hwads="http://schemas.android.co,沒有它的話下面hwads會報錯。
注意最后的BANNER_SIZE_360_144,如果是BANNER_SIZE_360_57可能就不顯示圖像。
2. 修改MainActivity.java
主要修改onCreate方法的內容,使用loadAd()來獲取廣告,修改后的代碼主要代碼如下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); BannerView bannerView = findViewById(R.id.hw_banner_view); bannerView.setAdId("testw6vs28auh3");
bannerView.setBannerAdSize(BannerAdSize.BANNER_SIZE_360_57); AdParam adParam = new AdParam.Builder().build();
bannerView.loadAd(adParam); }}
最后,你需要有一臺華為的手機,打開開發者模式,授權USB調試,并連接到AndroidStudio,安裝調試才能看到華為廣告出現在畫面上。
非華為手機都不能正常顯示這個廣告內容。
文本識別
如何開發一個能夠識別拍照照片中文字的APP?這要用到HMS的機器學習服務ML Kit。
從HMS文檔頁面瀏覽到【機器學習服務/Android/應用開發/開發準備/集成HMS Core SDK】頁面,參照以下步驟進行。
1. 添加AGC配置文件
如前所述,確保agconnect-services.json被正常下載和添加。
2. 配置Maven倉庫
如前所述,確保在項目級構建設置【Gradle Scripts/build.gradle(Project…)】中的兩個jcenter()后面添加了新的倉庫地址。
3. 添加依賴實現
往下層瀏覽【集成HMS Core SDK/添加編譯依賴/集成文本識別服務SDK】,參照下面說明繼續。
如前所述,在模塊級構建設置【Gradle Scripts/build.gradle(Module…)】
中添加幾行新代碼:
implementation 'com.huawei.hms:ml-computer-vision-ocr:2.0.1.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr-latin-model:2.0.1.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr-jk-model:2.0.1.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:2.0.1.300'
這里包含了拉丁日韓中英文識別工具包。
別忘了檢查插件行apply plugin: 'com.huawei.agconnect'被添加在結尾。
4. 云端識別開發
切換頁面到【應用開發/文本類服務開發/文本識別】頁面,參照下面內容繼續。
HMS的文本識別基本步驟是:
- 創建一個分析器MLTextAnalyzer,并設置分析器參數
- 創建一個機器學習框架MLFrame
- 將MLFrame傳遞給分析器MLTextAnalyzer進行識別,利用onSuccess回調執行操作
- 識別完成后停止分析器,釋放資源。
我們創建一個新的Activity,把這個邏輯寫入java代碼。由于MLFrame需要使用到位圖進行識別,所以我們利用照相機獲取拍攝的圖片。
界面xml部分:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".textActivity">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="請先拍照"
android:minHeight="100dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="100dp"
android:onClick="shot"
android:text="SHOT!" />
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="100dp"
android:onClick="recog"
android:text="RECOG!"
/>
</LinearLayout>
</LinearLayout>
邏輯代碼java部分:
public class textActivity extends AppCompatActivity {
public static final int REQUEST_CODE = 5;
Bitmap bitmap=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text); } public void shot(View view) {
Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CODE); } @Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==REQUEST_CODE && resultCode==RESULT_OK){
assert data != null;
bitmap=(Bitmap) Objects.requireNonNull(data.getExtras()).get("data");
ImageView imageView=findViewById(R.id.image_shot); imageView.setImageBitmap(bitmap); } } public void read2(View view) {
final MLTextAnalyzer analyzer = MLAnalyzerFactory.getInstance().getRemoteTextAnalyzer();
MLFrame frame = MLFrame.fromBitmap(bitmap); Task<MLText> task = analyzer.asyncAnalyseFrame(frame); task.addOnSuccessListener(new OnSuccessListener<MLText>() {
@Override
public void onSuccess(MLText text) {
TextView textView=findViewById(R.id.text_Recog); textView.setText(text.getStringValue()); Toast.makeText(textActivity.this, text.getStringValue(), Toast.LENGTH_LONG).show();
try {
analyzer.stop(); } catch (IOException e) {
Toast.makeText(textActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
} } }); }}
運行后點擊SHOT按鈕拍照,照片會顯示在畫面上;然后點擊RECOG按鈕進行識別。
非華為手機都不能正常運行這個內容。
實時語音識別
如何利用HMS服務實現實時的語音轉文字?仍然是機器學習服務的功能。
在文檔中瀏覽到【應用開發/語音語言類服務開發/實時語音識別/開發步驟-實時語音識別(有界面)】,參照下面提示進行。
我們仍然先創建新的Activity用來測試。
1. 集成語音服務
在【Gradle Scripts/build.gradle(Module…)】中添加兩個依賴。
implementation 'com.huawei.hms:ml-computer-voice-asr-plugin:2.0.3.300'
implementation 'com.huawei.hms:ml-computer-voice-asr:2.0.3.300'
2. 添加授權
因為語音識別要用到很多權限,所以要在AndroidManifest.xml中添加授權,如果分不清的話就把下面的授權都添加。詳細說明地址在【應用開發/開發準備/制定權限】中有詳細說明。
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
但只在這里授權還不夠,后面還要使用動態授權。
3. 界面代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".LangActivity">
<TextView
android:id="@+id/text_lang"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="請先拍照"
android:minHeight="200dp" />
<Button
android:layout_width="200dp"
android:layout_height="100dp"
android:text="GO"
android:onClick="go"/>
</LinearLayout>
4. 邏輯代碼
public class LangActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lang);
MLApplication.getInstance().setApiKey("CgB6e3x9gLm4...aaxYEnxvjg9");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
}
public void go(View view) {
// 通過intent進行識別設置。
Intent intent = new Intent(this, MLAsrCaptureActivity.class)
.putExtra(MLAsrCaptureConstants.LANGUAGE, "en-US")
.putExtra(MLAsrCaptureConstants.FEATURE, MLAsrCaptureConstants.FEATURE_wordFLUX);
startActivityForResult(intent, 100);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
String text = "";
if (requestCode == 100) {
switch (resultCode) {
case MLAsrCaptureConstants.ASR_SUCCESS:
if (data != null) {
Bundle bundle = data.getExtras();
if (bundle != null && bundle.containsKey(MLAsrCaptureConstants.ASR_RESULT)) {
text = bundle.getString(MLAsrCaptureConstants.ASR_RESULT);
TextView textView=findViewById(R.id.text_lang);
textView.setText(text);
}
}
break;
case MLAsrCaptureConstants.ASR_FAILURE:
if(data != null) {
String msg="";
Bundle bundle = data.getExtras();
if(bundle != null && bundle.containsKey(MLAsrCaptureConstants.ASR_ERROR_CODE)) {
int errorCode = bundle.getInt(MLAsrCaptureConstants.ASR_ERROR_CODE);
}
if(bundle != null && bundle.containsKey(MLAsrCaptureConstants.ASR_ERROR_MESSAGE)){
String errorMsg = bundle.getString(MLAsrCaptureConstants.ASR_ERROR_MESSAGE);
msg=errorMsg;
}
if(bundle != null && bundle.containsKey(MLAsrCaptureConstants.ASR_SUB_ERROR_CODE)) {
int subErrorCode = bundle.getInt(MLAsrCaptureConstants.ASR_SUB_ERROR_CODE);
}
Toast.makeText(LangActivity.this,msg,Toast.LENGTH_LONG).show();
}
default:
break;
}
}
}
}
注意這里的ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);是動態添加錄音權限。MLApplication.getInstance().setApiKey("CgB6e3x9gLm4...aaxYEnxvjg9");是添加ApiKey驗證。
運行后點擊GO按鈕啟動語音識別。
非華為手機都不能正常運行這個內容。
內容匯總
使用HMS配置很麻煩,既要遵循官方文檔,又要隨時解決各種奇怪問題,而且幾乎所有功能都是必須在華為手機上才能進行測試。一般要注意下面幾點:
- 本地項目的包名要和線上應用完全一致。
- 要下載AGC配置文件,放到project模式app根目錄。
- 最好先設置好AGC的幾個配置,再配置一遍具體服務。
- 要修改項目級構建文件,添加classpath和2個maven倉庫。
- 要修改模塊級構建文件,添加plugin行,添加各種dependencies。
- 可能需要給Mainifest配置中添加用戶權限,還可能要在每個Activity里重復動態添加權限。
- 可能需要在Activity里面添加API key信息。