现在的位置: 首页 > 数据库 > 正文

android实现音乐播放器,SQLite数据库的操作

2019年10月11日 数据库 ⁄ 共 21501字 ⁄ 字号 评论关闭

下面实现播放列表的功能。

当选择某一首歌曲后,自动将该歌曲加入到整个播放列表中,每次进入播放歌曲的界面时,查询出所有的播放列表中的歌曲,并加入到ListView里,供用户选择。

这样就需要建立一张歌曲表,保存所有的歌曲,主键是歌曲的完整路径。

具体的效果:

第一,先进入到sdcard中

然后,选择一个map3音乐,进入到播放页面,这里实现是通过先将数据的路劲和名称存入数据库,然后再读取数据库中的音乐信息,完成的

代码实现:首先是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:background="#cccccc"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/music_name"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center"
        android:text="@string/hello_world"
        android:textColor="#000000"
        android:textSize="16sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/audio_identify_start_default" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3" >
    </ListView>

    <SeekBar
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5" />

    <TextView
        android:id="@+id/time_text"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.5"
        android:gravity="center"
        android:text="00:00 / 00:00"
        android:textColor="#000000"
        android:textSize="12sp" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.5" />

        <Button
            android:id="@+id/pre_btn"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ic_player_prev_default" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <Button
            android:id="@+id/play_btn"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.5"
            android:background="@drawable/ic_player_play_default" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <Button
            android:id="@+id/next_btn"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/ic_player_next_default" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.5" />
    </LinearLayout>

</LinearLayout>

这里实现的是播放器的页面。

然后是实现数据处理的xml,song_line.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="wrap_content"
    android:background="#ffffff" >

    <TextView
        android:id="@+id/song_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:textSize="14sp" >
    </TextView>

</LinearLayout>

然后是activity_file_list.xml,这是实现sdcard页面的显示

<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:id="@+id/title_text"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:text="当前位置: /mnt/sdcard"
        android:textSize="14sp" />

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="8"
        android:cacheColorHint="#00000000" >
    </ListView>

</LinearLayout>

然后是实现sdcard页面数据的xml,fine_line.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="wrap_content"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/file_img"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <TextView
        android:id="@+id/file_name"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="4"
        android:textSize="14sp" />

</LinearLayout>

第二步,java代码,首先实现数据库的创建

