Android请求网络数据下载APK安装包

       今天写了个输入网址从网络下载一个apk安装包的小例子。把它记录下来以后方便自己使用。

运行效果图:

注意事项:安卓6.0系统以上要动态申请一些危险的权限,就是要主动弹出对话框问用户愿不愿意调取通信录名单,获得存储权限,创建文件权限等等,安卓6.0以前是安装时在Manifest写入的权限默认就拥有了,不需要询问客户。今天我写的程序是没有主动询问客户的代码(动态申请权限),所以在manifest中对uses-sdkVersion要注意,最大的版本要小于23,这样6.0以上手机就知道帮助你用兼容模式运行程序,不然是运行不出来的。

Manifest代码:

 <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="22" />
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

XML代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center" >
    <TextView
        android:id="@+id/tv_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="文件存放位置" />
    <TextView
        android:id="@+id/tv_size"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SD卡剩余空间" />
    <Button
        android:id="@+id/b_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击下载文件" />
<RelativeLayout 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <!-- android:indeterminate="false"flase才是精确显示,开始写true不显示 !-->
     <ProgressBar
        android:id="@+id/pb_scheduel"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="200dp"
        android:layout_height="50dp" 
        android:layout_centerHorizontal="true"
        android:indeterminate="false"
        android:progress="0"
        android:max="100"/>
     <TextView
         android:id="@+id/tv_scheduel"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginLeft="5dp"
         android:layout_toRightOf="@+id/pb_scheduel"
         android:textColor="#000000"
         android:layout_centerHorizontal="true"
         android:text="0%" />
</RelativeLayout>

</LinearLayout>

JAVA代码:

