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

来源:互联网 发布:门诊系统的数据库设计 编辑:程序博客网 时间:2024/05/21 01:45

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

当选择某一首歌曲后,自动将该歌曲加入到整个播放列表中,每次进入播放歌曲的界面时,查询出所有的播放列表中的歌曲,并加入到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);}@Overridepublic void onCreate(SQLiteDatabase db) {// 建立表String sql = "CREATE TABLE music (" +"full_pathtextprimary key ," +"song_nametext" +");" ;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;}@Overridepublic int getCount() {return allValues.size();}@Overridepublic Object getItem(int arg0) {return allValues.get(arg0);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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();// 取得图片的idint 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;// 循环建立ViewIterator<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);}}}@Overridepublic int getCount() {return allViews.size();}@Overridepublic Object getItem(int position) {return allViews.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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>>();@Overrideprotected 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);// 建立Adapteradapter = new FileAdapter(this, allValues);list.setAdapter(adapter);// 加入监听事件list.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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");// 建立FileFile 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() {@Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 将SD卡中的文件删除if (f.exists()) {f.delete();}// 将列表中的数据删除allValues.remove(arg2);// 通知adapter.notifyDataSetChanged();}});builder.setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}});builder.create().show();}return false;}});}@Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {// 关闭当前Activityfinish();}});builder.setNegativeButton("再待会儿", new OnClickListener() {@Overridepublic 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";// 准备ListViewprivate 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;@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// 开始播放, 同时要倒到当前拖动条的位置player.seekTo(seekbar.getProgress());player.start();// 修改按钮的图片playBtn.setBackgroundResource(R.drawable.ic_player_pause_default);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// 暂停播放player.pause();playBtn.setBackgroundResource(R.drawable.ic_player_play_default);}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// 如果是因为人为拖动造成的值改变,则时间文本需要一起修改,如果是自动改变的拖动条的值,则不需要修改if (fromUser) {// 修改显示时间的数据timeText.setText(getTextByMs(progress) + "/"+ durationTimeStr);}}});// 设置点某一首歌,进行重新播放的功能list.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic 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;// 拼接字符串,并补0StringBuilder 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();}@Overrideprotected 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读取不出的话,可能是配置上出现问题,可以参看我之前的博客,上面对出现的问题做出了些说明。






0 0