華為HMS開發(fā)零基礎上手

本文是學習過程記錄,這一篇主要包含HMS的配置、APPGallery連接和廣告服務、機器學習服務等內(nèi)容。

幾個小技巧

對于紅色警告的單詞,鼠標放到單詞字母中間,然后Alt+Enter一般可以自動導入。
對于數(shù)字參數(shù),可以選中它,然后Ctrl+Shift+C,會把它變?yōu)橐粋€大寫的變量。
要把哪個Activ作為啟動頁,只要打開AndroidManifest.xml文件,把其中的<intent-filter>...部分剪切到目標Activity內(nèi)即可,例如:

<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則是完全的谷歌產(chǎn)品。HMS是華為搭建自有終端軟件生態(tài)系統(tǒng)的關鍵產(chǎn)品,也是未來鴻蒙系統(tǒng)生態(tài)的重要前提。

要在安卓APP開發(fā)中使用HMS的各種強大功能,首先需要注冊成為火花紋開發(fā)者聯(lián)盟開發(fā)者,并完成用戶身份認證,推薦使用銀行卡自動認證,基本上可以實時完成。

華為開發(fā)者聯(lián)盟傳送門

注冊并認證

創(chuàng)建在線項目和應用

在開發(fā)APP之前,應該先在華為開發(fā)者聯(lián)盟網(wǎng)站的【管理中心】創(chuàng)建一個項目,并在項目內(nèi)創(chuàng)建APP應用。

華為開發(fā)者管理中心傳送門

華為的應用商店叫做AppGallery,所以我們進入【AppGallery Connect(AGC)】來管理項目和應用。

管理中心

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

添加應用

然后我們回到【我的項目】首頁,進入這個新建的項目,可以看到這里有開發(fā)者ID(Developer ID)和APP ID、API Key等信息。

進入【API管理】可以設定這個項目能夠使用哪些HMS的服務功能。下面是一些常用服務的簡介。

服務 | 說明
-|-|-
Analytics Kit | 分析服務,幫助開發(fā)者分析用戶使用數(shù)據(jù)。
Auth Service | 第三方身份認證服務,比如蘋果賬號、微信賬號、QQ賬號等。
Remote Configuration | 遠程配置服務,利用云端配置自動更改APP行為或外觀。
App Linking | 跨應用的連接跳轉(zhuǎn),也幫助開發(fā)者跟蹤用戶連接點擊行為。
APMS | 應用性能管理和監(jiān)控。
App Messaging | 用于內(nèi)信息,各種彈窗和提示。
Cloud Hosting | 云主機服務。
Cloud Storage | 云存儲服務。
In-App Purchases | 應用內(nèi)購買付費服務。
Account Kit | 華為賬號服務,用華為賬號登陸APP。
Game Service | 游戲服務,玩家成就、排行榜和存檔。
Push Kit | 消息推送服務,向用戶推送通知。
Wallet Kit | 錢包服務,卡、證、券、票、鑰匙等各類憑證電子化。
Map Kit | 地圖服務。
Drive Kit | 云空間服務。
ML Kit | 機器學習服務,涉及文字識別、圖像識別、語音識別、人臉識別等。
Safety Detect | 安全檢測服務,防病毒和惡意程序。
Site kit | 位置服務,基于地理定位的服務。
Nearby Service | 近距離通信服務,與附加的手機傳數(shù)據(jù)。
FIDO | 線上快速身份驗證服務,生物特征認證和快速線上身份驗證。
Awareness Kit | 情景感知服務,包括位置、天氣、用戶狀態(tài)、環(huán)境光等。

如果搞不清這個些服務的狀況,那么可以先都打開。

配置開發(fā)項目

打開AndroidStudio新建項目。注意包名Package name要和在線的一致,如下圖所示,注意不要有多余的空格,否則無法下一步。建議Minimum最小SDK不要故意選太低,建議20以上。

設置項目

1. agc配置文件

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

agc配置文件位置

然后在網(wǎng)站項目頁面點擊【添加SDK】,根據(jù)下面提示進行配置。

2. 項目級構(gòu)建設置

然后再切換Project回到Android,找到【Gradle Scripts/build.gradle(Project…)】項目級構(gòu)建配置,編輯添加兩個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. 模塊級構(gòu)建設置

然后找到找到【Gradle Scripts/build.gradle(Module…)】模塊級構(gòu)建配置,頂部添加一個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頁面內(nèi)放入一個廣告條,這個廣告條內(nèi)容是華為提供的,如果APP用戶大量觀看這個廣告,華為就會向開發(fā)者支付一定的廣告酬勞。

幾乎所有的應用或游戲都可以放入廣告條,廣告條形式有很多種,常用的有banner廣告位和應用啟動畫面廣告位(開屏廣告)。

