Integrating the new Audio kit to create a simple music player (Kotlin) - Huawei Developers

More articles like this, you can visit HUAWEI Developer Forum and Medium.​
Introduction
In this article I would like to address the integration of the Audio Kit in an Android project to create a simple music player. The new Audio Kit is a set of audio capabilities developed by Huawei. It provides us with audio playback capabilities based on the HMS Core ecosystem, including audio encoding and decoding capabilities at the hardware level and lower layer of the system.
Steps
1.-Create App in AGC
2.-Integrate the SDK in our new Android project
3.-Integrate the dependencies of Audio Kit
4.- Update the HMS Core to the latest version.
5.- Create the user interface for our Player.
6.-Add our audio file to the raw folder
7.- Program our MainActivity
1.-Create App in AGC
Well, as in most HMS Kits we must create an App in AGC.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
2.-Add the SDK in our new Android project
Place SHA 256 and download our Json Services, to place it at the project level in Android Studio.
3.-Integrate the dependencies of Audio Kit
Build.gradle(project)
Code:
Build.gradle(project)
buildscript {
ext.kotlin_version = "1.3.72"
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:3.4.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
build.gradle(app)
Code:
//Add the following dependency
implementation 'com.huawei.hms:audiokit-player:1.0.0.302'
proguard-rules.pro obfuscating the code
Code:
-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
4.- Update the HMS Core to the latest version.
Depending on the Huawei device you have for testing, sometimes we do not have the latest version of the HMS core. In my case I have a Huawei Y9 EMUI 9.1.0, Android version 9. And I must download the apk with the latest version of the HMS core
I regularly download my updates from this link
https://www.******************/download-the-latest-hms-core-apk/
I have tested some versions of HMS Core and the only one that worked for me was [5.0.0.304].
5.-Create the user interface of our player
Code:
<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"
tools:context=".MainActivity"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/music"/>
<SeekBar
android:id="@+id/positionBar"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/elapsedTimeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0:11"
android:layout_marginLeft="40dp"/>
<TextView
android:id="@+id/remainingTimeLabelTimeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="-1:11"
android:layout_marginLeft="240dp"/>
</LinearLayout>
<Button
android:id="@+id/playBtn"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/play"
android:layout_marginTop="40dp"
android:onClick="playBtnClick"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="40dp"
android:gravity="center">
<ImageView
android:layout_width="18dp"
android:layout_height="18dp"
android:src="@drawable/mute"/>
<SeekBar
android:id="@+id/volumeBar"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:progress="5"
android:max="100"/>
<ImageView
android:layout_width="26dp"
android:layout_height="26dp"
android:src="@drawable/volup"/>
</LinearLayout>
</LinearLayout>
6.-Add our audio to the RAW folder
Android Studio allows us to create a Raw Folder in a very simple way, we just have to right click on app > New > Folder > RAW, with this Android Studio will create a Folder where we will add the Audio to play.
drag the audio to the RAW Folder
7.- Program our MainActivity
In this final step we will add our necessary variables, we will create the Player and we will also create a PlayList with a single song which is stored in the RAW folder.
Create our instance variables
Code:
private lateinit var mHwAudioManager : HwAudioManager
private lateinit var mHwAudioPlayerManager: HwAudioPlayerManager
We create our Player and the PlayList
Code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var hwAudioPlayerConfig = HwAudioPlayerConfig(applicationContext)
HwAudioManagerFactory.createHwAudioManager(hwAudioPlayerConfig, object : HwAudioConfigCallBack {
override fun onSuccess(audiomanager: HwAudioManager?) {
if (audiomanager != null) {
try {
mHwAudioManager = audiomanager
mHwAudioPlayerManager = audiomanager.playerManager
var cancion:HwAudioPlayItem = HwAudioPlayItem()
val song = Uri.parse("android.resource://com.huawei.simplemusicplayer/raw/jimihendrix").toString()
cancion.filePath = song
cancion.audioTitle = "Jimi Hendrix"
cancion.audioId = "123"
var canciones:List<HwAudioPlayItem> = listOf(cancion)
mHwAudioPlayerManager.playList(canciones,0,0)
mHwAudioPlayerManager.setVolume(100)
totalTime = mHwAudioPlayerManager.duration.toInt()
}catch (ex: Exception){
}
}
}
override fun onError(p0: Int) {
Log.d("TAG1", p0.toString())
}
})
}
Add the click behavior on the button
Code:
fun playBtnClick(v: View){
if(mHwAudioPlayerManager.isPlaying){
mHwAudioPlayerManager.pause()
playBtn.setBackgroundResource(R.drawable.play)
}else{
mHwAudioPlayerManager.play()
playBtn.setBackgroundResource(R.drawable.stop)
}
}
Conclusion
With this little exercise we have managed to integrate the new Huawei Audio Kit to play a song stored locally. I hope this article is very helpful to you and see you next time