package org.liky.music.util;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DataBaseConnection extends SQLiteOpenHelper {

	public DataBaseConnection(Context ctx) {
		super(ctx, "music.db", null, 1);
	}
	
	public DataBaseConnection(Context context, String name,
			CursorFactory factory, int version) {
		super(context, name, factory, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// 建立表
		String sql = "CREATE TABLE music (" +
				"full_path			text			primary key ," +
				"song_name			text			" +
				");" ;
		
		db.execSQL(sql);
	}

然后是公共类初始化的一些设置Global,如控制屏幕显示的

package org.liky.music.util;

import java.util.HashMap;
import java.util.Map;

import org.liky.music.R;

import android.app.Activity;
import android.os.Environment;

public class Globals {

	public static int SCREEN_WIDTH;
	public static int SCREEN_HEIGHT;
	// 建立一个Map集合, 里面封装了所有扩展名对应的图标图片, 以便进行文件图标的显示
	public static Map<String, Integer> allIconImgs = new HashMap<String, Integer>();

	public static Map<String, String> allSongNameMap = new HashMap<String, String>();

	// 初始化数据库连接
	public static DataBaseConnection dbc;

	public static void init(Activity a) {
		SCREEN_WIDTH = a.getWindowManager().getDefaultDisplay().getWidth();
		SCREEN_HEIGHT = a.getWindowManager().getDefaultDisplay().getHeight();

		dbc = new DataBaseConnection(a);
		
		// 初始化一些歌曲名称
		allSongNameMap.put("/storage/sdcard/a.mp3", "Fly Me To The Moon");
		allSongNameMap.put("/storage/sdcard/b.mp3", "时间都去哪儿了");
		allSongNameMap.put("/storage/sdcard/c.mp3", "卷珠帘");

		// 初始化所有扩展名和图片的对应关系
		allIconImgs.put("txt", R.drawable.txt_file);
		allIconImgs.put("mp3", R.drawable.mp3_file);
		allIconImgs.put("mp4", R.drawable.mp4_file);
		allIconImgs.put("bmp", R.drawable.image_file);
		allIconImgs.put("gif", R.drawable.image_file);
		allIconImgs.put("png", R.drawable.image_file);
		allIconImgs.put("jpg", R.drawable.image_file);
		allIconImgs.put("dir_open", R.drawable.open_dir);
		allIconImgs.put("dir_close", R.drawable.close_dir);
	}

}

然后是对数据库SQLite的数据的创建和更新;

package org.liky.music.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.database.Cursor;

public class MusicDAOUtils {

	public static void insertData(String fullPath) {
		// 先判断数据库中是否有这条数据
		String sql = "SELECT song_name FROM music WHERE full_path = ?";
		Cursor c = Globals.dbc.getReadableDatabase().rawQuery(sql,
				new String[] { fullPath });
		if (!c.moveToFirst()) {
			// 之前没有添加过,需要添加新数据
			sql = "INSERT INTO music VALUES (?,?)";
			Globals.dbc.getWritableDatabase().execSQL(
					sql,
					new Object[] { fullPath,
							Globals.allSongNameMap.get(fullPath) });
		}
		c.close();
	}

	public static List<Map<String, Object>> listData() {
		String sql = "SELECT full_path,song_name FROM music";
		Cursor c = Globals.dbc.getReadableDatabase().rawQuery(sql, null);

		List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();
		c.moveToFirst();
		while (!c.isAfterLast()) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("fullPath", c.getString(0));
			map.put("songName", c.getString(1));
			allValues.add(map);

			c.moveToNext();
		}

		c.close();

		return allValues;
	}
}

第三步,创建adapter,两个简单的adapter,处理文件,和音乐

package org.liky.music.adapter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.liky.music.R;
import org.liky.music.util.Globals;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class FileAdapter extends BaseAdapter {

	private Context ctx;
	private List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();

	public FileAdapter(Context ctx, List<Map<String, Object>> allValues) {
		this.ctx = ctx;
		this.allValues = allValues;
	}

	@Override
	public int getCount() {
		return allValues.size();
	}

	@Override
	public Object getItem(int arg0) {
		return allValues.get(arg0);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if (convertView == null) {
			convertView = LayoutInflater.from(ctx).inflate(R.layout.file_line,
					null);
			// 设置高度
			convertView.setLayoutParams(new LayoutParams(
					LayoutParams.MATCH_PARENT, Globals.SCREEN_HEIGHT / 9));
		}

		// 取得组件
		TextView fileImg = (TextView) convertView.findViewById(R.id.file_img);

		fileImg.getLayoutParams().height = Globals.SCREEN_HEIGHT / 9;

		TextView fileName = (TextView) convertView.findViewById(R.id.file_name);

		// 取得数据,设置到组件里
		Map<String, Object> map = allValues.get(position);

		// 设置内容, 文字
		fileName.setText(map.get("fileName").toString());

		// 图片要根据扩展名取得
		String extName = map.get("extName").toString();
		// 取得图片的id
		int imgId = Globals.allIconImgs.get(extName);
		// 设置图片
		fileImg.setBackgroundResource(imgId);

		return convertView;
	}

}

package org.liky.music.adapter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.liky.music.R;

import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MusicAdapter extends BaseAdapter {

	private List<View> allViews = new ArrayList<View>();

	private Context ctx;

	public MusicAdapter(List<Map<String, Object>> allValues, Context ctx) {
		this.ctx = ctx;
		// 循环建立View
		Iterator<Map<String, Object>> iter = allValues.iterator();
		while (iter.hasNext()) {
			Map<String, Object> map = iter.next();

			View v = LayoutInflater.from(ctx).inflate(R.layout.song_line, null);
			TextView songName = (TextView) v.findViewById(R.id.song_name);
			songName.setText(map.get("songName").toString());

			allViews.add(v);
		}
	}

	public void setSelectedBackground(int index) {
		// 其他的索引全部清空成为白色
		for (int i = 0; i < allViews.size(); i++) {
			if (i == index) {
				allViews.get(index).setBackgroundColor(Color.RED);
			} else {
				allViews.get(i).setBackgroundColor(Color.WHITE);
			}
		}
	}

	@Override
	public int getCount() {
		return allViews.size();
	}

	@Override
	public Object getItem(int position) {
		return allViews.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		return allViews.get(position);
	}

}

最后是实现的Activity,FIleListActivity和mainActivity

package org.liky.music;

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

import org.liky.music.adapter.FileAdapter;
import org.liky.music.util.Globals;
import org.liky.music.util.MusicDAOUtils;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
import android.widget.TextView;

public class FileListActivity extends Activity {

	private TextView titleText;
	private ListView list;

	private FileAdapter adapter;
	private List<Map<String, Object>> allValues = new ArrayList<Map<String, Object>>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Globals.init(this);

		setContentView(R.layout.activity_file_list);

		// 取得组件
		titleText = (TextView) findViewById(R.id.title_text);
		list = (ListView) findViewById(R.id.list);

		// 准备数据
		// 取得SD卡根目录
		File root = Environment.getExternalStorageDirectory();

		loadFileData(root);

		// 建立Adapter
		adapter = new FileAdapter(this, allValues);

		list.setAdapter(adapter);

		// 加入监听事件
		list.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// 取得当前操作的数据
				Map<String, Object> map = allValues.get(arg2);
				// 判断所点的是文件还是文件夹
				boolean dirFlag = (Boolean) map.get("dirFlag");
				if (dirFlag) {
					// 文件夹
					// 建立该文件夹的File对象
					// 取得绝对路径
					String fullPath = (String) map.get("fullPath");
					// 建立File
					File dir = new File(fullPath);

					// 先清空原有数据
					allValues.clear();

					if (!Environment.getExternalStorageDirectory()
							.getAbsolutePath().equals(fullPath)) {
						// 加入返回上一级的操作行
						Map<String, Object> parent = new HashMap<String, Object>();
						parent.put("fileName", "返回上一级");
						parent.put("extName", "dir_open");
						parent.put("dirFlag", true);
						parent.put("fullPath", dir.getParent());

						// 保存一个标志
						parent.put("flag", "TRUE");

						// 将这一行加入到数据集合中
						allValues.add(parent);
					}

					// 加入新数据
					loadFileData(dir);

					// 使用Adapter通知界面ListView,数据已经被修改了,你也要一起改
					adapter.notifyDataSetChanged();
				} else {
					// 点某个文件时,将该文件完整路径传入到MainActivity中
					String fullPath = map.get("fullPath").toString();
					// 将数据保存到数据库中
					MusicDAOUtils.insertData(fullPath);

					Intent in = new Intent(FileListActivity.this,
							MainActivity.class);
					in.putExtra("fullPath", fullPath);
					startActivity(in);
				}

			}
		});

		list.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					final int arg2, long arg3) {
				// 取得数据
				Map<String, Object> map = allValues.get(arg2);
				final File f = new File(map.get("fullPath").toString());

				if (f.isFile()) {
					// 弹出确认框
					Builder builder = new Builder(FileListActivity.this);
					builder.setTitle("提示");
					builder.setMessage("确定要删除该文件(" + f.getName() + ")吗?");
					builder.setPositiveButton("确定", new OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// 将SD卡中的文件删除
							if (f.exists()) {
								f.delete();
							}

							// 将列表中的数据删除
							allValues.remove(arg2);
							// 通知
							adapter.notifyDataSetChanged();
						}
					});
					builder.setNegativeButton("取消", new OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
						}
					});

					builder.create().show();
				}

				return false;
			}
		});

	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// 根据keyCode判断用户按下了哪个键
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			// 判断当前是否在SD卡跟目录.
			// 取得第一行数据
			Map<String, Object> map = allValues.get(0);
			if ("TRUE".equals(map.get("flag"))) {
				// 里面,需要返回上一级
				list.performItemClick(list.getChildAt(0), 0, list.getChildAt(0)
						.getId());
			} else {
				// 弹出提示框
				Builder builder = new Builder(FileListActivity.this);
				builder.setTitle("提示");
				builder.setMessage("亲,真的要离开我吗?");
				builder.setPositiveButton("真的", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// 关闭当前Activity
						finish();
					}
				});
				builder.setNegativeButton("再待会儿", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {

					}
				});
				builder.create().show();
			}

			return false;
		}

		return super.onKeyDown(keyCode, event);
	}

	private void loadFileData(File dir) {
		// 列出该目录下的所有文件
		File[] allFiles = dir.listFiles();
		// 设置当前位置的提示信息
		titleText.setText("当前位置: " + dir.getAbsolutePath());

		// 判断
		if (allFiles != null) {
			// 循环
			for (int i = 0; i < allFiles.length; i++) {
				File f = allFiles[i];
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("fileName", f.getName());
				// 多保存一个文件的绝对路径,方便在进行点击时使用
				map.put("fullPath", f.getAbsolutePath());
				// 判断是文件夹还是文件
				if (f.isDirectory()) {
					// 是文件夹
					map.put("extName", "dir_close");
					map.put("dirFlag", true);
				} else {
					// 是文件
					// 截取出扩展名
					String extName = f.getName()
							.substring(f.getName().lastIndexOf(".") + 1)
							.toLowerCase();
					map.put("extName", extName);
					map.put("dirFlag", false);
				}

				// 只添加文件夹或所有mp3文件
				if (f.isDirectory() || "mp3".equals(map.get("extName"))) {
					allValues.add(map);
				}
			}
		}
	}

}

package org.liky.music;

import java.util.List;
import java.util.Map;

import org.liky.music.adapter.MusicAdapter;
import org.liky.music.util.MusicDAOUtils;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
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.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private MediaPlayer player;

	private String filePath = "/storage/sdcard/a.mp3";
	private String songName = "Fly Me To The Moon";
	// 准备ListView
	private ListView list;
	private MusicAdapter adapter;
	private List<Map<String, Object>> allValues;

	// 当前播放的歌曲索引
	private int playingIndex = 0;

	// 音乐名称
	private TextView musicName;
	// 播放时间长度的文本
	private TextView timeText;
	// 拖动条
	private SeekBar seekbar;
	// 播放/暂停 按钮
	private Button playBtn;
	// 上一首
	private Button preBtn;
	// 下一首
	private Button nextBtn;

	// 总播放时长的文本
	private String durationTimeStr;

	// 建立消息通道,以便在子线程中修改界面
	private Handler handler;

	// 线程对象,监听拖动条的移动
	private Thread t = null;

	private boolean flag = true;

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

		player = new MediaPlayer();

		// 接收传入的文件路径
		filePath = getIntent().getStringExtra("fullPath");
		// songName = Globals.allSongNameMap.get(filePath);

		// 提取所有歌曲数据,并初始化
		allValues = MusicDAOUtils.listData();

		// 判断当前应该播放的是列表中的哪一首
		for (int i = 0; i < allValues.size(); i++) {
			if (allValues.get(i).get("fullPath").equals(filePath)) {
				// 该歌曲就是要进行播放的歌曲
				playingIndex = i;
				songName = allValues.get(i).get("songName").toString();
				break;
			}
		}

		// 将数据放入到listView中列表
		list = (ListView) findViewById(R.id.list);

		adapter = new MusicAdapter(allValues, this);

		list.setAdapter(adapter);

		// 设置选中的背景
		adapter.setSelectedBackground(playingIndex);

		handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				seekbar.setProgress(player.getCurrentPosition());
				timeText.setText(getTextByMs(player.getCurrentPosition()) + "/"
						+ durationTimeStr);
			}
		};

		// 取得所有组件
		musicName = (TextView) findViewById(R.id.music_name);
		timeText = (TextView) findViewById(R.id.time_text);

		seekbar = (SeekBar) findViewById(R.id.seekbar);

		playBtn = (Button) findViewById(R.id.play_btn);
		preBtn = (Button) findViewById(R.id.pre_btn);
		nextBtn = (Button) findViewById(R.id.next_btn);

		// 初始化

		// 加入一个多线程,通过子线程控制拖动条以及显示时间的改变
		t = new Thread() {
			@Override
			public void run() {
				while (flag) {
					try {
						Thread.sleep(1000);

						// 取得当前的播放时间位置,设置到拖动条里
						if (player.isPlaying()) {
							// 传递一个空消息,不需要有具体的消息内容,因为消息通道中只有一个固定的操作,而且不需要参数.
							handler.sendEmptyMessage(0);
						}

					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		};
		t.start();

		// 播放歌曲
		playSong();

		// 为播放按钮加监听
		playBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (player.isPlaying()) {
					player.pause();
					playBtn.setBackgroundResource(R.drawable.ic_player_play_default);
				} else {
					player.start();
					playBtn.setBackgroundResource(R.drawable.ic_player_pause_default);
				}
			}
		});

		// 开始播放
		playBtn.performClick();

		// 加入拖动条的监听
		seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
				// 开始播放, 同时要倒到当前拖动条的位置
				player.seekTo(seekbar.getProgress());
				player.start();
				// 修改按钮的图片
				playBtn.setBackgroundResource(R.drawable.ic_player_pause_default);
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
				// 暂停播放
				player.pause();
				playBtn.setBackgroundResource(R.drawable.ic_player_play_default);
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress,
					boolean fromUser) {
				// 如果是因为人为拖动造成的值改变,则时间文本需要一起修改,如果是自动改变的拖动条的值,则不需要修改
				if (fromUser) {
					// 修改显示时间的数据
					timeText.setText(getTextByMs(progress) + "/"
							+ durationTimeStr);
				}
			}
		});

		// 设置点某一首歌,进行重新播放的功能
		list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				// 如果是当前正在播放的歌曲,不需要处理
				if (arg2 != playingIndex) {
					// 播放当前所点击的歌曲
					playingIndex = arg2;
					// 重新播放歌曲
					playSong();
					// 播放歌曲
					player.start();
					playBtn.setBackgroundResource(R.drawable.ic_player_pause_default);
					// 重新设置默认选中的歌曲
					adapter.setSelectedBackground(playingIndex);
				}

			}
		});

		// 设置播放上一首和下一首的功能
		preBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 判断当前是否在播放第一首
				if (playingIndex == 0) {
					Toast.makeText(MainActivity.this, "当前已经播放的是第一首歌,没有前一首!",
							Toast.LENGTH_SHORT).show();
				} else {
					list.performItemClick((View) adapter
							.getItem(playingIndex - 1), playingIndex - 1,
							((View) (adapter.getItem(playingIndex - 1)))
									.getId());
				}
			}
		});
		nextBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 判断当前是否在播放最后一首
				if (playingIndex == allValues.size() - 1) {
					Toast.makeText(MainActivity.this, "当前已经播放的是最后一首歌,没有后一首!",
							Toast.LENGTH_SHORT).show();
				} else {
					list.performItemClick((View) adapter
							.getItem(playingIndex + 1), playingIndex + 1,
							((View) (adapter.getItem(playingIndex + 1)))
									.getId());
				}
			}
		});

		// 加入播放完成后,自动播放下一首歌的功能
		player.setOnCompletionListener(new OnCompletionListener() {
			@Override
			public void onCompletion(MediaPlayer mp) {
				// 自动播放下一首歌,如果已经是最后一首,直接播放第一首
				if (playingIndex == allValues.size() - 1) {
					list.performItemClick((View) adapter.getItem(0), 0,
							((View) (adapter.getItem(0))).getId());
				} else {
					list.performItemClick((View) adapter
							.getItem(playingIndex + 1), playingIndex + 1,
							((View) (adapter.getItem(playingIndex + 1)))
									.getId());
				}

			}
		});

	}

	private void playSong() {
		filePath = allValues.get(playingIndex).get("fullPath").toString();
		songName = allValues.get(playingIndex).get("songName").toString();

		// 如果正在播放,则停止播放
		if (player.isPlaying()) {
			player.stop();
		}

		// 重置
		player.reset();

		try {
			// 设置要播放的文件
			player.setDataSource(filePath);
			// 进行准备操作
			player.prepare();
			// player.start();

			// 初始化拖动条的总长度
			seekbar.setMax(player.getDuration());
			seekbar.setProgress(0);

			durationTimeStr = getTextByMs(player.getDuration());

			// 修改歌曲标题
			musicName.setText(songName);

			// 设置显示的播放时间
			timeText.setText("00:00 / " + durationTimeStr);

		} catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(this, "当前加载的音乐有问题,请确定文件格式是否正确!", Toast.LENGTH_LONG)
					.show();
		}
	}

	// 编写一个算法, 将传入的毫秒数转换成为 分钟:秒钟 的格式
	private String getTextByMs(int ms) {
		// 先转换成秒
		int s = ms / 1000;
		// 计算分钟
		int min = s / 60;
		// 计算剩余的秒数
		s = s % 60;
		// 拼接字符串,并补0
		StringBuilder builder = new StringBuilder();
		if (min < 10) {
			builder.append(0);
		}
		builder.append(min);
		builder.append(":");
		if (s < 10) {
			builder.append(0);
		}
		builder.append(s);

		return builder.toString();
	}

	@Override
	protected void onDestroy() {
		// 退出时释放音乐
		if (player != null) {
			if (player.isPlaying()) {
				player.stop();
			}
			player.release();
		}
		if (t != null) {
			try {
				flag = false;
				t.interrupt();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		super.onDestroy();
	}
}


//注意,若是在执行时没有音乐,或是sdcard读取不出的话,可能是配置上出现问题,可以参看我之前的博客,上面对出现的问题做出了些说明。

抱歉!评论已关闭.