【项目案例】-音乐播放器-Android前端实现-Java后端实现

news2024/11/23 19:20:34

精品专题:

01.C语言从不挂科到高绩点

https://blog.csdn.net/yueyehuguang/category_12753294.html?spm=1001.2014.3001.5482icon-default.png?t=O83Ahttps://blog.csdn.net/yueyehuguang/category_12753294.html?spm=1001.2014.3001.5482

02. SpringBoot详细教程

https://blog.csdn.net/yueyehuguang/category_12789841.html?spm=1001.2014.3001.5482icon-default.png?t=O83Ahttps://blog.csdn.net/yueyehuguang/category_12789841.html?spm=1001.2014.3001.548203.SpringBoot电脑商城项目

https://blog.csdn.net/yueyehuguang/category_12752883.html?spm=1001.2014.3001.5482icon-default.png?t=O83Ahttps://blog.csdn.net/yueyehuguang/category_12752883.html?spm=1001.2014.3001.548204.VUE3.0 核心教程

https://blog.csdn.net/yueyehuguang/category_12769996.html?spm=1001.2014.3001.5482icon-default.png?t=O83Ahttps://blog.csdn.net/yueyehuguang/category_12769996.html?spm=1001.2014.3001.5482

================================

||   持续分享系列教程,关注一下不迷路  ||

||   视频教程:小破站:墨轩大楼             ||

================================

🌳 查询音乐列表功能

🌾 后端查询列表功能

🍄 数据库sql语句
/*
Navicat MySQL Data Transfer

Source Server         : hui
Source Server Version : 50525
Source Host           : localhost:3306
Source Database       : music

Target Server Type    : MYSQL
Target Server Version : 50525
File Encoding         : 65001

Date: 2023-09-07 00:34:12
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `music`
-- ----------------------------
DROP TABLE IF EXISTS `music`;
CREATE TABLE `music` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `pic` varchar(255) DEFAULT NULL,
  `author` varchar(255) DEFAULT NULL,
  `location` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of music
-- ----------------------------
INSERT INTO `music` VALUES ('1', '听说爱情回来过', null, '蔡依林', 'music/听说爱情回来过 - 蔡依林.mp3');
INSERT INTO `music` VALUES ('2', '天外来物', null, '薛之谦', 'music/天外来物 - 薛之谦.mp3');
INSERT INTO `music` VALUES ('3', '药水歌', null, '药水哥', 'music/药水歌 - 药水哥.mp3');
🍄 添加数据库驱动依赖

访问Mysql数据库,需要用到Mysql的驱动,我们在Pom.xml中添加数据库的依赖,代码如下:

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.46</version>
</dependency>
🍄 数据库操作工具类

在项目的util包中添加DBUtil类,该类用来访问mysql数据,具体代码如下:

package com.softeem.webService.util;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 操作数据库的工具类  -》  Mybatis 的原理
 */
public class DBUtils {
    private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
    /** url��ַ  192.168.32.125 **/
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/music?useUnicode=true&characterEncoding=utf8";
    private static final String USER = "root";
    private static final String PASSWORD = "123456";

