【Android】Service+Seek Bar实现后台音乐播放器小呆萌

来源:互联网 发布:usb网络通道 编辑:程序博客网 时间:2024/06/06 10:58

1. Android四大组件之Service

相信大家对于身为四大组件之一的Service一定很熟悉。Service可以运行在后台来处理一些耗时操作,也可以用来维持一些需要长期运行的任务,甚至可以在用户退出程序是仍然运行在后台中。作为一个初学者,我可以联想到很多关于Service的应用场景。比如:闹钟、音乐播放器等等。
今天我就来给大家展示一个关于音乐播放器退出时后台播放的小Demo。

2.Android控件SeekBar

SeekBar相当与ProgressBar的一个扩展,SeekBar的主要应用场景是在多媒体播放器当中,用来控制播放的进度;也用作一些范围型参数的选择器,比如我们常见的音量调节和屏幕亮度调节。
这里写图片描述

3.Demo的具体实现

1.创建一个Service

首先进入到我们的工程,创建一个新的package为Service,再到其中创建一个MusicBindService类。
为了实现音乐播放的一些功能我们需要在这个类中新建一个MusicController方法,继承Binder类实现对内部组件的绑定。
下面就是MusicBindService的具体实现。

import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.os.Binder;import android.os.IBinder;import com.jinni.servicedemo.R;public class MusicBindService extends Service {    private MediaPlayer mPlayer;    public MusicBindService() {    }    /*    * 绑定服务的实现流程:    * 1.服务 onCreate, onBind, onDestroy 方法    * 2.onBind 方法需要返回一个 IBinder 对象    * 3.如果 Activity 绑定,Activity 就可以取到 IBinder 对象,可以直接调用对象的方法    */    // 相同应用内部不同组件绑定,可以使用内部类以及Binder对象来返回。    public class MusicController extends Binder {        public void play() {            mPlayer.start();//开启音乐        }        public void pause() {            mPlayer.pause();//暂停音乐        }        public long getMusicDuration() {            return mPlayer.getDuration();//获取文件的总长度        }        public long getPosition() {            return mPlayer.getCurrentPosition();//获取当前播放进度        }        public void setPosition (int position) {            mPlayer.seekTo(position);//重新设定播放进度        }    }    /**     * 当绑定服务的时候,自动回调这个方法     * 返回的对象可以直接操作Service内部的内容     * @param intent     * @return     */    @Override    public IBinder onBind(Intent intent) {        return new MusicController();    }    @Override    public void onCreate() {        super.onCreate();        mPlayer = MediaPlayer.create(this, R.raw.nobody);    }    /**     * 任意一次unbindService()方法,都会触发这个方法     * 用于释放一些绑定时使用的资源     * @param intent     * @return     */    @Override    public boolean onUnbind(Intent intent) {        return super.onUnbind(intent);    }    @Override    public void onDestroy() {        if (mPlayer.isPlaying()) {            mPlayer.stop();        }        mPlayer.release();        mPlayer = null;        super.onDestroy();    }}

2. MusicActivity的实现

首先进入我们的布局文件当中,编辑一个简单的音乐播放器界面。当中不仅加入了SeekBar同时还加入了一个ProgressBar作为对比。STOP按钮是用来停止服务的,点击之后退出程序将不会继续在后台播放音乐。在编写代码之前,还需要在res文件夹中新建一个raw文件夹,并且将我们的音乐文件拷贝到里面。
这里写图片描述这里写图片描述

1.activity_music.xml

<?xml version="1.0" encoding="utf-8"?><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"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.jinni.servicedemo.MusicActivity">    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="btnMusicPlay"        android:text="Play"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="btnMusicPause"        android:text="Pause"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="btnStopService"        android:text="Stop"/>    <TextSwitcher        android:id="@+id/text_switcher"        android:layout_width="match_parent"        android:layout_height="50dp">        <TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"/>    </TextSwitcher>    <ProgressBar        android:id="@+id/music_progress"        style="?android:attr/progressBarStyleHorizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content"/>    <SeekBar        android:id="@+id/music_seek_bar"        android:layout_width="match_parent"        android:layout_height="wrap_content"/></LinearLayout>

2.MusicActivity.java

package com.jinni.servicedemo;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.ProgressBar;import android.widget.SeekBar;import android.widget.TextSwitcher;import com.jinni.servicedemo.services.MusicBindService;import java.text.SimpleDateFormat;import java.util.Date;public class MusicActivity extends AppCompatActivity implements Runnable, ServiceConnection, SeekBar.OnSeekBarChangeListener {    private static final String TAG = MusicActivity.class.getSimpleName();    private MusicBindService.MusicController mMusicController;    private ProgressBar mProgressBar;    private boolean running;    private TextSwitcher mSwitcher;    private SeekBar mSeekBar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_music);        mSeekBar = (SeekBar) findViewById(R.id.music_seek_bar);        mSeekBar.setOnSeekBarChangeListener(this);        mProgressBar = ((ProgressBar) findViewById(R.id.music_progress));        mSwitcher = (TextSwitcher) findViewById(R.id.text_switcher);        mSwitcher.setInAnimation(this, android.R.anim.fade_in);        mSwitcher.setOutAnimation(this, android.R.anim.fade_out);        Intent intent = new Intent(this, MusicBindService.class);        //增加StartService,来增加后台播放功能        startService(intent);        // 绑定服务,使用context来绑定        // 那个界面需要绑定 就用哪个 Activity        // 参数1:Intent               代表需要绑定哪一个Service        // 参数2:ServiceConnection    回调接口,可以接收到Service连接成功和断开的回调,成功就可以取到对象。        // 绑定服务 参数2就是服务和指定的对象绑定在一起        bindService(intent, this, BIND_AUTO_CREATE);    }    @Override    protected void onStart() {        super.onStart();        Thread thread = new Thread(this);        thread.start();    }    @Override    protected void onStop() {        running = false;        super.onStop();    }    @Override    protected void onDestroy() {        // 解除绑定        unbindService(this);        super.onDestroy();    }    //------------------------    @Override    public void run() {        running = true;        try {            while (running) {                if (mMusicController != null) {                    long musicDuration = mMusicController.getMusicDuration();                    final long position = mMusicController.getPosition();                    final Date dateTotal = new Date(musicDuration);                    final SimpleDateFormat sb = new SimpleDateFormat("mm:ss");                    mProgressBar.setMax(((int) musicDuration));                    mProgressBar.setProgress(((int) position));                    mSeekBar.setMax((int) musicDuration);                    mSeekBar.setProgress((int) position);                    mSwitcher.post(                            new Runnable() {                                @Override                                public void run() {                                    Date date = new Date(position);                                    String time = sb.format(date) + "/" + sb.format(dateTotal);                                    mSwitcher.setCurrentText(time);                                }                            }                    );                }                Thread.sleep(500);            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }    //------------------------    public void btnMusicPlay(View view) {        if (mMusicController != null) {            mMusicController.play();        }    }    public void btnMusicPause(View view) {        if (mMusicController != null) {            mMusicController.pause();        }    }    //-----------------------------    //服务绑定与解除绑定的回调    /**     * 当服务与当前绑定对象,绑定成功,服务onBind方法调用并且返回之后     * 回调给这个方法     *     * @param name     * @param service IBinder 就是服务 onBind 返回的对象     */    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        mMusicController = ((MusicBindService.MusicController) service);    }    @Override    public void onServiceDisconnected(ComponentName name) {        mMusicController = null;    }    public void btnStopService(View view) {        Intent intent = new Intent(this, MusicBindService.class);        stopService(intent);    }    @Override    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {    }    @Override    public void onStartTrackingTouch(SeekBar seekBar) {    }    @Override    public void onStopTrackingTouch(SeekBar seekBar) {        mMusicController.setPosition(seekBar.getProgress());    }}

第一次写博客,写得好希望大家可以点个赞,如果不好也希望大家多多指点,谢谢大家!

0 0