android简单实现音乐播放器

来源:互联网 发布:网络举报网站 编辑:程序博客网 时间:2024/06/07 13:07
      程序实现如下功能:当点击播放按钮,按钮进行播放音乐,同时按钮背景图片切换成暂停按钮,当点击暂停按钮时,音乐暂停播放,同时按钮背景图片切换成播放按钮,点击重置按钮,音乐停止播放。


效果图如下:


首先简述下编写思路:
      程序通过service与广播接收者实现。在主功能代码中发送广播,有一个命令广播接收者,用来接收命令,一个更新UI的广播接收者,用来接收命令广播发送过来的状态,根据状态更新UI。


给出代码:

首先是布局文件:

<LinearLayout 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"    android:orientation="vertical" >    <ProgressBar         android:id="@+id/pb"        android:layout_marginTop="3dp"        android:layout_width="match_parent"        android:layout_height="wrap_content"        style="@android:style/Widget.ProgressBar.Horizontal"        />    <TextView         android:id="@+id/tv"        android:layout_marginTop="8dp"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="0:00/0:00"        android:textSize="12sp"        />    <LinearLayout         android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:orientation="horizontal"        >        <ImageButton             android:id="@+id/pause"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/pause"            />        <ImageButton             android:id="@+id/stop"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:background="@drawable/stop"            android:layout_marginLeft="5dp"            />    </LinearLayout></LinearLayout>

布局文件给出一个进度条,一个TextView控件,用来标识播放进度,一个播放暂停按钮,一个重置按钮,成垂直布局。

接下来实现主功能代码:

