带有SeekBar的Android Media Player歌曲

In this tutorial, we’ll use the MediaPlayer class to implement a basic Audio Player in our Android Application. We’ll add a Play/Stop feature and also allow the user to change the position of the song with a SeekBar.

在本教程中,我们将使用MediaPlayer类在我们的Android应用程序中实现基本的Audio Player。 我们将添加播放/停止功能,还允许用户使用SeekBar更改歌曲的位置。

Android MediaPlayer (Android MediaPlayer)

MediaPlayer class is used for playing Audio and Video files. The common methods of the MediaPlayer class that we’ll use are:

MediaPlayer类用于播放音频和视频文件。 我们将使用的MediaPlayer类的常见方法是:

  • start()

    开始()
  • stop()

    停()
  • release() – To prevent memory leaks.

    release()–防止内存泄漏。
  • seekTo(position) – This will be used with the SeekBar

    seekTo(position)–将与SeekBar一起使用
  • isPlaying() – Let’s us know whether the song is being played or not.

    isPlaying()–让我们知道歌曲是否正在播放。
  • getDuration() – Is used to get the total duration. Using this we’ll know the upper limit of our SeekBar. This function returns the duration in milli seconds

    getDuration()–用于获取总持续时间。 使用此方法,我们将知道SeekBar的上限。 此函数返回以毫秒为单位的持续时间
  • setDataSource(FileDescriptor fd) – This is used to set the file to be played.

    setDataSource(FileDescriptor fd)–用于设置要播放的文件。
  • setVolume(float leftVolume, float rightVolume) – This is used to set the volume level. The value is a float between 0 an 1.

    setVolume(float leftVolume,float rightVolume)–用于设置音量。 取值范围是0到1。

We’ll be playing an mp3 file stored in the assets folder of our Android Studio Project.

我们将播放一个存储在Android Studio项目资产文件夹中的mp3文件。

Fetching the sound assets file from the Assets folder

从Assets文件夹中获取声音资产文件

AssetFileDescriptor descriptor = getAssets().openFd("filename");
                mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                descriptor.close();

In order to create an Application that plays Audio and lets you change the position of the current song track we need to implement three things:

为了创建一个播放音频并允许您更改当前歌曲轨道位置的应用程序,我们需要实现三件事:

  • MediaPlayer

    媒体播放器
  • SeekBar With Text – To show the current progress time besides the thumb.

    SeekBar With Text –用拇指显示当前的进度时间。
  • Runnable Thread – To update the Seekbar.

    可运行线程–更新Seekbar。

项目结构 (Project Structure)

Add the following dependency in your build.gradle:

在build.gradle中添加以下依赖项:

implementation 'com.android.support:design:28.0.0-alpha3'

(Code)

The code for the activity_main.xml is given below:

下面给出了activity_main.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:gravity="center"
    android:layout_margin="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="PLAY/STOP SONG.\nSCRUB WITH SEEKBAR"
        android:textStyle="bold" />


    <SeekBar
        android:id="@+id/seekbar"
        android:layout_margin="16dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@android:drawable/ic_media_play"
        android:text="PLAY SOUND" />

</LinearLayout>

We’ve added a FloatingActionButon that’ll play/stop when clicked.

