Android本地及网络音乐播放器-网络音乐的搜索(三)

当音乐播放器的本地音乐播放和音乐播放界面实现后,我们将逐渐开始网络音乐功能的拓展,本文主要将的是如何实现网络音乐的搜索以及将搜索到的结果以列表的形式展示出来,主要设计的内容包括:音乐接口的使用,添加网络请求(这里使用的是volley-下载地址,下载完将volley.jar拷到项目/libs下),处理响应返回的数据-json(相应的类在org.json包下)
网络音乐的搜索
NetFragment.java的主要代码如下:

package com.example.comfortmusic_1.fragment;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.example.comfortmusic_1.MainActivity;
import com.example.comfortmusic_1.R;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AbsListView.LayoutParams;
import android.widget.SearchView.OnQueryTextListener;

public class NetFragment extends Fragment {
    //搜索音乐接口
    public static final String CLOUD_MUSIC_API_PREFIX = "http://s.music.163.com/search/get/?";
    //搜索响应时返回的数据
    public static String getResponse;
    //将响应getResponse包装成JSONObject进行解析
    public static JSONObject jo;
    //解析出来的结果存在searchResults里并在musicList里以列表的形式展示
    public static List<Map<String, String>> searchResults = new ArrayList<Map<String, String>>();   

    private SearchView searchView;//搜索框
    ListView musicList;          //展示搜索的音乐结果
    String TAG = "NetFragment";
    Handler handler;            
    RequestQueue mQueue = null; //网络请求队列

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.netmusic, container, false);
        searchView = (SearchView)rootView.findViewById(R.id.searchView1);
        musicList = (ListView) rootView.findViewById(R.id.netmusiclist);
        mQueue = Volley.newRequestQueue(NetFragment.this.getActivity());  
        Log.d(TAG, Environment.getExternalStorageDirectory().getAbsolutePath());
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == 0) {
                    musicList.setAdapter(getAdapter());
                    Log.d(TAG,"getMusic!");
                } else if (msg.what == 1) {
                    Toast.makeText(NetFragment.this.getActivity(), "下载完成!", 300).show();
                    Log.d(TAG,"下载完成!");
                }
            }               
        };
        searchView.setOnQueryTextListener(new OnQueryTextListener() {

            @Override
            public boolean onQueryTextChange(String arg0) {
                return false;
            }

            @Override
            public boolean onQueryTextSubmit(String query) {//搜索框输入内容点击搜索调用getSong(query)方法
                Toast.makeText(NetFragment.this.getActivity(), "搜索内容为:" + query, 300).show();
                musicList.setAdapter(null);
                searchResults.clear();
                getSong(query);             
                return false;
            }

        });
        return rootView;
    }

    /**
     * 这里先将搜索内容进行UTF-8编码,再与音乐搜索接口进行拼接组成网络请求url
     * @param search
     */
    public void getSong(String search) {
        if (search.equals("")) return;
        Log.d(TAG,"connecting...");
        Toast.makeText(NetFragment.this.getActivity(), "connectURL...", 300).show();    
        String s = null;
        if (search != null) {           
                try {
                    s= URLEncoder.encode(search, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }           
        }

        final String url = CLOUD_MUSIC_API_PREFIX + "type=1&s='" + s + "'&limit=20&offset=0";  
        Log.d(TAG, "url = " + url);
        //请求类,请求返回数据response类型为String
        StringRequest stringRequest = new StringRequest(Method.GET,url,  
                new Response.Listener<String>() {  
                    @Override  
                    public void onResponse(String response) {  
                        Log.d(TAG, response); 
                        getResponse = response;          
                        showList();
                    }  
                }, new Response.ErrorListener() {  
                    @Override  
                    public void onErrorResponse(VolleyError error) {  
                        Log.e(TAG, error.getMessage(), error);  
                        Toast.makeText(NetFragment.this.getActivity(), "请检查网络连接!", 300).show();
                    }  
                }); 
        mQueue.add(stringRequest);  //请求添加到队列里
    }

    /**
     * 将String类型的响应包装成JSONObject类型进行解析
     * 其中JSONObject是{key1:value1, key2:value2, ...}形式的类似map的键值对,其中value也可以是JSONObject,即嵌套
     * JSONArray是[JSONObject, JSONObject, ...]形式的数据结构
     */
    protected  void showList() {
         Log.d(TAG, "showList");
        try {
            jo = new JSONObject(getResponse);
            String result = jo.getString("result");
            String songs = new JSONObject(result).getString("songs");
            JSONArray js = new JSONObject(result).getJSONArray("songs");
            for (int i=0; i<js.length(); i++) {
                JSONObject child = js.getJSONObject(i);
                JSONArray artists = child.getJSONArray("artists");
                String artist = artists.getJSONObject(0).getString("name");
                String name = child.getString("name");
                String audioUrl = child.getString("audio");
                JSONObject album = child.getJSONObject("album");
                String picUrl = album.getString("picUrl");

                Map<String, String> item = new HashMap<String, String>();
                item.put("name", name);
                item.put("artist", artist);
                item.put("audioUrl", audioUrl);
                item.put("picUrl", picUrl);
                searchResults.add(item);
                Log.d(TAG, "name = " + name + "---artists:" + artist);
                Log.d(TAG, "audioUrl = " + audioUrl);
                Log.d(TAG, "picUrl = " + picUrl);
            }
            handler.sendEmptyMessage(0);
            Toast.makeText(NetFragment.this.getActivity(), "下载完成!", 300).show();
        } catch (JSONException e) {
            e.printStackTrace();
        }       
    }


    //构建搜索结果列表的适配器
    private BaseAdapter getAdapter() {

        BaseAdapter adapter = new BaseAdapter() {

            @Override
            public int getCount() {
                return searchResults.size();
            }

            @Override
            public Object getItem(int position) {
                return null;
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @Override
            public View getView(int position, View view, ViewGroup parent) {
                Map<String, String> map = searchResults.get(position);
                LinearLayout line = new LinearLayout(NetFragment.this.getActivity());
                line.setOrientation(LinearLayout.HORIZONTAL);
                line.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,100));

                ImageView musicTag = new ImageView(NetFragment.this.getActivity());
                musicTag.setImageResource(R.drawable.music);
                musicTag.setLayoutParams(new LayoutParams(80,80));
                //标题格式设置
                TextView songTitle = new TextView(NetFragment.this.getActivity());
                String musicName = map.get("name");
                songTitle.setWidth(MainActivity.screenWidth/2);
                songTitle.setHeight(100);
                songTitle.setMaxLines(1);
                songTitle.setTextColor(Color.MAGENTA);
                songTitle.setTextSize(18);
                songTitle.setText(musicName);
                songTitle.setGravity(TextView.TEXT_ALIGNMENT_CENTER);               
                songTitle.setGravity(Gravity.CENTER_VERTICAL);
                //艺术家格式设置
                TextView artist = new TextView(NetFragment.this.getActivity());
                artist.setGravity(TextView.TEXT_ALIGNMENT_CENTER);
                artist.setWidth(MainActivity.screenWidth/3);
                artist.setHeight(100);
                artist.setTextColor(Color.MAGENTA);
                artist.setText(map.get("artist"));
                artist.setTextSize(15);
                artist.setMaxLines(1);
                artist.setPadding(50, 0, 0, 10);
                artist.setGravity(Gravity.RIGHT);
                //下载图标
                ImageView download = new ImageView(NetFragment.this.getActivity());
                download.setImageResource(R.drawable.downloaded_music);
                download.setLayoutParams(new LayoutParams(70,80));
                download.setPaddingRelative(10, 0, 0, 0);

                line.addView(musicTag);
                line.addView(songTitle);
                line.addView(artist);
                line.addView(download);


                return line;
            }};
        return adapter;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

}

