实践--音乐播放器

  • 话不多说,先上效果图

  • 这里由于模拟器的适配不太好,一些显示的细节并不如意,在我的手机上就都能实现功能
  • 比如我每次打开软件是一张图片,后台执行筛选音乐文件,模拟器上却不显示图片
  • 我每次放歌都有个Notification告诉我在放哪一首,然后消失,模拟器上却也不不显示
  • 基本细节就是这些吧,这个软件运行在手机上效果更理想一些。

基本思路

  • 音乐播放器其实就是应用了Activity,Service和BroadcaReceiver这三个组件,再配合MediaPlayer的使用,完成各种逻辑的设计,就可以实现一个简单的本地音乐播放器了。
  • 我这里使用了一个服务专门用来处理各种播放音乐的逻辑,用服务是因为Activity可能被回收,而且依赖Activity的逻辑会在界面隐藏或者退出后无法继续播放音乐,而是用服务就可以实现后台播放的功能。
  • 同时我们的主界面和服务之间的通信,我们用到了广播机制,通过广播我们可以轻松的实现主界面和服务之间的协调、信息交流等事宜。

界面设计

  • 主界面的布局如图所示,布局较为简单,用到了一个ListView展示音乐,一个SeekBar展示播放进度,若干个Button进行播放的控制等。
  • 布局较为简单,这里就不再过多解释了。
<?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:background="@mipmap/background"
    tools:context=".activity.MainActivity">

    <ListView
        android:id="@+id/listView_music"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"></ListView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView_nowDuration"
            android:layout_width="30dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_gravity="center_vertical"
            android:gravity="center"
            android:text="00:00"/>

        <SeekBar
            android:id="@+id/seekBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"/>

        <TextView
            android:id="@+id/textView_duration"
            android:layout_width="30dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center"
            android:layout_marginRight="20dp"
            android:text="00:00"/>

    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >

        <Button
            android:id="@+id/button_shunxu"
            android:layout_width="@dimen/many_pic"
            android:layout_height="@dimen/many_pic"
            android:background="@mipmap/shunxu_shunxu"
            android:layout_centerVertical="true"
            android:layout_toLeftOf= "@+id/button_left"/>

        <Button
            android:id="@+id/button_left"
            android:layout_width="@dimen/many_pic"
            android:layout_height="@dimen/many_pic"
            android:layout_marginLeft="30dp"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@+id/button_play"
            android:background="@mipmap/left_pic" />

        <Button
            android:id="@+id/button_play"
            android:layout_width="@dimen/play_pic"
            android:layout_height="@dimen/play_pic"
            android:layout_marginLeft="40dp"
            android:layout_marginRight="40dp"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:layout_centerHorizontal="true"
            android:background="@mipmap/pause_pic" />

        <Button
            android:id="@+id/button_right"
            android:layout_width="@dimen/many_pic"
            android:layout_height="@dimen/many_pic"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/button_play"
            android:layout_marginRight="30dp"
            android:background="@mipmap/right_pic" />

        <Button
            android:layout_width="@dimen/many_pic"
            android:layout_height="@dimen/many_pic"
            android:background="@mipmap/list_music_pic"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/button_right"/>
    </RelativeLayout>

</LinearLayout>

-ListView子项布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_margin="10dp"
        android:src="@mipmap/music_ic"/>

    <LinearLayout
        android:id="@+id/linearlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/music_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:textSize="20sp"
            android:singleLine="true"
            android:text="歌曲名称" />
        <TextView
            android:id="@+id/music_singer"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:textSize="15sp"
            android:text="歌手" />
    </LinearLayout>

</LinearLayout>
  • 状态栏的下拉菜单如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="wrap_content">

        <ImageView
            android:layout_width="70dp"
            android:layout_height="match_parent"
            android:padding="10dp"
            android:layout_gravity="center"
            android:src="@mipmap/stateline_ic"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/musicbar_songname"
                android:textSize="20dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:textColor="#000000"
                android:singleLine="true"
                android:text="歌曲名称"/>
            <TextView
                android:id="@+id/musicbar_exit"
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:textColor="#000000"
                android:text="X"/>

        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:id="@+id/musicbar_left"

                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_toLeftOf="@+id/musicbar_play"
                android:layout_centerVertical="true"
                android:src="@mipmap/left_pic"/>

            <ImageView
                android:id="@+id/musicbar_play"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:padding="5dp"
                android:layout_centerHorizontal="true"
                android:src="@mipmap/play_pic"/>

            <ImageView
                android:id="@+id/musicbar_right"
                android:layout_width="20dp"
                android:layout_height="20dp"
                android:layout_toRightOf="@+id/musicbar_play"
                android:layout_centerVertical="true"
                android:src="@mipmap/right_pic"/>
        </RelativeLayout>
    </LinearLayout>

