在安卓中,可以直接用java的java.net.URL包訪問網絡下載數據。不同的是,安卓程序需要權限,需要在AndroidManifest.xml文件中聲明權限
<!-- 網絡權限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 操作sd卡權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
不過有個需要注意的是,我使用的是最新的adt安卓開發集成eclipse的安裝包,在使用網絡服務的時候,處理網絡請求的代碼,不能在主線程中進行,不然安卓會提示錯誤。
但是,有些組件設置值,他必須是在主線程的循環中,纔可以。
Looper loop = Looper.getMainLooper();
handler = new Handler(loop){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case SETTEXT:
//主線程ui更新text值
text.setText(msg.obj.toString());
break;
}
}
};
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
//新線程下載
new Thread(new Runnable() {
@Override
public void run() {
//新建一個下載
Download load = new Download(url);
String value = load.downloadAsString();
Message msg = handler.obtainMessage();
msg.obj = value;
msg.what = SETTEXT;
msg.sendToTarget();
}
}).start();
}
});
Download類:
package com.example.org.suju.download;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Environment;
import android.util.Log;
public class Download {
/** 連接url */
private String urlstr;
/** sd卡目錄路徑 */
private String sdcard;
/** http連接管理類 */
private HttpURLConnection urlcon;
public Download(String url)
{
this.urlstr = url;
//獲取設備sd卡目錄
this.sdcard = Environment.getExternalStorageDirectory() + "/";
urlcon = getConnection();
}
/*
* 讀取網絡文本
*/
public String downloadAsString()
{
StringBuilder sb = new StringBuilder();
String temp = null;
try {
InputStream is = urlcon.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
/*
* 獲取http連接處理類HttpURLConnection
*/
private HttpURLConnection getConnection()
{
URL url;
HttpURLConnection urlcon = null;
try {
url = new URL(urlstr);
urlcon = (HttpURLConnection) url.openConnection();
} catch (Exception e) {
e.printStackTrace();
}
return urlcon;
}
/*
* 獲取連接文件長度。
*/
public int getLength()
{
return urlcon.getContentLength();
}
/*
* 寫文件到sd卡 demo
* 前提需要設置模擬器sd卡容量,否則會引發EACCES異常
* 先創建文件夾,在創建文件
*/
public int down2sd(String dir, String filename, downhandler handler)
{
StringBuilder sb = new StringBuilder(sdcard)
.append(dir);
File file = new File(sb.toString());
if (!file.exists()) {
file.mkdirs();
//創建文件夾
Log.d("log", sb.toString());
}
//獲取文件全名
sb.append(filename);
file = new File(sb.toString());
FileOutputStream fos = null;
try {
InputStream is = urlcon.getInputStream();
//創建文件
file.createNewFile();
fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
while ((is.read(buf)) != -1) {
fos.write(buf);
//同步更新數據
handler.setSize(buf.length);
}
is.close();
} catch (Exception e) {
return 0;
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return 1;
}
/*
* 內部回調接口類
*/
public abstract class downhandler
{
public abstract void setSize(int size);
}
}
線程下載提示Activity:
用一個線程循環處理網絡下載,並使用下載類回調函數,發送處理消息給主線程消息處理方法,同步更新滾動條值。
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.download);
text = (TextView) findViewById(R.id.label);
load = (ProgressBar) findViewById(R.id.load);
//獲取傳遞的Intent的Bundle的url鍵值
final String url = getIntent().getExtras().getString("url");
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//這裏就一條消息
int pro = load.getProgress() + msg.arg1;
load.setProgress(pro);
text.setText(Integer.toString(pro));
if (pro >= load.getMax()) {
finish(); //結束下載進度框
}
}
};
new Thread(new Runnable() {
@Override
public void run() {
//另起線程執行下載,安卓最新sdk規範,網絡操作不能再主線程。
Download l = new Download(url);
load.setMax(l.getLength());
/**
* 下載文件到sd卡,虛擬設備必須要開始設置sd卡容量
* downhandler是Download的內部類,作爲回調接口實時顯示下載數據
*/
int status = l.down2sd("downtemp/", "1.ddd", l.new downhandler() {
@Override
public void setSize(int size) {
Message msg = handler.obtainMessage();
msg.arg1 = size;
msg.sendToTarget();
Log.d("log", Integer.toString(size));
}
});
//log輸出
Log.d("log", Integer.toString(status));
}
}).start();
}
<activity
android:name="com.example.org.suju.download.DownloadActivity"
android:theme="@android:style/Theme.Dialog"
></activity>
使用一個按鈕啓動下載對話框Activity,並傳遞數據
down2sd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, DownloadActivity.class);
Bundle bundle = new Bundle();
bundle.putString("url", urlstr.getText().toString());
intent.putExtras(bundle);
startActivity(intent);
}
});