下载网络文件到SD卡上
下面一个一个类的来进行介绍:
1.DownLoadProgress.java主控件界面:
package cn.com;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class DownLoadProgress extends Activity {
private Button download;// 下载按钮
private MediaPlayer mMediaPlayer;
Thread downThread;// 下载子线程
private ProgressBar myProgressBar;//显示进度条的ProgressBar
TextView resultView;
//子线程发送消息给UI线程来更新ProgressBar的进度
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (!Thread.currentThread().isInterrupted()) {
switch (msg.what) {
case 1:
int size = msg.getData().getInt("size");
myProgressBar.setProgress(size);// 设置当前刻度
int result = (int) (((float) myProgressBar.getProgress() / (float) myProgressBar
.getMax()) * 100);
resultView.setText(result + "%");
if (myProgressBar.getMax() == myProgressBar.getProgress()) {
Toast.makeText(DownLoadProgress.this, R.string.success,
1).show();
}
break;
case -1:
String error = msg.getData().getString("error");
Toast.makeText(DownLoadProgress.this, error, 1).show();
break;
}
}
super.handleMessage(msg);
}
};
public Thread getThreadInstance() {
return downThread;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//在SD卡上新建文件夹来进行文件存储
DirectoryHelper fileHelper = new DirectoryHelper();
fileHelper.getSdCardPath();
myProgressBar = (ProgressBar) findViewById(R.id.progressBar);
resultView = (TextView) findViewById(R.id.result);
download = (Button) findViewById(R.id.download);
download.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
downLoadVideo();
}
});
}
//新起一个线程进行文件下载
public void downLoadVideo() {
mMediaPlayer = new MediaPlayer();
// Sets the audio stream type for this MediaPlayer
mMediaPlayer.setAudioStreamType(2);
MediaPlayerListener listener = new MediaPlayerListener();
listener.setAllListener(mMediaPlayer);
ThreadForRunnable thread = new ThreadForRunnable(this, myProgressBar,
handler);
new Thread(thread).start();
}
}
2.当启动一个新线程后,就调用ThreadForRunnable类,此类实现了Runnable接口的类,就调用此类的run方法: ThreadForRunnable.java文件内容:
package cn.com;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ProgressBar;
public class ThreadForRunnable implements Runnable {
String TAG = "***********************";
Context con;
ProgressBar myProgressBar;
Handler handler;
public ThreadForRunnable(Context con, ProgressBar myProgressBar,
Handler handler) {
this.con = con;
this.myProgressBar = myProgressBar;
this.handler = handler;
}
@Override
public void run() {
// http://lh5.ggpht.com/_2N-HvtdpHZY/SYjwSZO8emE/AAAAAAAABGI/EHe7N52mywg/s144-c/20090129.jpg
// http://forum.ea3w.com/coll_ea3w/attach/2008_10/12237832415.3gp
//String url = "http://www.dubblogs.cc:8751/Android/Test/Media/3gp/test.3gp";
//String url = "http://net.itcast.cn/QQWubiSetup.exe";
String url = "http://wd.ggzx.net/myfile/xinge/wozaizheli.mp3";
try {
// 在线程运行中,调用自定义函数抓下文件
VideoDownload vd = new VideoDownload(con, url, handler);
vd.setDataSource1();
//vd.setDataSource1();// 下特定视频文件
//vd.setDataSource2();//下载exe文件
//vd.setDataSource();// 下载apk文件
//vd.videoGet();
myProgressBar.setMax((int) vd.getFileSize());// 设置进度条的最大刻度
} catch (Exception e) {
Message msg = new Message();
msg.what = -1;
msg.getData().putString("error", "下载失败");
handler.sendMessage(msg);
Log.e(TAG, e.toString());
}
}
}
3.VideoDownload.java这个类文件主要是对各种文件进行下载的一些方法,里面我只使用了setDataSource1()方法,其他的方法,大家可以自己进行测试:
package cn.com;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class VideoDownload {
String TAG = "***********************";
Context con;
private String downloadUrl;// 下载路径
File dFile1;
FileOutputStream outs1;
private long fileSize = 0;// 原始文件大小
Handler handler;
/**
* 获取文件大小
*
* @return
*/
public long getFileSize() {
return fileSize;
}
public VideoDownload(Context con, String url, Handler handler) {
this.con = con;
this.downloadUrl = url;
this.handler = handler;
}
public void videoGet() {//下载一个视频
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
HttpPost httpost = new HttpPost(Constants.videoURL);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("type", "video"));
nvps.add(new BasicNameValuePair("id", String.valueOf(29)));
nvps.add(new BasicNameValuePair("fileId", String.valueOf(1)));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
// This is always a final response
response = httpclient.execute(httpost);
HttpEntity entity = response.getEntity();
fileSize = entity.getContentLength();
System.out.println("fileSize----------->" + fileSize);
InputStream is = entity.getContent();
if (is == null) {
// 680kb
throw new RuntimeException("stream is null");
}
dFile1 = new File(Constants.filePath, 29 + ".mp4");
FileOutputStream fos = new FileOutputStream(dFile1);
int numread = 0;
int readLen = 0;
byte buf[] = new byte[128];
do {
numread = is.read(buf);
readLen = readLen + numread;
System.out.println("readLen----------->" + readLen);
if (fileSize != -1 ) {
updateProgressBar(readLen);
}
if (numread < 0) {
break;
}
fos.write(buf, 0, numread);
} while (true);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void apkGet() {
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
HttpPost httpost = new HttpPost(Constants.imageURL);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("type", "demo"));
nvps.add(new BasicNameValuePair("id", String.valueOf(29)));
nvps.add(new BasicNameValuePair("fileId", "1"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
// This is always a final response
response = httpclient.execute(httpost);
HttpEntity entity = response.getEntity();
fileSize = entity.getContentLength();
System.out.println("fileSize----------->" + fileSize);
InputStream is = entity.getContent();
System.out.println("***************************" + is);
dFile1 = new File(Constants.filePath, 29 + ".apk");
outs1 = new FileOutputStream(dFile1);
byte buf[] = new byte[1024];
int numread = 0;
int readLen = 0;
do {
// Start reading data from the URL stream
numread = is.read(buf);
readLen = readLen + numread;
updateProgressBar(readLen);
if (numread < 0) {
System.out.println("the end !!!!");
break;
}
outs1.write(buf, 0, numread);
} while (true);
// openFile(dFile1);
System.out.println("_____apk download success!!!_____");
} catch (Exception e) {
e.printStackTrace();
}
}
//更新进度条(当可以通过getContentLength来获取文件长度的情况下)
public void updateProgressBar(int readLen) {
Message msg = new Message();
msg.what = 1;
msg.getData().putInt("size", readLen);
//通过主线程的handler通知主线程更新UI进度条的进度
handler.sendMessage(msg);
}
/* 自定义setDataSource,由线程启动 */
public void setDataSource1() throws Exception {
URL myURL = new URL(downloadUrl);
URLConnection conn = myURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
//当可以返回下载文件大小的情况下
//方便后续显示进度条的总内容长度
fileSize = conn.getContentLength();
System.out.println("fileSize--------------->" + fileSize);
//将下载文件保存到指定文件夹
File myFileTemp = new File(Constants.filePath, "video."
+ getFileExtension(downloadUrl));
// the file to which this stream writes
FileOutputStream fos = new FileOutputStream(myFileTemp);
byte buf[] = new byte[128];
int numread = 0;
int readLen = 0;
do {
numread = is.read(buf);
if (numread <= 0) {
break;
}
fos.write(buf, 0, numread);
readLen = readLen + numread;
System.out.println("readLen----------->" + readLen);
if(fileSize != -1)
//不断的更新进度条
updateProgressBar(readLen);
} while (true);
try {
is.close();
System.out.println("Download is over!!!!!!");
} catch (Exception ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
}
//下载特定类型文件
public void setDataSource2() throws Exception {
URL myURL = new URL(downloadUrl);
HttpURLConnection conn = (HttpURLConnection) myURL.openConnection();
conn.setConnectTimeout(6 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Referer", downloadUrl);
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty(
"User-Agent",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
InputStream is = conn.getInputStream();
fileSize = conn.getContentLength();
System.out.println("fileSize--------------->" + fileSize);
File myFileTemp = new File(Constants.filePath, "video."
+ getFileExtension(downloadUrl));
// the file to which this stream writes
FileOutputStream fos = new FileOutputStream(myFileTemp);
byte buf[] = new byte[128];
int numread = 0;
int readLen = 0;
do {
numread = is.read(buf);
if (numread <= 0) {
break;
}
fos.write(buf, 0, numread);
readLen = readLen + numread;
updateProgressBar(readLen);
} while (true);
try {
is.close();
System.out.println("Download is over!!!!!!");
} catch (Exception ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
}
// 取得加载文件的后缀名
private String getFileExtension(String strFileName) {
File myFile = new File(strFileName);
String strFileExtension = myFile.getName();
strFileExtension = (strFileExtension.substring(strFileExtension
.lastIndexOf(".") + 1)).toLowerCase();
if (strFileExtension == "") {
/* 若无法顺利取得扩展名,默认为.dat */
strFileExtension = "dat";
}
return strFileExtension;
}
}
4.DirectoryHelper.java文件,这个文件是在判断SD卡是否存在需要的文件夹的判断,如果没有就新建目标文件夹
package cn.com;
import java.io.File;
import android.os.Environment;
public class DirectoryHelper
{
//构建应用在SD卡上的相关文件夹
public void getSdCardPath()
{
File sdcardDir = Environment.getExternalStorageDirectory();
String path = sdcardDir.getParent() + sdcardDir.getName();
Constants.filePath = path + java.io.File.separator + "VideoDownLoad";
System.out.println("__________" + Constants.filePath);
createFile();
}
public void createFile()
{
try
{
// 1.判断是否存在sdcard
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState()))
{
// 目录
System.out.println("_______create Directory________");
File path = new File(Constants.filePath);
if (!path.exists())
{
// 2.创建目录,可以在应用启动的时候创建
path.mkdirs();
}
// 文件
// File f = new File(fileDirectory + "/notes.txt");
// if (!f.exists()) {
// // 3.创建文件
// f.createNewFile();
// }
}
} catch (Exception e)
{
e.printStackTrace();
}
}
}
5.Constants.java这是个常量类:
package cn.com;
public class Constants {
//这里的地址大家可以自己修改下
public static String filePath = "";
public final static String HOST = "********";
public final static int PORT = **;
public final static String HOST_IP = "http://" + HOST + ":" + PORT;
public static String imageURL = HOST_IP + "****************";
public final static String videoURL = HOST_IP
+ "********";
}
6.MediaPlayerListener.java这个文件主要是在文件下载完成后的一些额外播放操作:
package cn.com;
import android.media.MediaPlayer;
import android.util.Log;
public class MediaPlayerListener {
String TAG = "_____TAG_____";
public MediaPlayerListener() {
}
public void setAllListener(MediaPlayer mMediaPlayer) {
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
Log.i(TAG, "Error on Listener, what: " + what + "extra: "
+ extra);
return false;
}
});
mMediaPlayer
.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
// TODO Auto-generated method stub
Log.i(TAG, "Update buffer: "
+ Integer.toString(percent) + "%");
}
});
mMediaPlayer
.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.i(TAG, "mMediaPlayer Listener Completed");
}
});
mMediaPlayer
.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.i(TAG, "Prepared Listener");
}
});
}
}
最后一个类我基本没有用上,也懒得删除掉了,因为后续完善代码的时候肯定也会用上;
7.main.xml文件很简单:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ProgressBar android:layout_width="fill_parent"
android:layout_height="18dip" style="?android:attr/progressBarStyleHorizontal"
android:id="@+id/progressBar" />
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:gravity="center"
android:id="@+id/result" />
<Button android:text="download" android:id="@+id/download"
android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>
8.最后是配置文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.com" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".DownLoadProgress" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 访问internet权限 -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>