会飞的鱼

奇乐云
首页 » Android » Android 使用服务完成后台播放本地音乐

Android 使用服务完成后台播放本地音乐

[1]布局代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click1"
        android:text="播放" />

    
     <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click2"
        android:text="暂停" />
     
      <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="click3"
        android:text="继续播放" />

      <SeekBar
          android:id="@+id/seekBar1"
          android:layout_width="match_parent"
          android:layout_height="wrap_content" />
    
</LinearLayout>

[2]主文件代码
package com.example.yinyuebofanqi;

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.View;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends Activity {

	private Iservice iservice; //这个是我们定义的中间人对象
	private MyConn conn;

	public static Handler handler = new Handler(){

		public void handleMessage(android.os.Message msg) {
			//获取我们携带的数据
			Bundle data = msg.getData();
			//获取歌曲的总时长 和 当前进度
			int duration = data.getInt("duration");
			int currentPosition = data.getInt("currentPosition");

			//设置seekbar 的进度
			sbar.setMax(duration);
			sbar.setProgress(currentPosition);



		};
	};
	private static SeekBar sbar;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		//混合方式开启服务
		//[1] 先调用startservice 目的是可以保证服务在后台长期运行
		Intent intent = new Intent(this,MusicService.class);
		startService(intent);
		//[2]调用bindservice 目的为了获取我们定义的中间人对象  就可以间接的调用服务里面的方法了
		conn = new MyConn();
		bindService(intent, conn, BIND_AUTO_CREATE);

		//[3]找到seekbar   设置进度
		sbar = (SeekBar) findViewById(R.id.seekBar1);

		//[4]给seekbar设置监听事件
		sbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

			//当拖动停止的时候调用
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				iservice.callSeekTo(seekBar.getProgress());
				//传入拖拽的位置
			}

			//当开始拖动
			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {

			}
			//当进度改变
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
										  boolean fromUser) {

			}
		});


	}

	@Override
	protected void onDestroy() {
		//当Activity销毁的时候 解绑服务   目的是为了不报红色日志
		unbindService(conn);

		super.onDestroy();
	}


	// 点击按钮 播放音乐
	public void click1(View v) {

		//调用播放音乐的方法
		iservice.callPlayMusic();
	}

	// 点击按钮 暂停音乐
	public void click2(View v) {

		//调用暂停音乐的方法
		iservice.callPauseMusic();
	}

	// 点击按钮 继续播放音乐
	public void click3(View v) {

		//调用继续播放音乐的方法
		iservice.callRePlayMusic();
	}


	//监听服务的状态
	private class MyConn implements ServiceConnection{



		//当服务连接成功
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			//获取我们定义的中间人对象

			iservice = (Iservice) service;

		}

		@Override
		public void onServiceDisconnected(ComponentName name) {

		}

	}




}

[3]服务代码(主要处理部分暂停等后台服务)
package com.example.yinyuebofanqi;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;

public class MusicService extends Service {

	private MediaPlayer mediaPlayer;

	//[2]把我们定义的中间人对象返回
	@Override
	public IBinder onBind(Intent intent) {
		return new MyBinder();
	}

	//服务一开启 就执行这个方法
	@Override
	public void onCreate() {

		//[1]初始化mediaplayer

		mediaPlayer = new MediaPlayer();

		super.onCreate();
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
	}

	//实现指定播放的位置
	public void seekTo(int position){
		mediaPlayer.seekTo(position);
	}


	// 播放音乐的方法
	public void playMusic() {

		//[2]设置要播放的资源位置  path 可以是网络 路径 也可是本地路径
		try {
			//重置播放数据
			mediaPlayer.reset();

			mediaPlayer.setDataSource("/storage/emulated/0/ll.mp3");
			//[3]准备播放
			mediaPlayer.prepare();
			//[4]开始播放
			mediaPlayer.start();

			//[5]更新进度条
			updateSeekBar();


		} catch (Exception e) {
			e.printStackTrace();
		}




	}

	//更新进度条的方法
	private void updateSeekBar() {

		//[1]获取到当前播放的总长度
		final int duration = mediaPlayer.getDuration();

		//[2]使用Timer 定时器去定时获取当前进度
		final Timer timer = new Timer();
		final TimerTask task = new TimerTask(){

			@Override
			public void run() {
				//[3]一秒钟获取一次当前进度
				int currentPosition = mediaPlayer.getCurrentPosition();

				//[4]拿着我们在MainActivity 创建的handler 发消息 消息就可以携带数据

				Message msg = Message.obtain();
				Bundle bundle = new Bundle(); //map
				bundle.putInt("duration", duration);
				bundle.putInt("currentPosition", currentPosition);
				msg.setData(bundle);
				//发送一条消息  mainActivity里面的handlemessage方法就会执行
				MainActivity.handler.sendMessage(msg);

			}
		};
		//100 毫秒后 每隔1秒执行一次run方法
		timer.schedule(task, 100, 1000);
		//当歌曲执行完毕后 把timer 和 timertask取消
		//设置播放完成的监听

		mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

			@Override
			public void onCompletion(MediaPlayer mp) {
				System.out.println("歌曲播放完成了");

				//把timer 和 timertast 取消定时器
				timer.cancel();
				task.cancel();

			}
		});


	}

	// 暂停音乐的方法
	public void pauseMusic() {

		//暂停音乐
		mediaPlayer.pause();


	}

	// 继续播放音乐的方法
	public void rePlayMusic() {

		mediaPlayer.start();
	}

	//[1]在服务的内部定义一中间人对象(IBinder)
	private class MyBinder extends Binder implements Iservice{

		//调用播放音乐的方法
		@Override
		public void callPlayMusic() {

			playMusic();
		}

		//调用暂停音乐的方法
		@Override
		public void callPauseMusic() {

			pauseMusic();
		}

		//调用继续播放音乐的方法
		@Override
		public void callRePlayMusic() {
			rePlayMusic();
		}

		@Override
		public void callSeekTo(int position) {

			seekTo(position);
		}


	}




}

[4]服务接口暴露文件
package com.example.yinyuebofanqi;

public interface Iservice {

	//把想暴露的方法都定义在接口中
	public void callPlayMusic();
	public void callPauseMusic();
	public void callRePlayMusic();
	public void callSeekTo(int position);

}

[4]清单文件添加服务
  <service android:name=".MusicService"></service>

[5]效果图
点击查看原图

文章如无特别注明均为原创! 作者: 奇乐云, 转载或复制请以 超链接形式 并注明出处 奇乐云's blog - 奇乐云的个人博客
原文地址《 Android 使用服务完成后台播放本地音乐》发布于2019-1-22

分享到:
打赏

评论

游客

切换注册

登录

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册