</LinearLayout>

主要逻辑功能

  • 当我们从主界面操作的时候,通过点击事件的监听,判断逻辑,先去更新我们的UI变化,同时开启服务,将所必须的歌曲的位置等信息通过广播传递给服务,而后服务在处理逻辑判断,进行相应的操作。
public class MainActivity extends BaseActivity implements View.OnClickListener, AdapterView.OnItemClickListener, SeekBar.OnSeekBarChangeListener {

    private List<File> musicList;
    private ListView listView_music;
    private TextView textView_duration;
    private TextView textView_nowDuration;
    private SeekBar seekBar;
    private int nowPosition = 0;
    private Button button_play, button_left, button_right,button_shunxu;
    private UtilsReceiver utilsReceiver;
    private IntentFilter utilsFilter;

    private boolean isPlaying=false;
    private int nowDuration=0;
    private boolean flag=true;
    private boolean isOrderPlay=true;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        musicList = MusicListFactory.newInstance().getList();
        init();
        initUtilsReceiver();
        MusicAdapter adapter = new MusicAdapter(getApplicationContext(), musicList);
        listView_music.setAdapter(adapter);
        listView_music.setOnItemClickListener(this);
        Intent intent=new Intent("UPDATE_UI");
        sendBroadcast(intent);
    }

    private void initUtilsReceiver() {
        utilsReceiver = new UtilsReceiver();
        utilsFilter = new IntentFilter();
        utilsFilter.addAction("IS_PLAYING");
        utilsFilter.addAction("NOT_PLAYING");
        utilsFilter.addAction("ALL_SECONDS");
        utilsFilter.addAction("UPDATE_DURATION");
        utilsFilter.addAction("NEW_SONG");
        utilsFilter.addAction("PAUSE_SONG");
        utilsFilter.addAction("COUNTINUE_SONG");
        utilsFilter.addAction("BACK_UPDATE_UI");
        utilsFilter.addAction("UPDATE_POSITION");

        registerReceiver(utilsReceiver, utilsFilter);

        Thread countThread=new Thread(new Runnable() {
            @Override
            public void run() {
                while (flag){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (isPlaying){
                        nowDuration++;
                    }
                    Intent intent=new Intent("UPDATE_DURATION");
                    intent.putExtra("nowSeconds",nowDuration);
                    sendBroadcast(intent);
                }
            }
        });
        countThread.start();

    }

    private void init() {
        listView_music = (ListView) findViewById(R.id.listView_music);
        textView_duration = (TextView) findViewById(R.id.textView_duration);
        textView_nowDuration = (TextView) findViewById(R.id.textView_nowDuration);
        seekBar = (SeekBar) findViewById(R.id.seekBar);
        seekBar.setOnSeekBarChangeListener(this);
        button_play = (Button) findViewById(R.id.button_play);
        button_left = (Button) findViewById(R.id.button_left);
        button_right = (Button) findViewById(R.id.button_right);
        button_right.setOnClickListener(this);
        button_left.setOnClickListener(this);
        button_play.setOnClickListener(this);
        button_shunxu= (Button) findViewById(R.id.button_shunxu);
        button_shunxu.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Intent intent;
        switch (v.getId()) {
            case R.id.button_play:
                intent = new Intent(this, MusicService.class);
                intent.putExtra("POSITION", nowPosition);
                startService(intent);
                break;
            case R.id.button_left:
                clickLeftButton();
                break;
            case R.id.button_right:
                clickRightButton();
                break;
            case R.id.button_shunxu:
                changePlayOrder();
                break;
        }
    }

    private void changePlayOrder() {
        isOrderPlay=!isOrderPlay;
        if (isOrderPlay){
            Toast.makeText(MainActivity.this, "顺序播放", Toast.LENGTH_SHORT).show();
            button_shunxu.setBackgroundResource(R.mipmap.shunxu_shunxu);
        }else {
            Toast.makeText(MainActivity.this, "随机播放", Toast.LENGTH_SHORT).show();
            button_shunxu.setBackgroundResource(R.mipmap.shunxu_sujip);
        }
        Intent intent=new Intent("UPDATE_PLAY_ORDER");
        intent.putExtra("isOrderPlay",isOrderPlay);
        sendBroadcast(intent);
    }

    private void clickLeftButton() {
        Intent intent;
        if (isOrderPlay) {
            if (nowPosition == 0) {
                Toast.makeText(MainActivity.this, "当前已经第一首", Toast.LENGTH_SHORT).show();
            }else{
                nowPosition--;
            }
        }else {
            nowPosition=(int)(Math.random()*musicList.size());
        }
        intent = new Intent(this, MusicService.class);
        intent.putExtra("POSITION", nowPosition);
        startService(intent);
    }

    private void clickRightButton() {
        Intent intent;
        if (isOrderPlay){
            if (nowPosition == musicList.size()-1) {
                isPlaying=false;
                Toast.makeText(MainActivity.this, "当前已经最后一首", Toast.LENGTH_SHORT).show();
            }else{
                nowPosition++;
            }
        }else {
            nowPosition=(int)(Math.random()*musicList.size());
        }
        intent = new Intent(this, MusicService.class);
        intent.putExtra("POSITION", nowPosition);
        startService(intent);
    }

    class UtilsReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case "IS_PLAYING":
                    button_play.setBackgroundResource(R.mipmap.play_pic);
                    break;
                case "NOT_PLAYING":
                    button_play.setBackgroundResource(R.mipmap.pause_pic);
                    break;
                case "ALL_SECONDS":
                    int allSeconds=intent.getIntExtra("allSeconds",0);
                    seekBar.setMax(allSeconds);
                    textView_duration.setText(allSeconds/60+":"+allSeconds%60);
                    break;
                case "UPDATE_DURATION":
                    int nowSeconds=intent.getIntExtra("nowSeconds",0);
                    seekBar.setProgress(nowSeconds);
                    textView_nowDuration.setText(nowSeconds/60+":"+nowSeconds%60);
                    break;
                case "NEW_SONG":
                    nowDuration=0;
                    isPlaying=true;
                    break;
                case "PAUSE_SONG":
                    isPlaying=false;
                    break;
                case "COUNTINUE_SONG":
                    isPlaying=true;
                    break;
                case "UPDATE_POSITION":
                    nowPosition=intent.getIntExtra("POSITION",0);
                    Log.d("***","888888"+"**"+nowPosition);
                    break;
                case "BACK_UPDATE_UI":
                    isOrderPlay=intent.getBooleanExtra("isOrderPlay",true);
                    nowPosition=intent.getIntExtra("nowPosition",0);
                    isPlaying=intent.getBooleanExtra("MEDIA_IS_PLAYING",false);
                    nowDuration=intent.getIntExtra("nowDuration",0);
                    int duration=intent.getIntExtra("duration",0);
                    textView_duration.setText(duration/60+":"+duration%60);
                    textView_nowDuration.setText(nowDuration/60+":"+nowDuration%60);
                    seekBar.setMax(duration);
                    if (isPlaying){
                        button_play.setBackgroundResource(R.mipmap.play_pic);
                    }else {
                        button_play.setBackgroundResource(R.mipmap.pause_pic);
                    }
                    if (isOrderPlay){
                        button_shunxu.setBackgroundResource(R.mipmap.shunxu_shunxu);
                    }else {
                        button_shunxu.setBackgroundResource(R.mipmap.shunxu_sujip);
                    }
                    break;
            }
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        nowPosition=position;
        Intent intent = new Intent(this, MusicService.class);
        intent.putExtra("POSITION", nowPosition);
        startService(intent);
    }

    //seekBar中用不到的两个方法
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
    public void onStartTrackingTouch(SeekBar seekBar) {}

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        Intent intent=new Intent("SEEKBAR_UPDATE");
        intent.putExtra("seekBar_pargress",seekBar.getProgress());
        sendBroadcast(intent);
        nowDuration=seekBar.getProgress();
        textView_nowDuration.setText(seekBar.getProgress()/60+":"+seekBar.getProgress()%60);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        flag=false;
        unregisterReceiver(utilsReceiver);
    }

    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
    }
}
  • 服务中的逻辑代码如下:
  • 要想让MusicBar在下拉菜单中显示出来,还必须把它设置为前台服务
  • 同时对其中的点击事件设置逻辑处理。