    static {
        try {
            Class.forName(DRIVER_CLASS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
	 * 链接数据库的方法
	 */
    public static Connection getConn() {
        try {
            return DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
	 * 数据库更新的工具方法
	 * @param sql   需要执行的sql语句
	 * @param params  执行sql语句需要的参数
	 * @return
	 * @throws SQLException
	 */
    public static boolean exeUpdate(String sql,Object ...params) throws SQLException {
        //获取数据库链接
        Connection conn = getConn();
        //预编译sql语句
        PreparedStatement ps = conn.prepareStatement(sql);
        //配置sql语句中的问号
        for(int i = 0;i<params.length;i++) {
            ps.setObject(i+1, params[i]);
        }
        //执行sql语句
        int i = ps.executeUpdate();
        //关闭数据库链接
        ps.close();
        conn.close();
        //返回执行结果
        return i > 0 ? true : false;
    }

    /**
	 * 查询多条数据的工具方法
	 * @param t
	 * @param sql
	 * @param params
	 * @param <T>
	 * @return
	 */
    public static <T> List<T> queryList(Class<T> t, String sql, Object... params) {
        List<T> list = new ArrayList<>();
        T obj = null;
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            conn = getConn();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            Map<String, Object> map = new HashMap<>();
            while (rs.next()) {
                map.clear();
                for (int i = 0; i < rsmd.getColumnCount(); i++) {
                    String cname = rsmd.getColumnLabel(i + 1);
                    Object value = rs.getObject(cname);
                    map.put(cname, value);
                }
                if (!map.isEmpty()) {
                    Set<String> columnNames = map.keySet();
                    obj = t.newInstance();
                    for (String column : columnNames) {
                        Object value = map.get(column);
                        if(Objects.nonNull(value)){	
                            Field f = t.getDeclaredField(column);
                            f.setAccessible(true);
                            f.set(obj, value);
                        }
                    }
                    list.add(obj);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
            return list;
        }

            /**
            * 查询单条数据的工具方法
            * @param t
            * @param sql
            * @param params
            * @param <T>
            * @return
            */
            public static <T> T queryOne(Class<T> t, String sql, Object... params) {
            T obj = null;
            Connection conn = null;
            PreparedStatement ps = null;
            try {
            conn = getConn();
            ps = conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
            ps.setObject(i + 1, params[i]);
        }
            ResultSet rs = ps.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            if (rs.next()) {
            obj = t.newInstance();
            for (int i = 0; i < rsmd.getColumnCount(); i++) {
            String cname = rsmd.getColumnLabel(i + 1);
            Object value = rs.getObject(cname);
            if(Objects.nonNull(value)){						
            Field field = t.getDeclaredField(cname);
            field.setAccessible(true);
            field.set(obj, value);
        }
        }
        }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
            return obj;
        }


        }
🍄添加实体类

在项目中添加Music类,其中的属性与数据库中的music表字段对应,用来暂存从数据库中查询出来的音乐数据。具体代码如下:

package com.softeem.webService.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Music {

    private int id;
    private String name;
    private String pic;
    private String author;
    private String location ;
}
🍄 编写查询音乐列表的接口

在Controller包中添加MusicListController并绑定music_list请求,当发送music_list请求时,访问service方法,去查询出所有的音乐列表,返回给客户端,具体代码如下:

package com.softeem.webService.controller;

import com.alibaba.fastjson2.JSONObject;
import com.softeem.webService.service.MusicService;
import com.softeem.webService.util.Result;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/music_list")
public class MusicListController extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码
        req.setCharacterEncoding("utf-8");
        // 设置响应编码
        resp.setContentType("text/html;charset=utf-8");
        // 创建业务端
        MusicService service = new MusicService();
        // 调用服务端获取所有的音乐
        Result result = service.getAllMusics();
        // 将音乐列表转换成json对象
        JSONObject jsonObject = JSONObject.from(result);
        // 将结果返回给客户端
        PrintWriter out = resp.getWriter();
        out.println(jsonObject);
    }
}
🍄 编写业务端,查询音乐列表

在项目中新建一个MusicService类,用来作为业务端口,负责处理有关于音乐的业务,具体代码如下:

package com.softeem.webService.service;

import com.softeem.webService.dao.MusicDao;
import com.softeem.webService.entity.Music;
import com.softeem.webService.util.Result;

import java.util.List;

public class MusicService {

    /**
     * 获取所有的音乐
     * @return
     */
    public Result getAllMusics() {
        // 创建Dao
        MusicDao dao = new MusicDao();
        // 操作数据库,查询所有的音乐列表
        List<Music> musicList = dao.findAllMusics();
        // 将查询出来的音乐列表进行封装
        return Result.success(musicList);
    }
}
🍄 操作数据库,查询音乐

在项目中新建一个MusicDao类,该类负责操作数据库中的music表,目前我们先暂时只添加一个查询所有音乐的方法,具体代码如下:

package com.softeem.webService.dao;

import com.softeem.webService.entity.Music;
import com.softeem.webService.util.DBUtils;

import java.util.List;

public class MusicDao {
    public List<Music> findAllMusics() {
        String sql = "select * from music";
        return DBUtils.queryList(Music.class,sql);
    }
}
🍄测试

编写完毕之后,启动服务器,在浏览器中输入以下地址:

http://localhost:8080/music_list

显示结果如下:

🌾 前端Android程序

🍄 编写列表布局界面

在layout文件夹中新建music_list.xml,添加ListView代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#000000">
<ListView
    android:id="@+id/music_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@drawable/category_item_bg77"
    android:gravity="center"
    />
</LinearLayout>
🍄 编写列表选项布局界面

在layout文件夹中新建music_item.xml布局文件,为列表中的每一个选项进行布局,具体代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center">

    <TextView
        android:id="@+id/num"
        android:layout_width="100px"
        android:layout_height="50dp"
        android:textSize="30px"
        android:gravity="center_vertical"
        android:textColor="#FFFFFF"
        android:singleLine="true"/>

    <TextView
        android:id="@+id/music_name"
        android:layout_width="194dp"
        android:layout_height="50dp"
        android:layout_marginLeft="30px"
        android:text="过火"
        android:textSize="30px"
        android:gravity="center_vertical"
        android:textColor="#FFFFFF"
        android:singleLine="true"
        ></TextView>

    <TextView
        android:id="@+id/music_author"
        android:layout_width="138dp"
        android:layout_height="50dp"
        android:layout_marginLeft="50px"
        android:text="张信哲"
        android:textSize="30px"
        android:gravity="center_vertical"
        android:textColor="#FFFFFF"
        android:singleLine="true"></TextView>
    <TextView
        android:id="@+id/music_id"
        android:layout_width="100px"
        android:layout_height="50dp"
        android:textSize="30px"
        android:gravity="center_vertical"
        android:textColor="#FFFFFF"
        android:singleLine="true"
        />
</LinearLayout>
🍄Music实体类:
package com.moxuan.mytest;


public class Music {
    private int id;
    private String name;
    private String pic;
    private String author;
    private String location ;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}
🍄 编写列表适配器

新建MusicListAdapter类,用来适配查询出来的音乐数据和列表布局界面,具体代码如下:

package com.moxuan.mytest;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class MusicListAdapter extends BaseAdapter {
    // 音乐列表数据源
    private List mData;
    // 声明布局服务
    private LayoutInflater mLayoutInflater;


    /**
     * 构造方法,创建适配器
     * @param context
     * @param data
     */
    public MusicListAdapter(Context context, List data){
        mData = data;
        mLayoutInflater = LayoutInflater.from(context);
    }

    /**
     * 获取列表的总条目数
     * @return
     */
    @Override
    public int getCount() {
        return mData.size();
    }

    /**
     * 获取列表中指定位置上的条目
     * @param position
     * @return
     */
    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    /**
     * 获取条目在列表中的位置
     * @param position
     * @return
     */
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 适配数据到布局文件中
     * @param position 位置
     * @param convertView 选项布局视图
     * @param parent
     * @return
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            // 获取布局文件
            convertView = mLayoutInflater.inflate(R.layout.music_item, parent, false);
            viewHolder = new ViewHolder();
            //获取显示歌曲名称的视图
            viewHolder.nameView = convertView.findViewById(R.id.music_name);
            // 获取歌手的视图
            viewHolder.authorView = convertView.findViewById(R.id.music_author);
            // 获取歌曲编号的视图
            viewHolder.numView = convertView.findViewById(R.id.num);
            viewHolder.idView = convertView.findViewById(R.id.music_id);
            // 将视图设置到布局中
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        // 将音乐数据,适配到对应的视图中
        Music music = (Music) mData.get(position);

        viewHolder.nameView.setText(music.getName());
        viewHolder.authorView.setText(music.getAuthor());
        viewHolder.numView.setText((position+1)+".");
        // 传入id,方便后续根据id查找歌曲
        Log.i("info",music.getId()+"");
        viewHolder.idView.setText(music.getId()+"");
        // 将id隐藏起来
        viewHolder.idView.setVisibility(View.GONE);

        return convertView;
    }

    /**
     * 自定义子选项布局视图
     * 对应music_item.xml中的组件
     */
    static class ViewHolder {
        TextView numView;
        TextView nameView;
        TextView authorView;
        TextView idView;
    }
}

🍄 编写MusicListActivity

编写MusicListActivity发送请求,向服务器获取音乐列表,并通过适配器,显示出来,具体代码如下:

package com.moxuan.mytest;

import android.app.Activity;
import android.app.DownloadManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

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

import java.util.ArrayList;
import java.util.List;

import cz.msebera.android.httpclient.Header;

public class MusicListActivity extends Activity {
    // 显示音乐列表的列表视图
    ListView musicListView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 加载布局文件
        setContentView(R.layout.music_list);
        // 获取列表视图
        musicListView = findViewById(R.id.music_list);
        // 封装请求参数
        RequestParams requestParams = new RequestParams();
        // 发送异步请求 想服务端请求音乐列表数据
        // 注意:192.168.5.107 为我电脑上的IP,大家写的时候需要换成自己服务器端ip地址
        new AsyncHttpClient().post("http://192.168.5.107:8080/music_list", requestParams, new AsyncHttpResponseHandler() {
            /**
             * 当服务器成功响应时会执行的方法
             * @param status  服务器当前的状态, 值为200时,代表着服务成功处理请求,并返回了数据
             * @param headers
             * @param responseBody 服务器返回的数据
             */
            @Override
            public void onSuccess(int status, Header[] headers, byte[] responseBody) {
                // 如果服务器成功返回数据
                if(status==200){
                    // 将返回的数据转换成json对象
                    try {
                        JSONObject jsonObject = new JSONObject(new String(responseBody));
                        // 获取json数组,数组中存放的是音乐数据
                        JSONArray musics_array = jsonObject.getJSONArray("data");
                        List<Music> musicList = new ArrayList<>();
                        // 遍历音乐数据,将音乐数据封装到音乐列表中
                        for(int i=0;i<musics_array.length();i++){
                            Music music = new Music();
                            JSONObject jo = musics_array.getJSONObject(i);
                            music.setId(jo.getInt("id"));
                            music.setAuthor(jo.getString("author"));
                            music.setLocation(jo.getString("location"));
                            music.setName(jo.getString("name"));
                            musicList.add(music);
                        }
                        // 创建音乐列表适配器,将查询出来的音乐列表显示出来
                        MusicListAdapter adapter = new MusicListAdapter(MusicListActivity.this,musicList);
                        musicListView.setAdapter(adapter);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

            }

            /**
             * 如果服务器响应失败会执行的方法
             * @param i
             * @param headers
             * @param bytes
             * @param throwable
             */
            @Override
            public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                Toast.makeText(MusicListActivity.this,"服务器繁忙",Toast.LENGTH_LONG).show();
            }
        });
    }
}
🍄 注册MusicListActivity

在AndroidManifest.xml中注册MusicListActivity,并将其设置为启动页,具体代码如下:

<activity android:name=".MusicListActivity">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />

    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

🍄测试效果

启动模拟器,运行程序,效果如下所示:

🌳 歌曲详情页

🌾 后端查询歌曲详情

🍄编写查询接口

编写查询单曲的接口,调用业务端,传入id根据id查找歌曲,查询完毕之后,将查询出来的结果封装到Result中并转化为json对象,并返回给客户端。

package com.softeem.webService.controller;

import com.alibaba.fastjson2.JSONObject;
import com.softeem.webService.service.MusicService;
import com.softeem.webService.util.Result;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/music")
public class MusicController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        // 获取请求参数中的music_id
        int id = Integer.parseInt(req.getParameter("music_id"));
        // 创建业务端
        MusicService service = new MusicService();
        // 业务端根据id获取音乐,并封装成result
        Result result = service.getMusicById(id);
        // 将result转换为json对象
        JSONObject jsonObject = JSONObject.from(result);
        // 返回数据到客户端
        PrintWriter out = resp.getWriter();
        out.println(jsonObject);
    }
}
🍄 编写业务端

在业务端调用dao,根据id查询歌曲详情,并封装到result对象中,具体代码如下:

public Result getMusicById(int id) {
    MusicDao dao = new MusicDao();
    Music music = dao.findMusicById(id);
    return Result.success(music);
}
🍄 编写Dao

在Dao中使用工具类,根据id查询出歌曲信息,具体代码如下:

public Music findMusicById(int id) {
    String sql = "select * from music where id=?";
    return DBUtils.queryOne(Music.class,sql,id);
}
🍄 测试

运行服务器测试,输入以下请求地址进行测试:

🌾 前端展示歌曲详情

🍄 编写显示详情布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#000000"
    >
    <TextView
        android:id="@+id/music_name"
        android:text="旺财小宝贝"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="30sp"
        android:textColor="#FFFFFF"
        android:layout_marginTop="10dp"></TextView>
    <TextView
        android:id="@+id/music_author"
        android:text="攀哥"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="wrap_content"

        android:textSize="30sp"
        android:textColor="#FFFFFF"
        android:layout_marginBottom="30dp"
        android:layout_marginTop="10dp"></TextView>
    <LinearLayout
        android:layout_height="wrap_content"
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:gravity="center">
        <ImageButton
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:id="@+id/play"
            android:src="@drawable/play">

        </ImageButton>
        <ImageButton
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:id="@+id/pause"
            android:src="@drawable/pause"></ImageButton>
        <ImageButton
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:id="@+id/stop"
            android:src="@drawable/stop"></ImageButton>
    </LinearLayout>

</LinearLayout>

🍄 给列表选项添加点击监听器

在MusicListActivity中给ListView添加子选项点击事件监听器,代码如下:

在oncreate()方法中添加如下方法:

// 给列表视图添加点击事件
musicListView.setOnItemClickListener(this);

添加onItemClick方法:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        TextView tv = view.findViewById(R.id.music_id);
        String music_id = tv.getText().toString();
        Intent it = new Intent(this,MusicActivity.class);
        it.putExtra("music_id",music_id);
        startActivity(it);

}
🍄编写MusicActivity展示歌曲详情

在MusicActivity中将music_id发送给服务端,让服务端根据music_id查询数据,并将返回的数据设置到详情页中,具体代码如下:

package com.moxuan.mytest;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

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

import java.util.ArrayList;
import java.util.List;

import cz.msebera.android.httpclient.Header;

public class MusicActivity extends Activity {
    private ImageButton play,pause,stop;
    private MediaPlayer mp;