How to handle this kit in HMS & GMS Devices

Do you provide something like ExoPlayer to play videos also ?

Can we browse and play the audio from device instead giving a direct link to the path.
thank you

Related

Intermediate: How to Improves the quality of Image using Huawei HiAI Image super-resolution service in Android

Introduction
In this article, we will learn how to implement Huawei HiAI kit using Image super resolution service into android application, so we can easily convert the high resolution images and can reduce the image quality size automatically.
You can capture a photo or old photo with low resolution and if you want to convert the picture to high resolution automatically, so this service will help us to change.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
What is Huawei HiAI Service?
HiAI is Huawei’s AI computing platform. Huawei HiAI is a mobile terminal–oriented artificial intelligence (AI) computing platform that constructs three layers of ecology: service capability openness, application capability openness, and chip capability openness. Huawei HiAI Engine provides apps with a diversity of AI capabilities using device capabilities. These capabilities are as follows:
Computer Vision (CV) Engine
Computer Vision Engine focuses to sense the ambient environment to determine, recognize, and understand the space. Its capabilities are
· Image recognition
· Facial recognition
· Text recognition
Automatic Speech Recognition (ASR) Engine
Automatic Speech Recognition Engine converts human voice into text to facilitate speech recognition.
Natural Language Understanding (NLU) Engine
Natural Language Understanding Engine works with the ASR engine to enable apps to understand human voice or text to achieve word segmentation and text entity recognition.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Any IDE with Android SDK installed (IntelliJ, Android Studio).
3. Minimum API Level 23 is required.
4. Required EMUI 9.0.0 and later version devices.
5. Required process kirin 990/985/980/970/ 825Full/820Full/810Full/ 720Full/710Full
How to integrate HMS Dependencies
1. First of all, we need to create an app on AppGallery Connect and add related details about HMS Core to our project. For more information check this link
2. Add the required dependencies to the build.gradle file under root folder.
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
3. Add the App level dependencies to the build.gradle file under app folder.
Code:
apply plugin: 'com.huawei.agconnect'
4. Add the required permission to the Manifestfile.xml file.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.HARDWARE_TEST.camera.autofocus"/>
5. After adding them, sync your project.
How to apply for HiAI Engine Library
1. Navigate to this URL, choose App Service > Development and click HUAWEI HiAI.
2. Click Apply for HUAWEI HiAI kit.
3. Enter required information like product name and Package name, click Next button.
4. Verify the application details and click Submit button.
5. Click the Download SDK button to open the SDK list.
6. Unzip downloaded SDK and add into your android project under lib folder.
7. Add jar files dependences into app build.gradle file.
Code:
implementation fileTree(include: ['*.aar', '*.jar'], dir: 'libs')
implementation 'com.google.code.gson:gson:2.8.6'
repositories {
flatDir {
dirs 'libs'
}
}
8. After completing this above setup now Sync your gradle file.
Let’s do code
I have created a project with empty activity let’s create UI first.
activity_main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<LinearLayout
android:id="@+id/mainlayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="15dp"
android:text="Original Image"
android:textSize="20sp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5">
<ImageView
android:id="@+id/super_origin"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="30dp"
android:src="@drawable/emptyimage"
app:layout_constraintDimensionRatio="h,4:3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
<LinearLayout
app:layout_constraintTop_toBottomOf="@+id/mainlayout"
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintVertical_bias="0.5">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="20dp"
android:text="After Resolution Image"
android:textSize="20sp" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<ImageView
android:id="@+id/super_image"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:src="@drawable/emptyimage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="h,4:3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:text="PIC From Gallery"
android:textAllCaps="true"
android:textSize="15sp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.37" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
In the MainActivity.java we can create the business logic.
Java:
public class MainActivity extends AppCompatActivity {
private boolean isConnection = false;
private int REQUEST_CODE = 101;
private int REQUEST_PHOTO = 100;
private Bitmap bitmap;
private Bitmap resultBitmap;
private Button btnImage;
private ImageView originalImage;
private ImageView convertionImage;
private final String[] permission = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE};
private ImageSuperResolution resolution;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions(permission, REQUEST_CODE);
initHiAI();
originalImage = findViewById(R.id.super_origin);
convertionImage = findViewById(R.id.super_image);
btnImage = findViewById(R.id.btn_album);
btnImage.setOnClickListener(v -> {
selectImage();
});
}
private void initHiAI() {
VisionBase.init(this, new ConnectionCallback() {
@Override
public void onServiceConnect() {
isConnection = true;
DeviceCompatibility();
}
@Override
public void onServiceDisconnect() {
}
});
}
private void DeviceCompatibility() {
resolution = new ImageSuperResolution(this);
int support = resolution.getAvailability();
if (support == 0) {
Toast.makeText(this, "Device supports HiAI Image super resolution service", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Device doesn't supports HiAI Image super resolution service", Toast.LENGTH_SHORT).show();
}
}
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (data != null && requestCode == REQUEST_PHOTO) {
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
setBitmap();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void setBitmap() {
int height = bitmap.getHeight();
int width = bitmap.getWidth();
if (width <= 800 && height <= 600) {
originalImage.setImageBitmap(bitmap);
setHiAI();
} else {
Toast.makeText(this, "Image size should be below 800*600 pixels", Toast.LENGTH_SHORT).show();
}
}
private void setHiAI() {
VisionImage image = VisionImage.fromBitmap(bitmap);
SISRConfiguration paras = new SISRConfiguration
.Builder()
.setProcessMode(VisionConfiguration.MODE_OUT)
.build();
paras.setScale(SISRConfiguration.SISR_SCALE_3X);
paras.setQuality(SISRConfiguration.SISR_QUALITY_HIGH);
resolution.setSuperResolutionConfiguration(paras);
ImageResult result = new ImageResult();
int resultCode = resolution.doSuperResolution(image, result, null);
if (resultCode == 700) {
Log.d("TAG", "Wait for result.");
return;
} else if (resultCode != 0) {
Log.e("TAG", "Failed to run super-resolution, return : " + resultCode);
return;
}
if (result == null) {
Log.e("TAG", "Result is null!");
return;
}
if (result.getBitmap() == null) {
Log.e("TAG", "Result bitmap is null!");
return;
} else {
resultBitmap = result.getBitmap();
convertionImage.setImageBitmap(resultBitmap);
}
}
}
Demo
Tips and Tricks
1. Download latest Huawei HiAI SDK.
2. Set minSDK version to 23 or later.
3. Do not forget to add jar files into gradle file.
4. Image size should be must 800*600 pixels.
5. Refer this URL for supported Devices list.
Conclusion
In this article, we have learned how to convert low resolution images into high resolution pictures and to compress the actual image size. In this example we converted low quality image to 3x super resolution image.
Thanks for reading! If you enjoyed this story, please click the Like button and Follow. Feel free to leave a Comment below.
Reference
Huawei HiAI Kit URL
Original Source

Integration of Huawei Account Kit in Book Reading Android app (Kotlin) - Part 1

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we can learn how to integrate the Huawei Account Kit in Book Reading app. So, I will provide the series of articles on this Book Reading App, in upcoming articles I will integrate other Huawei Kits.
Account Kit
Huawei Account Kit provides for developers with simple, secure, and quick sign-in and authorization functions. User is not required to enter accounts, passwords and waiting for authorization. User can click on Sign In with HUAWEI ID button to quickly and securely sign in to the app.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Click Manage APIs tab and enable Account Kit.
9. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
[/CODE]
10. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Huawei Account Kit
implementation 'com.huawei.hms:hwid:6.3.0.301'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
[/CODE]
11. Now Sync the gradle.
12. Add the required permission to the AndroidManifest.xml file.
XML:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the MainActivity.kt we can find the business logic.
Java:
class MainActivity : AppCompatActivity() {
private var mAuthManager: AccountAuthService? = null
private var mAuthParam: AccountAuthParams? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sign_btn.setOnClickListener(mOnClickListener)
}
private fun signIn() {
mAuthParam = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.setProfile()
.createParams()
mAuthManager = AccountAuthManager.getService([email protected], mAuthParam)
startActivityForResult(mAuthManager?.signInIntent, 1002)
}
private val mOnClickListener: View.OnClickListener = object : View.OnClickListener {
override fun onClick(v: View?) {
when (v?.id) {
R.id.sign_btn -> signIn()
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1002 ) {
val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
if (authAccountTask.isSuccessful) {
Toast.makeText(this, "SigIn success", Toast.LENGTH_LONG).show()
val intent = Intent([email protected], Home::class.java)
startActivity(intent)
} else {
Toast.makeText(this, "SignIn failed: " + (authAccountTask.exception as ApiException).statusCode, Toast.LENGTH_LONG).show()
}
}
}
}
In the Home.kt we can find the business logic.
Java:
class Home : AppCompatActivity() {
lateinit var recyclerView: RecyclerView
var mBookAdapter: BookAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
recyclerView = findViewById(R.id.recycler_view)
mBookAdapter = BookAdapter()
recyclerView.adapter = mBookAdapter
}
}
Create BookAdapter.kt class for holding the list.
Java:
class BookAdapter(): RecyclerView.Adapter<BookAdapter.ViewHolder>() {
private var titles = arrayOf("Life", "Young Adult", "Comedy", "Women", "Tragedy", "Science Fiction",
"Horror Stories", "Drama", "Society", "Biography")
private var images = intArrayOf(R.drawable.life, R.drawable.youth, R.drawable.comedy, R.drawable.women,
R.drawable.tragedy, R.drawable.science, R.drawable.horror, R.drawable.drama,
R.drawable.society, R.drawable.biography)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
return BookAdapter.ViewHolder(view)
}
override fun onBindViewHolder(holder: BookAdapter.ViewHolder, position: Int) {
holder.itemTitle.text = titles[position]
holder.itemImage.setImageResource(images[position])
}
override fun getItemCount(): Int {
return titles.size
}
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
var itemTitle: TextView = itemView.findViewById(R.id.titles)
var itemImage: ImageView = itemView.findViewById(R.id.images)
}
}
In the activity_main.xml we can create the UI screen.
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@drawable/book_fly"
tools:context=".MainActivity">
<TextView
android:id="@+id/act_main_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginLeft="20dp"
android:layout_marginTop="30dp"
android:text="Huawei E-Book Store"
android:textSize="32sp"
android:textColor="@color/hwid_auth_button_color_red"
android:textStyle="bold" />
<ImageButton
android:id="@+id/sign_btn"
android:layout_width="290dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_margin="15dp"
android:paddingTop="10dp"
app:srcCompat="@drawable/huawei_id_buttons" />
</RelativeLayout>
In the activity_home.xml we can create the UI screen.
Java:
<?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:gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".Home">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_height="match_parent" />
</LinearLayout>
In the list_item.xml we can create the list of items.
Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/list_view"
android:layout_marginLeft="-3dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="5dp"
app:cardBackgroundColor="@color/hwid_auth_button_color_border"
app:cardCornerRadius="8dp"
app:cardElevation="3dp"
app:contentPadding="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:id="@+id/titles"
android:layout_width="160dp"
android:layout_height="50dp"
android:layout_marginStart="10dp"
android:layout_marginLeft="15dp"
android:text="Item"
android:textSize="20sp"
android:textAlignment="viewStart"
android:textColor="@color/black"
android:textStyle="bold" />
<ImageView
android:id="@+id/images"
android:layout_width="150dp"
android:layout_height="60dp"
android:layout_gravity="right"
android:layout_marginLeft="55dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to integrate the Huawei Account Kit in Book Reading app. So, I will provide the series of articles on this Book Reading App, in upcoming articles will integrate other Huawei Kits.
I hope you have read this article. If you found it is helpful, please provide likes and comments.
Reference
Account Kit