public class MusicService extends Service {
    private MediaPlayer mediaPlayer;
    private String nowFilePath = null;
    private static int startTime = 0;
    private RemoteViews rv;
    private List<File> musicList;
    private int nowPosition;
    private MySefReceiver mySefReceiver;
    private IntentFilter mySefFilter;
    private boolean flag = true;
    private boolean isOrderPlay = true;

    public MusicService() {
        this.musicList = MusicListFactory.newInstance().getList();
    }

    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        init();
        initMySefReceiver();
    }

    private void initMySefReceiver() {
        mySefReceiver = new MySefReceiver();
        mySefFilter = new IntentFilter();
        mySefFilter.addAction("MUSIC_EXIT");
        mySefFilter.addAction("SEEKBAR_UPDATE");
        mySefFilter.addAction("MUSICBAR_PLAY");
        mySefFilter.addAction("MUSICBAR_LEFT");
        mySefFilter.addAction("MUSICBAR_RIGHT");
        mySefFilter.addAction("UPDATE_PLAY_ORDER");
        mySefFilter.addAction("UPDATE_UI");
        registerReceiver(mySefReceiver, mySefFilter);
    }

    private void showMusicBar(String singer, String songName) {
        Notification notification = new Notification();

        notification.icon = R.mipmap.stateline_ic;
        rv = new RemoteViews(getPackageName(), R.layout.layout_musicbar);
        PendingIntent intent_play = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent("MUSICBAR_PLAY"), 0);
        rv.setOnClickPendingIntent(R.id.musicbar_play, intent_play);
        PendingIntent intent_left = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent("MUSICBAR_LEFT"), 0);
        rv.setOnClickPendingIntent(R.id.musicbar_left, intent_left);
        PendingIntent intent_right = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent("MUSICBAR_RIGHT"), 0);
        rv.setOnClickPendingIntent(R.id.musicbar_right, intent_right);
        PendingIntent intent_exit = PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent("MUSIC_EXIT"), 0);
        rv.setOnClickPendingIntent(R.id.musicbar_exit, intent_exit);

        rv.setTextViewText(R.id.musicbar_songname, (nowPosition + 1) + "." + songName + "-" + singer);
        if (mediaPlayer.isPlaying()) {
            rv.setImageViewResource(R.id.musicbar_play, R.mipmap.play_pic);
        } else {
            rv.setImageViewResource(R.id.musicbar_play, R.mipmap.pause_pic);
        }
        notification.contentView = rv;
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(this, MainActivity.class), 0);
        notification.contentIntent = pendingIntent;
        startForeground(1, notification);
    }

    private void init() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
        }
        if (intent == null) {
            //必须加入对intent是否为空的判断
        } else {
            nowPosition = intent.getIntExtra("POSITION", 0);
            String filePath = musicList.get(nowPosition).getAbsolutePath();
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(filePath);
            String singer = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
            String songName = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
            getMusicDuration(retriever);
            if (TextUtils.isEmpty(filePath)) {

            } else if (!filePath.equals(nowFilePath)) {
                nowFilePath = filePath;
                mediaPlayer.reset();
                try {
                    mediaPlayer.setDataSource(filePath);
                    mediaPlayer.prepare();
                    mediaPlayer.start();
                    startTime = 0;
                    Intent intent1 = new Intent("IS_PLAYING");
                    sendBroadcast(intent1);
                    showNotification("开始播放:" + (nowPosition + 1) + "." + songName);
                    sendBroadcast(new Intent("NEW_SONG"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                if (mediaPlayer.isPlaying()) {
                    mediaPlayer.pause();
                    Intent intent1 = new Intent("NOT_PLAYING");
                    sendBroadcast(intent1);
                    showNotification("暂停播放" + (nowPosition + 1) + "." + songName);
                    sendBroadcast(new Intent("PAUSE_SONG"));
                } else {
                    mediaPlayer.start();
                    Intent intent1 = new Intent("IS_PLAYING");
                    sendBroadcast(intent1);
                    showNotification("继续播放:" + (nowPosition + 1) + "." + songName);
                    sendBroadcast(new Intent("COUNTINUE_SONG"));
                }
            }
            showMusicBar(singer, songName);
        }

        if (mediaPlayer != null) {
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    sendBroadcast(new Intent("MUSICBAR_RIGHT"));
                }
            });
        }

        return super.onStartCommand(intent, flags, startId);
    }

    private void getMusicDuration(MediaMetadataRetriever retriever) {
        int allSeconds = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) / 1000;
        Intent intent = new Intent("ALL_SECONDS");
        intent.putExtra("allSeconds", allSeconds);
        sendBroadcast(intent);
    }

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

    public void showNotification(String msg) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setTicker(msg);
        Notification notification = builder.build();
        manager.notify(2, notification);
        manager.cancel(2);
    }

    class MySefReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case "MUSIC_EXIT":
                    flag = false;
                    if (mediaPlayer != null) {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                    }
                    sendBroadcast(new Intent("PAUSE_SONG"));
                    Intent intent1 = new Intent("NOT_PLAYING");
                    sendBroadcast(intent1);
                    stopSelf();
                    unregisterReceiver(mySefReceiver);
                    break;
                case "SEEKBAR_UPDATE":
                    startTime = intent.getIntExtra("seekBar_pargress", 0);
                    mediaPlayer.seekTo(startTime * 1000);
                    break;
                case "MUSICBAR_PLAY":
                    Intent intent2 = new Intent(getApplicationContext(), MusicService.class);
                    intent2.putExtra("POSITION", nowPosition);
                    startService(intent2);
                    break;
                case "MUSICBAR_LEFT":
                    if (isOrderPlay) {
                        if (nowPosition <= 0) {
                            showNotification("已经到列表第一首");
                        } else {
                            nowPosition--;
                        }
                    } else {
                        nowPosition=(int)(Math.random()*musicList.size());
                    }
                    Intent intent3 = new Intent(getApplicationContext(), MusicService.class);
                    intent3.putExtra("POSITION", nowPosition);
                    startService(intent3);
                    Intent left_intent=new Intent("UPDATE_POSITION");
                    left_intent.putExtra("POSITION", nowPosition);
                    sendBroadcast(left_intent);
                    break;
                case "MUSICBAR_RIGHT":
                    if (isOrderPlay){
                        if (nowPosition == musicList.size() - 1) {
                            showNotification("已经到列表最后一首");
                        } else {
                            nowPosition++;
                        }
                    }else {
                        nowPosition=(int)(Math.random()*musicList.size());
                    }
                    Intent intent4 = new Intent(getApplicationContext(), MusicService.class);
                    intent4.putExtra("POSITION", nowPosition);
                    startService(intent4);
                    Intent right_intent=new Intent("UPDATE_POSITION");
                    right_intent.putExtra("POSITION", nowPosition);
                    sendBroadcast(right_intent);
                    break;
                case "UPDATE_PLAY_ORDER":
                    isOrderPlay=intent.getBooleanExtra("isOrderPlay",true);
                    break;
                case "UPDATE_UI":
                    Intent intent5=new Intent("BACK_UPDATE_UI");
                    intent5.putExtra("nowPosition",nowPosition);
                    intent5.putExtra("MEDIA_IS_PLAYING",mediaPlayer.isPlaying());
                    intent5.putExtra("isOrderPlay",isOrderPlay);
                    intent5.putExtra("nowDuration",mediaPlayer.getCurrentPosition()/1000);
                    intent5.putExtra("duration",mediaPlayer.getDuration()/1000);
                    sendBroadcast(intent5);
                    break;
            }
        }
    }
}
  • 其实上面的这些代码大概看一下你就会明白,这个思路不是很复杂,就是代码比较啰嗦
  • 大概就是我从界面进行操作,我就给服务发送广播,告诉他我要干什么了,同时更新我自己的UI
  • 当我从前台服务操作的时候,我也需要给界面活动发送一个广播,告诉他去实时的更新自己的界面UI
  • 其次就是一些逻辑的处理部分了,比如我滑动seekBar,音乐也要跟着从制定位置播放啊,我界面退出了,音乐还在播放,我再次打开软件的时候,界面信息要从服务获取一下,这样才能和服务中播放信息一致等等。
  • 主要的代码思路就是这些
  • 还有一些小细节的代码并未贴出来,比如开机的界面,同时获取音乐文件,应用单例模式存放我们的音乐文件的List等等。
  • 本人菜鸟一枚,代码中各种实现可能并不是处理的很合理,代码中的肯定也存在各种漏洞,欢迎大家指出改正,谢谢。
  • 如果需要,欢迎下载源码
