安卓基础 论MediaPlayer的应用(二)

来源:互联网 发布:韩国研究生留学知乎 编辑:程序博客网 时间:2024/06/06 17:13
这篇博客,是基于上一篇博客实现的,使用到了主要知识点有:Service,MediaPlayer。等。。。好了,先说布局:

activity_main.xml
这里写图片描述

<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" >    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:text="@string/hello" />    <ListView        android:id="@+id/Music_list"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" >    </ListView>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:orientation="horizontal" >        <Button            android:id="@+id/button_start"            style="@android:attr/buttonBarButtonStyle"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/button_start" />        <Button            android:id="@+id/button_stop"            style="@android:attr/buttonBarButtonStyle"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/button_stop" />        <Button            android:id="@+id/button_loop"            style="@android:attr/buttonBarButtonStyle"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/button_loop" />        <Button            android:id="@+id/button_uplist"            style="@android:attr/buttonBarButtonStyle"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/button_uplist" />    </LinearLayout></LinearLayout>

这次因为用到了listView 所以要有一个Item布局
music_list_item.xml
这里写图片描述

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/music_list_item"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <TextView        android:id="@+id/music_name"        android:layout_width="match_parent"        android:layout_height="wrap_content" /></LinearLayout>

配置文件添加两个权限,另外,因为用到了service,所以要添加service

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<service            android:name=".MusicService"            android:exported="true" >        </service>

好,现在上主要代码,注释写的不是特别详细,我有些问题也是搞不懂,请轻喷
我这次采用了接口编程,那么,新建一个Path.java接口,代码如下

package com.android.MyMediaPlayer;import java.util.ArrayList;public interface Path {    /**     * 返回一个音乐名称数组     * @return     */    public ArrayList<String> getMusicList();    /**     * 返回一个音乐路径数组     * @return     */    public ArrayList<String> getMusicPath();}

实现这个接口
SongList.java

