在安卓中,可以直接用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:theme。
<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); } });
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://www.cnblogs.com/lzjsky/p/4933593.html