Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 初步學習BroadCast與Service實現簡單的音樂播放器

Android 初步學習BroadCast與Service實現簡單的音樂播放器

編輯:關於Android編程

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> 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>();

		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) list
				.get(currentPositionMusic)).get("path"));
		intent.putExtra("title", ((HashMap) 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 hashMap1 = new HashMap();
						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代碼





    

    

    
        
            
                

                
            
            
                

                

                
            
        

        
            
                
                
                
                
                
            
        
    



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved