android通过SQLite数据库的操作如何实现音乐播放器
发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,android通过SQLite数据库的操作如何实现音乐播放器,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。下面实现播放列表的功能。当
千家信息网最后更新 2025年02月02日android通过SQLite数据库的操作如何实现音乐播放器
android通过SQLite数据库的操作如何实现音乐播放器,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
下面实现播放列表的功能。
当选择某一首歌曲后,自动将该歌曲加入到整个播放列表中,每次进入播放歌曲的界面时,查询出所有的播放列表中的歌曲,并加入到ListView里,供用户选择。
这样就需要建立一张歌曲表,保存所有的歌曲,主键是歌曲的完整路径。
具体的效果:
第一,先进入到sdcard中
然后,选择一个map3音乐,进入到播放页面,这里实现是通过先将数据的路劲和名称存入数据库,然后再读取数据库中的音乐信息,完成的
代码实现:首先是activity_main.xml
这里实现的是播放器的页面。
然后是实现数据处理的xml,song_line.xml
然后是activity_file_list.xml,这是实现sdcard页面的显示
然后是实现sdcard页面数据的xml,fine_line.xml
第二步,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 MapallIconImgs = 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", "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
第三步,创建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> allValues = new ArrayList >(); public FileAdapter(Context ctx, List > 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 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 ListallViews = new ArrayList (); private Context ctx; public MusicAdapter(List > allValues, Context ctx) { this.ctx = ctx; // 循环建立View Iterator > 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); } } } @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> allValues = new ArrayList >(); @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 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 parent = new HashMap (); 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 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 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 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); } } } }}
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> 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读取不出的话,可能是配置上出现问题。
关于android通过SQLite数据库的操作如何实现音乐播放器问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。
数据
文件
歌曲
一首
数据库
音乐
时间
图片
文件夹
路径
问题
位置
功能
扩展名
消息
线程
组件
页面
提示
监听
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全方法dos命令
软件开发游戏开发公司
自动化软件开发是做什么的
陈成功谈网络安全
山西服务器机柜定制虚拟主机
数据库结构数值型
独立拨号服务器
数据库启用语法
监控搜索服务器
数据库连续插入数据代码
办公网络安全的推文
驻场运维人员网络安全
什么是代理服务器ip
大学生接触网络安全教育心得
数据库应用习题解答
华为云服务器防护措施
新一代数据库技术课件
创建启动数据库
青浦区咨询软件开发厂家职责
论网络安全面临的威胁
滁州回收服务器价格
安卓视频会议服务器
课程软件开发合作协议
网络安全7种问责
数据库软件的是
前后端数据库文件导入
安全教育和网络安全
界面用什么软件开发
网络安全金盾杯在哪个平台
深圳口碑好的网络技术服务费