时间: 2024-10-14 09:54:56

实践--音乐播放器的相关文章

仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源代码)

转载请说明原出处,谢谢~~ 上一篇仿酷狗日志结束后,整个换肤功能就仅仅剩下调色板功能没有做了.我本以为会非常easy.可是研究了酷狗的调色板功能后发现不是那么简单的事情.首先看一下酷狗的调色板的样子: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1aG9uZ3NodQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" > waterm

HTML5 audio标签 打造属于自己的音乐播放器

最近学习了HTML5中的Audio标签,学习他的最好方式当然是实践,于是就自己写了一个.那就直接上演示链接吧 http://htmlpreview.github.io/?https://github.com/djlxiaoshi/Audio/blob/master/music.html.模仿了QQ音乐网页版的部分样式.谁叫自己不会UI呢! HTML5中增加了Audio和Video标签,这两个标签的用法非常相似.功能却是相当强大,我们先来看一下Audio标签各个浏览器的支持情况.这里用的依然是Ca

Android实现音乐播放器(一)

Graphical User Interface 本篇文章记录了我实现Android简单音乐播放器的过程,(一)中介绍了怎么构建音乐播放器的前端页面.首先大家看一下,界面最后是这样的(界面有点粗陋) 音乐文件列表是从SD卡中读取出来的. 首先我们先在Layout里面创建Music Player的GUI,diagram如下图所示: 根据diagram我们在activity_main.xml写出如下代码: <LinearLayout xmlns:android="http://schemas.

