简单音乐播放器

很简单的音乐播放器哦,网上的播放器东西有点多,自己做了一个简单的。
实现了扫描SD卡上的歌曲,声音控制,进度条控制,自动播放下一首,以及后台播放。因为时间仓促,界面美观,多包涵。

这里写图片描述效果图
效果图

下面是代码
Java代码

package com.phone1000.days24service03mediapalylist;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;

public class MainActivity extends ListActivity {
//  传地址给PlyerService
    public static Map<Integer, String> map = new HashMap<Integer, String>();
    // 四个按钮
    private Button playButton = null, mFrontButton = null, mLastButton = null,
            exitButton = null;

    // 播放进度seekbar
    public static SeekBar audioSeekBar = null;

    // 控制声音的seekbar
    private SeekBar audioVolumn = null;

    // 声音管理器
    private AudioManager mAudioManager = null;

    // 播放列表
    public static List<String> mMusicList = new ArrayList<String>();



    // 设置播放当前的选项条目
    public static int currentListItem = 0;
    Cursor mAudioCursor;

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

        getMusicList();
        initView();
    }

    /**
     * 给ListActivity中的ListView添加所有的以mp3结尾的音乐文件
     */
    private void getMusicList() {
        // 清空list
        mMusicList.clear();

        mAudioCursor = this.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,// 字段 没有字段 就是查询所有信息 相当于SQL语句中的 “ * ”                                              
                null, // 查询条件
                null, // 条件的对应?的参数
                MediaStore.Audio.AudioColumns.TITLE);// 排序方式
        // 循环输出歌曲的信息
        mMusicList = new ArrayList<String>();
        for (int i = 0; i < mAudioCursor.getCount(); i++) {
            mAudioCursor.moveToNext();
            // 找到歌曲标题和总时间对应的列索引
            int indexTitle = mAudioCursor
                    .getColumnIndex(MediaStore.Audio.AudioColumns.TITLE);
            int indexARTIST = mAudioCursor
                    .getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST);
            int indexALBUM = mAudioCursor
                    .getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM);
            int indexData = mAudioCursor
                    .getColumnIndex(MediaStore.Audio.AudioColumns.DATA);

            String strTitle = mAudioCursor.getString(indexTitle);
            String strARTIST = mAudioCursor.getString(indexARTIST);
            String strALBUM = mAudioCursor.getString(indexALBUM);

            String strData = mAudioCursor.getString(indexData);
            map.put(i,strData);
            mMusicList.add(strTitle + "---" + strARTIST + "---" + strALBUM);
            // 构建Adapter,将mMusicList的数据添加到Adapter内
            ArrayAdapter<String> musicAdapter = new ArrayAdapter<String>(
                    MainActivity.this, android.R.layout.simple_list_item_1,
                    mMusicList);
            // 设置当前ListActivity中id为android:list的适配器为musicAdapter
            setListAdapter(musicAdapter);
        }
    }

    // 内部工具类,过滤所有以mp3结尾的文件
    class MusicFilter implements FilenameFilter {

        @Override
        public boolean accept(File dir, String filename) {
            return filename.endsWith(".mp3");
        }
    }

    private void initView() {
        mFrontButton = (Button) findViewById(R.id.button3);
        playButton = (Button) findViewById(R.id.button2);
        mLastButton = (Button) findViewById(R.id.button1);
        exitButton = (Button) findViewById(R.id.button4);

        audioVolumn = (SeekBar) findViewById(R.id.seekBar2);
        audioSeekBar = (SeekBar) findViewById(R.id.seekBar1);

        playButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                playMusic(AppConstant.PAUSE);
            }
        });

        mFrontButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                nextMusic();
            }
        });

        mLastButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                frontMusic();
            }
        });

        exitButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this,
                        PlayerService.class);
                stopService(intent);

                finish();
            }
        });

        // 给播放进度添加监听
        audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());

        if (PlayerService.mMediaPlayer != null) {
            // 设置进度的最大值
            audioSeekBar.setMax(PlayerService.mMediaPlayer.getDuration());
            audioSeekBar.setProgress(PlayerService.mMediaPlayer
                    .getCurrentPosition());
        }

        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        audioVolumn.setProgress(mAudioManager
                .getStreamVolume(AudioManager.STREAM_MUSIC));

        audioVolumn.setOnSeekBarChangeListener(new AudioVolumnChangeEvent());
    }

    class AudioVolumnChangeEvent implements OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
                    0);
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }

    }

    class SeekBarChangeEvent implements OnSeekBarChangeListener {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            // 如果用户手动拖动seekbar的时候
            if (fromUser) {
                PlayerService.mMediaPlayer.seekTo(progress);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // 开始拖动进度条的时候,音乐暂停
            PlayerService.mMediaPlayer.pause();
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            // 停止拖動進度條的時候,音樂開始播放
            PlayerService.mMediaPlayer.start();
        }

    }

    protected void frontMusic() {
        if (--currentListItem >= 0) {
            playMusic(AppConstant.PLAY);
        } else {
            Toast.makeText(this, "已经是第一首歌曲了", Toast.LENGTH_LONG).show();
            currentListItem = 0;
        }
    }

    protected void nextMusic() {
        if (++currentListItem >= mMusicList.size()) {
            Toast.makeText(this, "已经是最后一首歌曲了", Toast.LENGTH_LONG).show();
            currentListItem = mMusicList.size() - 1;
        } else {
            playMusic(AppConstant.PLAY);
        }
    }

    private void playMusic(int pauseOrPlay) {

        Intent intent = new Intent(this, PlayerService.class);
        intent.putExtra("MSG", pauseOrPlay);
        startService(intent);
    }

    /**
     * 用户点击了ListActivity中的ListView的时候的操作
     * 
     * @param l
     *            listView控件本身
     * @param v
     *            TextView用户点击的某一条目所对应的TextView
     * @param position
     *            位置
     * @param id
     *            id
     */
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {

        currentListItem = position;

        playMusic(AppConstant.PLAY);

        super.onListItemClick(l, v, position, id);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

PlayerService :

package com.phone1000.days24service03mediapalylist;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
import android.widget.Toast;

public class PlayerService extends Service implements OnCompletionListener,
        Runnable {
    public static MediaPlayer mMediaPlayer = null;

    // 设置是否单曲循环
    private static boolean isLoop = false;

    // 用户的操作
    private int MSG;

    @Override
    public void onCreate() {

        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }

        mMediaPlayer = new MediaPlayer();

        mMediaPlayer.setOnCompletionListener(this);

        super.onCreate();
    }

    private void playMusic() {

        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(MainActivity.map
                    .get(MainActivity.currentListItem));

            mMediaPlayer.prepare();
            mMediaPlayer.start();

            mMediaPlayer.setLooping(isLoop);

            MainActivity.audioSeekBar.setMax(PlayerService.mMediaPlayer
                    .getDuration());

            new Thread(this).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        int currentPostion = 0;

        // 获得媒体的播放持续时间
        int toal = mMediaPlayer.getDuration();

        while (mMediaPlayer != null && currentPostion < toal) {
            try {
                Thread.sleep(1000);

                if (mMediaPlayer != null) {
                    // 获得媒体的当前播放位置
                    currentPostion = mMediaPlayer.getCurrentPosition();
                }

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

            // 设置MainActivity中audioSeekBar控件的当前进度为currentPostion
            MainActivity.audioSeekBar.setProgress(currentPostion);
        }
    }

    /**
     * 播放完当前歌曲,自动播放下一首
     */
    @Override
    public void onCompletion(MediaPlayer mp) {
        if (++MainActivity.currentListItem >= MainActivity.mMusicList.size()) {
            Toast.makeText(this, "已经到最后一首了", Toast.LENGTH_LONG).show();
            MainActivity.currentListItem--;
            MainActivity.audioSeekBar.setMax(0);
        } else {
            playMusic();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        MSG = intent.getIntExtra("MSG", AppConstant.PLAY);

        switch (MSG) {
        case AppConstant.PLAY:
            playMusic();
            break;
        case AppConstant.PAUSE:
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.pause();
            } else {
                mMediaPlayer.start();
            }
            break;

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

    @Override
    public void onDestroy() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }

        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

AppConstant

package com.phone1000.days24service03mediapalylist;

public interface AppConstant {

    int PLAY = 1;       //  播放
    int PAUSE = 2;      //  暂停
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/pic1"
    tools:context=".MainActivity" >

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

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

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="pre" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="pau" />

        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="nex" />

        <Button
            android:id="@+id/button4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="exi" />
    </LinearLayout>

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

    <Button
        android:id="@+id/button5"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Play list" />

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

        <ListView
            android:id="@+id/android:list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
    </LinearLayout>

</LinearLayout>

最后别忘记加权限了:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
[源代码下载](http://download.csdn.net/detail/qq_29089575/9172387)
今天发现了一个错误,没播放音乐时拖动进度条会报错。

解决办法是給监听事件设置条件。如果进度条不是0的时候给它注册监听。

if(PlayerService.currentPostion==0){    
        }
else{
audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
        }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值