如何通过操作SQLite数据库在android中实现一个音乐播放器

分类:编程技术 时间:2024-02-20 16:11 浏览:0 评论:0
0
如何通过操作SQLite数据库在Android中实现一个音乐播放器。针对这一问题,本文详细介绍了相应的分析和解答。希望能够帮助更多想要解决这个问题的朋友找到更简单、更容易的方法。

下面实现播放列表功能。

选择歌曲后,该歌曲会自动添加到整个播放列表中。每次进入歌曲播放界面时,都会查询播放列表中的所有歌曲并添加到ListView中。 ,供用户选择。

这样就需要创建一个歌曲表来保存所有的歌曲。主键是歌曲的完整路径。

具体效果:

首先进入sd卡

然后,选择一首map3音乐,进入播放页面,执行这里是先将数据的路径和名称存入数据库,然后读取数据库中的音乐信息来完成的

代码实现第一个是activity_main .xml

 < 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" />                                                                                                                                                                                                                                 android :id="@+id/list" android:layout_width =“match_parent”android:layout_height =“0dp”android:layout_weight =“3”>  < SeekBar android:id="@+id/seekbar" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.5" />     

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

然后是实现的xml数据处理,song_line.xml

    

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

   

然后是实现sdcard页面数据的xml,fine_line.xml

< pre code_snippet_id="272071" snippet_file_name="blog_20140403_4_7723121" name="code" class="java">

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

package org.liky.music.util;import android.content.Context;import android.database .sqlite.SQLiteDatabase;导入android.database.sqlite.SQLiteDatabase.CursorFactory;导入android.database.sqlite.SQLiteOpenHelper;公共类DataBaseConnection扩展SQLiteOpenHelper {公共DataBaseConnection(Context ctx){super(ctx,“music.db”,null,1);}公共DataBaseConnection(上下文上下文,字符串名称,CursorFactory工厂,int版本){super(上下文,名称) ,工厂,版本);}@Overridepublic void onCreate(SQLiteDatabase db) {//创建表 String sql = "CREATE TABLE music(" +"full_pathtextprimary key ," +"song_nametext" +") ;" ;db.execSQL(sql);}

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

包org.liky.music.util;导入java.util.HashMap;导入java.util.Map;导入org.liky.music.R;导入android.app.Activity;导入android .os.Environment;public class Globals {public static int SCREEN_WIDTH;public static int SCREEN_HEIGHT;//创建一个Map集合,里面封装了所有扩展名对应的图标图像,用于显示文件图标 public static Map  allIconImgs = new HashMap<字符串,整数>(); public static Map allSongNameMap = new HashMap();//初始化数据库连接 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", "带我飞向月球");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中数据的创建和更新;< /p>

包org.liky.music.util;导入java.util.ArrayList;导入java.util.HashMap;导入java.util.List;导入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();} 公共静态列表< Map> listData( ) {String sql = "SELECT full_path,song_name FROM music";Cursor c = Globals.dbc.getReadableDatabase().rawQuery(sql, null);List> allValues = new ArrayList>();c.moveToFirst();while (!c.isAfterLast()) {Map map = new HashMap();map. put("fullPath", c.getString(0));map.put("songName", c.getString(1));allValues.add(map);c.moveToNext();}c.close(); return allValues;}}

第三步,创建一个适配器,两个简单的适配器,用来处理文件和音乐

