4JPlayer.Ver1.1-软件评测

一、欢迎界面

双击app图标之后,首先显示的是欢迎界面(如下左图所示),该界面上含有1张静态图片和1个动态点状进度条;当进度条循环完2轮之后,跳转到程序主界面中的Local Tab(如下右图所示)。
4JPlayer 欢迎界面 welcome  4JPlayer Play Tab 播放页签

二、初始化界面

上右图展示的是初始化时Local Tab的界面,该界面罗列出SDCard上的音频文件。接下来展示该状态下Play Tab(如下左图所示)和Remote Tab界面(如下右图所示);该状态下Remote Tab罗列出服务器上的音频文件。

4JPlayer 初始化PlayTab界面  4JPlayer 初始化RemoteTab界面

三、音乐播放界面

当用户点击Local Tab中某一首歌曲,例如选择标题一的右图中“Vincent.mp3”时;传来歌曲声音,该歌曲后多出一个播放按钮(如下左图所示);音乐播放一段时间之后,将界面切换到Play Tab,该界面中的数字计时器以1s为单位进行增加,进度条也随之向前挪动,中间的控制键显示的是暂停图标(如下右图所示)。
4JPlayer 播放时Local Tab界面  4JPlayer 播放时Play Tab界面

四、音乐暂停界面

继续播放一段时间后,点击Play Tab中的暂停按钮,音乐停止播放,数字计时器停止,滚动条停止,中间的控制键变更成播放图标(如下左图所示)。切换到Local Tab,此时“Vincent.mp3”后面显示为暂停图标(如下右图所示)。一段时间之后,点击“Vincent.mp3”,传出音乐,变成播放图标;切换到Play Tab,数字计时器和滚动条都动起来。
4JPlayer 暂停时Play Tab界面  4JPlayer 暂停时Local Tab界面

五、音乐切换界面

在标题四的基础之上,点击“下一首”,传来“Nobody”歌声,数字计时器和滚动条从零开始变化。此时切换到Local Tab,“Nobody.mp3”后面显示一个播放图标。

在上文的基础上,点击“Secret.mp3”,Secret音乐传出,该列后面出现播放图标。切换到Play Tab,此时展示着Secret的播放进度。

六、下载Mp3

切换到Remote Tab,点击“Hero.mp3”后面的下载图标,弹出下载提示(如下左图所示);一段时间之后浏览sdcard\mp3路径,发现“Hero.mp3”文件。
4JPlayer Download mp3 下载mp3  4JPlayer mp3 notify

七、Notification

当退出Activity时,Status Bar里出现个播放图标和文字“4JPlayer”,滑开,如上右图所示。

八、总结

1. 不足之处

  • 拖动播放功能未实现
  • 歌词同步功能未实现
  • 界面布局过于简单

2. 可行之处

  • 基本功能已实现
  • 通过该demo进一步学习Android SDK

九、APK和源码下载

http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/src/4jplayer-1.1.zip

4JPlayer.Ver1.1-需求分析与实现方法

一、需求来源

为完善上一版本(4JPlayer.Ver1.0)中存在的不足和增加一些新的功能,从而来进一步学习Android SDK的相关知识点。

二、功能概要和涉及知识点

  1. 欢迎界面显示图片和动态点状进度条,并停留一段时间之后跳转到主界面
    • Activity:调用finish()方法来结束当前Activity和startActivity()来开启一个新的Activity。
    • Handler:调用sendEmptyMessageDelayed()方法来延迟发送消息和重写handleMessage()方法来接收消息,并用switch-case进行分类处理。
    • Thread:定义一个线程类,该类extends Thread,通过传递Handler对象进行实例化,在run()方法中调用Handler对象的sendEmptyMessageDelayed()方法发送消息。
  2. 主界面由4个Tab组成
    • 组件:TabHost、TabWidget和FrameLayout组件。
    • 类:TabActivity、TabHost和TabHost.TabSpec类
  3. 其中2个Tab(Local Tab和Remote Tab)的内容由ListView来进行布局,并且ListItem中包含文字、图片和按钮(需监听onClick事件)
    • 组件:ListVew、TextView、ImageView和ImageButton组件。
    • 类:SimpleAdapter和通过extends BaseAdapter来自定义一个Adapter类,并监听ImageButton的onClick事件。
  4. 从服务器上获取mp3文件列表
    • 下载XML文件:涉及到URL、HttpURLConnection类
    • 解析XML文件:通过extends DefaultHandler来自定义一个Handler类,并重写startElement()、endElement()和characters()方法来进行标签解析;还涉及到SAXParserFactory和XMLReader类。
  5. 后台从服务器下载mp3文件,并写入到SDCard中去(给予下载开始提示信息)
    • 下载开始提示信息:通过Toast.makeText()实现。
    • 后台从服务器下载mp3文件:通过extends Service来自定义一个Service类,并重写onStartCommand()方法,在该方法中开启一个Thread来进行下载。当然,同样也涉及到URL、HttpURLConnection类。
    • 将mp3文件写入到SDCard中去:涉及到一些文件和IO流的操作。
  6. 罗列SDCard中mp3文件
    • 当前的实现方法:直接遍历sdcard\mp3目录下后缀为“.mp3”的文件。
    • 更完善的实现方法:通过getContentResolver().query()方法返回一个承载sdcard上所有音频文件记录的Cursor对象,音频文件信息存放在data\data\com.android.providers.media\databases\external-**.db中,对应的Uri为:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;具体实现请参考>>http://blog.csdn.net/Android_Tutor/archive/2010/07/18/5743183.aspx(由于我编码完之后才知晓有这种更完备的方案,但改动太大,所以这个版本暂时就没做修改,下一版本可能会修改成这种方案。)
  7. 音乐播放控制:播放、暂停、上一首和下一首(可以循环播放)
    • Service:通过extends Service定义一个Serivce,用于后台进行歌曲播放控制。
    • MediaPlayer:reset()、prepare()、start()、pause()
  8. 播放音乐时有动态的SeekBar和动态的数字计时器
    • 组件:SeekBar
    • Thread:在用于播放音乐Service中,新建一个线程,该线程中通过Handler每隔1000ms发送一次消息。
    • Handler:在音乐播放控制Activity中,通过Handler的handleMessage()方法接收消息,并移动进度条和设置数字计时器。
  9. 当按后退键退出Activity之后,会在Status Bar显示播放信息
    • 涉及到Notification和PendingIntent类的相关方法。

