Android(安卓)网络请求,应用的下载与安装
今天总结下Android的网络部分。
今天实现应用的下载和安装。
我的实例:下载本地站点下的APK,在通知栏显示下载过程,下载完成后点击通知栏安装应用。
这里说的应用可以是网上的,也可以是本地的。这里说的本地是指基于免安装的tomcat —> webapps站点下的,怎么使用免安装的tomcat读者可上网搜索,也可以直接用流量访问其他站点,类似www.CSDN.com
应用宝等。不差钱或者有无线的可以直接用网络下载网上的apk。
这里说明下本地localhost测试的注意事项:
1:虚拟机:虚拟机测试本地localhost,tomcat主页地址固定是这样的http://10.0.2.2:8080
,然后后面跟着自己tomcat下的站点路径
2:真机测试:真机测试需要保证手机访问地址与电脑地址是一样的,可以打开电脑无线,手机连接电脑无线,可以不需要联网即局域网就行,地址应该是这样的:http://本机ip:8080
,查看本机ip,win+r ---> cmd ---> ipconfig
,找到ipV4对应的ip地址即为本机地址。但需要注意先后顺序:手机先连接无线,再ipconfig找到ip。不然真机测试可能会失败。真机直接访问网络的就不用设置了
思路:使用异步加载(异步加载学习:http://blog.csdn.net/little_shengsheng/article/details/51315935),应用io流达到下载apk的目的,应用PendingIntent
实现状态栏的下载过程与下载完成后的点击安装。
接下来直接上代码,代码中注释也会比较详细:
1:布局和权限
布局就一个button
,绑定监听。
清单文件中加入以下权限:
<!--访问网络权限--><uses-permission android:name="android.permission.INTERNET"/> <!--读写权限--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2:MainActivity代码
//按钮点击监听button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //实例异步类,开始下载过程,具体实现在下方 MyAsync4 myAsync4 = new MyAsync4(); myAsync4.execute("应用地址,可以是本地的也可以是网上的地址"); } });//内部类,异步加载类private NotificationManager nm = (NotificationManager) getSystemService(Activity.NOTIFICATION_SERVICE);private NotificationCompat.Builder notification = null;private Notification notification1;public class MyAsync4 extends AsyncTask<String,Integer,Integer>{ //初始化状态栏 @Override protected void onPreExecute() { super.onPreExecute(); //设置状态栏通知,用setProgress()设置下载进度,values[0]即为传入的最新进度 notification = new NotificationCompat.Builder(getBaseContext()) .setSmallIcon(R.mipmap.ic_launcher) .setContentText("weixin_780.apk下载") .setContentInfo("下载进度"); //建立显示状态栏通知 notification1 = notification.build(); nm.notify(0, notification1); } //重写方法---子线程中执行耗时操作,String... params类似为数组 @Override protected Integer doInBackground(String... params) { //HttpURLConnection网络连接,用来设置网络访问及获取输入流 HttpURLConnection connection = null; //输入流,用来读取下载 InputStream is = null; //输出流,将下载写入到指定路径 FileOutputStream fop = null; //下载进度,下载进度 = (已经下载的长度 * 100) / 整个下载的长度 double needLength = 0; try { //实例下载地址,params[0]为地址,固定用法,该地址从实例化中传入 URL url = new URL(params[0]); //获取网络连接 connection = (HttpURLConnection) url.openConnection(); //设置网络最大连接时间 connection.setConnectTimeout(5000); //设置网络最大读取时间 connection.setReadTimeout(5000); //获得输入流 is = connection.getInputStream(); //计算进度 connection.getContentLength()得到总的长度 int next = 0; byte[] bytes = new byte[1024*1024*10]; double countLength = 0; long length = connection.getContentLength(); if (sd()){ //将下载存放到指定路径,这里是:根目录+包名+应用名 File file = Environment.getExternalStorageDirectory();//手机根目录 File file2 = new File(file,getBaseContext().getPackageName());//手机根目录+包名 if (!file2.exists()){ file2.mkdir(); } file1 = new File(file2+"/com.leo.lovefood-2.apk");//手机根目录+包名+应用名 //输出流 fop = new FileOutputStream(file1); //输出缓冲流,用来优化写入 BufferedOutputStream bos = new BufferedOutputStream(fop); int auto = 0; while ((next = is.read(bytes))!=-1){ countLength += next; needLength = ((countLength*100/length)); //这里的if判断是用来优化下载的,只用当进度变化量为1的时候,才更新状态栏,不然手机会很卡 if(auto!=(int)needLength){ auto = (int)needLength; //使用publishProgress()将最新进度传入onProgressUpdate(),更新状态栏下载进度 publishProgress((int) needLength); } //写入下载 bos.write(bytes, 0, next); } //刷新与关闭 bos.flush(); bos.close(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (connection!=null){ connection.disconnect(); } } return 1; } @Override protected void onPostExecute(Integer s) { super.onPostExecute(s); if (s==1){ Toast.makeText(getBaseContext(),"下载完成",Toast.LENGTH_SHORT).show(); } } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); //设置状态栏通知,用setProgress()设置下载进度,values[0]即为传入的最新进度 notification.setProgress(100, values[0], false); //建立显示状态栏通知 notification1 = notification.build(); //更新状态栏通知 nm.notify(0, notification1); //当下载进度为100,即为下载完成后,更改状态栏状态 if (values[0]==100){ //应用安装,固定写法---start Intent it=new Intent(Intent.ACTION_VIEW); it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //Uri.parse()中的路径是下载存放的路径 it.setDataAndType(Uri.parse("file://" + String.valueOf(file1)), "application/vnd.android.package-archive"); //使用PendingIntent实现点击安装 PendingIntent pendingIntent = PendingIntent.getActivity(getBaseContext(),0,it,PendingIntent.FLAG_UPDATE_CURRENT); //应用安装,固定写法---end notification.setContentText("下载完成,点击安装").setContentIntent(pendingIntent); //以下两步绝对不能忘记,重建与更新转态栏 notification1 = notification.build(); nm.notify(0, notification1); } } }private boolean sd(){ String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)){ return true; } return false; }
更多相关文章
- Picasso之图片缓存机制
- Android(安卓)studio启动后卡在refreshing gradle project(包解决
- Android(安卓)ApiDemos示例解析(182):Views->Progress Bar->1. I
- 谷安: Android(安卓)Market 网上商店发现后门,赤裸裸的安全漏洞
- Android源码下载及开发环境的搭建
- MacOS 10.15 下 Android(安卓)Q 源码 下载 编译 详解
- 2017-2020历年字节跳动Android面试真题解析(累计下载1082万次,持续
- Android无线调试——抛开USB数据线
- 在Ubuntu下获取Android4.0源代码并编译