Android请求网络数据下载APK安装包
2018-03-19 00:00
176 查看
摘要: URLConnection InputStream OutputStream handler thread sd存储
今天写了个输入网址从网络下载一个apk安装包的小例子。把它记录下来以后方便自己使用。
运行效果图:
注意事项:安卓6.0系统以上要动态申请一些危险的权限,就是要主动弹出对话框问用户愿不愿意调取通信录名单,获得存储权限,创建文件权限等等,安卓6.0以前是安装时在Manifest写入的权限默认就拥有了,不需要询问客户。今天我写的程序是没有主动询问客户的代码(动态申请权限),所以在manifest中对uses-sdkVersion要注意,最大的版本要小于23,这样6.0以上手机就知道帮助你用兼容模式运行程序,不然是运行不出来的。
Manifest代码:
XML代码:
JAVA代码:
SD卡剩余空间的计算代码:
今天写了个输入网址从网络下载一个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; } }
相关文章推荐
- 网络数据请求实践一:android-async-http实现下载和上传
- 网络数据请求实践一:android-async-http实现下载和上传
- 网络数据请求实践一:android-async-http实现下载和上传
- 【Android Advanced Training - 05】传输数据时避免电量的浪费[Lesson 4 - 根据网络类型更改下载模式]
- Android-获取网络数据、发送请求
- Android(五)数据存储之五网络多线程断点下载
- android网络数据请求之HttpClient
- android 应用升级 下载安装包 完成后 自动安装apk文件
- Android开发之从网络URL上下载JSON数据
- android 应用升级 下载安装包 完成后 自动安装apk文件
- Android基于IIS的APK下载(三)用JSON传输更新数据
- iOS基础8:自定义MyData/自定义SQLite用于网络判断,版本判断,图片缓存处理,下载或者上传的GET或POST请求,加密手段,.数据解析
- Android异步下载网络图片&android解析xml文件的方式&使用Adapter为ListView提供数据
- 【Android】【嘿!Java】Android工程、Java工程中通过HttpClient请求网络数据的不同方式
- fiddler监控抓取Android请求网络数据包使用方法教程
- android 请求网络 和 httpclient的使用上传下载
- Android 网络应用重点———使用HttpGet 下载apk文件并安装
- Android实现检查并下载APK更新、安装APK及获取网络信息的方法
- Android 网络应用重点———使用HttpGet 下载apk文件并安装
- Android-PullToRefresh 分页请求网络数据的使用