Activity代码
package com.siyehuazhilian.musicplay;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener {
// ListView
private ListView listView;
// 适配器
private SimpleAdapter adapter;
// 数据源
private ArrayList<HashMap<String, String>> list;
// 当前播放的曲目
private int currentPositionMusic = -1;
// 上一首
private ImageButton lastImageButton;
// 播放
private ImageButton playImageButton;
// 下一首
private ImageButton nextImageButton;
// 循环
private ImageButton loopImageButton;
// 播放进度
private SeekBar playSeekBar;
// 当前播放曲目
private TextView currentPlayingSong;
// 是否是第一次进来
private boolean ifFirstIn = true;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listview);
lastImageButton = (ImageButton) findViewById(R.id.imagebutton_previous);
playImageButton = (ImageButton) findViewById(R.id.imagebutton_play);
nextImageButton = (ImageButton) findViewById(R.id.imagebutton_next);
loopImageButton = (ImageButton) findViewById(R.id.imagebutton_loops);
playSeekBar = (SeekBar) findViewById(R.id.seekbar_play);
currentPlayingSong = (TextView) findViewById(R.id.textview_songinformation);
list = new ArrayList<HashMap<String, String>>();
adapter = new SimpleAdapter(this, list, R.layout.list_item,
new String[] { "title" }, new int[] { R.id.textview_item });
listView.setAdapter(adapter);
// 为listView设置监听器
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
try {
currentPositionMusic = position;
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}
});
lastImageButton.setOnClickListener(this);
playImageButton.setOnClickListener(this);
nextImageButton.setOnClickListener(this);
loopImageButton.setOnClickListener(this);
playSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
// 改变进度条
intent = new Intent("changed");
intent.putExtra("seekbarprogress", progress);
startService(intent);
}
}
});
}
private void playMusic() {
// 启动播放音乐的服务
intent = new Intent("play");
intent.putExtra("uri", ((HashMap<String, String>) list
.get(currentPositionMusic)).get("path"));
intent.putExtra("title", ((HashMap<String, String>) list
.get(currentPositionMusic)).get("title"));
startService(intent);
// 把图片改为播放的图片
playImageButton.setImageResource(R.drawable.play);
// 同时更改SeekBar的进度,因为进度是不断变化的,所以需要一个子线程来刷新下
// playSeekBar.setMax(mp.getDuration());
// 设置当前播放曲目信息
currentPlayingSong.setTextColor(Color.GREEN);
currentPlayingSong.setText(list.get(currentPositionMusic).get("title"));
}
@Override
protected void onResume() {
super.onResume();
// 得到所有音频
if (ifFirstIn) {
ifFirstIn = false;
scanMusic();
}
// 动态注册广播
IntentFilter filter = new IntentFilter();
filter.addAction("seekbarmaxprogress");
filter.addAction("seekbarprogress");
filter.addAction("playNextSong");
filter.addAction("pause");
filter.addAction("setplay");
filter.addAction("stoploop");
filter.addAction("startloop");
registerReceiver(broadcastReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 关闭通知
intent = new Intent("stopnotification");
startService(intent);
// 停止服务
stopService(intent);
// 取消广播的注册
unregisterReceiver(broadcastReceiver);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("你确定要退出吗?");
builder.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.show();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
/**
* 得多所有的音频
*/
private void scanMusic() {
// 置空list集合中的所有元素,放置反复启动导致的数据重复,其实这个部分是因为每次进来都会重新获得焦点,执行onResume造成的
// 这个修改虽然可以,但是每次进来都有重新加载,增加了手机的符合,所以可以设置一个标志,只有在第一进来的时候才会加载数据
// list.clear();
new Thread() {
public void run() {
Cursor cursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
while (cursor.moveToNext()) {
String title = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String path = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
String size = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
if (Long.parseLong(size) > 1024 * 1024) {
HashMap<String, String> hashMap1 = new HashMap<String, String>();
hashMap1.put("title", title);
hashMap1.put("path", path);
list.add(hashMap1);
}
}
cursor.close();
};
}.start();
}
/**
* 监听
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.imagebutton_previous:
playLastSong();
break;
case R.id.imagebutton_play:
intent = new Intent("clickplay");
startService(intent);
break;
case R.id.imagebutton_next:
playNextSong();
break;
case R.id.imagebutton_loops:
intent = new Intent("loops");
startService(intent);
break;
default:
break;
}
}
/**
* 播放下一曲
*/
private void playNextSong() {
// 只有当有音乐在播放的时候才可以点击下一首
if (currentPositionMusic != -1) {
// 如果当前歌曲为最后一首,就播放第一首歌曲
if (currentPositionMusic == list.size() - 1) {
// 设置当前歌曲为第一首
currentPositionMusic = 0;
try {
// 播放第一首歌曲
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}// 否则就播放下一首歌曲
else {
// 设置当前歌曲为下一首
currentPositionMusic++;
try {
// 播放下一首歌曲
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 播放上一曲
*/
private void playLastSong() {
// 只有当有音乐在播放的时候才可以点击上一首
if (currentPositionMusic != -1) {
// 如果当前歌曲为第一首,就播放最后一首歌曲
if (currentPositionMusic == 0) {
// 设置当前歌曲为最后一首
currentPositionMusic = list.size() - 1;
try {
// 播放最后一首歌曲
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}// 否则就播放上一首歌曲
else {
// 设置当前歌曲为前一首
currentPositionMusic--;
try {
// 播放前一首歌曲
playMusic();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 广播对象,动态注册,用来接收从Service传过来的消息,根据不同的消息做不同的事情
*/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("seekbarmaxprogress")) {
playSeekBar.setMax(intent
.getIntExtra("seekbarmaxprogress", 100));
} else if (intent.getAction().equals("seekbarprogress")) {
playSeekBar.setProgress(intent
.getIntExtra("seekbarprogress", 0));
} else if (intent.getAction().equals("playNextSong")) {
playNextSong();
} else if (intent.getAction().equals("pause")) {
// 还要把图片改为暂停的图片
playImageButton.setImageResource(R.drawable.pause);
} else if (intent.getAction().equals("setplay")) {
// 把图片设置成播放的图片
playImageButton.setImageResource(R.drawable.play);
} else if (intent.getAction().equals("stoploop")) {
// 还要把图片改为不循环的图片
loopImageButton.setImageResource(R.drawable.loop_false);
} else if (intent.getAction().equals("startloop")) {
// 把图片设置成循环播放的图片
loopImageButton.setImageResource(R.drawable.loop_true);
}
}
};
}
Service代码
package com.siyehuazhilian.service;
import java.util.HashMap;
import com.siyehuazhilian.musicplay.MainActivity;
import com.siyehuazhilian.musicplay.R;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
public class PlayMusicService extends Service {
private MediaPlayer mediaPlayer;
// 设置Seebar最大进度
private static final int SET_SEEKBAR_MAX = 3;
// 刷新SeekBar进度
private static final int UPDATE_PROGRESS = 1;
// 加载数据
private static final int LOADING_DATA = 2;
// 通知管理
private NotificationManager notificationManager;
// 通知
private Notification notification;
private Intent intent;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressLint("ShowToast")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (intent.getAction().equals("play")) {// 如果是播放Action,就播放音乐
try {
Toast.makeText(getApplicationContext(), "开始播放", 1000).show();
playMusic(intent.getStringExtra("uri"));
showNotification(intent.getStringExtra("title"));
} catch (Exception e) {
e.printStackTrace();
}
} else if (intent.getAction().equals("changed")) {// 如果是拖动的Action,就跳至拖动的进度
if (mediaPlayer != null) {
mediaPlayer.seekTo(intent.getIntExtra("seekbarprogress", 0));
}
} else if (intent.getAction().equals("clickplay")) {// 如果是播放/暂停Action,就执行相应的播放或者暂停
Toast.makeText(getApplicationContext(), "播放被点击了", 1000).show();
if (mediaPlayer != null) {
// 如果音乐播放器正在播放
if (mediaPlayer.isPlaying()) {
// 那就暂停它
mediaPlayer.pause();
// 发送暂停广播给程序
this.intent = new Intent("pause");
sendBroadcast(this.intent);
} else {
// 否则就播放它
mediaPlayer.start();
// 发送播放广播
this.intent = new Intent("setplay");
sendBroadcast(this.intent);
}
}
} else if (intent.getAction().equals("loops")) {// 如果是loop循环Action,就把歌曲设置为循环播放
Toast.makeText(getApplicationContext(), "循环被点击了", 1000).show();
if (mediaPlayer != null) {
// 如果音乐播放器正在循环
if (mediaPlayer.isLooping()) {
// 那就终止循环它
mediaPlayer.setLooping(false);
// 发送终止循环广播
this.intent = new Intent("stoploop");
sendBroadcast(this.intent);
} else {
// 否则就循环播放它
mediaPlayer.setLooping(true);
// 发送开始循环广播
this.intent = new Intent("startloop");
sendBroadcast(this.intent);
}
}
} else if (intent.getAction().equals("stopnotification")) {
notificationManager.cancelAll();
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
handler.removeMessages(UPDATE_PROGRESS);
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
/**
* 播放音乐
*
* @param path
* @throws Exception
*/
private void playMusic(String path) throws Exception {
if (mediaPlayer == null) {
// 新建一个mediaPalyer对象
mediaPlayer = new MediaPlayer();
}
// 使mediaPalyer进入Idle状态
mediaPlayer.reset();
// 设置数据源,使mediaPlayer进入Intialized状态
mediaPlayer.setDataSource(path);
// 准备播放
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// 开始播放音乐
mp.start();
handler.sendEmptyMessage(SET_SEEKBAR_MAX);
handler.sendEmptyMessage(UPDATE_PROGRESS);
}
});
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (mp.isLooping()) {
mp.start();
} else {
intent = new Intent("playNextSong");
sendBroadcast(intent);
}
}
});
}
private Handler handler = new Handler() {
@SuppressLint("HandlerLeak")
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_PROGRESS:
// 设置最大当前播放进度
intent = new Intent("seekbarprogress");
intent.putExtra("seekbarprogress",
mediaPlayer.getCurrentPosition());
sendBroadcast(intent);
// 需要随着播放设置
handler.sendEmptyMessageDelayed(UPDATE_PROGRESS, 1000);
break;
case LOADING_DATA:
// adapter.notifyDataSetInvalidated();
break;
case SET_SEEKBAR_MAX:
intent = new Intent("seekbarmaxprogress");
intent.putExtra("seekbarmaxprogress", mediaPlayer.getDuration());
sendBroadcast(intent);
// 因为进度条只需要设置一次就够了,所以不需要反复发送Message;
break;
default:
break;
}
};
};
/**
* 显示通知
*
*/
private void showNotification(String title) {
notification = new Notification(R.drawable.app_icon, "百度音乐",
System.currentTimeMillis());
notification.flags |= Notification.FLAG_NO_CLEAR;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
Intent intent = new Intent(this, MainActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, 0);
notification.setLatestEventInfo(this, "正在播放", title, pendingIntent);
notificationManager.notify(1, notification);
}
}
AndroidManifest.xml代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.siyehuazhilian.musicplay"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light.NoTitleBar" >
<activity
android:name="com.siyehuazhilian.musicplay.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="audio/*" />
</intent-filter>
</activity>
<service android:name="com.siyehuazhilian.service.PlayMusicService" >
<intent-filter>
<action android:name="play" />
<action android:name="changed" />
<action android:name="clickplay" />
<action android:name="loops" />
<action android:name="stopnotification" />
</intent-filter>
</service>
</application>
</manifest>