我用eclipse上写android音乐播放器,用tomcat建服务器,
想实现从服务器上下载歌曲、歌词文件。
结果下载的歌曲和歌词文件是一样大?为什么?我想了好几天了。求高人解答?
声明:电脑里的原文件是不一样大的
他当时什么错都没报我,最后才看到两个大小相同
代码太长了,贴不上来
下载前:
下载后:
如果有哪位热心的大神帮我解决的话,联系我QQ:1129826190
跪等大神
看看文件的具体内容吧,是不是错误我将歌曲的数据下载到 LRC 文件中了。
上一张图是正确的,下载有问题。具体问题需要仔细排查。
这需要仔细的看你的代码了,把你代码贴出来看看吧!
主函数:
package com.mp3player;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import com.download.HttpDownloader;
import com.model.Mp3Info;
import com.mp3player.service.DownloadService;
import com.xml.Mp3ListContentHandler;
public class Mp3ListActivity extends ListActivity{
private List<Mp3Info> mp3Infos =null;
private ListView listView;
private Handler handler = new Handler();
private List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
private int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_mp3_list);
listView = getListView();
}
@Override
protected void onResume() {
super.onResume();
update();
}
// //再点击MENU按钮之后,会调用该方法,我们可以在这个方法中加入自己的空间按钮
// private static final int UPDATE = 1;
// private static final int ABOUT = 2;
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// menu.add(0, UPDATE, 1, R.string.mp3list_update);
// menu.add(0, ABOUT, 2, R.string.mp3list_about);
// return super.onCreateOptionsMenu(menu);
// }
//
// @Override
// public boolean onOptionsItemSelected(MenuItem item) {
// if(item.getItemId() == UPDATE){
// //点击更新按钮
// update();
// }else if(item.getItemId() == ABOUT){
// //点击关于按钮
// }
// return super.onOptionsItemSelected(item);
// }
//写一个update方法,用update调用子线程update
private void update(){
new UpdateThread().start();
}
class UpdateThread extends Thread{
public void run() {
//下载包含所有MP3基本信息的resources.xml文件
String xml = downloadXML("http://100.66.3.39:8080/mp3/resources.xml");
// String xml = downloadXML("http://192.168.191:8080/mp3/resources.xml");
//对xml文件进行解析,并将解析的结果放置到Mp3Infos对象中,最后将这些Mp3Infos对象放置到List中
mp3Infos = parse(xml);
Runnable r = new Runnable() {
@Override
public void run() {
buildSimpleAdapter();
//创建一个SimpleAdapter对象
SimpleAdapter simpleAdapter = new SimpleAdapter(Mp3ListActivity.this, list, R.layout.mp3info_item,
new String[]{"mp3_name","mp3_size"}, new int[]{R.id.mp3_name, R.id.mp3_size});
listView.setAdapter(simpleAdapter);
//将指针指向一个空地址
list = new ArrayList<Map<String,Object>>();
System.out.println("1111" + Thread.currentThread().getName());
}
};
//认真了解 handler、looper、message、queue之间的关系。
//Thread.currentThread()返回当前该线程的对象
//post调用子线程中的方法,在主线程中运行
handler.post(r);
System.out.println("2222" + Thread.currentThread().getName());
}
}
//下载resources.XML文件
private String downloadXML(String urlStr){
HttpDownloader httpDownloader = new HttpDownloader();
String result = httpDownloader.download(urlStr);
return result;
}
//解析XML文件
private List<Mp3Info> parse (String xmlStr){
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
Mp3ListContentHandler mp3ListContentHandler = new Mp3ListContentHandler();
try{
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
//获得mp3ListContentHandler的处理规则
xmlReader.setContentHandler(mp3ListContentHandler);
xmlReader.parse(new InputSource(new StringReader(xmlStr)));
}catch(Exception e){
return null;
}
return mp3ListContentHandler.getInfos();
}
//迭代出mp3Infos里的内容
private void buildSimpleAdapter(){
if(mp3Infos != null){
for (Iterator<Mp3Info> iterator = mp3Infos.iterator(); iterator.hasNext();) {
Mp3Info mp3Info = (Mp3Info) iterator.next();
Map<String,Object> map = new HashMap<String, Object>();
map.put("mp3_name", mp3Info.getMp3Title());
map.put("mp3_size", mp3Info.getMp3Size());
list.add(map);
}
}
}
//下载MP3
/*ListView:整个屏幕的ListView
* view:点击的view对象
* position:点击view条目处于那一个位置
* id:点击这个条目的ID
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
new HttpDownThread(position).start();
super.onListItemClick(l, v, position, id);
}
class HttpDownThread extends Thread{
private int position;
public HttpDownThread(int position) {
super();
this.position = position;
}
@Override
public void run() {
//根据用户点击列表当中的位置来得到之前的mp3Infos中获得的Mp3Info对象
Mp3Info mp3Info = mp3Infos.get(position);
System.out.println("----------------从取出List<Mp3Info> mp3Infos中mp3Info对象---------------->" + mp3Info);
//生成Intent对象
Intent intent = new Intent();
//将Mp3Info对象存入Intent对象中
intent.putExtra("mp3Info", mp3Info);
//在Mp3Info.java里面设置序列化后,设置Intent跳转的目的地
intent.setClass(Mp3ListActivity.this, DownloadService.class);
//启动Service
startService(intent);
}
}
}
HttpDownloader
package com.download;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.net.IpPrefix;
import mars.utils.FileUtils;
/*根据URL下载文件,前提是文件中的内容是文本,函数的返回值就是文件中的内容
4.从InputStream当中读取数据
*/
public class HttpDownloader {
private URL url = null;
private InputStream inputStream = null;
public String download(String urlStr){
StringBuffer sb = new StringBuffer();
String line = null;
BufferedReader buffer = null;
try {
// //创建一个URL对象
// url = new URL(urlStr);
// ///创建一个http链接
// HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
try{
inputStream = getInputStreamFromUrl(urlStr);
//使用IO流读取数据
buffer = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
while((line = buffer.readLine()) != null){
sb.append(line);
}
}finally {
buffer.close();
}
} catch (Exception e) {
return null;
}
return sb.toString();
}
/**
urlStr下载文件的链接; path把文件存在sd卡的那一个目录上; fileName以什么样的文件名保存文件
*/
public int downFile(String urlStr, String path, String fileName) {
try {
FileUtils fileUtils = new FileUtils();
if (fileUtils.isFileExist(path , fileName)) {
return 1;
}
try{
inputStream = getInputStreamFromUrl(urlStr);
if(inputStream != null){
File resultFile = fileUtils.write2SDFromInput(path,fileName, inputStream);
if (resultFile == null) {
return -1;
}
}
}finally{
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
return -1;
}
return 0;
}
//根据URL得到输入流
public InputStream getInputStreamFromUrl(String urlStr)
throws MalformedURLException, IOException {
url = new URL(urlStr);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
if(urlConn.getResponseCode() == 200){
inputStream = urlConn.getInputStream();
return inputStream;
}else{
System.out.println("网址错误");
return null;
}
}
}
DownloadService
package com.mp3player.service;
import com.download.HttpDownloader;
import com.model.Mp3Info;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;
public class DownloadService extends Service {
private Handler handler = new Handler();
@Override
public IBinder onBind(Intent intent) {
return null;
}
//每次用户点击ListActivity当中的一个条目时,就会调用该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//从Intent对象中将Mp3Info对象取出
Mp3Info mp3Info = (Mp3Info)intent.getSerializableExtra("mp3Info");
System.out.println("----------------在DownloadService中取出Intent对象中mp3Info对象--------------->"+mp3Info);
//生成一个下载线程,并将mp3Info对象作为参数传递到对象中
DownloadThread downloadThread = new DownloadThread(mp3Info);
//启动新线程
Thread thread = new Thread(downloadThread);
thread.start();
return super.onStartCommand(intent, flags, startId);
}
class DownloadThread implements Runnable{
private int mp3Result;
private int lrcResult;
private Mp3Info mp3Info = null;
public DownloadThread(Mp3Info mp3Info){
this.mp3Info = mp3Info;
}
@Override
public void run() {
//根据Mp3文件名字,生成下载地址100.66.3.39
String mp3Url = "http://100.66.3.39:8080/mp3/" + mp3Info.getMp3Name();
//根据lrc文件名字,生成下载地址
String lrcUrl = "http://100.66.3.39:8080/mp3/" + mp3Info.getLrcName();
//创建httpDownloader对象
HttpDownloader httpDownloader = new HttpDownloader();
//将文件下载下来,并储存到SDCard当中
mp3Result = httpDownloader.downFile(mp3Url, "mp3", mp3Info.getMp3Title());
lrcResult = httpDownloader.downFile(mp3Url, "mp3", mp3Info.getLrcTitle());
//-1:代表下载文件出错 0:代表下载文件成功 1:代表文件已经存在
System.out.println("----------------lrcResult------------->" + lrcResult);
Runnable r = new Runnable() {
@Override
public void run() {
switch(mp3Result){
case 0:
Toast.makeText(DownloadService.this, mp3Info.getMp3Title()+ "下载成功", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(DownloadService.this, mp3Info.getMp3Title()+"文件已存在", Toast.LENGTH_SHORT).show();
break;
case -1:
Toast.makeText(DownloadService.this, mp3Info.getMp3Title()+"下载失败", Toast.LENGTH_SHORT).show();
break;
}
switch(lrcResult){
case 0:
Toast.makeText(DownloadService.this, mp3Info.getLrcTitle()+"下载成功", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(DownloadService.this, mp3Info.getLrcTitle()+"文件已存在", Toast.LENGTH_SHORT).show();
break;
case -1:
Toast.makeText(DownloadService.this, mp3Info.getLrcTitle()+"下载失败", Toast.LENGTH_SHORT).show();
break;
}
}
};
handler.post(r);
}
}
}
Mp3Info
package com.model;
import java.io.Serializable;
public class Mp3Info implements Serializable{
/**
* Serializable序列化
* 作用:把对象从内存中变成字节码,然后放到硬盘里去
*/
private static final long serialVersionUID = 1L;
private String id;
private String mp3Title;
private String mp3Name;
private String mp3Size;
private String lrcTitle;
private String lrcName;
private String lrcSize;
//get、set 方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMp3Title() {
return mp3Title;
}
public void setMp3Title(String mp3Title) {
this.mp3Title = mp3Title;
}
public String getMp3Name() {
return mp3Name;
}
public void setMp3Name(String mp3Name) {
this.mp3Name = mp3Name;
}
public String getMp3Size() {
return mp3Size;
}
public void setMp3Size(String mp3Size) {
this.mp3Size = mp3Size;
}
public String getLrcTitle() {
return lrcTitle;
}
public void setLrcTitle(String lrcTitle) {
this.lrcTitle = lrcTitle;
}
public String getLrcName() {
return lrcName;
}
public void setLrcName(String lrcName) {
this.lrcName = lrcName;
}
public String getLrcSize() {
return lrcSize;
}
public void setLrcSize(String lrcSize) {
this.lrcSize = lrcSize;
}
//有参构造函数
public Mp3Info(String id, String mp3Title, String mp3Name, String mp3Size,
String lrcTitle, String lrcName, String lrcSize) {
super();
this.id = id;
this.mp3Title = mp3Title;
this.mp3Name = mp3Name;
this.mp3Size = mp3Size;
this.lrcTitle = lrcTitle;
this.lrcName = lrcName;
this.lrcSize = lrcSize;
}
//无参构造函数
public Mp3Info() {
super();
}
@Override
public String toString() {
return "Mp3Info [id=" + id + ", mp3Title=" + mp3Title + ", mp3Name="
+ mp3Name + ", mp3Size=" + mp3Size + ", lrcTitle=" + lrcTitle
+ ", lrcName=" + lrcName + ", lrcSize=" + lrcSize + "]";
}
}
FileUtils
package mars.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.model.Mp3Info;
import android.os.Environment;
import android.util.Log;
public class FileUtils{
private String SDCardRoot;
public FileUtils() {
//Environment.getExternalStorageDirectory()
//通过Environment的静态方法getExternalStorageDirectory()得到当前SD卡的目录
SDCardRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
}
/**
* 在SD卡上创建文件
* dir 目录
* @throws IOException
*/
public File creatFileInSDCard(String dir, String fileName) throws IOException {
File file = new File(SDCardRoot+ dir + File.separator + fileName);
System.out.println("----------------创建文件dirFile------------>"+file.getName());
file.createNewFile();
return file;
}
/**
* 在SD卡上创建目录
* @param dirName
*/
public File creatSDDir(String dir) {
File dirFile = new File(SDCardRoot + dir + File.separator);
System.out.println("----------------创建目录dirFile------------>"+dirFile.mkdirs());
return dirFile;
}
/**
* 判断SD卡上的文件夹是否存在
*/
public boolean isFileExist(String path , String fileName){
File file = new File(SDCardRoot + path +File.separator + fileName);
return file.exists();
}
/**
* 将一个InputStream里面的数据写入到SD卡中
* path:把InPutStream的数据写到那个目录(路径)
* filName:文件名
* input:从此inputstream写入数据到新建的文件里去
*/
public File write2SDFromInput(String path,String fileName,InputStream inputStream){
File file = null;
OutputStream output = null;
try{
try{
//创建目录
creatSDDir(path);
//在SD卡上创建文件
file = creatFileInSDCard(path , fileName);
output = new FileOutputStream(file);//output写入数据
byte buffer [] = new byte[4 * 1024];
int temp;
while((temp = inputStream.read(buffer)) != -1){
output.write(buffer, 0, temp);
}
output.flush();//flush清空缓存
}finally{
output.close();
}
} catch(Exception e){
e.printStackTrace();
}
return file;//file关闭数据
}
/*
* 读取目录中的mp3文件的名字和大小
*/
//@SuppressWarnings("unchecked")
public List<Mp3Info> getMp3Files(String path){
List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>();
try{
File file = new File(SDCardRoot + path);
//返回指定路径下所有文件列表
File [] files = file.listFiles();
for(int i = 0; i < files.length; i++){
//读取以.mp3为后缀名的目录名
if (files [i] .getName().endsWith("mp3")){
Mp3Info mp3Info = new Mp3Info();
mp3Info.setMp3Title(files[i].getName());
mp3Info.setMp3Size(files[i].length() + "");
mp3Infos.add(getLrcTitle(mp3Info,path));
System.out.println("----------------写入到本地的歌曲----------->" + mp3Infos);
}
}
}catch(Exception e){
return null;
}
return mp3Infos;
}
//读取目录中的lrc文件的名字和大小
private Mp3Info getLrcTitle(Mp3Info mp3Info,String path){
try{
File file = new File(SDCardRoot + path);
File [] files = file.listFiles();
for(File ff : files){
//读取以lrc为后缀明的文件,并且是放在第0个位置的目录名
问题应该出在这里
mp3Info.setLrcTitle(ff.getName());
mp3Info.setLrcSize(ff.length()+ "");
Log.d("mp3", mp3Info.getMp3Size()+"");
Log.d("lrc", mp3Info.getLrcSize()+"");
System.out.println("----------------写入到本地的歌词----------->"+ mp3Info);
}
}
}catch(Exception e){
System.out.println("歌词不存在!");
}
return mp3Info;
}
}
应该是下载的问题,我也遇到过这样的问题。而且下载过后的mp3文件虽然可以播放,但音质完全不行。目测是下载的问题