第158页
(1)修改新建项目的res\layout目录下的布局文件main.xml,将默认添加的LinearLayout布局管理器修改为水平布局管理器,并将默认添加的TextView组件的android:id属性设置为@+id/editText_url;android:layout_weight属性设置为1;android:text属性设置为@string/defaultvalue;android:lines属性设置为1,然后在该TextView组件的下方添加一个“下载”按钮,具体代码请参见光盘。
(2)在该MainActivity中,创建程序中所需的成员变量,具体代码如下:
private EditText urlText; //下载地址编辑框
private Button button; //下载按钮
private Handler handler; //声明一个Handler对象
private boolean flag = false; //标记是否成功的变量
(3)在onCreate()方法中,获取布局管理器中添加的下载地址编辑框和“下载”按钮,并为“下载”按钮添加单击事件监听器,在重写的onClick()方法中,创建并开启一个新线程,用于从网络上获取文件;在重写的run()方法中,首先获取文件的下载地址,并创建一个相关的连接,然后获取输入流对象,并从下载地址中获取要下载文件的文件名及扩展名,再读取文件到一个输出流对象中,并关闭相关对象及断开连接,最后获取一个Message并发送消息,具体代码如下:
urlText = (EditText) findViewById(R.id.editText_url); //获取布局管理器中添加的下载地址编辑框
button = (Button) findViewById(R.id.button_go); //获取布局管理器中添加的“下载”按钮
//为“下载”按钮添加单击事件监听器
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//创建一个新线程,用于从网络上获取文件
new Thread(new Runnable() {
public void run() {
try {
String sourceUrl = urlText.getText().toString(); //获取下载地址
URL url = new URL(sourceUrl); //创建下载地址对应的URL对象
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection(); //创建一个连接
InputStream is = urlConn.getInputStream(); //获取输入流对象
if (is != null) {
String expandName = sourceUrl.substring(
sourceUrl.lastIndexOf(".") + 1,
sourceUrl.length()).toLowerCase(); //获取文件的扩展名
String fileName = sourceUrl.substring(
sourceUrl.lastIndexOf("/") + 1,
sourceUrl.lastIndexOf(".")); //获取文件名
File file = new File("/sdcard/pictures/"
+ fileName + "." + expandName); //在SD卡上创建文件
FileOutputStream fos = new FileOutputStream(
file); //创建一个文件输出流对象
byte buf[] = new byte[128]; //创建一个字节数组
//读取文件到输出流对象中
while (true) {
int numread = is.read(buf);
if (numread <= 0) {
break;
} else {
fos.write(buf, 0, numread);
}
}
}
is.close(); //关闭输入流对象
urlConn.disconnect(); //关闭连接
flag = true;
} catch (MalformedURLException e) {
e.printStackTrace(); //输出异常信息
flag = false;
} catch (IOException e) {
e.printStackTrace(); //输出异常信息
flag = false;
}
Message m = handler.obtainMessage(); //获取一个Message
handler.sendMessage(m); //发送消息
}
}).start(); //开启线程
}
});
(4)创建一个Handler对象,在重写的handleMessage()方法中,根据标记变量flag的值显示不同的消息提示,具体代码如下:
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (flag) {
Toast.makeText(MainActivity.this, "文件下载完成!",
Toast.LENGTH_SHORT).show(); //显示消息提示
} else {
Toast.makeText(MainActivity.this, "文件下载失败!",
Toast.LENGTH_SHORT).show(); //显示消息提示
}
super.handleMessage(msg);
}
};
(5)由于在本实例中需要访问网络资源并向SD卡上写文件,所以还需要在AndroidManifest.xml文件中指定允许访问网络资源和向SD卡上写文件的权限,具体代码如下:
运行本实例,在下载地址编辑框中输入要下载文件的URL地址,单击“下载”按钮,即可将指定的文件下载到SD卡上。成功的前提是指定的URL地址真实存在,并且相应的文件也存在。实例运行结果如图14.5和图14.6所示。