    private TextView music_name;
    private TextView music_author;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.music);
        play = findViewById(R.id.play);
        pause = findViewById(R.id.pause);
        stop = findViewById(R.id.stop);
        music_name = findViewById(R.id.music_name);
        music_author = findViewById(R.id.music_author);

        Intent it = getIntent();
        String music_id = it.getStringExtra("music_id");


        RequestParams requestParams = new RequestParams();
        requestParams.add("music_id", music_id);
        new AsyncHttpClient().post("http://172.17.29.89:8080/music", requestParams, new AsyncHttpResponseHandler() {
            /**
             * 当服务器成功响应时会执行的方法
             *
             * @param status       服务器当前的状态, 值为200时,代表着服务成功处理请求,并返回了数据
             * @param headers
             * @param responseBody 服务器返回的数据
             */
            @Override
            public void onSuccess(int status, Header[] headers, byte[] responseBody) {
                // 如果服务器成功返回数据
                if (status == 200) {
                    // 将返回的数据转换成json对象
                    try {
                        JSONObject jsonObject = new JSONObject(new String(responseBody));
                        // 获取json数组,数组中存放的是音乐数据
                        JSONObject music_str = jsonObject.getJSONObject("data");
                        music_name.setText("歌曲名:" + music_str.getString("name"));
                        music_author.setText("歌手:" + music_str.getString("author"));


                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

            }

            /**
             * 如果服务器响应失败会执行的方法
             *
             * @param i
             * @param headers
             * @param bytes
             * @param throwable
             */
            @Override
            public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
                Toast.makeText(MusicActivity.this, "服务器繁忙", Toast.LENGTH_LONG).show();
            }
        });
    }
}
🍄 测试效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212744.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目管理系统如何助力新药研发?药物研发企业康诺亚上线瑞杰项目管理系统