该功能实现的核心在于对网络响应返回的json数据的解析-(另为了便于理解解析json数据过程,附上一段json数据格式的response,结合showList()看更容易理解)

{"result":{"songCount":463,"songs":[
{"id":65126,
 "name":"红玫瑰",
 "artists":[{"id":2116,"name":"陈奕迅","picUrl":null}],
 "album":{"id":6404,"name":"1997-2007 跨世纪国语精选",
 "artist":{"id":0,"name":"","picUrl":null},"picUrl":"http://p1.music.126.net/WJgLE2ImnLgqPPLQSlF7iQ==/114349209289440.jpg"},
 "audio":"http://m2.music.126.net/J_dEE5O0YuytnLWoFHsYCw==/8002245628486539.mp3",
 "djProgramId":0,"page":"http://music.163.com/m/song/65126"},
{"id":420513158,
 "name":"红蔷薇白玫瑰",
 "artists":[{"id":7763,"name":"G.E.M.邓紫棋","picUrl":null}],
 "album":{"id":34767677,"name":"红蔷薇白玫瑰",
 "artist":{"id":0,"name":"","picUrl":null},
 "picUrl":"http://p1.music.126.net/ExDuzcVK5vkMNpPpzmFX6Q==/3446968958754370.jpg"},
 "audio":"http://m2.music.126.net/HrWiNyX5yRroNh4QCcJy4A==/3413983618586421.mp3",
 "djProgramId":0,"page":"http://music.163.com/m/song/420513158"},
{"id":65533,
 "name":"红玫瑰",
 "artists":[{"id":2116,"name":"陈奕迅","picUrl":null}],
 "album":{"id":6434,"name":"认了吧",
 "artist":{"id":0,"name":"","picUrl":null},
 "picUrl":"http://p1.music.126.net/obu1uFbrm9EjrVpqaaKQvw==/90159953489756.jpg"},
 "audio":"http://m2.music.126.net/eeSo9acw4OUaGtqnOpV2hA==/3273246115947004.mp3",
 "djProgramId":0,"page":"http://music.163.com/m/song/65533"},......] }

Android本地及网络音乐播放器源码下载

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要读取SD卡中的歌曲,你需要先获取读取SD卡的权限,可以通过在AndroidManifest.xml文件中添加如下代码实现: ``` <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ``` 然后,你可以使用MediaStore类来获取SD卡中的音乐文件,如下所示: ```java String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0"; String[] projection = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DURATION }; Cursor cursor = getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null, null); if (cursor != null) { while (cursor.moveToNext()) { // 获取音乐文件的相关信息 long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID)); String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)); String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); String displayName = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)); long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); // 在这里处理获取到的音乐文件信息 } cursor.close(); } ``` 上述代码中,我们先定义了一个查询条件 selection,然后在 projection 数组中指定我们需要获取的音乐文件信息,接着通过 getContentResolver().query() 方法查询 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,获取到 Cursor 对象,最后通过 Cursor 对象遍历获取到的音乐文件信息。 需要注意的是,获取到的音乐文件的路径存储在 DATA 列中,我们可以通过这个路径来播放音乐。同时,还需要给应用程序授予读取SD卡的权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值