華為廣告服務首頁

從廣告服務首頁點【查看文檔】進入文檔頁面。然后左側(cè)瀏覽到【廣告服務/流量變現(xiàn)服務/應用開發(fā)/集成HMS Core SDK】,參照下面提示進行配置。

1. Project模式添加json配置

參見上面內(nèi)容,在project模式下,確保agconnect-services.json文件被放到了src同級目錄。

2 項目級build添加2個倉庫和1個路徑

參見上面內(nèi)容,在【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個實現(xiàn)和1個插件

參見上面內(nèi)容,在【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. 創(chuàng)建AdSampleApplication類

在應用目錄上右擊,創(chuàng)建java類class,命名為AdSampleApplication

新建類

然后編輯內(nèi)容為下面內(nèi)容,注意第一行應該不同。

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方法的內(nèi)容,使用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);
    }
}

最后,你需要有一臺華為的手機,打開開發(fā)者模式,授權(quán)USB調(diào)試,并連接到AndroidStudio,安裝調(diào)試才能看到華為廣告出現(xiàn)在畫面上。

非華為手機都不能正常顯示這個廣告內(nèi)容。

文本識別

如何開發(fā)一個能夠識別拍照照片中文字的APP?這要用到HMS的機器學習服務ML Kit。

從HMS文檔頁面瀏覽到【機器學習服務/Android/應用開發(fā)/開發(fā)準備/集成HMS Core SDK】頁面,參照以下步驟進行。

1. 添加AGC配置文件

如前所述,確保agconnect-services.json被正常下載和添加。

2. 配置Maven倉庫

如前所述,確保在項目級構(gòu)建設置【Gradle Scripts/build.gradle(Project…)】中的兩個jcenter()后面添加了新的倉庫地址。

3. 添加依賴實現(xiàn)

往下層瀏覽【集成HMS Core SDK/添加編譯依賴/集成文本識別服務SDK】,參照下面說明繼續(xù)。

如前所述,在模塊級構(gòu)建設置【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'被添加在結(jié)尾。

4. 云端識別開發(fā)

切換頁面到【應用開發(fā)/文本類服務開發(fā)/文本識別】頁面,參照下面內(nèi)容繼續(xù)。

HMS的文本識別基本步驟是:

  • 創(chuàng)建一個分析器MLTextAnalyzer,并設置分析器參數(shù)
  • 創(chuàng)建一個機器學習框架MLFrame
  • MLFrame傳遞給分析器MLTextAnalyzer進行識別,利用onSuccess回調(diào)執(zhí)行操作
  • 識別完成后停止分析器,釋放資源。

我們創(chuàng)建一個新的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按鈕進行識別。

非華為手機都不能正常運行這個內(nèi)容。

實時語音識別

如何利用HMS服務實現(xiàn)實時的語音轉(zhuǎn)文字?仍然是機器學習服務的功能。

在文檔中瀏覽到【應用開發(fā)/語音語言類服務開發(fā)/實時語音識別/開發(fā)步驟-實時語音識別(有界面)】,參照下面提示進行。

我們?nèi)匀幌葎?chuàng)建新的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. 添加授權(quán)

因為語音識別要用到很多權(quán)限,所以要在AndroidManifest.xml中添加授權(quán),如果分不清的話就把下面的授權(quán)都添加。詳細說明地址在【應用開發(fā)/開發(fā)準備/制定權(quán)限】中有詳細說明。

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

但只在這里授權(quán)還不夠,后面還要使用動態(tài)授權(quán)。

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);是動態(tài)添加錄音權(quán)限。MLApplication.getInstance().setApiKey("CgB6e3x9gLm4...aaxYEnxvjg9");是添加ApiKey驗證。
運行后點擊GO按鈕啟動語音識別。

非華為手機都不能正常運行這個內(nèi)容。

內(nèi)容匯總

使用HMS配置很麻煩,既要遵循官方文檔,又要隨時解決各種奇怪問題,而且?guī)缀跛泄δ芏际潜仨氃谌A為手機上才能進行測試。一般要注意下面幾點:

  • 本地項目的包名要和線上應用完全一致。
  • 要下載AGC配置文件,放到project模式app根目錄。
  • 最好先設置好AGC的幾個配置,再配置一遍具體服務。
  • 要修改項目級構(gòu)建文件,添加classpath和2個maven倉庫。
  • 要修改模塊級構(gòu)建文件,添加plugin行,添加各種dependencies。
  • 可能需要給Mainifest配置中添加用戶權(quán)限,還可能要在每個Activity里重復動態(tài)添加權(quán)限。
  • 可能需要在Activity里面添加API key信息。

未完待續(xù)。
歡迎批評指正,交流學習。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容