项目实例:https://download.csdn.net/download/qq_37437983/10484636

实现环境:

1)Lenovo G50-80 Ubuntu16.04笔记本

2)Android Studio

3)Eclipse J2EE

4)Tomcat 8.5

5)sqlServer

6)jdk1.8

概要设计

基于Android平台的MP3在线播放器的设计与实现的目标为:

(l)采用布局和组件绘制系统界面。

(2)完成系统中登录界面和播放界面之间的跳转。

(3)实现界面上端的歌曲信息展示。

(4)实现在线播放功能。

(4)实现歌曲的上一首和下一首切换。

数据库表设计

(1) 用户表Userlogin,管理员信息表用于存放管理员的相关信息,结构如表1所示。

(2) 题目表Mp3Info,题目表用于存放用户答错的题目,结构如表2所示。

登录模块

运行在线Mp3播放系统,首先进入系统的登录界面。如图所示:

图8 登陆界面

  登陆时需要判断用户名和密码是否正确,首先Android端提出登录请求并将请求帐号和密码通过Get形式传送出去,代码如下:

public class UserLogin extends AsyncTask<Void,Void,String> {private String account;private String password;UserLogin(String account,String password){this.account = account;this.password = password;}@Overrideprotected String doInBackground(Void... voids) {String PATH = "http://192.168.43.102:8080/Mp3Manager/login?account="+account+"&password="+password;String result = "";try {HttpGet get = new HttpGet(new URI(PATH));HttpClient client = new DefaultHttpClient();HttpResponse response = client.execute(get);if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {result = EntityUtils.toString(response.getEntity());Log.v("+++++++++++++++++++", result);}else {Log.v("-------------------", result);}} catch (Exception e) {e.printStackTrace();}return result;}protected void onPostExecute(String result){if(result.equals("yes")){Intent intent = new Intent(mactivity,PlayArea.class);mactivity.startActivity(intent);//    Toast.makeText(mactivity, "登录成功", Toast.LENGTH_SHORT).show();}else{Toast.makeText(mactivity, "登录失败,请输入正确的帐号和密码", Toast.LENGTH_SHORT).show();}}
}

JavaEE后台收到请求后,通过web.xml筛选后执行UserLogin.java文件,代码如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubString account = request.getParameter("account");String password = request.getParameter("password");String sql = "select password from UserCollection where account = '"+account+"'";DBOper db = new DBOper();ResultSet rs = db.exeQuery(sql);try {if(rs.next()&&rs.getString(1).equals(password)) {response.getWriter().append("yes");// System.out.println("yes");}else {response.getWriter().append("no");// System.out.println("no");}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

图9,用户名后台

5.2  播放音乐模块

登录成功之后进入主界面,如图所示:

图10 主界面

此界面分为两部分,上面的部分是歌曲列表,可以根据歌曲多少自适应调整高度,并且点击之后会显示出歌曲的详细信息;下面部分是播放模块,可进行音乐的播放和暂停,并且还可进行上一曲和下一曲的音乐切换.Android端实现的代码如下:

public class myAsyncTask extends AsyncTask<Void, Void, String> {/*** 用于异步下载数据*/@Overrideprotected String doInBackground(Void... arg0) {// TODO Auto-generated method stubString result = "";String PATH = "http://192.168.43.102:8080/Mp3Manager/getMp3Info?";try {HttpGet get = new HttpGet(new URI(PATH));HttpClient client = new DefaultHttpClient();HttpResponse response = client.execute(get);if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {result = EntityUtils.toString(response.getEntity());// 从后台获得的数据去掉空格result = result.trim();Log.v("++++++++++", result);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}/*** 解析result(json格式的字符串)并将之存入到lists中*/@Overrideprotected void onPostExecute(String result) {// TODO Auto-generated method stubtry {JSONArray array = new JSONObject(result).getJSONArray("MP3INFO");for (int i = 0; i < array.length(); i++) {Mp3Info mp3 = new Mp3Info();JSONObject object = array.getJSONObject(i);//    Log.v("+++++++++++++++++++++", i+"+++++++++++++++++++");String id = object.getString("id").toString();String song = object.getString("song").toString();String Zsong = object.getString("Zsong").toString();String singer = object.getString("singer").toString();String album = object.getString("album").toString();String notes = object.getString("notes").toString();mp3.setAlbum(album);mp3.setId(id);mp3.setNotes(notes);mp3.setSong(song);mp3.setZsong(Zsong);mp3.setSinger(singer);lists.add(mp3);listSong.add(Zsong);}lenMp3 = lists.size();ArrayAdapter<String> adapter = new ArrayAdapter<String>(PlayArea.this,android.R.layout.simple_list_item_1,listSong);listView.setAdapter(adapter);listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {curMp3 = i;Mp3Info mp3Info = (Mp3Info)lists.get(i);String id = mp3Info.getId().toString();final String song = mp3Info.getSong().toString();final String Zsong = mp3Info.getZsong().toString();final String singer = mp3Info.getSinger().toString();String album = mp3Info.getAlbum().toString();String notes = mp3Info.getNotes().toString();new AlertDialog.Builder(PlayArea.this).setIcon(R.drawable.title).setTitle("歌曲简介").setMessage("歌曲:  "+Zsong+"\n\ni d:  "+id+"\n\n歌 手:  "+singer+"\n\n专 辑:  "+album+"\n\n备 注:  "+notes).setPositiveButton("播放",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {PlayMp3 playMp3 = new PlayMp3();playMp3.init(song,Zsong,singer);//    Toast.makeText(PlayArea.this, "点击播放 ", Toast.LENGTH_SHORT).show();}}).setNegativeButton("关闭",null).show();}});ivMusicPlay.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {PlayMp3 playMp3 = new PlayMp3();playMp3.init();}});ivMusicPre.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {curMp3--;if(curMp3<0) curMp3 = lenMp3-1;Mp3Info mp3Info = (Mp3Info) lists.get(curMp3);final String song = mp3Info.getSong().toString();final String Zsong = mp3Info.getZsong().toString();final String singer = mp3Info.getSinger().toString();PlayMp3 playMp3 = new PlayMp3();playMp3.init(song,Zsong,singer);}});ivMusicNext.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {curMp3++;if(curMp3>=lenMp3) curMp3 = 0;Mp3Info mp3Info = (Mp3Info) lists.get(curMp3);final String song = mp3Info.getSong().toString();final String Zsong = mp3Info.getZsong().toString();final String singer = mp3Info.getSinger().toString();PlayMp3 playMp3 = new PlayMp3();playMp3.init(song,Zsong,singer);}});} catch (Exception e) {// TODO Auto-generated catch blockLog.v("+++++++++++++++++++++", e.getMessage());e.printStackTrace();}super.onPostExecute(result);}
}

图11 点击列表显示详情信息

 

Android端显示的信息是后台Gson将封装好的list转换为String对象传给Android端解析.代码如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stub//获取gsonGson gson = new Gson();List<Mp3Info> infos = new ArrayList<>();//获取数据库信息DBOper db = new DBOper();String sql = "select * from Mp3Info";ResultSet rs = db.exeQuery(sql);try {while(rs.next()) {Mp3Info info = new Mp3Info();String id = rs.getString(1);String song = rs.getString(2);String Zsong = rs.getString(3);String singer = rs.getString(4);String album = rs.getString(5);String notes = rs.getString(6);info.setId(id);info.setSong(song);info.setAlbum(album);info.setNotes(notes);info.setZsong(Zsong);info.setSinger(singer);infos.add(info);}//将infos转换为json格式的字符串String str = gson.toJson(infos);request.setAttribute("MP3INFO", "{\"MP3INFO\":"+str+"}");request.getRequestDispatcher("index.jsp").forward(request, response);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}response.getWriter().append("Served at: ").append(request.getContextPath());}

图12 后台歌曲信息界面

5.3  播放器数据源获取

本系统的最关键之处就是从后台Mp3库中获取数据源交给MediaPlayer.主要想法就是定义两个Socket:远程Socket和本地Socket.其中远程Socket用于请求服务器资源,本地Socket负责监听mediaplayer请求,并将远程Socket获得数据写入mediaPlayer中进行播放.

(1)首先初始化本地Socket,代码如下:

public MediaPlayerProxy(String writeFileName, boolean writeFile) throws Exception {currPlayDegree = 0;//当前音乐播放进度proxyFail = false;//代理播放失败了cachedFileLength = 0;//已缓存的文件长度fileTotalLength = 0;//要缓存的文件总长度currMusicCachedProgress = 0;//当前的音乐缓冲值(seekbar上的缓冲值)proxyIdle = false;  //代理忙this.writeFile = writeFile;this.writeFileName = writeFileName;try {if (localServer == null || localServer.isClosed()) {//创建本地socket服务器,用来监听mediaplayer请求和给mediaplayer提供数据localServer = new ServerSocket();localServer.setReuseAddress(true);//创建IP地址为192.168.43.1,端口号为9090的本地端口地址InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName(LOCAL_IP_ADDRESS), local_ip_port);//本地socket绑定本地端口地址localServer.bind(socketAddress);}} catch (Exception e) {Log.e("1111111111111111+++++++",e.getMessage());try {local_ip_port--;  //端口号非空闲,自减localServer = new ServerSocket();localServer.setReuseAddress(true);//创建IP地址为192.168.43.1,端口号为9090的本地端口地址InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName(LOCAL_IP_ADDRESS), local_ip_port);//本地socket绑定本地端口地址localServer.bind(socketAddress);} catch (Exception e2) {Log.e("22222222222222++++++",e2.getMessage());throw new Exception();}}
}

(2)根据真实的请求音源文件地址,得到本地音源文件地址将本地音源地址通过setDataSource的方式传递给mediaplayer. 前面创建的本地socket对象监听这个地址,用于获取mediaplayer的请求数据。代码如下:

public String getLocalURLAndSetRemotSocketAddr(String url) {try {remotUrl = url;if (writeFile) {  //正在缓存的音乐地址bufferingMusicUrlList.add(remotUrl);}String localProxyUrl = "";final URI originalURI = URI.create(url);final String remoteHost = originalURI.getHost();  //服务器主机if (!TextUtils.isEmpty(remoteHost)) {  //存在主机if (originalURI.getPort() != -1) {//URL带Portnew Thread(new Runnable() {@Overridepublic void run() {//服务器的主机号和端口remoteAddress = new InetSocketAddress(remoteHost, originalURI.getPort());}}).start();//替换localProxyUrl = url.replace(remoteHost + ":" + originalURI.getPort(), LOCAL_IP_ADDRESS + ":" + local_ip_port);remoteHostAndPort = remoteHost + ":" + originalURI.getPort();} else {//URL不带Port,使用80端口if (!TextUtils.isEmpty(remoteHost)) {new Thread(new Runnable() {@Overridepublic void run() {remoteAddress = new InetSocketAddress(remoteHost, HTTP_PORT);//使用80端口}}).start();localProxyUrl = url.replace(remoteHost, LOCAL_IP_ADDRESS + ":" + local_ip_port);remoteHostAndPort = remoteHost;}}}return localProxyUrl;} catch (Exception e) {Log.e("+333333333333++++++++++",e.getMessage());return "";}
}

  (3)本地socket监听mediaplayer,通过getInputStream方法可以获取到mediaplayer传递过来的请求信息数据,由于我们是通过本地代理地址的方式获取到的,所以我们需要根据这个本地的请求信息替换成真实的远程socket请求信息,向服务器获取真实请求数据。代码如下:

public void getTrueSocketRequestInfo(Socket localSocket) throws Exception {InputStream in_localSocket = localSocket.getInputStream();String trueSocketRequestInfoStr = "";//保存MediaPlayer的真实HTTP请求byte[] local_request = new byte[1024];while (in_localSocket.read(local_request) != -1) {String str = new String(local_request);trueSocketRequestInfoStr = trueSocketRequestInfoStr + str;if (trueSocketRequestInfoStr.contains("GET") && trueSocketRequestInfoStr.contains("\r\n\r\n")) {//把request中的本地ip改为远程iptrueSocketRequestInfoStr = trueSocketRequestInfoStr.replace(LOCAL_IP_ADDRESS + ":" + local_ip_port, remoteHostAndPort);this.trueSocketRequestInfoStr = trueSocketRequestInfoStr;//如果用户拖动了进度条,因为拖动了滚动条还有Range则表示本地歌曲还未缓存完,不再保存if (trueSocketRequestInfoStr.contains("Range")) {Log.e("+44444++++Range++++++","");writeFile = false;}break;}}
}

(4)上一步我们获取到了真实的请求数据信息,此时通过远程socket连接远程请求,代码如下:

public Socket sendRemoteRequest() throws Exception {//创建远程socket用来请求网络数据Socket remoteSocket = new Socket();remoteSocket.connect(remoteAddress, socketTimeoutTime);remoteSocket.getOutputStream().write(trueSocketRequestInfoStr.getBytes());remoteSocket.getOutputStream().flush();return remoteSocket;
}

(5)将远程socket的数据,通过本地socket写入mediaplayer进行播放

(6)最后在PlayMp3.java文件中调用,代码如下:

private void playMusic() {if(Zsong!=""&&singer!=""){tv_Name.setText(Zsong);tv_author.setText(singer);}ivMusicPlay.setImageResource(R.mipmap.music_button_pause);currentState = STATE_PLAY;* 第一次执行加载数据,之后执行暂停,开始* */if (!firstPlay && mediaPlayer.getCurrentPosition() > 0) {mediaPlayerHttpProxy = null;mediaPlayer.start();} else {try {//   Toast.makeText(playArea, Zsong+"加载"+mediaPlayer.getCurrentPosition(), Toast.LENGTH_SHORT).show();mediaPlayerHttpProxy = new MediaPlayerProxy(Zsong, false);//setProgress是文件写入本地进度,setSecondaryProgress就是文件加载进度mediaPlayerHttpProxy.setOnCaChedProgressUpdateListener(new MediaPlayerProxy.OnCaChedProgressUpdateListener() {@Overridepublic void updateCachedProgress(int progress) {sb_music.setSecondaryProgress(progress);}});//得到从服务器得到的数据源String localProxyUrl = mediaPlayerHttpProxy.getLocalURLAndSetRemotSocketAddr(TEST_URL);mediaPlayerHttpProxy.startProxy();mediaPlayer.setDataSource(localProxyUrl);mediaPlayer.prepareAsync();firstPlay = false;} catch (Exception e) {Log.e("++++++++++++++++++++",e.getMessage());}}
}

项目实例:https://download.csdn.net/download/qq_37437983/10484636

下载积分不够的,留言中有百度云下载链接。

Android从本地服务器获取Mp3实现边下边播(JavaEE+Tomcat+SQLServer)相关推荐

  1. Android开发本地音乐获取专辑封面图片

    某项目中需要用到音乐功能,只有音乐还是有一些单调,于是乎想跟音乐播放器一样展示专辑图片,查阅了部分大佬们的代码,总结代码如下: import android.content.ContentResolv ...

  2. Android开发本地及网络Mp3音乐播放器(二十)歌曲下载完成后通知主界面更新本地音乐

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51448597 项目源码(打赏5积分请点这边):http://download.csdn ...

  3. Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51290181 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 实现NetM ...

  4. Android开发本地及网络Mp3音乐播放器(十三)网络音乐搜索功能实现,歌名歌手专辑名搜索

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51298411 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 实现网络音乐 ...

  5. android 关联mp3,Android开发本地及网络Mp3音乐播放器(四)实现音乐播放

    建立PlayService服务 package com.iwanghang.drmplayer; import android.app.Service; import android.content. ...

  6. Android开发本地及网络Mp3音乐播放器(十)最近播放界面与数据保存更新

    实现功能: 实现MyLoveMusicActivity(音乐收藏界面) 实现MyRecordMusicActivity(最近播放界面) 实现MyMusicListFragment(本地音乐界面)Ite ...

  7. Android开发本地及网络Mp3音乐播放器(十七)已存在歌曲歌词下载

    转载请注明出处: http://blog.csdn.net/iwanghang/article/details/51388896 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 已存在歌曲 ...

  8. Android开发本地及网络Mp3音乐播放器(十五)网络音乐及歌词下载功能实现

    实现功能: 实现网络音乐歌词下载功能(下载音乐的同时,下载对应歌词) 下载好的歌词目前不在播放器内,可以通过文件浏览器查看. 后续将博文,将实现本地音乐歌词下载和已下载音乐扫描功能. 因为,没有自己的 ...

  9. Android开发本地及网络Mp3音乐播放器(十六)歌词显示及滚动事件实现、ViewPager使用

    转载请注明出处: http://blog.csdn.net/iwanghang/article/details/51386317 觉得博文有用,请点赞,请留言,请关注,谢谢!~ 实现功能: 歌词显示及 ...

最新文章

  1. 深度学习遇上稀缺数据就无计可施?这里有几个好办法
  2. mybatis 调用 oracle 存储过程 select into 无记录时NO_DATA_FOUND异常处理分析
  3. 微博遭鹿晗恋情暴击瘫痪,如何快速提高系统性能?
  4. Python+OpenCV人脸识别技术详解
  5. php获取域名方法,PHP实现获取域名的方法小结
  6. Linux:计划任务之at
  7. Maven模块聚合与继承
  8. 嵌入式、单片机开发必备软件
  9. SolidWorks一级减速器教程
  10. 计算机两个活动分区,硬盘无法设置活动分区,硬盘只能有一个活动分区吗
  11. 冬天装修完怎么散甲醛 刚装修的房子怎么除甲醛
  12. 对大学计算机课程的认识 感想,大学计算机基础学习感想复习课程.pdf
  13. linux 基金会 认证,Linux基金会宣布新的Linux认证计划
  14. Win7 64位下Kindle4、闪迪Cruzer BladeU盘等无法安装驱动问题的解决方法
  15. 远程办公导致企业网络被黑?请注意这三点
  16. 欧美女性flash网页模板
  17. Vuforia 使用
  18. HiApp移动开发案例,HTML5移动框架,看了绝不后悔
  19. GSYVideoPlayer视频播放器
  20. windows防火墙设置端口开放技巧

热门文章

  1. LeCo-238. 除自身以外数组的乘积
  2. Mac (M1) 软件及环境搭建
  3. 附件携马之CS免杀shellcode过国内主流杀软
  4. 从外包公司到今日头条offer,吐血整理
  5. 用Desmos玩极坐标
  6. 赛迪顾问《中国云计算市场研究年度报告》发布:“技术+服务”两手抓 华云数据成为云计算领域的重要核心厂商
  7. 手机外接usb摄像头软件下载_手机打碟app下载安装_手机打碟软件最新版免费下载...
  8. 【ESP 保姆级教程】疯狂Node.js服务器篇 ——案例:ESP8266 + MQ3酒精传感器 + NodeJs本地服务 + 文件存储数据
  9. xp升级到win7傻瓜教程_最简单xp一键升级win7重装
  10. 面试系列——爱奇艺Andromeda 跨进程通信组件分析