[Huawei Developers] XDARoni:
Playing audio on Android can be tricky, especially if you have to manage both online and offline services. Luckily, for apps targeting Huawei devices, there's HMS Audio Kit.

Audio Kit makes managing audio tracks and playlists a bit easier, by unifying the process for both online and offline sources. It allows you to aggregate songs into playlists, control those playlists, and all the other stuff you might want to do with your audio.

If you're making an app that plays audio, even if it isn't user-selected, and you're developing for Huawei devices, this library is worth a look.

Let's see how to implement it.

Preparation

First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.

Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.

On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:

C:\Program Files\Java\jdk1.8.0_231\bin\

Once you find the directory, "cd" into it:

C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\

Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:

E:\AndroidSDK\.android\debug.keystore

(Keytool also supports JKS-format keystores.)

Now you're ready to run the command. On Windows, it'll look something like this:

keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore

On Linux, the command should be similar, just using UNIX-style paths instead.

Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:

Make note of the SHA256 field.

SDK Setup

Now we're ready to add the Audio Kit SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.

Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.

Now, you should be on a screen that looks something like the following:

Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.

Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project. You'll also need to add the following to the "dependencies" section of your app-level build.gradle file:

implementation 'com.huawei.hms:audiokit-player:1.0.0.302'

If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.

Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.

Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.

For ProGuard:

-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.**{*;}

For AndResGuard:

"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*

That's it! The Audio Kit SDK should now be available in your project.

Basic Usage

Before we get into actually using the API, there are a few permissions you'll need to declare and have granted.

Add these to your AndroidManifest.xml and request access as needed:

<!-- Use these if you're going to play audio files from the internet -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<!-- Use these if you're going to play/save audio files from/to the device's storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />

Now let's start implementing! Below is an example of how to set up the class instances you'll need.

//Playback control
lateinit var hwAudioPlayerManager: HwAudioPlayerManager
//Playback configuration
lateinit var hwAudioConfigManager: HwAudioConfigManager
//Queue control
lateinit var hwAudioQueueManager: HwAudioQueueManager

fun setUpAudioManager(context: Context) {
//Use this config to set various player parameters.
//Check the API docs for other config methods.
val config = HwAudioPlayerConfig(context)

//Set the cache size for the player in Mebibytes.
//Default is 200.
config.playCacheSize = 500

//Enable debug mode for verbose logging.
config.debugMode = true

HwAudioManagerFactory.createHwAudioManager(config, object : HwAudioConfigCallBack() {
override fun onSuccess(audioManager: HwAudioManager) {
//Setup succeeded. Let's try getting our instances.
try {
hwAudioPlayerManager = audioManager.playerManager
hwAudioConfigManager = audioManager.configManager
hwAudioQueueManager = audioManager.queueManager
} catch (e: Exception) {
//Something went wrong
}
}

override fun onError(errorCode: Int) {
//Initialization failed. Check the error code.
}
})
}

Now that we have the relevant instances, we can start playing audio. The following example shows how to create a playlist and play it.

//An online music file.
val firstSongUrl = "https://lfmusicservice.hwcloudtest.cn:18084/HMS/audio/Taoge-chengshilvren.mp3"

//A local music file.
val secondSongPath = "/storage/emulated/0/Download/Some_song.mp3"

//The item representing the first song.
val firstSong = HwAudioPlayItem()

//Set the song's title.
firstSong.audioTitle = "Some Online Song"

//Set the song's artist.
firstSong.singer = "Some Artist"

//Set the song's album art, in different sizes.
//These might be able to take local content URLs,
//but documentation is unclear.
firstSong.smallImageUrl = "https://some.image.url/image_small.jpg"
firstSong.midImageUrl = "https://some.image.url/image_mid.jpg"
firstSong.bigImageUrl = "https://some.image.url/image_big.jpg"

//Set an ID for this song
firstSong.audioId = firstSongUrl.hashCode()

//Since this track is online, set the proper flag.
firstSong.online = 1

//Set the URL.
firstSong.onlinePath = firstSongUrl

//Set the current seek, in milliseconds
firstSong.playPosition = 10000

//The item representing the second song.
val secondSong = HwAudioPlayItem()

secondSong.audioTitle = "Some Local Song"
secondSong.singer = "Some Other Artist"
secondSong.smallImageUrl = "content://some.image.uri/image_small.jpg"
secondSong.midImageUrl = "content://some.image.uri/image_mid.jpg"
secondSong.bigImageUrl = "content://some.image.uri/image_big.jpg"
secondSong.audioId = secondSongPath.hashCode()

//Set the file path.
secondSong.filePath = secondSongPath

//Create a playlist.
val playlist = ArrayList<HwAudioPlayItem>()

//Add items to list.
playlist.add(firstSong)
playlist.add(secondSong)

//Play the playlist.
hwAudioPlayerManager.playList(
playlist,
/* The index of the playlist to start at */ 0,
/* The seek position to start at, in seconds */ 0
)

//Pause playback.
hwAudioPlayerManager.pause()

//Stop playback completely (i.e. shutting down app).
hwAudioPlayerManager.stop()

//Resume playback.
hwAudioPlayerManager.play()

//Play the song at the specified index in the playlist.
hwAudioPlayerManager.play(1)

//Play the song at the specific index in the playlist
//with a given seek time, in seconds.
hwAudioPlayerManager.play(1, 10)

//Go to previous audio track.
hwAudioPlayerManager.playPre()

//Go to the next audio track.
hwAudioPlayerManager.playNext()

//Check if music is currently playing.
val isPlaying: Boolean = hwAudioPlayerManager.isPlaying()

//Check if music is currently buffering.
val isBuffering: Boolean = hwAudioPlayerManager.isBuffering()

//Get the buffer progress.
val bufferPercent: Int = hwAudioPlayerManager.bufferPercent

//Seek to the specified time on the current track (in seconds).
hwAudioPlayerManager.seekTo(10)

//Get the current seek (in seconds)
val seek: Int = hwAudioPlayerManager.offsetTime

//Set the mode for playing the playlist.
//Use 0 for sequential playback
//Use 1 to shuffle the list
//Use 2 to repeat the playlist
//Use 3 to repeat the current song
hwAudioPlayerManager.playMode = 0

You can also manage a playlist after you've already pushed it to be played, using HwAudioQueueManager.

//Check the current playlist position.
val index: Int = hwAudioQueueManager.currentIndex

//Get the currently playing song.
val currentlyPlaying: HwAudioPlayItem = hwAudioQueueManager.currentPlayItem

//Get the entire playlist.
val currentPlaylist: List<HwAudioPlayItem> = hwAudioQueueManager.allPlaylist

//Remove a song from the playlist, by index.
hwAudioQueueManager.removeListByIndex(1)

//Remove an HwAudioPlayItem from the playlist.
hwAudioQueueManager.removeListByIndex(currentlyPlaying)

//Add a song to the playlist, at the specified position.
hwAudioQueueManager.addPlayItem(/* HwAudioPlayItem */ song, /* position */ 2)

//Add a list of songs to the playlist, starting at the
//specified position.
hwAudioQueueManager.addPlayItemList(
/* List<HwAudioPlayItem> */ songs,
/* position */ 3
)

//Set a new playlist.
hwAudioQueueManager.setPlayList(currentPlaylist)

Conclusion

And that's it! Audio Kit is a pretty simple SDK that makes it easier to manage playing music from various sources. If you're looking for a simple way to play audio on Huawei devices, trye this library out.

Make sure to read Huawei's documentation for more details on implementation and the API.