mp3播放器(四)(从服务器端下载mp3文件+service的应用+SDcard操作)

下载到本地的sd卡中 实现序列化接口 serializable 加一个id 表示接口 通过一个什么样的方式可以把对象变成字节码从内存中发送出去 。。。。。实体类中toString。。。能够把里面的参数都答应出来,直接写类名就行,特别方便 下载要放在线程里面执行,就创建一个内部类

下载文件的过程 1,得到用户所要下载的Mp3文件的名称,靠position获取名字 2,访问网络下载mp3文件 3,通知客户下载的结果

Mp3ListActivity.java

  1 package com.example.mp3player00;
  2 
  3 import java.io.IOException;
  4 import java.io.StringReader;
  5 import java.util.ArrayList;
  6 import java.util.HashMap;
  7 import java.util.Iterator;
  8 import java.util.List;
  9 
 10 import javax.xml.parsers.ParserConfigurationException;
 11 import javax.xml.parsers.SAXParserFactory;
 12 
 13 import org.xml.sax.InputSource;
 14 import org.xml.sax.SAXException;
 15 import org.xml.sax.XMLReader;
 16 
 17 import service.DownloadService;
 18 
 19 import xml.Mp3ListContentHandler;
 20 
 21 import model.Mp3Info;
 22 
 23 import com.example.download.HttpDownloader;
 24 
 25 import android.os.Bundle;
 26 import android.app.Activity;
 27 import android.app.ListActivity;
 28 import android.content.Intent;
 29 import android.view.Menu;
 30 import android.view.MenuItem;
 31 import android.view.View;
 32 import android.widget.ListView;
 33 import android.widget.SimpleAdapter;
 34 
 35 public class Mp3ListActivity extends ListActivity {
 36     private static final int upadate=1;
 37     private static final int about=2;
 38     private List<Mp3Info> mp3Infos=null;
 39    //以上定义常量,看到值的名字就知道按钮的名字    
 40    //且为后面修改提供方便
 41     @Override
 42     protected void onCreate(Bundle savedInstanceState) {
 43         super.onCreate(savedInstanceState);
 44         setContentView(R.layout.activity_mp3_list);
 45         updateListView();
 46     }
 47 
 48     @Override
 49     public boolean onCreateOptionsMenu(Menu menu) {
 50         // Inflate the menu; this adds items to the action bar if it is present.
 51         getMenuInflater().inflate(R.menu.activity_mp3_list, menu);
 52         menu.add(0, 1, 1,R.string.mp3list_update);
 53         menu.add(0, 2, 2, R.string.mp3list_about);
 54         return true;
 55     }
 56 
 57     @Override
 58     public boolean onOptionsItemSelected(MenuItem item) {
 59         // TODO Auto-generated method stub
 60         //System.out.println("--->"+item.getItemId());
 61         if(item.getItemId()==upadate)
 62         {
 63             updateListView();
 64             
 65             
 66         }
 67         else if(item.getItemId()==about)
 68         {
 69             //用户点击了关于按钮
 70         }
 71         return super.onOptionsItemSelected(item);
 72     }
 73     private SimpleAdapter buildSimpleAdapter(List<Mp3Info> mp3infos){
 74         //构建Adapter,首先生成一个List对象。List对象里面存的是HashMap,HashMap里面存的是String
 75         
 76         List<HashMap<String,String>> list=new ArrayList<HashMap<String,String>>();
 77         //将Mp3Info迭代出来
 78         for (Iterator iterator = mp3infos.iterator(); iterator.hasNext();) {
 79             Mp3Info mp3Info = (Mp3Info) iterator.next();
 80              //生成一个HashMap对象
 81             HashMap<String,String> map=new HashMap<String,String>();
 82             //构造一个map
 83             map.put("mp3_name", mp3Info.getMp3Name());
 84             map.put("mp3_size", mp3Info.getMp3Size());
 85             //构造好map后添加到List中,即将HashMap添加到List中
 86             list.add(map);
 87         }
 88         //生成adapter
 89         SimpleAdapter simpleAdapter=
new SimpleAdapter(this,list,R.layout.mp3info_item,new String[]{"mp3_name","mp3_size"},new int[]{R.id.mp3_name,R.id.mp3_size}); 90 91 92 return simpleAdapter; 93 94 } 95 private void updateListView(){ 96 //用户点击了更新按钮 97 98 String xml=downloadXML("http://192.168.1.100:8080/mp3/resources.xml"); 99 //System.out.println("----->"+xml); 100 101 102 103 try { 104 mp3Infos = parse(xml); 105 } catch (IOException e) { 106 // TODO Auto-generated catch block 107 e.printStackTrace(); 108 } 109 //List<Mp3Info>可以看出一个int,String这样一个类型 110 SimpleAdapter simpleAdapter=buildSimpleAdapter(mp3Infos); 111 setListAdapter(simpleAdapter); 112 113 } 114 //写一个单独的下载函数,更加清晰 115 private String downloadXML(String urlStr) 116 { 117 118 HttpDownloader httpdownloader=new HttpDownloader(); 119 String result=httpdownloader.download(urlStr); 120 return result; 121 } 122 //在这个函数中解析xml 123 //首先生成xml解析器 124 private List<Mp3Info> parse(String xmlStr) throws IOException 125 { 126 List<Mp3Info> info=new ArrayList<Mp3Info>(); 127 SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); 128 try { 129 XMLReader xmlReader=saxParserFactory.newSAXParser().getXMLReader(); 130 Mp3ListContentHandler mp3ListContentHandler=new Mp3ListContentHandler(info); 131 xmlReader.setContentHandler(mp3ListContentHandler); 132 xmlReader.parse(new InputSource(new StringReader(xmlStr))); 133 //解析完数据都天道info里面,然后用for循环迭代出来 134 for (Iterator iterator = info.iterator(); iterator.hasNext();) { 135 Mp3Info mp3Info = (Mp3Info) iterator.next(); 136 //System.out.println(mp3Info); 137 } 138 139 140 } catch (SAXException e) { 141 // TODO Auto-generated catch block 142 e.printStackTrace(); 143 } catch (ParserConfigurationException e) { 144 // TODO Auto-generated catch block 145 e.printStackTrace(); 146 } 147 return info; 148 149 } 150 //第一个是选择的哪一个List,第二个是选择的哪一行,第三个是条目处于的位置,第四个是条目的id 151 152 //点击第一个postion是0,就是代表第一行,就是List里面第0个元素,把List看成一个有顺序的链表,链表对象就是mp3infos 153 protected void onListItemClick(ListView l, View v, int position, long id) { 154 super.onListItemClick(l, v, position, id); 155 //根据用户点击的位置来确定获得哪一个mp3info对象 156 Mp3Info mp3info=mp3Infos.get(position); 157 //System.out.println("mp3info---"+mp3info);//因为已经复写了toString方法 158 //在这里启动service 159 Intent intent=new Intent(); 160 //将mp3info放到intent里面去再传到service里面去 161 intent.putExtra("mp3info", mp3info);//将mp3info实现序列化 162 //设置跳转的目的地 163 intent.setClass(this, DownloadService.class); 164 //启动Service 165 startService(intent); 166 167 } 168 169 170 }


DownloadService.java

 1 package service;
 2 
 3 import com.example.download.HttpDownloader;
 4 
 5 import model.Mp3Info;
 6 import android.app.Service;
 7 import android.content.Intent;
 8 import android.os.IBinder;
 9 
10 public class DownloadService extends Service {
11 
12     @Override
13     public IBinder onBind(Intent arg0) {
14         // TODO Auto-generated method stub
15         return null;
16     }
17     //Mp3ListActivity里面的,点击一行,onSelectedItem里的onStartService ,调用这里的onstart()
18     @Override
19     public void onStart(Intent intent, int startId) {
20         // TODO Auto-generated method stub
21         //从intent里面将mp3info取出来
22         Mp3Info mp3info=(Mp3Info) intent.getSerializableExtra("mp3info");
23         System.out.println("service----->"+mp3info);
24         DownloadThread downloadThread=new DownloadThread(mp3info);
25         Thread thread=new Thread(downloadThread);
26         thread.start();
27         super.onStart(intent, startId);
28     }
29     //onstar执行好,生成一个线程来执行下载
30     //创建线程的内部类
31     class DownloadThread implements Runnable{
32         //要能接受mp3info对象,创建构造函数
33         private Mp3Info mp3Info=null;
34         public DownloadThread(Mp3Info mp3Info){
35             this.mp3Info=mp3Info;
36             System.out.println("---in thread"+mp3Info.getMp3Name());
37         }
38         //在run里面实现下载
39             @Override
40       public void run() {
41         System.out.println("---in thread2"+mp3Info.getMp3Name());
42         // TODO Auto-generated method stub
43         //下载地址C:\apache-tomcat-7.0.42\webapps\mp3
44         String mp3Url="http://192.168.1.100:8080/mp3/"+mp3Info.getMp3Name();
45         HttpDownloader httpDownloader=new HttpDownloader();
46         int result=httpDownloader.downFile(mp3Url,"mp3/", mp3Info.getMp3Name());//放在sdcard里面哪个文件夹里
47     }
48     }
49 
50 
51 
52 }

HttpDownloader.java

 1 package com.example.download;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.File;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.InputStreamReader;
 8 import java.net.HttpURLConnection;
 9 import java.net.MalformedURLException;
10 import java.net.URL;
11 import utils.FileUtils;
12 
13 
14 
15 public class HttpDownloader {
16 
17     /**
18      * 根据URL下载文件,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容
19      * 1.创建一个URL对象
20      * 2.通过URL对象,创建一个HttpURLConnection对象
21      * 3.得到InputStram
22      * 4.从InputStream当中读取数据
23      * @param urlStr
24      * @return
25      */
26     public String download(String urlStr) {
27         StringBuffer sb = new StringBuffer();
28         String line = null;
29         BufferedReader buffer = null;
30         try {
31             // 创建一个URL对象
32             URL url = new URL(urlStr);
33             // 创建一个Http连接
34             HttpURLConnection urlConn = (HttpURLConnection) url
35                     .openConnection();
36             // 使用IO流读取数据
37             buffer = new BufferedReader(new InputStreamReader(urlConn
38                     .getInputStream()));
39             while ((line = buffer.readLine()) != null) {
40                 sb.append(line);
41             }
42         } catch (Exception e) {
43             e.printStackTrace();
44         } finally {
45             try {
46                 buffer.close();
47             } catch (Exception e) {
48                 e.printStackTrace();
49             }
50         }
51         return sb.toString();
52     }
53     public int downFile(String urlStr, String path, String fileName) {
54         InputStream inputStream = null;
55         try {
56             FileUtils fileUtils = new FileUtils();
57             
58             if (fileUtils.isFileExist(  fileName,path)) {
59                 return 1;
60             } else {
61                 inputStream = getInputStreamFromUrl(urlStr);
62                 System.out.println("urlStr----->"+urlStr+"path-->"+path+"filename-->"+fileName);
63                 File resultFile = fileUtils.write2SDFromInput(path,fileName, inputStream);
64                 System.out.println("httpDownloader---->"+resultFile);
65                 if (resultFile == null) {
66                     return -1;
67                 }
68             }
69         } catch (Exception e) {
70             e.printStackTrace();
71             return -1;
72         } finally {
73             try {
74                 inputStream.close();
75             } catch (Exception e) {
76                 e.printStackTrace();
77             }
78         }
79         return 0;
80     }
81     public InputStream getInputStreamFromUrl(String urlStr)
82             throws MalformedURLException, IOException {
83         URL url = new URL(urlStr);
84         HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
85         InputStream inputStream = urlConn.getInputStream();
86         return inputStream;
87     }
88 }

FileUtils.java

 1 package utils;
 2 
 3 import java.io.File;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 
 9 import android.os.Environment;
10 
11 public class FileUtils {
12     private String SDPATH;
13 
14     public String getSDPATH() {
15         return SDPATH;
16     }
17     public FileUtils() {
18         //得到当前外部存储设备的目录
19         // /SDCARD
20         SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator;
21         System.out.println("判断SDCard是否存在,是否有可读权限:"
22         + Environment.MEDIA_MOUNTED.endsWith(Environment.getExternalStorageState()));
23     }
24     /**
25      * 在SD卡上创建文件
26      * 
27      * @throws IOException
28      * 在哪个目录上生成这个文件,文件的名字
29      */
30     public File creatSDFile(String fileName,String dir) throws IOException {
31         File file = new File(SDPATH+dir + fileName);
32         System.out.println("file--->"+file);
33         file.createNewFile();
34         return file;
35     }
36     
37     /**
38      * 在SD卡上创建目录
39      * 
40      * @param dirName
41      */
42     public File creatSDDir(String dir) {
43         File dirFile = new File(SDPATH + dir+File.separator);
44         System.out.println("creatSDDir?---->"+dirFile.mkdirs());
45         return dirFile;
46     }
47 
48     /**
49      * 判断SD卡上的文件夹是否存在
50      */
51     public boolean isFileExist(String fileName,String path){
52         File file = new File(SDPATH + path+File.separator+fileName);
53         return file.exists();
54     }
55     
56     /**
57      * 将一个InputStream里面的数据写入到SD卡中
58      */
59     public File write2SDFromInput(String path,String fileName,InputStream input){
60         File file = null;
61         OutputStream output = null;
62         try{
63             creatSDDir(path);
64             file = creatSDFile( fileName,path );
65             output = new FileOutputStream(file);
66             byte buffer [] = new byte[4 * 1024];
67             int temp;
68             while((temp=input.read(buffer))!= -1){
69                 output.write(buffer,0,temp);
70             }
71             output.flush();
72         }
73         catch(Exception e){
74             e.printStackTrace();
75         }
76         finally{
77             try{
78                 output.close();
79             }
80             catch(Exception e){
81                 e.printStackTrace();
82             }
83         }
84         return file;
85     }
86 
87 }

Mp3ContentHandler.java

  1 package xml;
  2 
  3 import java.util.List;
  4 
  5 import model.Mp3Info;
  6 
  7 import org.xml.sax.Attributes;
  8 import org.xml.sax.SAXException;
  9 import org.xml.sax.helpers.DefaultHandler;
 10 //解析
 11 //内容处理器 ContentHandler 接口是解析xm的主体
 12 //handler使用的是adapter的设计模式
 13 //Adapter是连接后端数据和前端显示的适配器接口,
 14 //是数据和UI(View)之间一个重要的纽带。在常见的View(ListView,GridView)等地方都需要用到Adapter
 15 public class Mp3ListContentHandler extends DefaultHandler {
 16     private List<Mp3Info> info=null;//这边每次解析resource标签都会放入一个Mp3Info对象当中 ,一个标签就是一resource,再把每个对象放入List
 17     //Mp3ListActivity在调用此类的时候会生成List并且传进来
 18     private Mp3Info mp3info=null;//mp3info里面就是存放resource的值
 19     private String tagname;
 20     
 21     //添加get和set方便访问
 22     public List<Mp3Info> getInfo() {
 23         return info;
 24     }
 25 
 26     public void setInfo(List<Mp3Info> info) {
 27         this.info = info;
 28     }
 29     
 30     //Mp3ListActivity在调用此类的时候会生成List并且传进来
 31     public Mp3ListContentHandler(List<Mp3Info> info) {
 32         super();
 33         this.info = info;
 34     }
 35 
 36     @Override
 37    //遇到id这个标签,将值赋给Mp3Info的id属性
 38     public void characters(char[] ch, int start, int length)
 39             throws SAXException {
 40         // TODO Auto-generated method stub
 41         super.characters(ch, start, length);
 42         String temp=new String(ch,start,length);
 43         if(tagname.equals("id"))
 44         {
 45             mp3info.setId(temp);//如果标签是“id”,就把值赋予mp3info对象中的id变量中
 46         }
 47         else if(tagname.equals("mp3.name"))
 48         {
 49             mp3info.setMp3Name(temp);
 50         }
 51         else if(tagname.equals("mp3.size"))
 52         {
 53             mp3info.setMp3Size(temp);
 54         }
 55         else if(tagname.equals("Irc.name"))
 56         {
 57             mp3info.setIrcName(temp);
 58         }
 59         else if(tagname.equals("Irc.size"))
 60         {
 61             mp3info.setIrcSize(temp);
 62         }
 63         
 64     }
 65 
 66     @Override
 67     public void endDocument() throws SAXException {
 68         // TODO Auto-generated method stub
 69         super.endDocument();
 70     }
 71 
 72     @Override
 73     //标签解析结束
 74     public void endElement(String uri, String localName, String qName)
 75             throws SAXException {
 76         // TODO Auto-generated method stub
 77         super.endElement(uri, localName, qName);
 78         if(qName.equals("resource"))//这里用qName而不是tagname
 79         {
 80             info.add(mp3info);//如果遇到resource结尾,那么就把这个对象放入到List中
 81         }
 82         tagname="";
 83     }
 84 
 85     @Override
 86     public void startDocument() throws SAXException {
 87         // TODO Auto-generated method stub
 88         super.startDocument();
 89     }
 90 
 91     @Override
 92     //开始解析标签
 93     public void startElement(String uri, String localName, String qName,
 94             Attributes attributes) throws SAXException {
 95         // TODO Auto-generated method stub
 96         super.startElement(uri, localName, qName, attributes);
 97         this.tagname=localName;
 98         if(tagname.equals("resource"))
 99         {
100             mp3info=new Mp3Info();
101         }
102     }
103 
104 }

Mp3Info.java

 1 package model;
 2 
 3 import java.io.Serializable;
 4 
 5 /**
 6  * 把每一个<rescource>看成一个对象 mp3info对象 建一个实体类,代表现实中一个实体
 7  * Mp3info实体类
 8  * @author kyx
 9  */
10 public class Mp3Info implements Serializable{
11    /**
12      * 实现序列化接口
13      * 可以把对象变成字节码从内存中发送出去
14      */
15     private static final long serialVersionUID = 1L;
16 private String id;
17    private String mp3Name;
18    private String mp3Size;
19    private String IrcName;
20    private String IrcSize;
21 public String getId() {
22     return id;
23 }
24 public void setId(String id) {
25     this.id = id;
26 }
27 public String getMp3Name() {
28     return mp3Name;
29 }
30 public void setMp3Name(String mp3Name) {
31     this.mp3Name = mp3Name;
32 }
33 public String getMp3Size() {
34     return mp3Size;
35 }
36 public void setMp3Size(String mp3Size) {
37     this.mp3Size = mp3Size;
38 }
39 public String getIrcName() {
40     return IrcName;
41 }
42 public void setIrcName(String ircName) {
43     IrcName = ircName;
44 }
45 public String getIrcSize() {
46     return IrcSize;
47 }
48 public void setIrcSize(String ircSize) {
49     IrcSize = ircSize;
50 }
51 //还要生成一些构造函数,构造函数起码要有两个,一个是带参数的,一个是不带参数的
52 public Mp3Info(String id, String mp3Name, String mp3Size, String ircName,
53         String ircSize) {
54     super();
55     this.id = id;
56     this.mp3Name = mp3Name;
57     this.mp3Size = mp3Size;
58     IrcName = ircName;
59     IrcSize = ircSize;
60 }
61 //不带参数的的构造函数
62 public Mp3Info() {
63     super();
64 }
65 @Override
66 public String toString() {
67     return "Mp3Info [id=" + id + ", mp3Name=" + mp3Name + ", mp3Size="
68             + mp3Size + ", IrcName=" + IrcName + ", IrcSize=" + IrcSize + "]";
69 }
70 //toString方便测试鉴定
71 }


Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mp3player00"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="4"
        android:targetSdkVersion="4" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.mp3player00.Mp3ListActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="service.DownloadService"></service>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> 
</manifest>


调试中的问题

无法创建路径

问题根源

成功下载mp3文件

原文地址:https://www.cnblogs.com/kyxyes/p/3371585.html