Beginner: Find Nearby ATMS with integration of Huawei Site Kit in Banking app (Kotlin)

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, I will be integrating Huawei Site Kit in an Application.
Site Kit
This kit is used for getting the places and near-by places on keyword search. HUAWEI Site Kit provide users with convenient and secure access to diverse, place-related services.
Use Case
The Site Kit will be used to find nearby ATMs in a Banking Application which can perform basic functions such as Enter Pin, Withdraw Money, Deposit Money and Check Balance.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.2.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 installed.
4. Minimum API Level 21 is required.
5. Required EMUI 9.0.0 and later version devices.
Integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. Choose View > Tool Windows > Gradle > Signingreport > SHA256 code.
Or use cmd as explained in SHA256 CODE
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save, as follows.
8. Click Manage APIs tab and enable Site Kit.
9. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Code:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
10. Add the below plugin and dependencies in build.gradle(Module) file.
Code:
apply plugin: 'com.huawei.agconnect'
// Huawei AGC
Code:
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Site Kit
Code:
implementation 'com.huawei.hms:site:5.2.0.300'
11. Now Sync the gradle.
12. Add the required permission to the Manifestfile.xml file.
Code:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--check wifi state-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Development
activity_main.xml
XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="wrap_content"
android:layout_height="wrap_content"
tools:context=".MainActivity"
android:id="@+id/activity_main"
android:background="@color/purple_200">
<Button
android:id="@+id/btTrans"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="90dp"
android:layout_marginTop="100dp"
android:text="@string/click_to_start_transaction"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="327dp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="70dp"
android:layout_marginTop="10dp"
android:text="@string/welcome_to_world_s_best_bank"
android:textSize="20dp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:srcCompat="@drawable/hello" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="570dp"
android:layout_marginStart="120dp"
android:text="@string/find_atm"
android:textSize="18sp"
android:textStyle="bold"
android:visibility="visible" />
<EditText
android:id="@+id/search_query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:hint="@string/search_atm_here"
android:inputType="text"
android:padding="5dp"
android:layout_marginTop="530dp"/>
<Button
android:id="@+id/button_text_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="220dp"
android:layout_marginStart="60dp"
android:text="@string/search"
android:textAllCaps="false" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#D3D3D3"
android:gravity="center_vertical"
android:padding="5dp"
android:text="@string/result"
android:textSize="16sp"
android:layout_marginTop="600dp"/>
<TextView
android:id="@+id/response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:layout_marginTop="640dp"
/>
</FrameLayout>
MainActivity.kt
Code:
class MainActivity : AppCompatActivity() {
private var searchService: SearchService? = null
private var resultTextView: TextView? = null
private var queryInput: EditText? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
try {
searchService = SearchServiceFactory.create(
this,
URLEncoder.encode(
"CgB6e3x9Z0Sl/zgHigt2p775VippBazEDe6ujGs/R7iLuwd4Sum+m6aBgecx+gWQtkuVJu/BOp1UeLktd9cyuf66",
"utf-8"
)
)
} catch (e: UnsupportedEncodingException) {
Log.e("MainActivity", "encode apikey error")
}
queryInput = findViewById(R.id.search_query)
resultTextView = findViewById(R.id.response)
}
fun search(view: View?) {
val textSearchRequest = TextSearchRequest()
textSearchRequest.setQuery(queryInput!!.text.toString())
textSearchRequest.setHwPoiType(HwLocationType.TOWER)
searchService.textSearch(
textSearchRequest,
object : SearchResultListener<TextSearchResponse?>() {
fun onSearchResult(textSearchResponse: TextSearchResponse?) {
val response = StringBuilder("\n")
response.append("success\n")
var count = 1
var addressDetail: AddressDetail
if (null != textSearchResponse) {
if (null != textSearchResponse.getSites()) {
for (site in textSearchResponse.getSites()) {
addressDetail = site.getAddress()
response
.append(
String.format(
"[%s] name: %s, formatAddress: %s, country: %s, countryCode: %s \r\n",
"" + count++, site.getName(), site.getFormatAddress(),
if (addressDetail == null) "" else addressDetail.getCountry(),
if (addressDetail == null) "" else addressDetail.getCountryCode()
)
)
}
} else {
response.append("textSearchResponse.getSites() is null!")
}
} else {
response.append("textSearchResponse is null!")
}
Log.d("MainActivity", "search result is : $response")
resultTextView!!.text = response.toString()
}
fun onSearchError(searchStatus: SearchStatus) {
Log.e("MainActivity", "onSearchError is: " + searchStatus.getErrorCode())
}
})
}
}
Cloud Debugging
Use Cloud Debugging in HMS Toolkit to debug the app on a real device.
To use Cloud Debugging, you need to sign in using a HUAWEI ID, complete identity verification, and then authorize the sign-in.
Choose HMS > CloudDebugging.
You can use Available Devices. Select a device and click RUN.
Result
Tips and Tricks
1. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
2. Make sure you have added the agconnect-services.json file to app folder.
3. Make sure you have added SHA-256 fingerprint without fail.
4. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learnt integration of Site Kit in Banking application. It will guide you to show nearby ATM based on the user input.
Reference
Site Kit: Documentation

