1.概要
以前作ったMediaPlyer音楽プレイヤ―に、再生経過時間を表すcurrentPositionを表示するように改修を行った。
2.開発環境
Android Studio Ladybug | 2024.2.1 Patch 2
Build #AI-242.23339.11.2421.12550806, built on October 25, 2024
Runtime version: 21.0.3+-12282718-b509.11 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Toolkit: sun.awt.windows.WToolkit
Windows 10.0
#3 ソースコード
currentPositionの値を表示するにあたり、ポイントとなる箇所を抽出して以下のリスト1に紹介する。詳細についてはMediaPlyer音楽プレイヤ―や小生のGitHubを参照して欲しい。
// ーーーリスト1ーーー
class MainActivity : AppCompatActivity() {
val mediaPlayer = MediaPlayer() // MediaPlayerのインスタンス
// 省略
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 省略
// 再生経過時間を表示する
// 参考:https://qiita.com/kenichiro-yamato/items/161b43d152f32a3248c7
timer("curPos", period = 1000L){
HandlerCompat.createAsync(mainLooper).post{
tvCurPos.text = "再生経過時間:" + convertMillisTo60(mediaPlayer.currentPosition) // 一時停止した時にcurrentPosition(ミリ秒)を60進数に変換し表示する
}
}
}
// ミリ秒ー>60進数変換
// https://pisuke-code.com/android-ways-to-format-millis/
fun convertMillisTo60(millis: Int): String? {
val l = millis % 1000
val s = millis / 1000 % 60
val m = millis / 1000 / 60 % 60
var h = millis / 1000 / (60 * 60) % 24
h += millis / 1000 / (60 * 60 * 24) * 24
return String.format("%d:%02d:%02d.%02d", h, m, s, l)
}
}
3.1 timerとHandler/LooperによるcurrentPositionの取得
再生経過時間を取得するためには、MediaPlayerクラスのcurrentPositionプロパティで取得できる。
// ーーーリスト2ーーー
class MainActivity : AppCompatActivity() {
val mediaPlayer = MediaPlayer() // MediaPlayerのインスタンス
override fun onCreate(savedInstanceState: Bundle?) {
// 省略
mediaPlayer.currentPosition
// 省略
}
}
但し、リスト2のようにMainActivityクラスのonCreateメソッド上で一度だけcurrentPositionを取得しても、その瞬間の値を取得するだけで、継続的な値は取得できない。
そこで、リスト3のようにtimerとHandlerCompatを用い、定期的にcurrentPositionを取得する。
//ーーーリスト3ーーー
timer(name = "curPos", period = 1000L){
HandlerCompat.createAsync(mainLooper).post{
tvCurPos.text = mediaPlayer.currentPosition.toString()
}
}
この方法は、Qiitaの記事「AndroidStudio:kotlinで時刻を表示する」やKotlin:時計アプリを作成を参考にした。なお、これらの記事ではHanderクラスのコンストラクタを用いてオブジェクトを生成しているが、このコンストラクタがdeprecatedになったのでHandlerCompatを用いHandler/Looperによる非同期処理を実装した。HandlerCompatについては、山田著「はじめてのAndroidアプリ開発Kotlin編]の第10-02-03項(p555)を参照した。またスレッドや非同期処理については、結城著「Java言語で学ぶデザインパターン入門マルチスレッド編」で勉強した。第7章補講2にtimerが含まれるkotlin.concurrentパッケージのおおもとと考えられるJava.concurrentの説明が書かれている(但し、timerそのものの説明はない)。
3.2 ミリ秒を時分秒に変換
currentPositionプロパティは音声ファイルの先頭からの再生時間をミリ秒の単位で出力される。これではひと目でわかりにくいため、リスト4のconvertMillisTo60関数を用いて時分秒に変換する。この関数は「Java・Kotlinでミリ秒 ⇒ hhmmssにフォーマット変換…3つの方法」から引用し改変した。(DateTime Apiの中などに何か素晴らしいクラスがあるのではないかとGoogleで調べていたらこのサイトの記事を見つけ、単純明快なので採用した。)
// ーーーリスト4ーーー
fun convertMillisTo60(millis: Int): String? {
val l = millis % 1000
val s = millis / 1000 % 60
val m = millis / 1000 / 60 % 60
var h = millis / 1000 / (60 * 60) % 24
h += millis / 1000 / (60 * 60 * 24) * 24
return String.format("%d:%02d:%02d.%02d", h, m, s, l)
以上、