三、尚欠缺的功能

  1. 拖动播放
  2. 多播放列表
  3. 歌词同步

四、源码

http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/src/4jplayer-1.1.zip

4JPlayer.Ver1.0-软件评测

一、Welcome

双击app图标之后,首先显示的是欢迎界面,该界面上含有1张静态图片和1个动态点状滚动条;当滚动条循环完2轮之后,跳转到程序主界面;截屏如下:
4JPlayer 欢迎界面 welcome

二、Play Tab

Play Tab中含有3个控制按钮,分别是:上一首、播放(暂停)和下一首;但播放控制功能并未实现;截屏如下:

4JPlayer PlayTab 播放页签

三、Local Tab

点击Local Tab跳转到Local页签,该页签罗列出sdcard中名为mp3文件夹的所有mp3文件;截屏如下:
4JPlayer LocalTab 本地页签

四、Remote Tab

点击Remote Tab跳转到服务器页签,该页签罗列出服务器上所有的mp3文件,并针对每个列表提供1个对应的下载按钮;截屏如下:
4JPlayer LocalTab 本地页签

五、Download Mp3

点击上图中“Secret.mp3”记录之后的下载图标,弹出提示下载文字“Secret.mp3开始下载”,一段时间之后下载结束;再点击Local Tab,该页签中较上次多出1条“Secret.mp3”记录;截屏如下:
4JPlayer Download mp3 下载mp3

六、Lrc Tab

点击Lrc Tab跳转到歌词页签,该页签暂且预留,歌词同步功能尚未实现;截屏如下:
4JPlayer LrcTab 歌词页签

七、About

点击下方的“About”,弹出“About”窗口;点击其他4个按钮均无反应;截屏如下:
4JPlayer About 关于

八、总结

1. 不足之处

  • 播放控制功能未实现
  • 歌词同步功能未实现
  • 界面布局过于简单
  • 底部5个Button多余(为了满足需求保留着,下一个版本将去除)

2. 可行之处

  • 基本满足需求
  • 通过该demo将各个知识点串联起来

九、源码

http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/src/4jplayer-1.0.zip

4JPlayer.Ver1.0-需求分析与实现方法

一、需求来源

我最近正在找android开发方面的工作,并将GTalk的状态设置为“找工作:Android开发”。A公司通过GTalk联系到我,但由于我身在魔都,而A公司位在帝都,故面试方面可能会有所不便;最终想到一个解决方案:给我出一道题,就是以图片的形式展示一小应用的需求,然后由我来实现其功能;由于A公司了解我目前还在上班中,只能利用业余时间来完成,就以一个星期为期。需求如下:4jplayer-需求

二、功能概要

  1. 欢迎界面显示图片和动态点状进度条
  2. 欢迎界面停留一段时间之后跳转到主界面
  3. 主界面由两部分组成:上面3个Tab、下面5个Button
  4. ListItem由三部分组成:图片、文字和按钮
  5. 罗列sdcard中mp3文件
  6. 从服务器获取mp3文件列表
  7. 后台下载mp3文件,并给予提示

三、需求分析与现实方法

