您好,登錄后才能下訂單哦!
android通過(guò)SQLite數(shù)據(jù)庫(kù)的操作如何實(shí)現(xiàn)音樂(lè)播放器,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
下面實(shí)現(xiàn)播放列表的功能。
當(dāng)選擇某一首歌曲后,自動(dòng)將該歌曲加入到整個(gè)播放列表中,每次進(jìn)入播放歌曲的界面時(shí),查詢出所有的播放列表中的歌曲,并加入到ListView里,供用戶選擇。
這樣就需要建立一張歌曲表,保存所有的歌曲,主鍵是歌曲的完整路徑。
具體的效果:
第一,先進(jìn)入到sdcard中
然后,選擇一個(gè)map3音樂(lè),進(jìn)入到播放頁(yè)面,這里實(shí)現(xiàn)是通過(guò)先將數(shù)據(jù)的路勁和名稱存入數(shù)據(jù)庫(kù),然后再讀取數(shù)據(jù)庫(kù)中的音樂(lè)信息,完成的
代碼實(shí)現(xiàn):首先是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>
這里實(shí)現(xiàn)的是播放器的頁(yè)面。
然后是實(shí)現(xiàn)數(shù)據(jù)處理的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,這是實(shí)現(xiàn)sdcard頁(yè)面的顯示
<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="當(dāng)前位置: /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>
然后是實(shí)現(xiàn)sdcard頁(yè)面數(shù)據(jù)的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代碼,首先實(shí)現(xiàn)數(shù)據(jù)庫(kù)的創(chuàng)建
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); }
然后是公共類初始化的一些設(shè)置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; // 建立一個(gè)Map集合, 里面封裝了所有擴(kuò)展名對(duì)應(yīng)的圖標(biāo)圖片, 以便進(jìn)行文件圖標(biāo)的顯示 public static Map<String, Integer> allIconImgs = new HashMap<String, Integer>(); public static Map<String, String> allSongNameMap = new HashMap<String, String>(); // 初始化數(shù)據(jù)庫(kù)連接 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", "時(shí)間都去哪兒了"); allSongNameMap.put("/storage/sdcard/c.mp3", "卷珠簾"); // 初始化所有擴(kuò)展名和圖片的對(duì)應(yīng)關(guān)系 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); } }
然后是對(duì)數(shù)據(jù)庫(kù)SQLite的數(shù)據(jù)的創(chuàng)建和更新;
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) { // 先判斷數(shù)據(jù)庫(kù)中是否有這條數(shù)據(jù) String sql = "SELECT song_name FROM music WHERE full_path = ?"; Cursor c = Globals.dbc.getReadableDatabase().rawQuery(sql, new String[] { fullPath }); if (!c.moveToFirst()) { // 之前沒(méi)有添加過(guò),需要添加新數(shù)據(jù) 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; } }
第三步,創(chuàng)建adapter,兩個(gè)簡(jiǎn)單的adapter,處理文件,和音樂(lè)
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); // 設(shè)置高度 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); // 取得數(shù)據(jù),設(shè)置到組件里 Map<String, Object> map = allValues.get(position); // 設(shè)置內(nèi)容, 文字 fileName.setText(map.get("fileName").toString()); // 圖片要根據(jù)擴(kuò)展名取得 String extName = map.get("extName").toString(); // 取得圖片的id int imgId = Globals.allIconImgs.get(extName); // 設(shè)置圖片 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; // 循環(huán)建立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); } }
最后是實(shí)現(xiàn)的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); // 準(zhǔn)備數(shù)據(jù) // 取得SD卡根目錄 File root = Environment.getExternalStorageDirectory(); loadFileData(root); // 建立Adapter adapter = new FileAdapter(this, allValues); list.setAdapter(adapter); // 加入監(jiān)聽(tīng)事件 list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // 取得當(dāng)前操作的數(shù)據(jù) Map<String, Object> map = allValues.get(arg2); // 判斷所點(diǎn)的是文件還是文件夾 boolean dirFlag = (Boolean) map.get("dirFlag"); if (dirFlag) { // 文件夾 // 建立該文件夾的File對(duì)象 // 取得絕對(duì)路徑 String fullPath = (String) map.get("fullPath"); // 建立File File dir = new File(fullPath); // 先清空原有數(shù)據(jù) allValues.clear(); if (!Environment.getExternalStorageDirectory() .getAbsolutePath().equals(fullPath)) { // 加入返回上一級(jí)的操作行 Map<String, Object> parent = new HashMap<String, Object>(); parent.put("fileName", "返回上一級(jí)"); parent.put("extName", "dir_open"); parent.put("dirFlag", true); parent.put("fullPath", dir.getParent()); // 保存一個(gè)標(biāo)志 parent.put("flag", "TRUE"); // 將這一行加入到數(shù)據(jù)集合中 allValues.add(parent); } // 加入新數(shù)據(jù) loadFileData(dir); // 使用Adapter通知界面ListView,數(shù)據(jù)已經(jīng)被修改了,你也要一起改 adapter.notifyDataSetChanged(); } else { // 點(diǎn)某個(gè)文件時(shí),將該文件完整路徑傳入到MainActivity中 String fullPath = map.get("fullPath").toString(); // 將數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中 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) { // 取得數(shù)據(jù) Map<String, Object> map = allValues.get(arg2); final File f = new File(map.get("fullPath").toString()); if (f.isFile()) { // 彈出確認(rèn)框 Builder builder = new Builder(FileListActivity.this); builder.setTitle("提示"); builder.setMessage("確定要?jiǎng)h除該文件(" + f.getName() + ")嗎?"); builder.setPositiveButton("確定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 將SD卡中的文件刪除 if (f.exists()) { f.delete(); } // 將列表中的數(shù)據(jù)刪除 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) { // 根據(jù)keyCode判斷用戶按下了哪個(gè)鍵 if (keyCode == KeyEvent.KEYCODE_BACK) { // 判斷當(dāng)前是否在SD卡跟目錄. // 取得第一行數(shù)據(jù) Map<String, Object> map = allValues.get(0); if ("TRUE".equals(map.get("flag"))) { // 里面,需要返回上一級(jí) list.performItemClick(list.getChildAt(0), 0, list.getChildAt(0) .getId()); } else { // 彈出提示框 Builder builder = new Builder(FileListActivity.this); builder.setTitle("提示"); builder.setMessage("親,真的要離開(kāi)我嗎?"); builder.setPositiveButton("真的", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 關(guān)閉當(dāng)前Activity finish(); } }); builder.setNegativeButton("再待會(huì)兒", 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(); // 設(shè)置當(dāng)前位置的提示信息 titleText.setText("當(dāng)前位置: " + dir.getAbsolutePath()); // 判斷 if (allFiles != null) { // 循環(huán) 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()); // 多保存一個(gè)文件的絕對(duì)路徑,方便在進(jìn)行點(diǎn)擊時(shí)使用 map.put("fullPath", f.getAbsolutePath()); // 判斷是文件夾還是文件 if (f.isDirectory()) { // 是文件夾 map.put("extName", "dir_close"); map.put("dirFlag", true); } else { // 是文件 // 截取出擴(kuò)展名 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"; // 準(zhǔn)備ListView private ListView list; private MusicAdapter adapter; private List<Map<String, Object>> allValues; // 當(dāng)前播放的歌曲索引 private int playingIndex = 0; // 音樂(lè)名稱 private TextView musicName; // 播放時(shí)間長(zhǎng)度的文本 private TextView timeText; // 拖動(dòng)條 private SeekBar seekbar; // 播放/暫停 按鈕 private Button playBtn; // 上一首 private Button preBtn; // 下一首 private Button nextBtn; // 總播放時(shí)長(zhǎng)的文本 private String durationTimeStr; // 建立消息通道,以便在子線程中修改界面 private Handler handler; // 線程對(duì)象,監(jiān)聽(tīng)拖動(dòng)條的移動(dòng) 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); // 提取所有歌曲數(shù)據(jù),并初始化 allValues = MusicDAOUtils.listData(); // 判斷當(dāng)前應(yīng)該播放的是列表中的哪一首 for (int i = 0; i < allValues.size(); i++) { if (allValues.get(i).get("fullPath").equals(filePath)) { // 該歌曲就是要進(jìn)行播放的歌曲 playingIndex = i; songName = allValues.get(i).get("songName").toString(); break; } } // 將數(shù)據(jù)放入到listView中列表 list = (ListView) findViewById(R.id.list); adapter = new MusicAdapter(allValues, this); list.setAdapter(adapter); // 設(shè)置選中的背景 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); // 初始化 // 加入一個(gè)多線程,通過(guò)子線程控制拖動(dòng)條以及顯示時(shí)間的改變 t = new Thread() { @Override public void run() { while (flag) { try { Thread.sleep(1000); // 取得當(dāng)前的播放時(shí)間位置,設(shè)置到拖動(dòng)條里 if (player.isPlaying()) { // 傳遞一個(gè)空消息,不需要有具體的消息內(nèi)容,因?yàn)橄⑼ǖ乐兄挥幸粋€(gè)固定的操作,而且不需要參數(shù). handler.sendEmptyMessage(0); } } catch (Exception e) { e.printStackTrace(); } } } }; t.start(); // 播放歌曲 playSong(); // 為播放按鈕加監(jiān)聽(tīng) 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); } } }); // 開(kāi)始播放 playBtn.performClick(); // 加入拖動(dòng)條的監(jiān)聽(tīng) seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { // 開(kāi)始播放, 同時(shí)要倒到當(dāng)前拖動(dòng)條的位置 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) { // 如果是因?yàn)槿藶橥蟿?dòng)造成的值改變,則時(shí)間文本需要一起修改,如果是自動(dòng)改變的拖動(dòng)條的值,則不需要修改 if (fromUser) { // 修改顯示時(shí)間的數(shù)據(jù) timeText.setText(getTextByMs(progress) + "/" + durationTimeStr); } } }); // 設(shè)置點(diǎn)某一首歌,進(jìn)行重新播放的功能 list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // 如果是當(dāng)前正在播放的歌曲,不需要處理 if (arg2 != playingIndex) { // 播放當(dāng)前所點(diǎn)擊的歌曲 playingIndex = arg2; // 重新播放歌曲 playSong(); // 播放歌曲 player.start(); playBtn.setBackgroundResource(R.drawable.ic_player_pause_default); // 重新設(shè)置默認(rèn)選中的歌曲 adapter.setSelectedBackground(playingIndex); } } }); // 設(shè)置播放上一首和下一首的功能 preBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 判斷當(dāng)前是否在播放第一首 if (playingIndex == 0) { Toast.makeText(MainActivity.this, "當(dāng)前已經(jīng)播放的是第一首歌,沒(méi)有前一首!", 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) { // 判斷當(dāng)前是否在播放最后一首 if (playingIndex == allValues.size() - 1) { Toast.makeText(MainActivity.this, "當(dāng)前已經(jīng)播放的是最后一首歌,沒(méi)有后一首!", Toast.LENGTH_SHORT).show(); } else { list.performItemClick((View) adapter .getItem(playingIndex + 1), playingIndex + 1, ((View) (adapter.getItem(playingIndex + 1))) .getId()); } } }); // 加入播放完成后,自動(dòng)播放下一首歌的功能 player.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // 自動(dòng)播放下一首歌,如果已經(jīng)是最后一首,直接播放第一首 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 { // 設(shè)置要播放的文件 player.setDataSource(filePath); // 進(jìn)行準(zhǔn)備操作 player.prepare(); // player.start(); // 初始化拖動(dòng)條的總長(zhǎng)度 seekbar.setMax(player.getDuration()); seekbar.setProgress(0); durationTimeStr = getTextByMs(player.getDuration()); // 修改歌曲標(biāo)題 musicName.setText(songName); // 設(shè)置顯示的播放時(shí)間 timeText.setText("00:00 / " + durationTimeStr); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "當(dāng)前加載的音樂(lè)有問(wèn)題,請(qǐng)確定文件格式是否正確!", Toast.LENGTH_LONG) .show(); } } // 編寫一個(gè)算法, 將傳入的毫秒數(shù)轉(zhuǎn)換成為 分鐘:秒鐘 的格式 private String getTextByMs(int ms) { // 先轉(zhuǎn)換成秒 int s = ms / 1000; // 計(jì)算分鐘 int min = s / 60; // 計(jì)算剩余的秒數(shù) s = s % 60; // 拼接字符串,并補(bǔ)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() { // 退出時(shí)釋放音樂(lè) 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(); } }
//注意,若是在執(zhí)行時(shí)沒(méi)有音樂(lè),或是sdcard讀取不出的話,可能是配置上出現(xiàn)問(wèn)題。
關(guān)于android通過(guò)SQLite數(shù)據(jù)庫(kù)的操作如何實(shí)現(xiàn)音樂(lè)播放器問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。