package com.example.sample5_11tdw;import android.support.v7.app.ActionBarActivity;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ImageButton;public class MainActivity extends ActionBarActivity {private ImageButton pause;//暂停private ImageButton stop;//停止private String path = "/sdcard/zdan.mp3";private UpateUIReceiver uuRece;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);InitViews();}private void InitViews() {pause = (ImageButton) findViewById(R.id.pause);stop = (ImageButton) findViewById(R.id.stop);uuRece = new UpateUIReceiver(this);//当前状态为暂停,点击后进行播放pause.setOnClickListener(new View.OnClickListener() {//暂停事件监听@Overridepublic void onClick(View v) {if(uuRece.status == Constanly.STATUS_PLAY){//如果当前状态为播放Intent intent = new Intent(Constanly.MUSIC_CONTROL);//发送暂停命令intent.putExtra("cmd", Constanly.COMMAND_PAUSE);MainActivity.this.sendBroadcast(intent);}else if(uuRece.status == Constanly.STATUS_STOP){//当前状态为暂停Intent intent = new Intent(Constanly.MUSIC_CONTROL);intent.putExtra("path", path);intent.putExtra("cmd", Constanly.COMMAND_PLAY);MainActivity.this.sendBroadcast(intent);}else if(uuRece.status == Constanly.STATUS_PAUSE){//若当前状态为暂停,则继续播放Intent intent = new Intent(Constanly.MUSIC_CONTROL);intent.putExtra("cmd", Constanly.COMMAND_PLAY);MainActivity.this.sendBroadcast(intent);}}});stop.setOnClickListener(new View.OnClickListener() {//停止事件监听,将播放的路径发送过去@Overridepublic void onClick(View v) {Intent intent = new Intent(Constanly.MUSIC_CONTROL);intent.putExtra("cmd", Constanly.COMMADN_STOP);MainActivity.this.sendBroadcast(intent);}});//动态注册更新UI的广播事件IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(Constanly.UPDATE_UI);registerReceiver(uuRece, intentFilter);this.startService(new Intent(MainActivity.this,MyMusicService.class));}@SuppressWarnings("deprecation")@Overrideprotected void onStart() {super.onStart();NotificationManager nm =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);Intent intent = new Intent(this,MainActivity.class);//将Intent封装为PendingIntentPendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);Notification notification = new Notification();notification.icon = R.drawable.notilogo;notification.vibrate = new long[]{200,300};//200毫秒后震动300毫秒notification.setLatestEventInfo(this, "音乐播放器正在运行中", "单击查看", pi);nm.notify(0,notification);}@Overrideprotected void onDestroy() {super.onDestroy();this.unregisterReceiver(uuRece);}}

在主功能代码中获取按钮控件,为按钮控件设置事件监听,当点击播放暂停按钮时,需要判断当前的状态,如果为停止状态,则需要将路径,播放命令发送出去,如果为暂停状态,发送播放状态即可,在命令广播接收类中通过判断命令来对应相应的操作。同时动态注册命令接收广播,启动服务。

给出命令广播接收类:

package com.example.sample5_11tdw;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.media.MediaPlayer;import android.os.Looper;import android.view.LayoutInflater;import android.widget.ImageButton;public class CommandReceiver extends BroadcastReceiver{public MediaPlayer mp;public int status;@Overridepublic void onReceive(final Context context, Intent intent) {switch (intent.getIntExtra("cmd", -1)) {case Constanly.COMMAND_PLAY:String path = intent.getStringExtra("path");if(path != null){//path不为空,说明是停止后重新播放//说明之前已经有MediaPlayer对象了,要进行释放if(mp != null){mp.release();} mp=new MediaPlayer();try {//为音乐播放器添加完成监听mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {//歌曲播放完毕@Overridepublic void onCompletion(MediaPlayer mp) {mp.stop();status = Constanly.STATUS_STOP;updateUI(context);}});mp.setDataSource(path);//通过new MediaPlayer()一定要先进行prepare()mp.prepare();//开始播放mp.start();}  catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//发送消息改变进度条的进度new Thread(){@Overridepublic void run() {Looper:while(true){//如果当前状态为停止状态if(status == Constanly.STATUS_STOP){break Looper;}int duration = 0;//总时间int current = 0;//当前时间//如果状态为暂停或者播放if(status == Constanly.STATUS_PAUSE || status == Constanly.STATUS_PLAY){duration = mp.getDuration();current = mp.getCurrentPosition();Intent intent = new Intent(Constanly.UPDATE_UI);intent.putExtra("status", Constanly.PROGRESS_GO);intent.putExtra("duration", duration);intent.putExtra("current", current);//广播Intentcontext.sendBroadcast(intent);}}};}.start();}else{//如果是暂停后播放,直接继续播放即可mp.start();}status = Constanly.STATUS_PLAY;break;case Constanly.COMMAND_PAUSE:status = Constanly.STATUS_PAUSE;mp.pause();break;case Constanly.COMMADN_STOP:status = Constanly.STATUS_STOP;mp.stop();break;}updateUI(context);}protected void updateUI(Context context) {Intent intent = new Intent(Constanly.UPDATE_UI);intent.putExtra("status", status);context.sendBroadcast(intent);}}

在命令广播接收类中,判断命令,使用path是否为空来判断是暂停后播放,还是停止状态后播放。在这个类中主要实现播放音乐,同时更改当前状态发送至UI更新广播类中,

给出UI广播接收类:

package com.example.sample5_11tdw;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.view.LayoutInflater;import android.widget.ImageButton;import android.widget.ProgressBar;import android.widget.TextView;public class UpateUIReceiver extends BroadcastReceiver{private Activity ac;public int status;public UpateUIReceiver(Activity ac) {this.ac = ac;}@Overridepublic void onReceive(Context context, Intent intent) {ImageButton pauseButton = (ImageButton) ac.findViewById(R.id.pause);ProgressBar pb = (ProgressBar) ac.findViewById(R.id.pb);int tempStatus = intent.getIntExtra("status", -1);switch (tempStatus) {case Constanly.STATUS_PLAY:pauseButton.setImageResource(R.drawable.pause);status = tempStatus;break;case Constanly.STATUS_PAUSE:pauseButton.setImageResource(R.drawable.play);status = tempStatus;break;case Constanly.STATUS_STOP:pb.setProgress(0);pauseButton.setImageResource(R.drawable.play);status = tempStatus;break;case Constanly.PROGRESS_GO:int duration = intent.getIntExtra("duration", 0);int current = intent.getIntExtra("current", 0);pb.setMax(duration);pb.setProgress(current);TextView tv = (TextView) ac.findViewById(R.id.tv);tv.setText(convertToMinute(current)+"/"+convertToMinute(duration));break;}}private String convertToMinute(int value) {//得到的是毫秒值,返回格式0:00int second = value / 1000;int minute = second / 60;second = second % 60;String minStr = String.valueOf(minute);String secStr = String.valueOf(second);return minStr+":"+(second>9?second:"0"+second);}}

在这个广播接收类中主要实现UI的更新。

一个常量类:

package com.example.sample5_11tdw;public class Constanly {//常量类//播放命令public final static int COMMAND_PLAY = 0;//暂停命令public final static int COMMAND_PAUSE = 1;//停止命令public final static int COMMADN_STOP = 2;//播放状态public final static int STATUS_PLAY = 3;//暂停状态public final static int STATUS_PAUSE = 4;//停止状态public final static int STATUS_STOP = 5;//状态更新常量public final static int PROGRESS_GO = 6;//更新界面public final static String UPDATE_UI = "UPDATE_UI";//音乐控制public final static String MUSIC_CONTROL = "MUSIC_CONTROL";}


给出service服务类:

package com.bn.chap5.no;import android.app.Service;import android.content.Intent;import android.content.IntentFilter;import android.media.MediaPlayer;import android.os.IBinder;//后台播放的Service类public class MyMusicPlayerService extends Service {CommandReceiver cr;//命令Intent接收者对象引用@Overridepublic IBinder onBind(Intent intent) {//因为本例用不到Bind功能,因此直接返回nullreturn null;}@Overridepublic void onCreate(){super.onCreate();//创建命令Intent接收者对象cr=new CommandReceiver();//创建媒体播放器对象cr.mp=new MediaPlayer();//初始状态为停止状态cr.status=Constant.STATUS_STOP;//动态注册接收播放、暂停、停止命令Intent的CommandReceiverIntentFilter filter=new IntentFilter();filter.addAction(Constant.MUSIC_CONTROL);this.registerReceiver(cr, filter);}@Overridepublic void onDestroy(){super.onDestroy();//取消注册接收播放、暂停、停止命令Intent的CommandReceiverthis.unregisterReceiver(cr);//释放播放器对象cr.mp.release();}@Overridepublic void onStart(Intent intent, int id){//更新界面状态cr.updateUI(this.getApplicationContext());}}

记得在清单文件需要注册service类:

 <service android:name=".MyMusicService" android:process=":remote"></service>


代码链接:


0 0
原创粉丝点击