本文是學習過程記錄,這一篇主要包含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。
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資訊。未完待續。歡迎批評指正,交流學習。