1. 程式人生 > >【達內課程】音樂播放器4.0(播放準備)

【達內課程】音樂播放器4.0(播放準備)

這一節我們需要實現播放歌曲的功能。想要實現播放歌曲,需要得到歌曲的url地址。由於上一節的介面中我們得到的歌曲列表中並沒有歌曲地址,所以我們需要根據song_id再次傳送請求,獲取歌曲url
百度音樂api介面

流程如下
在這裡插入圖片描述

NewMusicListFragment
中給listview新增點選事件

public class NewMusicListFragment extends Fragment {
    private ListView listView;
    private MusicAdapter adapter;
    private List<Music> musics;
    private MusicModel model = new MusicModel();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_music_list,null);

        setViews(view);
        setListeners();
        ......
        return view;
    }

    private void setListeners() {
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                final Music music = musics.get(i);
                String songId = music.getSong_id();
                Toast.makeText(getActivity(),"position:"+i,Toast.LENGTH_SHORT).show();
                //執行業務層 載入這首歌曲的基本資訊
                model.loadMusicInfoBySongId(songId, new MusicInfoCallback() {
                    @Override
                    public void onMusicInfoLoaded(Songinfo songinfo, BitrateModel bitrateModel) {
                        music.setSonginfo(songinfo);
                        music.setBitrate(bitrateModel);
                        //準備通過url地址執行播放業務
                    }
                });
            }
        });
    }

    ......
}

MusicModel
中增加根據songid獲取歌其他資訊的方法

public class MusicModel {