包 org.liky.music。适配器;导入 java.util.ArrayList;导入 java.util.Iterator;导入 java.util.List;导入 java.util.Map;导入 org.liky.music.R;导入 android.content.Context;导入 android.graphics .Color;导入android.view.LayoutInflater;导入android.view.View;导入android.view.ViewGroup;导入android.widget。 BaseAdapter;导入 android.widget.TextView;公共类 MusicAdapter 扩展 BaseAdapter {private List allViews = new ArrayList();private Context ctx;public MusicAdapter(List> allValues, Context ctx ) {this.ctx = ctx;//循环创建ViewIterator> iter = allValues.iterator();while (iter.hasNext()) {Map 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(intposition){return allViews.get(position);}@Overridepublic long getItemId(intposition){returnposition;} }@Overridepublic View getView(intposition,ViewconvertView,ViewGroupparent){returnallViews.get(position);}}

最后是实现的Activity、FIleListActivity和mainActivity

包 org.liky.music;导入java.io.File;导入java.util.ArrayList;导入java.util.HashMap;导入java.util.List;导入java.util.Map;导入org.liky.music.adapter.FileAdapter;导入org.likey。 music.util.Globals;导入 org.liky.music.util.MusicDAOUtils;导入 android.app.Activity;导入 android.app.AlertDialog.Builder;导入 android.content.DialogInterface;导入 android.content.DialogInterface.OnClickListener;导入android.content.Intent;导入android.os.Bundle;导入android.os.Environment;导入android.view.KeyEvent;导入android.view.View;导入android.widget.AdapterView;导入android.widget.AdapterView.OnItemClickListener;导入 android.widget.AdapterView.OnItemLongClickListener;导入 android.widget.ListView;导入 android.widget.TextView;公共类 FileListActivity 扩展 Activity {私有 TextView titleText;私有 ListView 列表;privateFileAdapter 适配器;私有 List> allValues = new ArrayList>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Globals.init(this) ;setContentView(R.layout.activity_file_list); // 获取组件 titleText = (TextView) findViewById(R.id.title_text);列表 = (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 map = allValues.get (arg2); // 判断点击的是文件还是文件夹 boolean dirFlag = (Boolean) map.get("dirFlag"); if (dirFlag) {// 文件夹 // 创建文件夹的File对象 // 获取绝对值path String fullPath = (String) map.get("fullPath");// 创建FileFile dir = new File(fullPath);// 先清除原始数据 allValues.clear();if (!Environment.getExternalStorageDirectory().getAbsolutePath().equals(fullPath)) {//添加返回上一级的操作行 Mapparent = new HashMap();parent.put("fileName", "返回上一级");parent.put("extName", "dir_open");parent.put("dirFlag", true);parent.put(" fullPath", dir.getParent());//保存一个Flag child.put("flag", "TRUE");//将这一行添加到数据集合中 allValues.add(parent);}//添加新数据loadFileData(dir);//使用Adapter通知界面ListView,数据已修改,也需要一起更改adapter.notifyDataSetChanged();} else {//点击文件时,传入文件的完整路径file to 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 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 (DialogInterfacedialog,intwhich){//删除SD卡中的文件 if (f.exists()) {f.delete();}//删除列表中的数据 allValues.remove(arg2); //通知adapter.notifyDataSetChanged();}}); builder.setNegativeButton("取消", new OnClickListener() {@Overridepublic void onClick(DialogInterfacedialog, int which) {}});builder.create().show(); }return false;}});}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// 判断哪个键user pressed based on keyCode if (keyCode == KeyEvent.KEYCODE_BACK) {//判断当前是否在SD卡及目录中 //获取第一行数据 Map 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(DialogInterfacedialog, int which) {//关闭当前Activityfinish();}});builder.setNegativeButton("稍等一下", new OnClickListener () {@Overridepublic void onClick (DialogInterfacedialog, int which) {}});builder.create().show();}return false;}return super.onKeyDown(keyCode, event);}private void loadFileData(File dir) {//列出该目录下的所有文件y 文件[] allFiles = dir.listFiles(); // 设置当前位置的提示信息 titleText.setText("当前位置:" + dir.getAbsolutePath()); // 判断 if (allFiles != null) {// 循环 for (int i = 0; i < allFiles.length; i++) {File f = allFiles[i];Map map = new HashMap();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);}}}}}
包org.liky.music;导入java.util.List;导入java.util.Map;导入org.liky.music.adapter.MusicAdapter;导入org.liky。 music.util.MusicDAOUtils;导入 android.app.Activity;导入 android.media.MediaPlayer;导入 android.media.MediaPlayer.OnCompletionListener;导入 android.os.Bundle;导入 android.os.Handler;导入 android.os.Message;导入 android.view.View;导入 android.view.View.OnClickListener;导入 android.widget.AdapterView;导入 android.widget .AdapterView.OnItemClickListener;导入 android.widget.Button;导入 android.widget.ListView;导入 android.widget .SeekBar;导入android.widget.SeekBar.OnSeekBarChangeListener;导入android.widget.TextView;导入android.widget.Toast;公共类MainActivity扩展Activity {私有MediaPlayer播放器;私有String filePath =“/storage/sdcard/a.mp3” ;private String SongName = "Fly Me To The Moon"; // 准备 ListView private ListView list; private MusicAdapter 适配器; private List> allValues; // 当前播放歌曲索引 private intplayingIndex = 0; // 音乐名称 private TextView musicName ;//播放时间长度文本 private TextView timeText;//拖拽栏 private SeekBar seebar;//播放/暂停按钮 private Button playBtn;//上一曲 private Button preBtn;//下一曲 private Button nextBtn;//总播放时长的文本 private StringurationTimeStr; // 建立消息通道,在子线程中修改接口 private Handler handler; // Thread对象,监听拖动条的移动 private Thread t = null;私有布尔标志= true; @Overrideprotected void onCreate(Bundle savingInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);player = new MediaPlayer();//接收传入的文件路径 filePath = getIntent().getStringExtra("fullPath" );// SongName = Globals.allSongNameMap.get(filePath);// 提取所有歌曲数据并初始化 allValues = MusicDAOUtils.listData();// 确定当前应该播放的内容 列表中的哪一首歌曲 (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()) + "/"+urationTimeStr);}};//获取所有组件musicName = (TextView) findViewById(R.id.music_name); timeText = (TextView) findViewById(R.id.time_text); eekbar = (SeekBar) findViewById(R.id.seekbar); playBtn = (按钮) findViewById(R.id.play_btn); preBtn = (按钮) findViewById(R.id.pre_btn);下一个BTn = (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(SeekBareekBar) {//开始播放,同时转到当前拖拽条位置player.seekTo(seekbar.getProgress());player.start(); //修改按钮图片 playBtn.setBackgroundResource(R.drawable.ic_player_pause_default);}@Overridepublic void onStartTrackingTouch(SeekBareekBar) {//暂停播放player.pause();playBtn.setBackgroundResource(R.drawable.ic_player_play_default);}@ Overridepublic void onProgressChanged(SeekBareekBar, intprogress,booleanfromUser) {//如果由于人为拖动导致值发生变化,则时间文本需要一起修改,如果是自动变化的话,拖动bar的值就不用了不需要修改 if (fromUser) {//修改显示时间数据 timeText.setText(getTextByMs(progress) + "/"+urationTimeStr);}}});// 设置某首歌曲并重播列表的功能.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 / " +urationTimeStr);} catch (Exception e) {e.printStackTrace();Toast.makeText(this,"当前加载的音乐有问题,请确保文件格式正确!",Toast.LENGTH_LONG).show();}}//写一个将传入的毫秒转换为分钟:秒格式的算法 private String getTextByMs(int ms){//转换为秒 int s first = 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();}@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();}}


//注意,如果执行时没有音乐,或者无法读取sd卡,可能是配置问题。

关于如何在Android中通过操作SQLite数据库来实现音乐播放器的问题的答案就分享在这里。希望以上内容能够对大家有所帮助。如果你还有很多d尚未解决的问题,您可以关注行业资讯频道,了解更多相关知识。

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > 如何通过操作SQLite数据库在android中实现一个音乐播放器

用户评论