我们添加了一个FloatingActionButon,它将在单击时播放/停止。

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidmediaplayersong;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements Runnable {


    MediaPlayer mediaPlayer = new MediaPlayer();
    SeekBar seekBar;
    boolean wasPlaying = false;
    FloatingActionButton fab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        fab = findViewById(R.id.button);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                playSong();
            }
        });

        final TextView seekBarHint = findViewById(R.id.textView);

        seekBar = findViewById(R.id.seekbar);

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

                seekBarHint.setVisibility(View.VISIBLE);
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
                seekBarHint.setVisibility(View.VISIBLE);
                int x = (int) Math.ceil(progress / 1000f);

                if (x  0 && mediaPlayer != null && !mediaPlayer.isPlaying()) {
                    clearMediaPlayer();
                    fab.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, android.R.drawable.ic_media_play));
                    MainActivity.this.seekBar.setProgress(0);
                }

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {


                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    mediaPlayer.seekTo(seekBar.getProgress());
                }
            }
        });
    }

    public void playSong() {

        try {


            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                clearMediaPlayer();
                seekBar.setProgress(0);
                wasPlaying = true;
                fab.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, android.R.drawable.ic_media_play));
            }


            if (!wasPlaying) {

                if (mediaPlayer == null) {
                    mediaPlayer = new MediaPlayer();
                }

                fab.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, android.R.drawable.ic_media_pause));

                AssetFileDescriptor descriptor = getAssets().openFd("suits.mp3");
                mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                descriptor.close();

                mediaPlayer.prepare();
                mediaPlayer.setVolume(0.5f, 0.5f);
                mediaPlayer.setLooping(false);
                seekBar.setMax(mediaPlayer.getDuration());

                mediaPlayer.start();
                new Thread(this).start();

            }

            wasPlaying = false;
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    public void run() {

        int currentPosition = mediaPlayer.getCurrentPosition();
        int total = mediaPlayer.getDuration();


        while (mediaPlayer != null && mediaPlayer.isPlaying() && currentPosition < total) {
            try {
                Thread.sleep(1000);
                currentPosition = mediaPlayer.getCurrentPosition();
            } catch (InterruptedException e) {
                return;
            } catch (Exception e) {
                return;
            }

            seekBar.setProgress(currentPosition);

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        clearMediaPlayer();
    }

    private void clearMediaPlayer() {
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}

In the above code on clicking the FloatingActionButton, the playSong function gets triggered in which we stop the song and reset the MediaPlayer and FloatingActionButton icon every second time.

在上面的单击FloatingActionButton的代码中,playSong函数被触发,在该函数中,我们停止播放歌曲并每隔第二次重置MediaPlayer和FloatingActionButton图标。

Once the mediaPlayer.prepare() is called, the details are available for the song. We can now get the duration and set it on the SeekBar max position.

调用mediaPlayer.prepare() ,该歌曲的详细信息即可使用。 现在,我们可以获取持续时间并将其设置在SeekBar的最大位置上。

setLoooping to false prevents the song from playing infinitely until stopped by the user.

setLoooping为false会阻止歌曲无限播放,直到被用户停止为止。

We start the thread which triggers the run method which was a part of the Runnable interface that we’ve implemented.

我们启动触发run方法的线程,该方法是我们已实现的Runnable接口的一部分。

Inside the run method, we update the progress every second which triggers the onProgressChanged method of the SeekBar listener.

在run方法内部,我们每秒更新进度,这会触发SeekBar侦听器的onProgressChanged方法。

Inside the listener, we’ve set the TextView offset to below the SeekBar’s thumb. We set the time duration by converting the milliseconds to seconds there.

在侦听器内部,我们已将TextView偏移设置为SeekBar的拇指下方。 我们通过将毫秒转换为秒来设置持续时间。

When the seek bar is moved the same method is triggered. When the user stops scrubbing the SeekBar the onStopTrackingTouch is triggered in which using the seekTo method we update the song position on the MediaPlayer instance.

移动搜索栏时,将触发相同的方法。 当用户停止擦拭SeekBar时,会触发onStopTrackingTouch,其中将使用seekTo方法更新MediaPlayer实例上的歌曲位置。

Once the song is completed, we update the position of the SeekBar back to the initial and clear the MediaPlayer instance.

歌曲完成后,我们将SeekBar的位置更新回初始位置,并清除MediaPlayer实例。

The output of the application without audio is given below:

没有音频的应用程序输出如下:

This brings an end to this tutorial. You can download the project from the link below and play the song for yourself.

本教程到此结束。 您可以从下面的链接下载项目,然后自己播放歌曲。

翻译自: https://www.journaldev.com/22203/android-media-player-song-with-seekbar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中的SeekBar是一种常见的用户界面组件,它允许用户通过滑动来选择一个范围内的值。然而,默认情况下,SeekBar只显示一个可移动的滑块,没有刻度。 如果我们想要一个带有刻度的SeekBar,我们需要进行一些自定义。其中一种方法是使用SeekBar的OnSeekBarChangeListener回调接口。我们可以编写一个自定义的OnSeekBarChangeListener,根据SeekBar的值来更新刻度。 首先,我们可以创建一个布局文件,包含一个SeekBar和一个用于显示刻度的TextView。然后,在代码中获取SeekBar和TextView的实例,并设置SeekBar的max值和初始值。 接下来,我们需要为SeekBar添加一个自定义的OnSeekBarChangeListener。在监听器的onProgressChanged方法中,我们可以获取SeekBar的当前值,并根据需要更新刻度。例如,我们可以将刻度的范围划分为10个等级,当SeekBar的值在某个等级范围内时,我们就更新TextView的显示内容为对应的刻度。 最后,我们将SeekBar和TextView添加到布局中,并显示在屏幕上。当用户滑动SeekBar时,刻度将会实时更新并显示在TextView上。 总结起来,要实现一个带有刻度的SeekBar,我们需要进行自定义,通过实现SeekBar的OnSeekBarChangeListener接口来更新刻度,并将SeekBar和显示刻度的TextView添加到布局中。 这样,我们就可以在Android应用程序中使用带有刻度的SeekBar,以更好地满足用户需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值