在新药研发过程中&#xff0c;其特点是&#xff1a;周期长、风险高、投入大&#xff0c;同时还要与其他科学相结合&#xff0c;相互渗透、更加需要多部门的共同参与&#xff0c;因此面临的问题相对复杂&#xff0c;而且要求也比较高。所以在这一过程中&#xff0c;必须对新药研…

软考系统分析师知识点十一:系统规划

前言 今年报考了11月份的软考高级&#xff1a;系统分析师。 考试时间为&#xff1a;11月9日。 倒计时&#xff1a;26天。 目标&#xff1a;优先应试&#xff0c;其次学习&#xff0c;再次实践。 复习计划第一阶段&#xff1a;扫平基础知识点&#xff0c;仅抽取有用信息&am…

49 | 桥接模式:如何实现支持不同类型和渠道的消息推送系统?

上一篇文章我们学习了第一种结构型模式&#xff1a;代理模式。它在不改变原始类&#xff08;或者叫被代理类&#xff09;代码的情况下&#xff0c;通过引入代理类来给原始类附加功能。代理模式在平时的开发经常被用到&#xff0c;常用在业务系统中开发一些非功能性需求&#xf…

嵌入式~CAN-专辑2

我自己的原文哦~ 只发CAN相关2 随时更新~~ 一、CAN总线错误分析与解决 从实际工作中碰到的具体问题来分析一些常见的CAN总线错误和解决办法。 CAN节点数据收发过程 我们知道&#xff0c;CAN总线上的每个节点往总线上发送数据的同时&#xff0c;会读取总线上的数据&#x…