package com.android.MyMediaPlayer;import android.annotation.SuppressLint;import java.io.File;import java.io.FilenameFilter;import java.util.ArrayList;@SuppressLint("SdCardPath")public class SongList implements Path {    // 用于保存歌曲名称    ArrayList<String> musicList = null;    // 用于保存歌曲路径    ArrayList<String> musicPath = null;    public static final String SD_PATH = "/sdcard/";    @Override    public ArrayList<String> getMusicList() {        musicList = new ArrayList<String>();        File home = new File(SD_PATH);        if (home.listFiles(new mp3Filter()).length > 0) {            for (File file : home.listFiles(new mp3Filter())) {                musicList.add(file.getName());            }        }        return musicList;    }    @Override    public ArrayList<String> getMusicPath() {        musicPath = new ArrayList<String>();        if (musicList != null && musicList.size() > 0) {            for (int i = 0; i < musicList.size(); i++) {                musicPath.add(SD_PATH + musicList.get(i));            }        }        return musicPath;    }    private class mp3Filter implements FilenameFilter {        @Override        public boolean accept(File dir, String filename) {            // TODO Auto-generated method stub            return (filename.endsWith(".mp3"));        }    }}

好了,获取路径都写好了,接下来就可以写服务类了
MusicService.java

package com.android.MyMediaPlayer;import java.io.IOException;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.net.Uri;import android.os.IBinder;import android.util.Log;public class MusicService extends Service {    // 标识    public static final String TAG = "MusicService";    // 各种动作的标识    public static final String PLAY_ACTION = "com.android.MyMediaPlayer.PLAY_ACTION";    public static final String PAUSE_ACTION = "com.android.MyMediaPlayer.PAUSE_ACTION";    public static final String STOP_ACTION = "com.android.MyMediaPlayer.STOP_ACTION";    public static final String LOOP_ACTION = "com.android.MyMediaPlayer.LOOP_ACTION";    public static final String NOTLOOP_ACTION = "com.android.MyMediaPlayer.NOTLOOP_ACTION";    public static final String SONG_LIST = "com.android.MyMediaPlayer.SONG_LIST";    private MediaPlayer player;    // 音乐地址    private Uri uri = null;    @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        return null;    }    @Override    public void onCreate() {        // TODO Auto-generated method stub        super.onCreate();        init();        // 用log输出来了解service的生命周期        Log.d(TAG, "onCreate__");    }    @SuppressWarnings({ "deprecation" })    @Override    public void onStart(Intent intent, int startId) {        super.onStart(intent, startId);        // 将从Activity传来的值进行判断,在对这些动作进行操作        if (intent != null) {            String action = intent.getAction();            if (action.equals(SONG_LIST)) {                uri=intent.getData();                initByPath(uri);                if (player.isPlaying()==true) {                    player.pause();;                }else {                    play();                }            } else if (action.equals(PLAY_ACTION)) {                play();            } else if (action.equals(STOP_ACTION)) {                stop();            } else if (action.equals(PAUSE_ACTION)) {                pause();            } else if (action.equals(LOOP_ACTION)) {                looping(true);            } else if (action.equals(NOTLOOP_ACTION)) {                looping(false);            }        }        Log.d(TAG, "onStart__");    }    private void looping(boolean b) {        player.setLooping(b);    }    private void pause() {        player.pause();    }    private void stop() {        player.stop();        player.reset();        try {            // 必须调用prepare方法,不如停止之后不能再播放            player.prepare();        } catch (IllegalStateException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    private void play() {        player.start();    }    private void init() {        player = new MediaPlayer();// 对象初始化 避免空指针异常    }    @Override    public void onDestroy() {        // TODO Auto-generated method stub        super.onDestroy();        player.stop();        player.pause();    }    // 对象初始化    private void initByPath(Uri uri) {        if (uri != null) {            player = MediaPlayer.create(MusicService.this, uri);        }    }}

然后就是最关键的Activity了,在这个文件里,我加载了ListView,还写了一些其他东西。另外有一个BUG,我还没解决,这个BUG就是你重复点击一个listView的Item,会有多首歌同时播放。。。我知道问题出在item的点击事件里,但是我还没能解决,希望读者有解决方案可以告诉我,万分感谢。
MusicPlayer.java

package com.android.MyMediaPlayer;import java.util.ArrayList;import java.util.HashMap;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.Button;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;public class MusicPlayer extends Activity {    private Button button_start;// 开始 暂停按钮    private Button button_stop;// 停止按钮    private Button button_loop;// 重复按钮    private Button button_uplist;// 刷新列表    private ListView musicList;// 音乐列表    // 接口编程    private Path musicPath;    // listView的适配器    private SimpleAdapter adapter;    // 保存歌曲名的列表    private ArrayList<String> musicName = null;    // 用于保存歌曲的路径    private ArrayList<String> music_Path = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 获取 ‘获取列表类’的实例        musicPath = new SongList();        findView();        setListener();        if (musicName == null) {            // 如果为空加载listView            upList();        }    }    private void setListener() {        button_start.setOnClickListener(buttonListener);        button_stop.setOnClickListener(buttonListener);        button_loop.setOnClickListener(buttonListener);        button_uplist.setOnClickListener(buttonListener);        musicList.setOnItemClickListener(listItemListener);    }    private void upList() {        // 获取播放歌曲的列表        musicName = musicPath.getMusicList();        // 获取歌曲路径        music_Path = musicPath.getMusicPath();        ArrayList<HashMap<String, Object>> ListItem = new ArrayList<HashMap<String, Object>>();        for (int i = 0; i < musicName.size(); i++) {            HashMap<String, Object> map = new HashMap<String, Object>();            map.put("musicname", musicName.get(i));            // 暂时只用到歌曲名            ListItem.add(map);        }        // new适配器,为了扩展性 ,我采用了simpleAdapter        adapter = new SimpleAdapter(MusicPlayer.this, ListItem,                R.layout.music_list_item, new String[] { "musicname" },                new int[] { R.id.music_name });        musicList.setAdapter(adapter);    }    private OnItemClickListener listItemListener = new OnItemClickListener() {        @Override        public void onItemClick(AdapterView<?> parent, View view, int position,                long id) {            if (music_Path != null) {                String Path = music_Path.get(position);                // 把按下Item之后得到的歌曲路径传给服务                Intent intent = new Intent();                intent.setClass(MusicPlayer.this, MusicService.class);                intent.setAction(MusicService.SONG_LIST);                Uri uri = Uri.parse(Path);                intent.setData(uri);                startService(intent);                buttonListener.onClick(button_start);            }        }    };    private OnClickListener buttonListener = new View.OnClickListener() {        @Override        public void onClick(View v) {            switch (v.getId()) {            // 根据刚刚setid进行按钮操作            case 0:                // 根据点击按钮切换暂停继续                Intent intent_play = new Intent(MusicService.PLAY_ACTION);                intent_play.setClass(MusicPlayer.this, MusicService.class);                startService(intent_play);                if (button_start.getText() == "暂停") {                    button_start.setText("播放");                    Intent intent_pause = new Intent(MusicService.PAUSE_ACTION);                    intent_pause.setClass(MusicPlayer.this, MusicService.class);                    startService(intent_pause);                } else {                    button_start.setText("暂停");                }                break;            case 1:                if (button_start.getText() == "暂停") {                    button_start.setText("播放");                    Intent intent_pause = new Intent(MusicService.PAUSE_ACTION);                    intent_pause.setClass(MusicPlayer.this, MusicService.class);                    startService(intent_pause);                }                Intent intent_stop = new Intent(MusicService.STOP_ACTION);                intent_stop.setClass(MusicPlayer.this, MusicService.class);                startService(intent_stop);                break;            case 2:                Intent intent_loop = new Intent(MusicService.LOOP_ACTION);                intent_loop.setClass(MusicPlayer.this, MusicService.class);                startService(intent_loop);                // 按下按钮 文字切换                if (button_loop.getText() == "取消重复") {                    button_loop.setText("重复");                    Intent intent_notLoop = new Intent(                            MusicService.NOTLOOP_ACTION);                    intent_notLoop.setClass(MusicPlayer.this,                            MusicService.class);                    startService(intent_notLoop);                    Toast.makeText(MusicPlayer.this, "重复已关闭",                            Toast.LENGTH_SHORT).show();                } else {                    button_loop.setText("取消重复");                    Toast.makeText(MusicPlayer.this, "重复已开启",                            Toast.LENGTH_SHORT).show();                }                break;            case 3:                if (musicName == null) {                    // 如果为空加载listView                    upList();                } else {                    // 刷新listView                    adapter.notifyDataSetChanged();                }                break;            }        }    };    private void findView() {        // 给每个按钮setid是为了监听按钮时分辨按钮        button_start = (Button) findViewById(R.id.button_start);        button_start.setId(0);        button_stop = (Button) findViewById(R.id.button_stop);        button_stop.setId(1);        button_loop = (Button) findViewById(R.id.button_loop);        button_loop.setId(2);        button_uplist = (Button) findViewById(R.id.button_uplist);        button_uplist.setId(3);        musicList = (ListView) findViewById(R.id.Music_list);    }    // 按下menu键会执行这个方法    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // 增加两个选项        menu.add(0, 0, 0, R.string.menu_about);        menu.add(0, 1, 0, R.string.menu_exit);        return super.onCreateOptionsMenu(menu);    }    // 点击menu中的选项会执行这个方法    @Override    public boolean onOptionsItemSelected(MenuItem item) {        super.onOptionsItemSelected(item);        switch (item.getItemId()) {        case 0:            // 创建新的dialog            new AlertDialog.Builder(MusicPlayer.this)                    .setTitle(R.string.menu_about)                    .setMessage(R.string.about_message)                    .setPositiveButton(R.string.dialog_yes,                            new DialogInterface.OnClickListener() {                                @Override                                public void onClick(DialogInterface dialog,                                        int which) {                                    // 不做任何处理                                }                            }).show();// 要show 要不然显示不出            break;        case 1:            //系统关闭进程            android.os.Process.killProcess(android.os.Process.myPid());            finish();            Intent intent = new Intent();            stopService(intent);            break;        }        return true;    }}

好了,今天的编写到此结束,明天我会继续完善音乐播放器,那好,大家晚安!

0 0
原创粉丝点击