Android手机开发课程设计之音乐播放器
一、音樂播放器概述與分析
目前手機的音樂播放功能已經是大家比較關注的一個部分,不少在人在購買手機的時候都會關心手機的音樂播放的能力,這也足以看出目前大家對音樂播放功能的重視,所以一款性能良好的手機音樂播放器軟件一定會受到歡迎。和傳統的音樂播放器相比,手機播放音樂更加的容易攜帶,其他方面也都不輸于傳統音樂播放器,而且還具有網上聽音樂功能,所以開發一款受歡迎的手機音樂播放軟件是具有良好的市場和應用前景的。不同手機平臺的手機,所支持的音樂播放軟件也是各不相同,而現在最流行的手機平臺之一就是google 的android手機平臺,所以本課題就致力于開發出一款基于android手機平臺的音樂播放器,來滿足用戶的使用需求。
本次Android課設音樂播放器完成的基本功能有:
(1)主界面音樂播放管理:實現音樂的播放、暫停、播放進度條顯示及拉動、播放上一首、播放下一首、播放模式的列表循環、單曲循環、隨機播放等基本功能。
(2)通知欄音樂播放管理:使用Service、BroadcastReceiver可以在狀態通知欄實現音樂播放的基本功能、打開和退出等功能。
(3)桌面小組件音樂播放管理:使用Service、BroadcastReceiver、重寫AppWidgetProvider類在桌面以小組件的方式實現音樂播放基本功能。
(4)音樂搜索管理:獲取QQ音樂的音樂數據,實現音樂搜索,保存并顯示搜索記錄,可對歷史搜索記錄進行刪除和清空。
(5)歌單管理:獲取QQ音樂的音樂數據的榜單信息,實現榜單歌單,可添加歌曲到我喜歡和播放列表等。
二、音樂播放器的設計
針對音樂播放器系統的功能進行詳細分析,整個應用程序應劃分為3個模塊,分別是程序啟動、用戶界面和數據庫適配器。
程序啟動時需要連接網絡訪問數據,獲取數據并更新顯示到主界面榜單列表頁面中,具體如下圖所示:
用戶界面模塊包括榜單列表的主界面、用戶界面、播放界面、搜索界面、播放界面、歌單界面,具體如下圖所示:
數據庫模塊數據庫適配器主要對存入數據庫的專輯圖片、專輯名稱、歌手、歌名、音樂、付費情況數據進行管理,包括添加、刪除、查詢相關數據,具體如下圖所示:
用戶進入音樂播放器后,會看到榜單列表的主界面。在主界面上進行的各種操作,截圖如下流程圖所示:
(1)在主界面(榜單列表)時,可以選擇點擊播放列表,查看播放列表中的歌曲,如有想要播放的音樂,點擊歌曲進入播放,否則可以選擇關閉按鈕關閉播放列表回到原來的界面,也可以通過歌曲欄中的播放按鈕播放當前歌曲。
(2)在主界面(榜單列表)中點擊歌曲欄,可以進入播放界面,進行播放音樂的操作,如播放、暫停、上一首、下一首,以及更改播放模式,或者返回主界面。
(3)在主界面(榜單列表)中點擊“我的”可以進入用戶界面,在用戶界面中可以點擊“喜歡”查看喜歡列表的歌曲,點擊“最近”查看最近播放列表的歌單,或者返回主界面。
(4)在主界面(榜單列表)中點擊榜單列表中的榜單(包括我喜歡列表),可以查看榜單中的歌曲,如有想要播放的歌曲可以點擊歌曲播放,或者返回主界面。
(5)在主界面(榜單列表)中點擊“搜索”,可以在編輯欄輸入想要搜索的歌手、歌名、專輯等,查詢后出現相關歌單列表,選擇可以播放歌曲。同時,會顯示搜索歷史,點擊可以繼續搜索以前的記錄,或刪除歷史記錄,或清空所有歷史,否則選擇返回主界面。
(6)在播放界面中,滑動可查看歌詞,拖動進度條可拖動播放,點擊暫停或播放、上一首、下一首控制播放,點擊“模式”可實現隨機播放、順序播放、單曲循環,也可查看播放列表。點擊“操作”可以添加我喜歡聲音控制,或者選擇關閉。
三、音樂播放器的實現
1、功能實現
1.1 獲取QQ音樂數據
1.2 搜索功能
private void searchMusic() {musicList.clear();musicAdapter.notifyDataSetChanged();mPresenter.getData(toolbar.getText());dbHelper.insertData(toolbar.getText());historyAdapter.setList(dbHelper.queryData());layoutHistory.setVisibility(View.GONE);rvMusic.setVisibility(View.VISIBLE); }1.3 桌面組件
@Override public void onEnabled(Context context) {super.onEnabled(context);Log.d(TAG, "onEnabled: ");//第一個被添加 }@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {super.onUpdate(context, appWidgetManager, appWidgetIds);Log.d(TAG, "onUpdate: ");RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.music_widget);views.setImageViewResource(R.id.mw_albumimg, R.drawable.pic_launcher);views.setTextViewText(R.id.mw_text, "選擇一首音樂");views.setProgressBar(R.id.mw_progress, 100, 0, false);views.setOnClickPendingIntent(R.id.mw_layout, startActivity(context));views.setOnClickPendingIntent(R.id.mw_play, sendBrocast(context, ACTION_WIDGET_PLAY));views.setOnClickPendingIntent(R.id.mw_previous, sendBrocast(context, ACTION_WIDGET_PREVIOUS));views.setOnClickPendingIntent(R.id.mw_next, sendBrocast(context, ACTION_WIDGET_NEXT));appWidgetManager.updateAppWidget(appWidgetIds, views); }@Override public void onDisabled(Context context) {super.onDisabled(context);Log.d(TAG, "onDisabled: ");//最后一個被移除 }@Override public void onReceive(Context context, Intent intent) {super.onReceive(context, intent);Log.d(TAG, "onReceive: " + intent.getAction());if (MusicPlayerUtils.isMusicPlayer()) {MyMusicPlayerView mPlayerView = (MyMusicPlayerView) XXPlayerManager.instance().getCurrentPlayer();switch (intent.getAction()) {case ACTION_WIDGET_UPDATE:updatePlayer(context, mPlayerView);break;case ACTION_WIDGET_PLAY:if (mPlayerView.isIdle()) {mPlayerView.start();} else if (mPlayerView.isPlaying() || mPlayerView.isBufferingPlaying()) {mPlayerView.pause();} else if (mPlayerView.isPaused() || mPlayerView.isBufferingPaused() ||mPlayerView.isCompleted() || mPlayerView.isError()) {mPlayerView.restart();}break;case ACTION_WIDGET_PREVIOUS:mPlayerView.playNext(false);break;case ACTION_WIDGET_NEXT:mPlayerView.playNext(true);break;}} else {switch (intent.getAction()) {case ACTION_WIDGET_PLAY:case ACTION_WIDGET_PREVIOUS:case ACTION_WIDGET_NEXT:Toast.makeText(context, "選擇一首音樂", Toast.LENGTH_SHORT).show();break;}} }1.4 通知欄
//更新通知欄 private void updateViews(RemoteViews views) {Log.d(TAG, "updateViews: " + isPlaying);if (isPlaying) {notification.contentView = views;notificationManager.notify(NOTIFICATION_ID, notification);Intent intent = new Intent(this, MusicWidgetProvider.class);intent.setAction(MusicWidgetProvider.ACTION_WIDGET_UPDATE);sendBroadcast(intent);} } //創建通知欄 private Notification createNotification() {Notification.Builder builder;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0要通過NotificationChannel顯示通知NotificationChannel channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_HIGH);channel.enableLights(false);channel.enableVibration(false);channel.setVibrationPattern(new long[]{0});channel.setSound(null, null);notificationManager.createNotificationChannel(channel);builder = new Notification.Builder(this, channel.getId());} else {builder = new Notification.Builder(this);}Notification notification = builder.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(getResources().getString(R.string.app_name)).setContentIntent(startActivity()).build();return notification; }1.5 播放欄的暫停、播放、切歌、播放模式
public void onClick(View v) {switch (v.getId()) {case R.id.tv_music:if (TextUtils.isEmpty(mPlayerView.getUrl())) {((BaseActivity) getContext()).showToast("選擇一首音樂");} else {enterFullScreen();}break;case R.id.iv_musiclist:if (TextUtils.isEmpty(mPlayerView.getUrl())) {((BaseActivity) getContext()).showToast("選擇一首音樂");} else {showListDialog();}break;case R.id.ppv_music:if (TextUtils.isEmpty(mPlayerView.getUrl())) {((BaseActivity) getContext()).showToast("選擇一首音樂");break;}if (mPlayerView.isIdle()) {mPlayerView.start();ppv_music.play();} else if (mPlayerView.isPlaying() || mPlayerView.isBufferingPlaying()) {mPlayerView.pause();ppv_music.pause();} else if (mPlayerView.isPaused() || mPlayerView.isBufferingPaused() ||mPlayerView.isCompleted() || mPlayerView.isError()) {mPlayerView.restart();ppv_music.play();}break;case R.id.ppv_play:if (mPlayerView.isIdle()) {mPlayerView.start();ppv_play.play();} else if (mPlayerView.isPlaying() || mPlayerView.isBufferingPlaying()) {mPlayerView.pause();ppv_play.pause();} else if (mPlayerView.isPaused() || mPlayerView.isBufferingPaused() ||mPlayerView.isCompleted() || mPlayerView.isError()) {mPlayerView.restart();ppv_play.play();}break;case R.id.iv_mode:if (mPlayerView.getPlayMode() == BasePlayerView.PLAY_MODE_LIST_LOOP) {//列表循環iv_mode.setImageResource(R.drawable.ic_singleloop);mPlayerView.setPlayMode(BasePlayerView.PLAY_MODE_LOOP);ShareUtils.setMusicMode(getContext(), BasePlayerView.PLAY_MODE_LOOP);((BaseActivity) getContext()).showToast("切換到單曲循環");} else if (mPlayerView.getPlayMode() == BasePlayerView.PLAY_MODE_LOOP) {//單曲循環iv_mode.setImageResource(R.drawable.ic_random);mPlayerView.setPlayMode(BasePlayerView.PLAY_MODE_RANDOM);ShareUtils.setMusicMode(getContext(), BasePlayerView.PLAY_MODE_RANDOM);((BaseActivity) getContext()).showToast("切換到隨機播放");} else if (mPlayerView.getPlayMode() == BasePlayerView.PLAY_MODE_RANDOM) {//隨機播放iv_mode.setImageResource(R.drawable.ic_listloop);mPlayerView.setPlayMode(BasePlayerView.PLAY_MODE_LIST_LOOP);ShareUtils.setMusicMode(getContext(), BasePlayerView.PLAY_MODE_LIST_LOOP);((BaseActivity) getContext()).showToast("切換到順序播放");}break;case R.id.iv_list:showListDialog();break;case R.id.iv_previous:mPlayerView.playNext(false);break;case R.id.iv_next:mPlayerView.playNext(true);break;} }2、界面實現
(1)榜單列表主界面由SimpleToolbar,SlidingTabLayout,ViewPager,MusicView四種組件組成,界面如下圖所示:
(2)用戶界面主要有RecyclerView,AppBarLayout,Toolbar,SimpleToolbar,CircleImageView,ImageView六種組件組成,界面如下圖所示:
(3)搜索界面主要有SearchToolbar,TextView,RecyclerView,FrameLayout,RecyclerView幾種組件,界面如下圖所示:
(4)播放界面主要控件ImageView,SimpleToolbar,ViewPager,TextView,SeekBar等組件組成,界面如下圖所示:
(5)播放列表的界面如下圖所示:
(6)音樂菜單的界面如下圖所示:
四、音樂播放器的演示
1、滑動或點擊榜單實現查看不同的榜單中的榜單列表,產生下圖變化。點擊其中的榜單,以點擊“我喜歡”為例,查看其中歌曲信息。
2、在主界面中點擊“我的”進入我的界面,,點擊“喜歡”后的列表,“最近播放”的列表分別如下圖所示。
3、在主頁面中點擊“搜索”進入搜索頁面,搜索“周深”出現相關的歌曲信息,輸入為空時,出現提示。刪除一項歷史記錄,清空歷史記錄分別如下圖所示。
4、在主頁或其他界面點擊播放欄的操作,點擊“播放”按鈕可以播放當前音樂,點擊“播放列表”會顯示播放列表信息。點擊整個播放欄,進入播放界面,點擊播放、暫停、下一首、上一首按鈕可實現播放控制。點擊播放模式分別彈出順序播放、循環播放、單曲循環,以隨機播放為例。點擊播放列表還是如前面一樣,滑動屏幕可以實現歌詞界面,點擊操作欄,可將當前播放歌曲添加到“我喜歡”列表,同時支持搜索歌手和專輯信息、音量控制,分別如下圖所示。
5、桌面小組件和狀態通知欄的顯示分別如下圖所示。
需要源碼的小伙伴們可以在后臺私信我。
總結
以上是生活随笔為你收集整理的Android手机开发课程设计之音乐播放器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android数据存储_SharedPr
- 下一篇: TCP拥塞控制详解