手把手教你做音乐播放器(八)桌面小工具(上)

第8节 桌面小工具 桌面小工具是可以放置在主界面的.快速控制应用的小助手.例如我们的音乐小工具,它可以帮助用户在桌面上就完成音乐的暂停.播放.切换等操作,而不需要启动应用本身. 在安卓系统中,我们也常常叫它App widget. 实现一个App widget要经过以下几个步骤, 创建一个App widget类,让它继承自AppWidgetProvider,例如AnddleMusicAppWidget类: 放在res\layout目录下,为App widget的界面定义一个布局,例如anddle_

毕业设计——基于STM32的音乐播放器设计(一)

基于STM32的音乐播放器设计, 源代码下载地址:http://download.csdn.net/detail/cxp2205455256/8334021      SD卡文件下载地址:http://download.csdn.net/detail/cxp2205455256/8334089 电路图下载地址:文件太大了,上传不了....... 以下是截图: 1.硬件电路 2.软件主界面 3.音乐播放器界面 4.音乐定时播放界面 5.音乐列表界面 6.日历功能界面 9.温度功能界面 10.计算器

Xamarin.Android开发音乐播放器

最近.Net开源着实让C#火了一把,好久就听说Mono for Android一直没静下心来看,上周末找来看看,确实不错,前台界面axml编写跟Java安卓开发毫无区别,后台用C#其实很多windows下的方法都可以用,做一个安卓音乐播放器,主要实现音乐播放,上一曲下一曲,音乐播放列表,随机播放,扫描SD卡内所有音乐. 先show一组界面啊,话说有图有真相啊: 项目结构如图: Lrc是歌词处理方法 MusicService是安卓服务播放音乐,服务Broadcast,以及界面接收Receiver

