0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Android】MediaPlayer音楽プレイヤ―にtimerを使ってcurrentPoisitionを表示してみた。

Last updated at Posted at 2024-11-22

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)

以上、

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?