Intermediate: Find Doctor Near to Me using Huawei Kits (Account, Crash and Analytics) in Android App

Overview
In this article, I will create a FindDoctorNearMe android application in which I will integrate HMS Core kits such as Huawei ID, Crash and Analytics.
Huawei ID Service Introduction
Huawei ID login provides you with simple, secure, and quick sign-in and authorization functions. Instead of entering accounts and passwords and waiting for authentication, users can just tap the Sign in with HUAWEI ID button to quickly and securely sign in to your app with their HUAWEI IDs.
Prerequisite
Huawei Phone EMUI 3.0 or later.
Non-Huawei phones Android 4.4 or later (API level 19 or higher).
HMS Core APK 4.0.0.300 or later
Android Studio
AppGallery Account.
App Gallery Integration process
Sign In and Create or Choose a project on AppGallery Connect portal.
Navigate to Project settings and download the configuration file.
Navigate to General Information, and then provide Data Storage location.
App Development
Create A New Project.
Configure Project Gradle.
Code:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
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.4.2.300'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Configure App Gradle.
Code:
implementation 'com.huawei.hms:identity:5.3.0.300'
implementation 'com.huawei.agconnect:agconnect-auth:1.4.1.300'
implementation 'com.huawei.hms:hwid:5.3.0.302'
implementation 'com.huawei.hms:hianalytics:5.0.3.300'
implementation 'com.huawei.agconnect:agconnect-crash:1.4.1.300'
Configure AndroidManifest.xml.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Create Activity class with XML UI.
MainActivity:
Code:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int REQUEST_SIGN_IN_LOGIN = 1002;
private static String TAG = MainActivity.class.getName();
private HuaweiIdAuthService mAuthManager;
private HuaweiIdAuthParams mAuthParam;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button view = findViewById(R.id.btn_sign);
view.setOnClickListener(this);
}
private void signIn() {
mAuthParam = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.createParams();
mAuthManager = HuaweiIdAuthManager.getService(this, mAuthParam);
startActivityForResult(mAuthManager.getSignInIntent(), REQUEST_SIGN_IN_LOGIN);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign:
signIn();
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_SIGN_IN_LOGIN) {
Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (authHuaweiIdTask.isSuccessful()) {
AuthHuaweiId huaweiAccount = authHuaweiIdTask.getResult();
Log.i(TAG, huaweiAccount.getDisplayName() + " signIn success ");
Log.i(TAG, "AccessToken: " + huaweiAccount.getAccessToken());
Intent intent = new Intent(this, HomeActivity.class);
intent.putExtra("user", huaweiAccount.getDisplayName());
startActivity(intent);
this.finish();
} else {
Log.i(TAG, "signIn failed: " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode());
}
}
}
}
Xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark">
<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="Find Doctor Near Me"
android:textAlignment="center"
android:textColor="@color/colorAccent"
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/colorPrimary"
android:text="Login With Huawei Id"
android:textColor="@color/hwid_auth_button_color_white"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
App Build Result
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Tips and Tricks
Identity Kit displays the HUAWEI ID registration or sign-in page first. You can use the functions provided by Identity Kit only after signing in using a registered HUAWEI ID.
Conclusion
In this article, we have learned how to integrate Huawei ID in Android application. After completely read this article user can easily implement Huawei ID in the FindDoctorNearMe application.
Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.
References
HMS Docs:
https://developer.huawei.com/consum.../HMSCore-Guides/introduction-0000001050048870
Account Kit - Training Video

