zoukankan      html  css  js  c++  java
  • Android 开发自己的网络收音机4——读取XML文件的电台数据

      国内外的电台数据很多,起码有好几百,所以把这些数据都写到代码里面是不实际的。只能写成一个数据文件,程序启动的时候再去加载。保存这些简单数据,我们肯定会优先使用XML文件,今天讲讲如何读取XML里面的数据,然后填充到列表里面。

      再把这张老截图贴出来,方便后面对应查看XML的数据。

     

     (PS:新建的QQ群,有兴趣可以加入一起讨论:Android群:322599434)

    1、Android解析XML方法

      Android里面读取XML文件有3种方法,其中两种是解析XML的常规方法:SAX和文档对象模型方法。以前我写C++的时候,最常用的是文档对象模型方法,因为这个方法遍历数据很方便,缺点是会把整个文件加载到内存,构建一个文档的树模型。对于数据量比较大的文件,比较耗内存。以前就经常使用TinyXML的解析库,我在博客园第一篇文章就是说如何使用TinyXML库,O(∩_∩)O哈哈~

      SAX方法是事件驱动模型,也就是解析到哪个节点会回调相应方法,你需要做的就是在相应的方法里面编写你的解析代码,这个有点是解析速度快,而且不耗内存,不过需要你解析完整个文件。查找灵活性没有文档对象模型方便。

      Android支持上述两种方法,TinyXML的解析库也集成在Android里面。除了上面两种方法,Android自己修改了一种新的方法来解析XML文件——XmlPullParser,这个新方法是基于SAX方法改进的。传统SAX是需要解析完整个XML文件,而XmlPullParser是可以中途中断,停止解析。也就是说只要你获取了你想要的信息,你就可以停止XML的解析工作,因此速度效率上都不错。

      既然是Android官方的方法,这次就使用XmlPullParser来作为XML的解析(我这里数据量不大,用任何一种方法差别不大)。

    2、定义XML数据格式

      首先我们需要定义我们保存电台数据的XML格式,这是我定义的一种保存电台类型,以及电台类型下面具体电台数据的XML格式,<ChannelType>标签代表是什么类型的电台,包含了ID、名称、图标、级别等信息。

      <RadioChannel>是具体的电台数据标签,保存了电台名称、图标、以及URL等重要信息。

    //Edited by mythou
    //http://www.cnblogs.com/mythou/
      <ChannelType 
            ID="1"
            name="推荐电台"
            Icon="fm_icon"
            Level="1">    
            
                <RadioChannel
                    ID="001"
                    name="猫扑电台"
                    Icon="default_channel_icon"
                    Level="2"
                    URL="mms://ting.mop.com/mopradio"
                    />
                    
                <RadioChannel
                    ID="002"
                    name="国际电台怀旧金曲"
                    Icon="default_channel_icon"
                    Level="2"
                    URL="mms://live.cri.cn/oldies/"
                    />
                    
                <RadioChannel
                    ID="003"
                    name="国际电台都市流行"
                    Icon="default_channel_icon"
                    Level="2"
                    URL="mms://live.cri.cn/pop/"
                    />
        </ChannelType>    

    3、使用Pull解析XML

    
    
    //Edited by mythou
    //http://www.cnblogs.com/mythou/
    public boolean getRadioListData(InputStream is, ArrayList<RadioChannelData> ChannelTypeList, 
                ArrayList<ArrayList<RadioChannelData>> finalChanneldata) throws Exception 
        {  
            Log.d(TAG, "parse InputStream="+is);
            //临时电台类型
            RadioChannelData tempChannelTypeItem = null;
            //临时电台数据对象
            RadioChannelData tempChannelItem = null;  
            //保存每个频道类型里面具体电台数据
            ArrayList<RadioChannelData> channelDataList = null;
            
            //显示ChannelType string
            String channelTypeString="";
              
            //由android.util.Xml创建一个XmlPullParser实例  
            XmlPullParser parser = Xml.newPullParser(); 
            //设置输入流 并指明编码方式  
            parser.setInput(is, "UTF-8");               
      
            int eventType = parser.getEventType();  
            while (eventType != XmlPullParser.END_DOCUMENT) 
            {
                switch (eventType) 
                {
                case XmlPullParser.START_DOCUMENT:  
                    //处理文档开始
                    break;  
                case XmlPullParser.START_TAG:  
                    if (parser.getName().equals("ChannelType")) 
                    {
                        //电台类型信息
                        tempChannelTypeItem = new RadioChannelData();  
                        tempChannelTypeItem.setChannelID(parser.getAttributeValue(0));
                        tempChannelTypeItem.setChannelName(parser.getAttributeValue(1));
                        tempChannelTypeItem.setChannelICON(parser.getAttributeValue(2));
                        tempChannelTypeItem.setLevel(Integer.valueOf(parser.getAttributeValue(3)));
                        
                        //创建每个类型下的列表
                        channelDataList = new ArrayList<RadioChannelData>();
                    } 
                    else if (parser.getName().equals("RadioChannel")) 
                    {
                        //具体电台信息
                        tempChannelItem = new RadioChannelData();
                        tempChannelItem.setChannelID(parser.getAttributeValue(0));
                        tempChannelItem.setChannelName(parser.getAttributeValue(1));
                        tempChannelItem.setChannelICON(parser.getAttributeValue(2));
                        tempChannelItem.setLevel(Integer.valueOf(parser.getAttributeValue(3)));
                        tempChannelItem.setChannelURL(parser.getAttributeValue(4));
                    }  
                    break;  
                case XmlPullParser.END_TAG:  
                    if (parser.getName().equals("ChannelType")) 
                    {  
                        //电台类型列表保存
                        ChannelTypeList.add(tempChannelTypeItem);  
                        tempChannelTypeItem = null;   
                        
                        //把每个类型电台列表加入到总数据列表
                        finalChanneldata.add(channelDataList);
                        channelDataList = null;
                    }  
                    else if (parser.getName().equals("RadioChannel"))
                    {
                        channelDataList.add(tempChannelItem);  
                        tempChannelItem = null;     
                    }
                    break;
                case XmlPullParser.END_DOCUMENT:
                        
                    break;  
                }  
                
                eventType = parser.next();  
            }  
            
            //Test mythou 打印读取的数据
            Log.d(TAG, "Print all radio channel Type----->"+ChannelTypeList.toString());
            Log.d(TAG, "Print all radio final channel data----->"+finalChanneldata.toString());
    
            return true;  
        }  

      上面代码是我用来解析XML的代码,解析的数据保存到对应的ArrayList里面,当然我在程序里面也定义了响应的数据格式类用来保存数据,使用Pull解析XML很方便也很简单,这里不做详细介绍,对此不了解的朋友可以去查看相关文档,个人感觉使用Pull解析文档比使用文档对象模型要方便,起码遍历一次数据要快捷很多。

       补充一点,我这里的图片文件只保存了图片文件的名字(不带后缀),我在程序里面会根据图片名称读取Drawable里面的图片资源。

      界面数据相关的就讲到这里,下一次会讲解如何控制播放,也就是一个播放器的核心。

    系列文章:

    Android 开发自己的网络收音机1——功能要求及设计方案

    Android 开发自己的网络收音机2——电台列表(SlidingMenu侧滑栏)

    Android 开发自己的网络收音机3——电台分类(ExpandableListView)

    Edited by mythou

    原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3231184.html 

  • 相关阅读:
    Java 7如何操纵文件属性
    MS Server中varchar与nvarchar的区别
    【Unity3D】【NGUI】UICamera
    2007LA 3902 网络(树+贪心)
    读取图片的几种方式
    AssetsLibrary 实现访问相册,选取多张照片显示
    UIImagePickerController的用法
    画板的实现
    最近的状态
    富文本的使用-----实现图文混排 文字的检索 (正则表达式)
  • 原文地址:https://www.cnblogs.com/mythou/p/3231184.html
Copyright © 2011-2022 走看看