android音乐播放器拖放播放进度设计
效果图:

播放器设计中需要显示播放进度,并随着播放的进行,进度条要走动。当我们直接拖放播放进度条,也能调整播放进度。这里我们使用了SeekBar来完成这个任务。
下面直接上代码:
界面布局不多说
main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="match_parent" android:layout_height="match_parent" > <SeekBar android:id="@+id/seekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" /> <Button android:id="@+id/previous" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="前一个" /> <Button android:id="@+id/next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:text="下一个" /> <Button android:id="@+id/play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_toLeftOf="@id/next" android:layout_toRightOf="@id/previous" android:text="播放" /> </RelativeLayout></LinearLayout>
在前台的界面,只设置了播放操作,可以看到点击播放后,我们启动了service播放音乐,这里我们要注意看到SeekBarReceiver这个。我们是通过接收受service发过来的广播,并调整进度条的。还有这个SeekBarListener,我们通过它设置了SeekBar的拖放操作
MusicseekbarActivity.java
package org.hwq.music.seekbar;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.SeekBar;import android.widget.SeekBar.OnSeekBarChangeListener;public class MusicseekbarActivity extends Activity implements OnClickListener{ Button pre,play,next; SeekBar seekbar; SeekBarReceiver receiver; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pre = (Button) findViewById(R.id.previous); play = (Button) findViewById(R.id.play); next = (Button) findViewById(R.id.next); seekbar = (SeekBar) findViewById(R.id.seekBar1); pre.setOnClickListener(this); play.setOnClickListener(this); next.setOnClickListener(this); seekbar.setOnSeekBarChangeListener(new SeekBarListener()); } @Override protected void onStart() { super.onStart(); //注册receiver接受service中发送过来的广播 receiver = new SeekBarReceiver(); this.registerReceiver(receiver, new IntentFilter("org.hwq.receiver.seekbar")); } @Override protected void onDestroy() { super.onStop(); Intent intent = new Intent(this,PlayService.class); stopService(intent); PlayService.isrunning = false; this.unregisterReceiver(receiver); super.onDestroy(); } //是否正在进行拖放(没设置这个的话,在拖放的过程中会出现点小小不爽的效果,自己可以测试下) boolean seekbarTrackTouch = false; //SeekBar拖放事件处理了 class SeekBarListener implements OnSeekBarChangeListener{ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } public void onStartTrackingTouch(SeekBar seekBar) { seekbarTrackTouch = true; } public void onStopTrackingTouch(SeekBar seekBar) { seekbarTrackTouch = false; int currentPosition = seekBar.getProgress(); Intent intent = new Intent("org.hwq.music.seekbar.seekto"); intent.putExtra("currentPosition", currentPosition); sendBroadcast(intent); } } public void onClick(View v) { switch(v.getId()){ case R.id.previous: playPrevious(); break; case R.id.play: play(); break; case R.id.next: playNext(); break; } } private void playNext() { } private void play() { System.out.println("play()被点击"); Intent intent = new Intent(this,PlayService.class); intent.putExtra("op", "play"); startService(intent); } private void playPrevious() { } class SeekBarReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { int currentPosition = intent.getIntExtra("currentPosition", 0); int duration = intent.getIntExtra("duration", 0); System.out.println("activity收到一个广播:currentPosition="+currentPosition+" duration="+duration); if(!seekbarTrackTouch){ seekbar.setProgress(currentPosition*100/duration); seekbar.invalidate(); } } }}
播放service,播放过程中通过发出广播,影响前台的SeekBar的播放进度。并接收前台SeekBar的拖放事件广播,调整音乐播放进度。
PlayService.java
package org.hwq.music.seekbar;import java.util.List;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.MediaPlayer;import android.net.Uri;import android.os.Bundle;import android.os.IBinder;public class PlayService extends Service implements Runnable { private MediaPlayer player; private List<Music> musicList; private SeekbarReceiver receiver ; public static boolean isrunning = true; @Override public void onCreate() { player = new MediaPlayer(); musicList = MusicList.getMusicData(this); new Thread(this).start(); receiver = new SeekbarReceiver(); registerReceiver(receiver, new IntentFilter("org.hwq.music.seekbar.seekto")); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onDestroy() { if(player != null){ player.release(); player = null; } unregisterReceiver(receiver); super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { Bundle extras = intent.getExtras(); String op = extras.getString("op"); if("play".equals(op)){ play(); } } private void play() { System.out.println("service中的play执行"); Music m = musicList.get(0); Uri uri = Uri.parse(m.getUrl()); try{ player.setDataSource(this,uri); player.prepare(); player.start(); }catch (Exception e) { e.printStackTrace(); } } public void run() { while(isrunning){ try{ Thread.sleep(100); }catch (Exception e) { } if(player!=null){ int currentPosition = player.getCurrentPosition(); int duration = player.getDuration(); Intent intent = new Intent("org.hwq.receiver.seekbar"); intent.putExtra("currentPosition", currentPosition); intent.putExtra("duration", duration); System.out.println("发出一个广播:currentPosition="+currentPosition); sendBroadcast(intent); } } } //接收前台拖放的进度,并调整歌曲的播放进度 class SeekbarReceiver extends BroadcastReceiver{ public void onReceive(Context context, Intent intent) { int currentPosition = intent.getIntExtra("currentPosition", 0); System.out.println("seekbar拖放了currentPosition="+currentPosition); player.seekTo(player.getDuration()*currentPosition/100); player.start(); } }}
大致就讲完。这里想起一个网上看到的题目,没有activity,能否启动一个运用。答案是可以的:首先,我们得添加权限<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> ,然后注册一个receiver侦听<action android:name="android.intent.action.BOOT_COMPLETED" />,并在receiver来启动一个service或一个activity就ok了。
下面是这个demo: