应用开发实例-音乐播放器

1 业务流程分析说明:

使用Android studio创建一个音乐播放器的面板,使其能够实现主界面,播放列表,歌曲播放,歌曲停止,下一曲的功能。

业务流程可以分为以下几个步骤:

1)初始化界面:用户打开应用后,界面加载包含播放/暂停按钮、下一曲按钮、歌曲信息显示区域、播放列表和进度条的布局。

2)初始化MediaPlayer:在 onCreate 方法中,创建 MediaPlayer 对象,并通过 MediaPlayer.create() 方法加载一个初始的音频文件(示例中使用 sample_song)。

3)处理播放/暂停按钮点击事件:当用户点击播放/暂停按钮时,检查 MediaPlayer 的状态。如果正在播放,暂停音乐;如果已暂停,开始播放音乐。

4)处理下一曲按钮点击事件:当用户点击下一曲按钮时,实现切换到下一首歌曲的逻辑。这可能涉及更新歌曲信息显示区域,并加载新的音频文件。

2 功能核心技术 :

1、用户界面设计:

使用XML布局文件或代码创建用户界面,包括播放/暂停按钮、下一曲按钮、歌曲信息显示区域、播放列表和进度条等。

使用Android的布局管理器和控件来实现界面的合理排布和美观呈现。

2、音频处理和播放:

使用Android MediaPlayer 类或其他音频处理库来管理音频文件的加载、播放和控制。

处理音频焦点,确保应用在播放音乐时能够优先获得系统音频焦点,并在需要时释放焦点,以便其他应用能够正常播放音频。

3、播放控制:

实现播放/暂停按钮的点击事件处理,根据当前音频状态执行相应的操作。

处理下一曲按钮的点击事件,实现切换到下一首歌曲的逻辑。

使用 MediaPlayer 的监听器来监控音频播放状态,例如,在歌曲播放完成时自动切换到下一曲。

3 功能模块说明与核心代码

        1、设计用户界面:使用xml布局文件设计播放器界面

    <!-- activity_main.xml -->

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity">

    <!-- 播放/暂停按钮 -->

    <Button

        android:id="@+id/playPauseButton"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Play/Pause"

        />

    <!-- 下一曲按钮 -->

    <Button

        android:id="@+id/nextButton"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Next"

        />

    <!-- 歌曲信息显示区域 -->

    <TextView

        android:id="@+id/songInfoTextView"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Song Info"

        />

    <!-- 播放列表显示区域 -->

    <ListView

        android:id="@+id/playlistListView"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        />

    <!-- 进度条 -->

    <SeekBar

        android:id="@+id/seekBar"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        />

</RelativeLayout>             

        2、在MainActivity.java中处理界面交互问题,为按钮以及众多控件添加点击事件的处理逻辑创建需要用到的控件,然后绑定控件

import androidx.appcompat.app.AppCompatActivity;

import androidx.fragment.app.FragmentManager;

import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;

import android.view.View;

import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //创建需要用到的控件的变量

    private TextView tv1,tv2;

    private FragmentManager fm;

    private FragmentTransaction ft;

        @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            //绑定控件

            tv1=(TextView)findViewById(R.id.menu1);

            tv2=(TextView)findViewById(R.id.menu2);

            //设置监听器,固定写法

            tv1.setOnClickListener(this);

            tv2.setOnClickListener(this);

            //若是继承FragmentActivityfm=getFragmentManger();

            fm=getSupportFragmentManager();

            //fm可以理解为Fragment显示的管理者,ft就是它的改变者

            ft=fm.beginTransaction();

            //默认情况下就显示frag1

            ft.replace(R.id.content,new frag1());

            //提交改变的内容

            ft.commit();

    }

    @Override

    //控件的点击事件

    public void onClick(View v){

        ft=fm.beginTransaction();

        //切换选项卡

        switch (v.getId()){

            case R.id.menu1:

                ft.replace(R.id.content,new frag1());

                break;

            case R.id.menu2:

                ft.replace(R.id.content,new frag2());

                break;

            default:

                break;

        }

        ft.commit();

    }

}

        3、创建一个服务类MusicService.java该服务负责音乐的播放和停止。MainActivity 中通过绑定服务的方式来与 MusicService 通信,实现了在界面上点击按钮控制音乐的播放和停止。不过必须确保在清理资源时正确地解绑服务,以实现对播放的覆盖。

