«

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

时间:2024-3-2 16:59     作者:韩俊     分类: Html+Css


这篇博客,是基于上一篇博客实现的,使用到了主要知识点有: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;
    }
}

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

标签: javascript html css

热门推荐