stm32单片机个人学习笔记10(TIM编码器接口)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

简单实现手机投屏到电脑代码

1、从手机截图到sdcard 2、将图片导出到PC 3、从PC加载图片 4、开启定时器 1、 private static void takeScreenshot(String path) {long t1 System.currentTimeMillis();String command "adb devices"; // 替换为你需要执行的shell命令String command1 "…

氧化锆ZrO2纳米颗粒50nm|L-ZrO2@mSiO2|Ir1-N-C/ZrO2|AuPd/HB-ZrO2

氧化锆ZrO2纳米颗粒50nm|L-ZrO2mSiO2|Ir1-N-C/ZrO2|AuPd/HB-ZrO2 氧化锆&#xff08;ZrO₂&#xff09;纳米颗粒&#xff0c;特别是直径为50纳米&#xff08;nm&#xff09;的颗粒&#xff0c;是一种具有多种应用前景的功能材料。这种材料因其独特的物理和化学性质&#xff0c…

大一计算机课程之线性代数

《大一计算机课程之线性代数》 在大一的计算机课程中&#xff0c;线性代数是一门极为重要的基础学科&#xff0c;它就像一把神奇的钥匙&#xff0c;为计算机科学领域的诸多方面开启了智慧之门。 线性代数主要研究线性方程组、向量空间、线性变换等内容。对于计算机专业的学生…

Python基础语法条件

注释 注释的作用 通过用自己熟悉的语言&#xff0c;在程序中对某些代码进行标注说明&#xff0c;这就是注释的作用&#xff0c;能够大大增强程序的可读性。 注释的分类及语法 注释分为两类&#xff1a;单行注释 和 多行注释。 单行注释 只能注释一行内容&#xff0c;语法如下…

LabVIEW提高开发效率技巧----事件触发模式

事件触发模式在LabVIEW开发中是一种常见且有效的编程方法&#xff0c;适用于需要动态响应外部或内部信号的场景。通过事件结构&#xff08;Event Structure&#xff09;和用户自定义事件&#xff08;User Events&#xff09;&#xff0c;开发者可以设计出高效的事件驱动程序&am…

深度探索:Linux CentOS 7内核的奥秘与管理之道

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Linux简介 2、CentOS 7简介 3、什么是内核 …

【3dgs】总结3DGS与NeRF如何重塑SLAM(24年4月最新进展)

【3dgs】总结3DGS与NeRF如何重塑SLAM&#xff01; 1. 摘要2. 简洁3. 背景3.1 Existing SLAM Surveys3.2 progress in Radiance Field Theory3.3.1 NeRF3.3.2 3dgs3.4 数据集 4 数据集4.1 SLAM3.1 RGB-D SLAM方法3.1.1 基于NeRF风格的RGB-D SLAM3.1.2 基于3DGS风格的 RGB-D SLAM…

PHP政务招商系统——高效连接共筑发展蓝图

政务招商系统——高效连接&#xff0c;共筑发展蓝图 &#x1f3db;️ 一、政务招商系统&#xff1a;开启智慧招商新篇章 在当今经济全球化的背景下&#xff0c;政务招商成为了推动地方经济发展的重要引擎。而政务招商系统的出现&#xff0c;更是为这一进程注入了新的活力。它…

【C++】踏上C++学习之旅(一):初识C++和命名空间

文章目录 前言1. 初识C2. C的发展阶段2. 命名空间2.1 为什么要有命名空间&#xff1f;2.2 命名空间的语法2.3 命名空间的原理2.4 使用命名空间的三种方式2.4.1 加命名空间名称及作用域限定符( :: )2.4.2 使用using关键字将命名空间中某个成员 引入2.4.3 使用using namespace 命…

注意力机制篇 | 清华大学提出Focused Linear Attention取代Self-Attention成为ViT的新宠

前言:Hello大家好,我是小哥谈。Focused Linear Attention(聚焦线性注意力)是一种用于视觉Transformer模型的注意力机制,旨在提高效率和表现力,它解决了传统线性注意力方法的两个主要问题:聚焦能力和特征多样性。🌈 目录 🚀1.基础概念 🚀2.网络结构 🚀3.…

网络安全学习路线-适合入门小白

首先说明&#xff0c;我是一名CTF的web手&#xff0c;这是我自己亲身学习网络安全的路线&#xff0c;希望能够帮到大家&#xff0c;我虽然不是大牛&#xff0c;但我也希望能够帮助一些网安小白找到自己学习的方向&#xff0c;后面有就业的详细安全技术要求&#xff0c;如果真想…

大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

基于知识图谱的宁夏非遗问答系统

八维视角探索宁夏非遗文化——基于知识图谱的非遗问答系统 作为一名程序员&#xff0c;能将大数据与文化传承结合&#xff0c;赋予历史新的生命&#xff0c;是件多么振奋的事&#xff01;今天给大家介绍的是一款基于知识图谱技术的宁夏非物质文化遗产问答系统。无论你是学术研…

数字化转型最佳实践与实施技巧:理论指导与企业应用路径

数字化转型中的最佳实践与实施技巧 企业在实施数字化转型时&#xff0c;面对的最大挑战之一是如何将理论转化为实际可操作的行动。成功的转型不仅依赖于新技术的引入&#xff0c;还涉及如何确保架构蓝图与业务目标一致&#xff0c;如何在确保合规的基础上进行创新&#xff0c;…

重磅!博世「入局」Chiplets,汽车芯片格局或迎来新「拐点」

汽车行业似乎并不想重复PC、手机时代的老路。 在过去几年时间里&#xff0c;由于消费类芯片巨头&#xff08;包括英伟达、高通、AMD、英特尔等&#xff09;大举进军汽车行业&#xff0c;导致传统Tier1和汽车芯片厂商逐步失去了市场控制权。如今&#xff0c;chiplets技术或许将重…