    /**
     * 根據songid非同步記載這首歌的其他資訊
     * @param songid
     * @param callback
     */
    public void loadMusicInfoBySongId(final String songid, final MusicInfoCallback callback){
        AsyncTask<String,String,Music> task = new AsyncTask<String, String, Music>() {
            //工作執行緒中傳送請求 獲取基本資訊
            @Override
            protected Music doInBackground(String... strings) {
                String url = UrlFactory.getSongInfoUrl(songid);
                try {
                    InputStream is = HttpUtils.getInputStream(url);
                    String json = HttpUtils.isToString(is);
                    Log.d("info",json);

                    JSONObject object = new JSONObject(json);
                    JSONObject songInfo = object.getJSONObject("songinfo");
                    JSONObject bitrate = object.getJSONObject("bitrate");

                    Songinfo songinfoModel = JSONParser.parseSongInfo(songInfo);
                    BitrateModel bitrateModel = JSONParser.parseBitrate(bitrate);

                    Music music = new Music();
                    music.setSonginfo(songinfoModel);
                    music.setBitrate(bitrateModel);
                    //把music交給onPostExecute
                    return music;
                } catch (IOException e) {
                    e.printStackTrace();
                }catch (JSONException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onPostExecute(Music music) {
                if(music == null){
                    callback.onMusicInfoLoaded(null,null);
                }else {
                    //從上面傳來的music
                    callback.onMusicInfoLoaded(music.getSonginfo(),music.getBitrate());
                }
            }
        };
        task.execute();
    }
	......
}

MusicInfoCallback

/**
 * 音樂資料相關的回撥介面
 */
public interface MusicInfoCallback {
    /**
     * 當音樂資訊載入完成將會執行該方法
     */
    void onMusicInfoLoaded(Songinfo songinfo,BitrateModel bitrateModel);
}

根據介面返回的json,需要再Model模型中增加

**
 * 封裝一首歌的資訊
 */
public class Music {
   ......
    private Songinfo songinfo;
    private BitrateModel bitrate;

    public Music() { ;
    }

    ......
    public Songinfo getSonginfo() {
        return songinfo;
    }

    public void setSonginfo(Songinfo songinfo) {
        this.songinfo = songinfo;
    }

    public BitrateModel getBitrate() {
        return bitrate;
    }

    public void setBitrate(BitrateModel bitrate) {
        this.bitrate = bitrate;
    }


    @Override
    public String toString() {
        return this.title;
    }
}

根據介面返回資料建立BitrateModel

public class BitrateModel {
    private String show_link;//"http://zhangmenshiting.qianqian.com/data2/music/45bddc070feaeb4e690da721bf92a938/604682956/604682956.mp3?xcode=9ecab6d33c85c56ddcd0b1435228577d",
    private String free;//1,
    private String song_file_id;//604682956,
    private String file_size;//3857267,
    private String file_extension;//"mp3",
    private String file_duration;//240,
    private String file_bitrate;//128,
    private String file_link;//"http://zhangmenshiting.qianqian.com/data2/music/45bddc070feaeb4e690da721bf92a938/604682956/604682956.mp3?xcode=9ecab6d33c85c56ddcd0b1435228577d",
    private String hash;
    
    ......
	省略各種set、get方法
}

根據介面返回資料建立SongInfo

public class Songinfo {
    public String pic_huge;// "http://qukufile2.qianqian.com/data2/pic/920b3f0596b54f54a3c5575aabefe2b8/604682905/[email protected]_1,w_1000,h_1000",
    public String pic_premium;// "http://qukufile2.qianqian.com/data2/pic/920b3f0596b54f54a3c5575aabefe2b8/604682905/[email protected]_1,w_500,h_500",
    public String author;// "李劍青",
    public String song_id;// "604682907",
    public String title;// "找到你(電影《找到你》同名主題曲)",
    public String artist_id;// "107692473",
    public String lrclink;// "http://qukufile2.qianqian.com/data2/lrc/f1a7467936a4cff1c7c52483a741d4ce/605187388/605187388.lrc",
    public String pic_big;// "http://qukufile2.qianqian.com/data2/pic/920b3f0596b54f54a3c5575aabefe2b8/604682905/[email protected]_1,w_150,h_150",
    public String album_id;// "604682904",
    public String pic_radio;// "http://qukufile2.qianqian.com/data2/pic/920b3f0596b54f54a3c5575aabefe2b8/604682905/[email protected]_1,w_300,h_300",
    public String album_title;// "找到你(電影《找到你》同名主題曲)",
    public String pic_small;

	......
	省略各種set、get方法
}

UrlFactory增加

    /**
     * 新歌榜url地址
     * @param offSet
     * @param size
     * @return  xml格式字串
     */
    public static String getNewMusicListUrl(int offSet,int size){
        String url = "http://tingapi.ting.baidu.com/v1/restserver/ting?format=xml&calback=&from=webapp_music&method=baidu.ting.billboard.billList&type=1&size="+size+"&offset="+offSet;
        return url;
    }

JSONParser
來解析資料

public class JSONParser {

    public static Songinfo parseSongInfo(JSONObject songInfo) throws JSONException {
        Songinfo songinfoModel = new Songinfo(
                songInfo.getString("pic_huge") ,
                songInfo.getString("pic_premium") ,
                songInfo.getString("author") ,
                songInfo.getString("song_id") ,
                songInfo.getString("title") ,
                songInfo.getString("artist_id") ,
                songInfo.getString("lrclink") ,
                songInfo.getString("pic_big") ,
                songInfo.getString("album_id") ,
                songInfo.getString("pic_radio") ,
                songInfo.getString("album_title") ,
                songInfo.getString("pic_small")
                );
        return songinfoModel;
    }

    public static BitrateModel parseBitrate(JSONObject bitrate) throws JSONException {
        BitrateModel bitrateModel = new BitrateModel(
                bitrate.getString("show_link") ,
                bitrate.getString("free") ,
                bitrate.getString("song_file_id") ,
                bitrate.getString("file_size") ,
                bitrate.getString("file_extension") ,
                bitrate.getString("file_duration") ,
                bitrate.getString("file_bitrate") ,
                bitrate.getString("file_link") ,
                bitrate.getString("hash")
        );
        return bitrateModel;
    }
}

下一節中根據url來實現播放