基於android的網路音樂播放器-回撥實現音樂播放及音樂收藏的實現(三)
作為android初學者,最近把瘋狂android講義和瘋狂Java講義看了一遍,看到書中介紹的知識點非常多,很難全部記住,為了更好的掌握基礎知識點,我將開發一個網路音樂播放器-EasyMusic來鞏固下,也當作是練練手。感興趣的朋友可以看看,有設計不足的地方也歡迎指出。
開發之前首先介紹下該音樂播放器將要開發的功能(需求):
1.本地音樂的載入和播放;
2.網路音樂的搜尋,試聽和下載;
3.音樂的斷點下載;
4.點選播放圖示載入專輯圖片,點選歌詞載入歌詞並滾動顯示(支援滑動歌詞改變音樂播放進度);
5.支援基於popupWindow的彈出式選單;
6.支援後臺工作列顯示和控制。
該篇主要介紹音樂的回撥播放及收藏音樂的實現,其中音樂的收藏需要用到SQLite資料庫:
1.回撥監聽實現音樂的點選播放
該部分對MusicListFragment 的主要修改如下
public class MusicListFragment extends Fragment {
......
private CallBack mCallBack;
.....
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.musiclist, container, false );
musicListView = (ListView)view.findViewById(R.id.musicList);
musicListView.setAdapter(musicListAdapter);
musicListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//mCallBack指向MainActivity,實際呼叫的是MainActivity的onItemSelected方法
mCallBack.onItemSelected((String)dbMusic.get(position).get("url"));
TextView title = (TextView)view.findViewWithTag("title");
Toast.makeText(mContext, "title = " + title.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
return view;
}
/**
* 回撥介面指向MainActivity,因為MainActivity實現了CallBack介面,所有這裡用到了多型-父類引用指向子類物件,然後在該Fragment中可
* 通過mCallBack呼叫MainActivity播放音樂的方法
*/
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallBack = (CallBack)activity;
}
public interface CallBack {
public void onItemSelected(String url);
}
}
MainActivity還需要實現MusicListFragment的內部介面CallBack,這樣當點選音樂列表時即可呼叫MainActivity的onItemSelected方法,實現音樂的播放,MainActivity的調整如下:
public class MainActivity extends FragmentActivity implements MusicListFragment.CallBack, View.OnClickListener {
......
@Override
public void onItemSelected(String url) {
playMusic(url);
}
}
2.音樂收藏的實現
這裡設計的收藏思路為:點選音樂後端的五角星實現五角星的點亮和熄滅,分別對應收藏和取消收藏,收藏任務的執行使用非同步任務,非同步任務定義為MusicListFragment的內部類,其定義如下:
//執行收藏音樂/取消收藏的非同步任務
private class MyAsyncTask extends AsyncTask<String, Void, Void> {
private ImageView starView;
private Map<String, Object> musicInfo;
private boolean storeSuccess;
public MyAsyncTask(ImageView starView, Map<String, Object> musicInfo) {
this.starView = starView;
this.musicInfo = musicInfo;
}
protected void onPreExecute() {
super.onPreExecute();
}
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
protected Void doInBackground(String... params) {
Log.d(TAG, "doInBackground");
Cursor cursor = myHelper.getReadableDatabase().rawQuery("select * from stored_music", null);
while (cursor.moveToNext()) {
String title = cursor.getString(1);
String artist = cursor.getString(2);
Log.d(TAG, "title = " + title + " artist = " + artist);
Log.d(TAG, "musicInfo.title = "+(String)musicInfo.get("title")+ " musicInfo.artist = "+(String)musicInfo.get("artist"));
if (title.equals((String)musicInfo.get("title")) && artist.equals((String)musicInfo.get("artist"))) {
//已經收藏的音樂取消收藏並移出收藏音樂表格-stored_music
myHelper.getReadableDatabase().execSQL("delete from stored_Music where title like ? and artist like ?",
new String[] {title, artist});
storeSuccess = false;
return null;
}
}
//未收藏的音樂加入到收藏中
myHelper.getReadableDatabase().execSQL("insert into stored_music values(null, ?, ?, ?, ?)",
new Object[] {musicInfo.get("title"),musicInfo.get("artist"),musicInfo.get("duration"),musicInfo.get("url")});
storeSuccess = true;
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (storeSuccess) {
starView.setImageResource(android.R.drawable.btn_star_big_on);
Toast.makeText(mContext, "收藏成功", 100).show();
} else {
starView.setImageResource(android.R.drawable.btn_star_big_off);
Toast.makeText(mContext, "取消收藏", 100).show();
}
}
當點選音樂的收藏圖示-五角星時即可開啟一個非同步任務,當非同步任務執行即為相應的收藏資料庫音樂資訊的增加和刪除,執行完成完成後再點亮/熄滅五角星。另外,我們音樂收藏資料庫的定義如下:
package com.sprd.easymusic.mysql;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDBHelper extends SQLiteOpenHelper {
//收藏音樂的資料表
private final String CREATE_TABLE_LOCALMUSIC = "create table stored_music(" +
"_id integer primary key autoincrement,title,artist,duration,url)";
public MyDBHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_LOCALMUSIC);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
非同步任務的啟動源於收藏圖示的監聽:
// 音樂列表介面卡
private BaseAdapter musicListAdapter = new BaseAdapter() {
@Override
public int getCount() {
return dbMusic.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
Map<String, Object> item = dbMusic.get(position);
if (convertView == null) {
view = inflater.inflate(R.layout.musiclist_item, null);
}
final ImageView storeMusic = (ImageView) view.findViewById(R.id.love);
if (checkIfStored((String) item.get("url"))) {
storeMusic.setImageResource(android.R.drawable.btn_star_big_on);
} else {
storeMusic.setImageResource(android.R.drawable.btn_star_big_off);
}
//收藏或取消收藏的監聽
storeMusic.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
new MyAsyncTask(storeMusic, dbMusic.get(position)).execute();
}
});
TextView musicTitle = (TextView) view.findViewById(R.id.musicTitle);
musicTitle.setTag("title");
TextView musicArtist = (TextView) view.findViewById(R.id.musicArtist);
musicTitle.setText((String) item.get("title"));
musicArtist.setText((String) item.get("artist"));
return view;
}
};
音樂收藏的關鍵程式碼就如上面所述,其他就不多講了。當然在進入音樂列表的時候需要查詢當前音樂是否被收藏了,是的話就需要點亮收藏圖示,加上一個判斷即可,上面程式碼中的checkIfStored((String) item.get(“url”))方法就是進行該判斷的。
好了,該篇先講這麼多了,後面一篇我將把這些主要類的程式碼都貼上並附上效果圖供大家參考。
相關推薦
基於android的網路音樂播放器-回撥實現音樂播放及音樂收藏的實現(三)
作為android初學者,最近把瘋狂android講義和瘋狂Java講義看了一遍,看到書中介紹的知識點非常多,很難全部記住,為了更好的掌握基礎知識點,我將開發一個網路音樂播放器-EasyMusic來鞏固下,也當作是練練手。感興趣的朋友可以看看,有設計不足的地方也
回撥方法、模板方法模式、鉤子(hook)區分
其實這三者之間沒什麼可區分的,因為他們是不同領域的概念。但是他們非常相似都是在抽象的定義了方法,然後子類實現它。他們都是java多型特性的實踐。 概念領域區分: 1.正確的說應該就是模板方法模式,模板方法模式提供模板方法,這個方法是一個模板演算法,或者說在方
【Android】從無到有:手把手一步步教你使用最簡單的Fragment(三)
轉載請註明出處,原文連結:https://blog.csdn.net/u013642500/article/details/80585416 【本文適用讀者】 用程式碼建立並使用了 Fragment,新增 Fragment 之
Android進階——效能優化之程序拉活原理及手段完全解析(二)
引言 上一篇文章Android進階——效能優化之程序保活原理及手段完全解析(一)總結了Android程序和執行緒的相關知識,主要介紹了幾種提升程序優先順序的手段,通常僅僅是提高優先順序只能讓你的程序存活時間久一點,但是真正的被殺死之後就不會自動拉活的,如果你的程
基於RISC-V架構的開源處理器及SoC研究綜述(三)
3 基於RISC-V的開源SoC研究現狀 3.1 Rocket-Chip UCB為了方便使用者學習,同時也為了便於重複使用已設計好的硬體模組,在GitHub上建立了Rocket-Chip Generator的專案,其中包括了Chisel、GCC、Rocket處理器,以及
Vim編輯器與Shell命令指令碼---Linux就該這麼學(三)
Vim編輯器與Shell命令指令碼—Linux就該這麼學(三) 學習總覽 Vim文字編輯器 編寫Shell指令碼 流程控制語句 計劃任務服務程式 Vim文字編輯器 Vim的三種模式 命令模式:控制游標,增強對文字的複製、貼上、刪除和查詢功能。 編輯
基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(三)
## 系列文章 1. **[基於 abp vNext 和 .NET Core 開發部落格專案 - 使用 abp cli 搭建專案](https://www.cnblogs.com/meowv/p/12896177.html)** 2. **[基於 abp vNext 和 .NET Core 開發部落格專案
基於QT的網路音樂播放器(三)
得到AlbumID和FileHash後訪問http://www.kugou.com/yy/index.php?r=play/getdata&hash= &album_id= &_=1497972864535 其中hash後面跟的就是前面
Android RxJava 實戰系列:優雅實現 網路請求巢狀回撥
轉自-----http://blog.csdn.net/carson_ho/article/details/78315696,請為大神打call 前言 Rxjava,由於其基於事件流的鏈式呼叫、邏輯簡潔 & 使用簡單的特點,深受各大 Android
Android RxJava操作符的學習---變換操作符---網路請求巢狀回撥
變換操作符的主要開發需求場景 = 巢狀回撥(Callback hell) 下面,我將採用一個實際應用場景例項來講解巢狀回撥(Callback hell) 1. 需求場景 1.1 背景 需要進行巢狀網路請求:即在第1個網路請求成功後,繼續再進行一次網路請求 如
Android 視訊播放器 VideoView 的使用,播放本地視訊 和 網路視訊
轉自:https://www.cnblogs.com/zhaoyanjun/p/5412984.html1、佈局檔案<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="ht
android網路圖片檢視器
package com.itheima74.internetpicturelook; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; impo
Rxjava解決android的請求介面的回撥地獄
Consumer consumer1 = new Consumer<HttpResult<List<User>>>() { @Override public void accept(HttpResult<List&
android.database.ContentObserver#onChange(boolean, android.net.Uri) 多次回撥的妥協處理方案
android.database.ContentObserver#onChange(boolean, android.net.Uri) 在呼叫資料庫監聽的方法的時候發現,該方法會被多次觸發。比如,只是
Uncaught ReferenceError: jp2 is not defined,用jsonp抓取qq音樂總是說回撥函式沒有定義
問題如下參考連結:https://segmentfault.com/q/1010000010051040 用jsonp抓取qq音樂總是說回撥函式沒有定義, 我的要實現時候的步驟 1。第一步 我要實現的目的 問題:如題 我的部分程式碼: import originJSON
[Android]RecyclerView基本使用+adapter回撥介面實現點選事件
一、概述 RrcyclerView是ListView的加強版,不僅可以輕鬆實現和ListView同樣的效果,還優化了ListView中存在的各種不同之處。 Android官方推薦我們使用RecyclerView。 二、基本用法 1.首先需要在專案的build.gradle中新增相
MFC 基於VLC的視訊播放器(三)---介面設計以及對話方塊接受檔案的拖拽
北京時間23點11分 2018年12月20日 前面已經完成了vlc的環境的搭建,下面便開始真正的程式設計。 前面的介面是這樣的: 理想的介面應該是這樣的: 所以新增按鈕、進度條和播放列表控制元件,並且修改好ID。 介面設計完成,執行,還是隻是一個空殼,因為沒加任
Android 視頻播放器 VideoView 的使用,播放本地視頻 和 網絡 視頻(轉載)
reat listen 效果 sch span show dma import str 1、布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http:/
Android http請求使用介面回撥
Android中不支援在主執行緒發起http請求資料,我們需要把http請求放到子執行緒中處理。為了保證程式碼的執行順序,可以使用介面回撥的方式拿到請求到的資料並進行處理。 定義回撥介面 public interface OnConnectResult
基於FFmpeg的視訊播放器開發系列教程(三)
本篇開始講解音訊解碼播放,該專案用Qt的音訊類QAudioFormat, QAudioOutput等進行解碼,先講解一些關於音訊的知識。 1.取樣頻率 指每秒鐘取得聲音樣本的次數。取樣的過程就是抽取某點的頻率值,很顯然,在一秒中內抽取的點越多,獲取得頻率資