1. 欢迎界面显示图片和动态点状进度条,停留一段时间之后跳转到主界面

  • 需求分析
    • 运行app时,首先显示的是欢迎界面
    • 欢迎界面居中显示一张静态图片和一串动态点状进度条
    • 点状进度条循环2轮之后跳转到主界面
  • 实现方法
    • 静态图片和“Loading”字符可以通过配置文件解决
    • 动态点的5种不同状态分别来自于string.xml文件中5个不同的字符串;例如:
      <string name="tv_welcome_dot_1">.</string>
      <string name="tv_welcome_dot_2">..</string>
      <string name="tv_welcome_dot_3">...</string>
      <string name="tv_welcome_dot_4">....</string>
      <string name="tv_welcome_dot_5">.....</string>
    • 新建1个名为LoadHandler的class,该class继承android.os.Handler并重写handleMessage()方法,该方法中通过接收参数使用switch-case进行分类显示string.xml中的5个不同字符串。
    • 新建1个名为LoadThread的class,该class继承java.lang.Thread并重写run()方法,在该方法中调用LoadHandler实例的sendEmptyMessageDelayed()方法来间隔性的发送消息。
    • 在该Activity的onCreate()中调用new LoadThread(loadHandle).start()开启线程。

2. 主界面由两部分组成:上面3个Tab、下面5个Button

  • 需求分析
    • 切换Tab时,中间数据变化,底部button不动。
  • 实现方法
    • 利用1个TabHost组件和1个LinearLayout组件来完成布局,其中LinearLayout组件中包含5个Button组件。
    • 通过以下方法来添加4个不同的Tab:
      // add tab named Remote
      Intent remoteIntent = new Intent();
      remoteIntent.setClass(this, RemoteListActivity.class);
      TabHost.TabSpec remoteSpec = tabHost.newTabSpec("Remote");
      remoteSpec.setIndicator("", res.getDrawable(R.drawable.tab_remote_64));
      remoteSpec.setContent(remoteIntent);
      tabHost.addTab(remoteSpec);

3. 从服务器上下载数据

  • 需求分析
    • 该过程分为两部分:第一,读取服务器上的文件;第二,将读取到的数据写入sdcard中。
  • 实现方法
    • 提供1个字符串形式的URL,通过HttpURLConnection类的getInputStream()得到InputStream。
    • 将得到的InputStream通过FileOutputStream类的write()写入到sdcard中去,当然其中会涉及到File的相关操作。

4. 从服务器获取mp3文件列表

  • 需求分析
    • 该过程分为两部分:第一,读取服务器上承载mp3文件列表的xml文件;第二,通过解析读取到的xml文件来获得mp3文件列表。
  • 实现方法
    • 该xml文件的来源为:
      http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/server/4jplayer/resources.xml
      代码片段如下:

      <resources> 
      	<resource> 
      		<id>0001</id> 
      		<mp3.name>Vincent.mp3</mp3.name> 
      		<mp3.size>7685487</mp3.size> 
      		<lrc.name>Vincent.lrc</lrc.name> 
      		<lrc.size>2428</lrc.size> 
      	</resource>
      	<resource>...</resource>
      <resources>
    • 通过继承org.xml.sax.helpers.DefaultHandler,并重写其中的startElement()、endElement()和characters()方法来新建1个名为Mp3ListContentHandler类;然后通过以下代码来实现具体的解析:
      /**
       * 传入一String,通过解析其中的标签,返回一个ArrayList对象。
       */
      public static ArrayList parserXML(String xmlContent) {
      	ArrayList mp3InfoList = new ArrayList();
      
      	SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
      	try {
      		XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
      		Mp3ListContentHandler mp3ListContentHandler = new Mp3ListContentHandler(mp3InfoList);
      		xmlReader.setContentHandler(mp3ListContentHandler);
      		xmlReader.parse(new InputSource(new StringReader(xmlContent)));
      
      		for (Iterator iterator = mp3InfoList.iterator(); iterator.hasNext();) {
      			Mp3Info mp3Info = (Mp3Info) iterator.next();
      			//System.out.println("mp3Info --> " + mp3Info.toString());
      		}
      	} catch (Exception e) {
      		e.printStackTrace();
      	}
      
      	return mp3InfoList;
      }

5. ListItem由三部分组成:图片、文字和按钮

  • 需求分析
    • 图片位于最左端,文字其次,按钮位于最右端。
  • 实现方法
    • 通过继承android.widget.BaseAdapter,并重写其中的getCount()、getItem()、getItemId()和getView()方法来完成布局。

6. 后台下载mp3文件,并给予提示。

  • 需求分析
    • 点击下载按钮之后,后台启动下载线程;而不是让当前界面停留,直至等到下载完成。
  • 实现方法
    • 通过继承android.app.service,并重写其中的onStartCommand()方法,在该方法中启动线程进行下载;并通过Toast.makeText()方法给予提示。

四、尚欠缺的功能

  1. 播放控制:播放、暂停、上一首、下一首
  2. 显示播放进度条,并能拖动选择播放
  3. 歌词同步
  4. 下载目录可选
  5. 扫描目录可选
  6. 多播放列表

五、源码

http://7xl53s.com1.z0.glb.clouddn.com/download/2015/08/src/4jplayer-1.0.zip