import android.app.Service;

import android.content.Intent;

import android.media.MediaPlayer;

import android.net.Uri;

import android.os.Binder;

import android.os.Bundle;

import android.os.IBinder;

import android.os.Message;

import java.util.Timer;

import java.util.TimerTask;

//这是一个Service服务类

public class MusicService extends Service {

    //声明一个MediaPlayer引用

    private MediaPlayer player;

    //声明一个计时器引用

    private Timer timer;

    //构造函数

    public MusicService() {}

    @Override

    public  IBinder onBind(Intent intent){

        return new MusicControl();

    }

    @Override

    public void onCreate(){

        super.onCreate();

        //创建音乐播放器对象

        player=new MediaPlayer();

    }

    //添加计时器用于设置音乐播放器中的播放进度条

    public void addTimer(){

        //如果timer不存在,也就是没有引用实例

        if(timer==null){

            //创建计时器对象

            timer=new Timer();

            TimerTask task=new TimerTask() {

                @Override

                public void run() {

                    if (player==null) return;

                    int duration=player.getDuration();//获取歌曲总时长

                    int currentPosition=player.getCurrentPosition();//获取播放进度

                    Message msg= MusicActivity.handler.obtainMessage();//创建消息对象

                    //将音乐的总时长和播放进度封装至bundle

                    Bundle bundle=new Bundle();

                    bundle.putInt("duration",duration);

                    bundle.putInt("currentPosition",currentPosition);

                    //再将bundle封装到msg消息对象中

                    msg.setData(bundle);

                    //最后将消息发送到主线程的消息队列

                    MusicActivity.handler.sendMessage(msg);

                }

            };

   //开始计时任务后的5毫秒,第一次执行task任务,以后每500毫秒(0.5s)执行一次

            timer.schedule(task,5,500);

        }

    }

    //Binder是一种跨进程的通信方式

    class MusicControl extends Binder{

        public void play(int i){//String path

                Uri uri=Uri.parse("android.resource://"+getPackageName()+"/raw/"+"music"+i);

                try{

                    //重置音乐播放器

                    player.reset();

                    //加载多媒体文件

                    player=MediaPlayer.create(getApplicationContext(),uri);

                    player.start();//播放音乐

                    addTimer();//添加计时器

                }catch(Exception e){

                e.printStackTrace();

            }

        }

        //下面的暂停继续和退出方法全部调用的是MediaPlayer自带的方法

        public void pausePlay(){

            player.pause();//暂停播放音乐

        }

        public void continuePlay(){

            player.start();//继续播放音乐

        }

        public void seekTo(int progress){

            player.seekTo(progress);//设置音乐的播放位置

        }

    }

    //销毁多媒体播放器

    @Override

    public void onDestroy(){

        super.onDestroy();

        if(player==null) return;

        if(player.isPlaying()) player.stop();//停止播放音乐

        player.release();//释放占用的资源

        player=null;//player置为空

    }

}

4 系统结果及分析

播放功能: 用户可以通过点击播放按钮(Play Button)成功启动音乐播放器服务,开始播放音频文件。播放状态的切换是实时的,用户能够听到音乐的播放。

停止功能: 用户可以通过点击停止按钮(Stop Button)成功停止当前播放的音频,音乐播放器服务暂停播放并回到音频的开头。

播放列表: 播放列表(Playlist)显示了预定义的歌曲列表,用户可以点击列表中的歌曲以切换当前播放的歌曲。点击列表中的歌曲时,音乐播放器服务能够成功切换到相应的歌曲。

后台播放: 在应用切换到后台或用户切换到其他应用时,音乐播放器服务继续在后台播放音频。用户可以通过通知或其他手段查看当前播放的歌曲信息,并在通知中控制音乐的播放和暂停。

服务生命周期管理: 服务的生命周期得到正确管理,确保在需要时启动,在不需要时正确解绑和销毁。这有助于避免资源泄漏和提高系统的稳定性。

  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值