編輯:關於Android編程
這是一個基於Service組件的音樂播放器,程序的音樂將會由後台的Service組件負責播放,當後台的播放狀態改變時,程序將會通過發送廣播通知前台Activity更新界面;當用戶單擊前台Activity的界面按鈕或拖動進度條時,系統通過發送廣播通知後台Service來改變播放狀態和播放指定音樂。
程序運行效果圖:
vc=">

程序代碼:
程序界面類(MusicBox.java):
package com.jph.musicbox;
import com.jph.util.ConstUtil;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
/**
* Describe:
* 基於Service的音樂播發器
* 本應用主要實現了:
* 1.通過前台Activity發出播放相關的控制信息,以廣播的形式
* 傳遞給後台的Service,後台的Service負責音樂的播放。
* 並負責接收後台的廣播來更新播放界面的歌曲名、歌手名。
* 2.通過進度條來顯示當前播放的位置,當用戶拖動進度條時
* 通過OnSeekBarChangeListener事件來控制
* 後台的mediaPlayer播放指定位置的音樂。
* @author jph
* Date:2014.08.07
* */
public class MusicBox extends Activity {
ImageButton btnPlayOrPause,btnPre,btnNext;
//進度條
static SeekBar skbMusic;
// 獲取界面中顯示歌曲標題、作者文本框
TextView title, author;
String[] titleStrs = new String[] { "濤聲依舊", "油菜花", "You Are The One" };
String[] authorStrs = new String[] { "毛寧", "成龍", "未知藝術家" };
//是否正在播放
boolean isPlaying=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
skbMusic=(SeekBar)findViewById(R.id.skbMusic);
skbMusic.setOnSeekBarChangeListener(sChangeListener);
btnNext=(ImageButton)findViewById(R.id.btnNext);
btnPlayOrPause=(ImageButton)findViewById(R.id.btnPlayOrPause);
btnPre=(ImageButton)findViewById(R.id.btnPre);
btnNext.setOnClickListener(listener);
btnPlayOrPause.setOnClickListener(listener);
btnPre.setOnClickListener(listener);
title=(TextView)findViewById(R.id.title);
author=(TextView)findViewById(R.id.author);
title.setText(titleStrs[0]);
author.setText(authorStrs[0]);
//注冊接收器
MusicBoxReceiver mReceiver=new MusicBoxReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction(ConstUtil.MUSICBOX_ACTION);
registerReceiver(mReceiver, filter);
//啟動後台Service
Intent intent=new Intent(this, MusicService.class);
startService(intent);
}
OnClickListener listener=new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnNext://下一首
btnPlayOrPause.setBackgroundResource(R.drawable.state_pasue);
sendBroadcastToService(ConstUtil.STATE_NEXT);
isPlaying=true;
break;
case R.id.btnPlayOrPause://播放或暫停
if (!isPlaying) {
btnPlayOrPause.setBackgroundResource(R.drawable.state_pasue);
sendBroadcastToService(ConstUtil.STATE_PLAY);
isPlaying=true;
}else {
btnPlayOrPause.setBackgroundResource(R.drawable.state_play);
sendBroadcastToService(ConstUtil.STATE_PAUSE);
isPlaying=false;
}
break;
case R.id.btnPre://上一首
btnPlayOrPause.setBackgroundResource(R.drawable.state_pasue);
sendBroadcastToService(ConstUtil.STATE_PREVIOUS);
isPlaying=true;
break;
default:
break;
}
}
};
/**
* SeekBar進度改變事件
*/
OnSeekBarChangeListener sChangeListener=new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
//當拖動停止後,控制mediaPlayer播放指定位置的音樂
MusicService.mediaPlayer.seekTo(seekBar.getProgress());
MusicService.isChanging=false;
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
MusicService.isChanging=true;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
menu.add(Menu.NONE, ConstUtil.MENU_ABOUT, Menu.NONE, "關於");
menu.add(Menu.NONE, ConstUtil.MENU_EXIT, Menu.NONE, "退出");
return true;
}
/**
*向後台Service發送控制廣播
*@param state int state 控制狀態碼
* */
protected void sendBroadcastToService(int state) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setAction(ConstUtil.MUSICSERVICE_ACTION);
intent.putExtra("control", state);
//向後台Service發送播放控制的廣播
sendBroadcast(intent);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case ConstUtil.MENU_ABOUT:
LayoutInflater inflater=LayoutInflater.from(this);
LinearLayout layout=(LinearLayout) inflater.inflate(R.layout.about, null);
AlertDialog dialog=new AlertDialog.Builder(this).create();
dialog.setTitle("關於");
dialog.setIcon(R.drawable.ic_launcher);
dialog.setView(layout);
dialog.show();
break;
case ConstUtil.MENU_EXIT:
sendBroadcastToService(ConstUtil.STATE_STOP);
this.finish();
break;
default:
break;
}
return true;
}
//創建一個廣播接收器用於接收後台Service發出的廣播
class MusicBoxReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// 獲取Intent中的current消息,current代表當前正在播放的歌曲
int current = intent.getIntExtra("current", -1);
title.setText(titleStrs[current]);//更新音樂標題
author.setText(authorStrs[current]);//更新音樂作者
}
}
}
負責音樂播放的後台Service類:MusicService.java
package com.jph.musicbox;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import com.jph.util.ConstUtil;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
/**
* Describe:
* 負責音樂播放的後台Service
* 1.通過接收來自前台的控制播放信息的廣播來播放指定音樂
* 2.加載assets目錄下的音樂
* 3.為mediaPlayer的完成事件創建監聽器當當前音樂播放
* 完成後自動播放下一首音樂
* 4.為每一首正在播放的音樂創建一個定時器,用於檢測播放進度
* 並更新進度條
* @author jph
* Date:2014.08.07
* */
public class MusicService extends Service {
Timer mTimer;
TimerTask mTimerTask;
static boolean isChanging=false;//互斥變量,防止定時器與SeekBar拖動時進度沖突
//創建一個媒體播放器的對象
static MediaPlayer mediaPlayer;
//創建一個Asset管理器的的對象
AssetManager assetManager;
//存放音樂名的數組
String[]musics=new String[]{"taoshengyijiu-maoning.mp3", "youcaihua-chenglong.mp3","You Are The One.mp3" };
//當前的播放的音樂
int current=0;
//當前播放狀態
int state=ConstUtil.STATE_NON;
//記錄Timer運行狀態
boolean isTimerRunning=false;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
//注冊接收器
MusicSercieReceiver receiver=new MusicSercieReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction(ConstUtil.MUSICSERVICE_ACTION);
registerReceiver(receiver, filter);
mediaPlayer=new MediaPlayer();
assetManager=getAssets();
//為mediaPlayer的完成事件創建監聽器
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
// mTimer.cancel();//取消定時器
current++;
prepareAndPlay(current);
}
});
}
/**
* 裝載和播放音樂
* @param index int index 播放第幾首音樂的索引
* */
protected void prepareAndPlay(int index) {
// TODO Auto-generated method stub
if (isTimerRunning) {//如果Timer正在運行
mTimer.cancel();//取消定時器
isTimerRunning=false;
}
if (index>2) {
current=index=0;
}
if (index<0) {
current=index=2;
}
//發送廣播停止前台Activity更新界面
Intent intent=new Intent();
intent.putExtra("current", index);
intent.setAction(ConstUtil.MUSICBOX_ACTION);
sendBroadcast(intent);
try {
//獲取assets目錄下指定文件的AssetFileDescriptor對象
AssetFileDescriptor assetFileDescriptor=assetManager.openFd(musics[current]);
mediaPlayer.reset();//初始化mediaPlayer對象
mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(),
assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
//准備播放音樂
mediaPlayer.prepare();
//播放音樂
mediaPlayer.start();
//getDuration()方法要在prepare()方法之後,否則會出現Attempt to call getDuration without a valid mediaplayer異常
MusicBox.skbMusic.setMax(mediaPlayer.getDuration());//設置SeekBar的長度
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//----------定時器記錄播放進度---------//
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
isTimerRunning=true;
if(isChanging==true)//當用戶正在拖動進度進度條時不處理進度條的的進度
return;
MusicBox.skbMusic.setProgress(mediaPlayer.getCurrentPosition());
}
};
//每隔10毫秒檢測一下播放進度
mTimer.schedule(mTimerTask, 0, 10);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
//創建廣播接收器用於接收前台Activity發去的廣播
class MusicSercieReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
int control=intent.getIntExtra("control", -1);
switch (control) {
case ConstUtil.STATE_PLAY://播放音樂
if (state==ConstUtil.STATE_PAUSE) {//如果原來狀態是暫停
mediaPlayer.start();
}else if (state!=ConstUtil.STATE_PLAY) {
prepareAndPlay(current);
}
state=ConstUtil.STATE_PLAY;
break;
case ConstUtil.STATE_PAUSE://暫停播放
if (state==ConstUtil.STATE_PLAY) {
mediaPlayer.pause();
state=ConstUtil.STATE_PAUSE;
}
break;
case ConstUtil.STATE_STOP://停止播放
if (state==ConstUtil.STATE_PLAY||state==ConstUtil.STATE_PAUSE) {
mediaPlayer.stop();
state=ConstUtil.STATE_STOP;
}
break;
case ConstUtil.STATE_PREVIOUS://上一首
prepareAndPlay(--current);
state=ConstUtil.STATE_PLAY;
break;
case ConstUtil.STATE_NEXT://下一首
prepareAndPlay(++current);
state=ConstUtil.STATE_PLAY;
break;
default:
break;
}
}
}
}
常量工具類(ConstUtil.java):
package com.jph.util;
/**
* Describe:
* 常量工具類
* 主要用於為其它類提供程序所用到的常量
* @author jph
* Date:2014.08.07
* */
public class ConstUtil {
//MusicBox接收器所能響應的Action
public static final String MUSICBOX_ACTION="com.jph.musicbox.MUSICBOX_ACTION";
//MusicService接收器所能響應的Action
public static final String MUSICSERVICE_ACTION="com.jph.musicbox.MUSICSERVICE_ACTION";
//初始化flag
public static final int STATE_NON=0x122;
//播放的flag
public static final int STATE_PLAY=0x123;
//暫停的flag
public static final int STATE_PAUSE=0x124;
//停止放的flag
public static final int STATE_STOP=0x125;
//播放上一首的flag
public static final int STATE_PREVIOUS=0x126;
//播放下一首的flag
public static final int STATE_NEXT=0x127;
//菜單關於選項的itemId
public static final int MENU_ABOUT=0x200;
//菜單退出選的項的itemId
public static final int MENU_EXIT=0x201;
public ConstUtil() {
// TODO Auto-generated constructor stub
}
}
項目清單配置文件:AndroidManifest.xml:
加載3種狀態架構
基類LoadintPager(加載三種狀態)通常都知道,android中一個頁面的加載,無非三種狀態:加載中 加載成功 加載失敗當然,如果從網絡獲取數據,可能會出現數據為
【Android】GreenDao操作外部DB數據庫文件
1.背景所謂外部數據庫文件此處指的就是一個在外部單獨創建的db文件,假設有這麼一個場景,我們項目中有一些本地數據,不需要接口去獲取的(不需要進行網絡操作),寫死的數據,比
如何對手機應用進行安全分析
手機殺毒軟件大都通過特征碼對病毒進行判斷,在沒有截獲這個手機病毒以前是不能對其進行防范的。不過,PC端的殺毒軟件裡面都有一個文件分析器的功能,那麼在手機裡面
android 驗證碼之短信驗證(雲之訊短信平台)
好久沒更新過博客了。這段時間總算是忙完了,抽點時間出來更新下博客。這次跟大家帶來的是一個很簡單的短信驗證碼。相信這個驗證碼的功能基本上99的項目都需要用到,我這裡是用的雲