Integration of Text to Speech feature of Huawei ML Kit in Book Reading Android app (Kotlin) - Part 4

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we can learn how to integrate the Text to Speech feature of Huawei ML Kit in Book Reading app. Text to speech (TTS) can convert text information into human voice in real time. This service uses Deep Neural Networks in order to process the text and create a natural sound, rich timbers are also supported to enhance the result. TTS is widely used in broadcasting, news, voice navigation, and audio reading. For example, TTS can convert a large amount of text into speech output and highlight the content that is being played to free users eyes, bringing interests to users. TTS records a voice segment based on navigation data, and then synthesizes the voice segment into navigation voice, so that navigation is more personalized.
Precautions
1. The text in a single request can contain a maximum of 500 characters and is encoded using UTF-8.
2. Currently, TTS in French, Spanish, German, Italian, Russian, Thai, Malay, and Polish is deployed only in China, Asia, Africa, Latin America, and Europe.
3. TTS depends on on-cloud APIs. During commissioning and usage, ensure that the device can access the Internet.
4. Default specifications of the real-time output audio data are as follows: MP3 mono, 16-bit depth, and 16 kHz audio sampling rate.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Click Manage APIs tab and enable ML Kit.
9. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
10. Add the below plugin and dependencies in build.gradle(Module) file.
Code:
apply plugin: id 'com.huawei.agconnect'
dataBinding {
enabled = true
}
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// ML Kit - Text to Speech
implementation 'com.huawei.hms:ml-computer-voice-tts:3.3.0.305'
// Data Binding
implementation 'androidx.databinding:databinding-runtime:7.1.1'
11. Now Sync the gradle.
12. Add the required permission to the AndroidManifest.xml file.
Code:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the ListActivity.kt to find the button click.
Java:
class ListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list)
btn_voice.setOnClickListener {
val intent = Intent([email protected], TranslateActivity::class.java)
startActivity(intent)
}
}
}
In the TranslateActivity.kt to find the business logic for text translation.
Java:
class TranslateActivity : AppCompatActivity() {
private lateinit var binding: ActivityTranslateBinding
private lateinit var ttsViewModel: TtsViewModel
private var sourceText: String = ""
private lateinit var mlTtsEngine: MLTtsEngine
private lateinit var mlConfigs: MLTtsConfig
private val TAG: String = TranslateActivity::class.java.simpleName
private var callback: MLTtsCallback = object : MLTtsCallback {
override fun onError(taskId: String, err: MLTtsError) {
}
override fun onWarn(taskId: String, warn: MLTtsWarn) {
}
override fun onRangeStart(taskId: String, start: Int, end: Int) {
Log.d("", start.toString())
img_view.setImageResource(R.drawable.on)
}
override fun onAudioAvailable(p0: String?, p1: MLTtsAudioFragment?, p2: Int, p3: android.util.Pair<Int, Int>?, p4: Bundle?) {
}
override fun onEvent(taskId: String, eventName: Int, bundle: Bundle?) {
if (eventName == MLTtsConstants.EVENT_PLAY_STOP) {
Toast.makeText(applicationContext, "Service Stopped", Toast.LENGTH_LONG).show()
}
img_view.setImageResource(R.drawable.off)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(activity_translate)
binding = setContentView(this, activity_translate)
binding.lifecycleOwner = this
ttsViewModel = ViewModelProvider(this).get(TtsViewModel::class.java)
binding.ttsViewModel = ttsViewModel
setApiKey()
supportActionBar?.title = "Text to Speech Conversion"
ttsViewModel.ttsService.observe(this, Observer {
startTtsService()
})
ttsViewModel.textData.observe(this, Observer {
sourceText = it
})
}
private fun startTtsService() {
mlConfigs = MLTtsConfig()
.setLanguage(MLTtsConstants.TTS_EN_US)
.setPerson(MLTtsConstants.TTS_SPEAKER_FEMALE_EN)
.setSpeed(1.0f)
.setVolume(1.0f)
mlTtsEngine = MLTtsEngine(mlConfigs)
mlTtsEngine.setTtsCallback(callback)
// ID to use for Audio Visualizer.
val id = mlTtsEngine.speak(sourceText, MLTtsEngine.QUEUE_APPEND)
Log.i(TAG, id)
}
private fun setApiKey(){
MLApplication.getInstance().apiKey = "DAEDAOB+zyB7ajg1LGcp8F65qxZduDjQ1E6tVovUp4lU/PywqhT4g+bxBCtStYAa33V9tUQrKvUp89m+0Gi/fPwfNN6WCJxcVLA+WA=="
}
override fun onDestroy() {
super.onDestroy()
mlTtsEngine.shutdown()
}
override fun onPause() {
super.onPause()
mlTtsEngine.stop()
}
}
In the activity_list.xml we can create the UI screen.
Code:
<?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:paddingTop="10dp"
android:paddingBottom="10dp"
tools:context=".ListActivity">
android:id="@+id/btn_voice"
android:layout_width="310dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:textColor="@color/black"
android:padding="8dp"
android:textAllCaps="false"
android:text="Text to Voice" />
</LinearLayout>
In the activity_translate.xml we can create the UI screen.
Java:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="ttsViewModel"
type="com.example.huaweibookreaderapp1.TtsViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".TranslateActivity">
<Button
android:id="@+id/btn_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> ttsViewModel.callTtsService()}"
android:text="@string/speak"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.43" />
<EditText
android:id="@+id/edt_text"
android:layout_width="409dp"
android:layout_height="wrap_content"
android:layout_marginBottom="36dp"
android:ems="10"
android:textSize="20sp"
android:hint="@string/enter_text_here"
android:inputType="textPersonName"
android:onTextChanged="@{ttsViewModel.noDataChangedText}"
android:paddingStart="70dp"
app:layout_constraintBottom_toTopOf="@+id/btn_click"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
android:autofillHints="@string/enter_text_here" />
<ImageView
android:id="@+id/img_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="7dp"
app:layout_constraintBottom_toTopOf="@+id/edt_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8"
app:srcCompat="@drawable/off"
android:contentDescription="@string/speaker" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to integrate the Text to Speech feature of Huawei ML Kit in Book Reading app. Text to speech (TTS) can convert text information into human voice in real time. This service uses Deep Neural Networks in order to process the text and create a natural sound, rich timbers are also supported to enhance the result.
I hope you have read this article. If you found it is helpful, please provide likes and comments.
Reference
ML Kit – Text to Speech
ML Kit – Training Video

Categories

Resources