public class DownLoadFile extends FragmentActivity {
	private Handler handler;
	private TextView tv_address, tv_size, tv_scheduel;
	private Button b_click;
	private ProgressBar pb_scheduel;
	private URL url;
	private Message msg;
	double totalLength = 0.0;
	String downloadFileDirectory;
	InputStream stream;
	OutputStream output;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.download_file);
		tv_address = (TextView) findViewById(R.id.tv_address);
		tv_size = (TextView) findViewById(R.id.tv_size);
		b_click = (Button) findViewById(R.id.b_click);
		pb_scheduel = (ProgressBar) findViewById(R.id.pb_scheduel);
		tv_scheduel = (TextView) findViewById(R.id.tv_scheduel);
		pb_scheduel.setProgress(0);
		
		try {
			// url=new
			// URL("https://clfile.imooc.com/class/assist/119/4858629/Android%206.0%20%E5%8A%A8%E6%80%81%E6%9D%83%E9%99%90%E7%94%B3%E8%AF%B7.pdf");
			url = new URL("https://www.imooc.com/mobile/mukewang.apk");
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		handler = new myHandler();
		b_click.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				Thread thread = new myThread();
				thread.start();
			}
		});
	}

	class myHandler extends Handler {
		int Progress;

		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			if (msg.what == 555) {
				Progress = msg.arg1;//handler创建在主线程中,现在的代码运行在主线程中
				pb_scheduel.setProgress(Progress);// 设置进度条进度
				tv_scheduel.setText(Progress + "%");// 显示
			} else if (msg.what == 777) {
				tv_size.setText("SD卡剩余空间:" + msg.getData().getString("sd"));// bundle的方式取数据
				tv_address.setText("SD卡路径:" + msg.getData().getString("a"));
			}
		}
	}

	class myThread extends Thread {

		@SuppressWarnings("unused")
		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			// 判断存储卡是否存在是否可读可写
			if (Environment.MEDIA_MOUNTED.equals(Environment
					.getExternalStorageState())) {
				downloadFileDirectory = Environment
						.getExternalStorageDirectory()
						+ File.separator
						+ "downSB" + File.separator + "mukewang.apk";// 下载的文件路径
				File file = new File(downloadFileDirectory);
				if (!file.exists())// 判断文件目录是否存在
					file.getParentFile().mkdirs();// File.getParentFile()获取父目录不包括文件名,不存在则创建
				try {
					file.createNewFile();// 创建what.apk文件
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				URLConnection connect = null;
				try {
					if (url != null)
						connect = url.openConnection();// 返回一个connection
					else {
						System.out.println("你提供那个的网址不能下载。");
						return;
					}
					totalLength = connect.getContentLength();// 下载的文件总长度
					msg = handler.obtainMessage(777);
					Bundle bundle = new Bundle();// bundle方式传递数据
					bundle.putString("a", Environment
							.getExternalStorageDirectory().getPath());
					bundle.putString("sd", SDStorage
							.GetSDAvailableSize(getApplicationContext()));
					msg.setData(bundle);// bundle和msg的联系
					handler.sendMessage(msg);
					if (totalLength < SDStorage
							.GetSDAvailableSize2(getApplicationContext())) {// 错误点看错了,long和double可以比较
						int length = 0;
						stream = connect.getInputStream();// 返回输入流
						byte[] b = new byte[1024];
						output = new FileOutputStream(file);// 创建输出到文件的输出流
						int downloadSize = 0;// 已经下载的文件长度
						while ((length = stream.read(b)) != -1) {// 每次读取到数组b中返回实际读取的字节数
							output.write(b,0,length);// 从b数组中拿到往文件中写入
							downloadSize += length;
							msg = handler.obtainMessage(555);// 555标志消息
							msg.arg1 = (int) (downloadSize * 100 / totalLength);// 求出现在的进度
							handler.sendMessage(msg);// 发送到主线程更新进度条
						}
						stream.close();
						output.close();
					} else {
						// Toast.makeText(DownLoadFile.this, "手机存储空间不够",
						// 1).show();//子线程中不显示toast,不该写
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} else {
				// Toast.makeText(DownLoadFile.this, "您的存储设备不允许使用",
				// Toast.LENGTH_LONG).show();
			}
		}
	}

}

SD卡剩余空间的计算代码:

public class SDStorage {
	/**
	 * @获取手机SD卡里剩余可用空间大小
	 * 存储区域被划分为多个块,有些块不能使用
	 */
	@SuppressLint("NewApi") public static String GetSDAvailableSize(Context context){
		long blockSize=0;//单个存储分块大小
		long availableBlocks;//可用的存储分块数
		File file=Environment.getExternalStorageDirectory();//获取外部存储设备的抽象形式,SD卡
		StatFs statFs=new StatFs(file.getPath());//file.getPath()获取文件的路径,statFs获取存储设备的使用情况的抽象
		    if(Build.VERSION.SDK_INT>Build.VERSION_CODES.JELLY_BEAN_MR2 ){//安卓API的版本号>18,进build文件看每个版本的常量名
		    	blockSize=statFs.getBlockSizeLong();//获取存储块的大小
			    availableBlocks=statFs.getAvailableBlocksLong();//获取能使用的存储快数
		  }else{
			   blockSize=statFs.getBlockSize();
			   availableBlocks=statFs.getAvailableBlocks();
		  }
		    return Formatter.formatFileSize(context, availableBlocks*blockSize);//long字节转化为字符串GB字节
 	   }
	@SuppressLint("NewApi") public static long GetSDAvailableSize2(Context context){
		long blockSize=0;//单个存储分块大小
		long availableBlocks;//可用的存储分块数
		File file=Environment.getExternalStorageDirectory();//获取外部存储设备的抽象形式,SD卡
		StatFs statFs=new StatFs(file.getPath());//file.getPath()获取文件的路径,statFs获取存储设备的使用情况的抽象
		    if(Build.VERSION.SDK_INT>Build.VERSION_CODES.JELLY_BEAN_MR2 ){//安卓API的版本号>18,进build文件看每个版本的常量名
		    	blockSize=statFs.getBlockSizeLong();//获取存储块的大小
			    availableBlocks=statFs.getAvailableBlocksLong();//获取能使用的存储快数
		  }else{
			   blockSize=statFs.getBlockSize();
			   availableBlocks=statFs.getAvailableBlocks();
		  }
			   return blockSize*availableBlocks;
 	   }
}

猜你喜欢

转载自my.oschina.net/u/3630543/blog/1647368