html网页音乐播放器自带播放列表

基于网页的音乐播放器demo  http://pan.baidu.com/s/1dDgm7HR 自己diy了一个手机端在线音乐播放器演示地址http://shanxi2014.com/zhuandizhi/dom.php 全面支持手机端浏览器. 主要修改引用路径(不要修改文件相对存放地址) 第二就是正则拼接参数了 <script src="/city/js/libs/jquery-1.10.2.min.js"></script> <script src=&

【源码分享】mui实现简单的手机音乐播放器

mui实现简单的手机音乐播放器 最近先来无事,我用mui写了一个可以跨页面控制的音乐播放器.主要功能有上一曲,下一曲,播放,暂停,感兴趣的可以继续看下去. 说的总是不实在,直接上源码,有兴趣的可以读下注释. 1首页代码 ①首页的html代码 1 <a> 2 <i id="bofang" class="iconfont icon-play-o"></i> <!--就是一个播放按钮没啥特殊的--> 3 </a>

HTML5项目笔记4:使用Audio API设计绚丽的HTML5音乐播放器

HTML5 有两个很炫的元素,就是Audio和 Video,可以用他们在页面上创建音频播放器和视频播放器,制作一些效果很不错的应用. 无论是视屏还是音频,都是一个容器文件,包含了一些音频轨道,视频轨道和一些元数据,这些是和你的视频或者音频控件绑定到一块的,这样才形成了一个完整的播放组件. 浏览器支持情况: 浏览器 支持情况 编解码器 Chrome 3.0 Theora . Vorbis .Ogg H.264 . AAC .MPEG4 FireFox 3.5 Theora . Vorbis .Og