您的位置:首页 > 移动开发 > Android开发

android简单实现音乐播放器

2015-04-22 20:56 369 查看
程序实现如下功能:当点击播放按钮,按钮进行播放音乐,同时按钮背景图片切换成暂停按钮,当点击暂停按钮时,音乐暂停播放,同时按钮背景图片切换成播放按钮,点击重置按钮,音乐停止播放。

效果图如下:



首先简述下编写思路:

程序通过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;
@Override
protected 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() {//暂停事件监听

@Override
public 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() {//停止事件监听,将播放的路径发送过去

@Override
public 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")
@Override
protected void onStart() {
super.onStart();
NotificationManager nm =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this,MainActivity.class);
//将Intent封装为PendingIntent
PendingIntent 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);
}

@Override
protected 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;

@Override
public 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() {
//歌曲播放完毕
@Override
public 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 block
e.printStackTrace();
}

//发送消息改变进度条的进度
new Thread(){
@Override
public 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);
//广播Intent
context.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;
}
@Override
public 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:00
int 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接收者对象引用

@Override
public IBinder onBind(Intent intent)
{//因为本例用不到Bind功能,因此直接返回null
return null;
}

@Override
public void onCreate()
{
super.onCreate();

//创建命令Intent接收者对象
cr=new CommandReceiver();
//创建媒体播放器对象
cr.mp=new MediaPlayer();
//初始状态为停止状态
cr.status=Constant.STATUS_STOP;

//动态注册接收播放、暂停、停止命令Intent的CommandReceiver
IntentFilter filter=new IntentFilter();
filter.addAction(Constant.MUSIC_CONTROL);
this.registerReceiver(cr, filter);
}

@Override
public void onDestroy()
{
super.onDestroy();
//取消注册接收播放、暂停、停止命令Intent的CommandReceiver
this.unregisterReceiver(cr);
//释放播放器对象
cr.mp.release();
}

@Override
public void onStart(Intent intent, int id)
{
//更新界面状态
cr.updateUI(this.getApplicationContext());
}
}


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

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


代码链接:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: