編輯:關於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:
基類LoadintPager(加載三種狀態)通常都知道,android中一個頁面的加載,無非三種狀態:加載中 加載成功 加載失敗當然,如果從網絡獲取數據,可能會出現數據為
1.背景所謂外部數據庫文件此處指的就是一個在外部單獨創建的db文件,假設有這麼一個場景,我們項目中有一些本地數據,不需要接口去獲取的(不需要進行網絡操作),寫死的數據,比
手機殺毒軟件大都通過特征碼對病毒進行判斷,在沒有截獲這個手機病毒以前是不能對其進行防范的。不過,PC端的殺毒軟件裡面都有一個文件分析器的功能,那麼在手機裡面
好久沒更新過博客了。這段時間總算是忙完了,抽點時間出來更新下博客。這次跟大家帶來的是一個很簡單的短信驗證碼。相信這個驗證碼的功能基本上99的項目都需要用到,我這裡是用的雲