Android开发必有功能,更新版本提示,检测是否有新版本更新。下载完成后进行安装。
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985,转载请说明出处。
给大家介绍个东西,MarkDown真的超级超级好用。哈哈。好了,
正题内容如下:
先说明,此文章是教程详解,而不是直接拿来用的Demo,想要Demo的
朋友可以在下面留言或者私信,看到有要的朋友会做一个Demo。下面
文章是教大家理解这个内容。
先看一下效果:
1,检测更新
/*
* 从服务器端读取相关信息
*/
private String getInfoFromServer(String url) throws ClientProtocolException,
IOException
{
// sb 是从updateServerUrl上面读取到的内容
StringBuffer sb = new StringBuffer();
HttpClient httpClient = new DefaultHttpClient();
HttpParams httpParams = httpClient.getParams();
// 设置网络超时参数
HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpResponse response = httpClient.execute(new HttpGet(url));
HttpEntity entity = response.getEntity();
if (entity != null)
{
BufferedReader reader = new BufferedReader(new InputStreamReader(
entity.getContent(), "UTF-8"), 8192);
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
reader.close();
}
else
{
// 如果网络不通则默认初始版本
sb.append("1");
}
Log.i("getInfoFromServer", sb.toString().trim());
return sb.toString().trim();
}
/**
* 获取软件版本号
*
* @param context
* @return
*/
private float getVersionCode(Context context)
{
float versionCode = 0;
try
{
// 获取软件版本号,对应AndroidManifest.xml下android:versionCode
versionCode = Float.valueOf(context.getPackageManager().getPackageInfo(
mContext.getPackageName(), 0).versionName);
}
catch (NameNotFoundException e)
{
e.printStackTrace();
}
return versionCode;
}
private void showUpdateDialog()
{
if (mDialog == null)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("提示更新");
builder.setMessage("有最新版本可更新,是否下载更新");
builder.setPositiveButton("更新", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
// 开启服务进行更新
Intent intent = new Intent();
intent.setClass(MainActivity.this, UpgradeService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
if (mDialog.isShowing())
{
mDialog.dismiss();
}
}
});
mDialog = builder.create();
}
mDialog.show();
}
2,创建通知,带有自定义视图通知
1)自定义布局:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/image"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginTop="2dp"
android:background="@drawable/ic_launcher" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:orientation="horizontal" >
<TextView
android:id="@+id/dw_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="xxxx.apk"
android:textSize="18sp"
android:textColor="#4b8df9" />
<TextView
android:id="@+id/tv_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center"
android:minWidth="60dp"
android:textSize="18sp"
android:textColor="#4b8df9" />
</LinearLayout>
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginRight="4dp"
android:layout_marginTop="3dp"
android:max="100"
android:progress="0"
android:text="xxxx.apk" />
</LinearLayout>
</LinearLayout>
2) 通知处理:
mNotificationManager = (NotificationManager)
getSystemService(android.content.Context.NOTIFICATION_SERVICE);
/**
* 创建通知
*/
private void setUpNotification()
{
CharSequence tickerText = getString(R.string.download_begin);
long when = System.currentTimeMillis();
mNotification = new Notification();
mNotification.icon = R.drawable.ic_launcher;
mNotification.tickerText = tickerText;
mNotification.when = when;
// 放置在"正在运行"栏目中
mNotification.flags = Notification.FLAG_ONGOING_EVENT;
RemoteViews contentView = new RemoteViews(getPackageName(),
R.layout.download_notification_layout);
contentView.setTextViewText(R.id.dw_name,
getString(R.string.tip_apk_download));
// 指定个性化视图
mNotification.contentView = contentView;
Intent intent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_NO_CREATE);
// 指定内容意图
mNotification.contentIntent = contentIntent;
mNotificationManager.notify(NOTIFY_ID, mNotification);
}
通知修改:
if (rate <= 100)
{
RemoteViews contentview = mNotification.contentView;
contentview.setTextViewText(R.id.tv_progress, rate + "%");
contentview.setProgressBar(R.id.progressbar, 100, rate, false);
}
else
{
// 下载完毕后变换通知形式
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
// mNotification.contentView = null;
stopSelf();
}
mNotificationManager.notify(NOTIFY_ID, mNotification);
3,下载逻辑处理
private int lastRate = 0;
private Runnable mdownApkRunnable = new Runnable()
{
@Override
public void run()
{
try
{
// 获取下载地址
URL url = new URL(DOWNLOAD_APK_URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.connect();
int length = conn.getContentLength();
InputStream is = conn.getInputStream();
File file = new File(savePath);
if (!file.exists())
{
file.mkdirs();
}
file = new File(saveFileName);
if (file.exists())
{
file.delete();
}
String apkFile = saveFileName;
File ApkFile = new File(apkFile);
FileOutputStream fos = new FileOutputStream(ApkFile);
int count = 0;
byte buf[] = new byte[1024];
do
{
int numread = is.read(buf);
count += numread;
progress = (int) (((float) count / length) * 100);
// 更新进度
Message msg = mHandler.obtainMessage();
msg.what = 1;
msg.arg1 = progress;
if (progress >= lastRate + 1)
{
mHandler.sendMessage(msg);
lastRate = progress;
}
if (numread <= 0)
{
// 下载完成通知安装
mHandler.sendEmptyMessage(0);
// 下载完了,cancelled也要设置
canceled = true;
break;
}
fos.write(buf, 0, numread);
}
while (!canceled);// 点击取消就停止下载.
fos.close();
is.close();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
};
4,安装APK
/**
* 安装apk
*
* @param url
*/
private void installApk()
{
File apkfile = new File(saveFileName);
if (!apkfile.exists())
{
return;
}
Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
"application/vnd.android.package-archive");
mContext.startActivity(i);
stopSelf();
mNotification = null;
}
Android开发必有功能,更新版本提示,检测是否有新版本更新。下载完成后进行安装。的更多相关文章
- 打造高质量Android应用:Android开发必知的50个诀窍
打造高质量Android应用:Android开发必知的50个诀窍
- Android开发学习总结——搭建最新版本的Android开发环境
原文出自:https://www.cnblogs.com/xdp-gacl/p/4322165.html#undefined 最近由于工作中要负责开发一款Android的App,之前都是做JavaWe ...
- android 开发必用的开源库
LogReport: https://github.com/wenmingvs/LogReport, 崩溃日志上传框架 wcl-permission-demo:Android 6.0 - 动态权 ...
- Android开发中Eclipse里的智能提示设置
今天开始学习一下Android开发,直接在Android Developers下载的一个开发工具包,然后再下了一个JDK,配置完环境变量等一系列的工作后环境就搭建好了,在新建好第一个Android项目 ...
- Android开发之发送邮件功能的实现(源代码分享)
Android开发中可能会碰到如何发送邮件的困扰,之前我也查了相关的文档,博友们也分享了不少的发送邮件的办法,总共有3种把,我仔细阅读了下,发现有的讲的太过复杂跟麻烦,不够清晰,我今天就来分享下我认为 ...
- Android开发之发送邮件功能的实现(源码分享)
Android开发中可能会碰到怎样发送邮件的困扰,之前我也查了相关的文档,博友们也分享了不少的发送邮件的办法.总共同拥有3种把,我细致阅读了下,发现有的讲的太过复杂跟麻烦,不够清晰.我今天就来分享下我 ...
- Android开发中的OpenCV霍夫直线检测(Imgproc.HoughLines()&Imgproc.HoughLinesP())
本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 //2017-04-21更新: 很多网友希望能得到源码,由于在公司做的,所以不太方便传出来 ...
- Android开发必知--自定义Toast提示
开发过Android的童鞋都会遇到一个问题,就是在打印Toast提示时,如果短时间内触发多个提示,就会造成Toast不停的重复出现,直到被触发的Toast全部显示完为止.这虽然不是什么大毛病,但在用户 ...
- Android开发必知--几种不同对话框的实现
在开发过程中,与用户交互式免不了会用到对话框以实现更好的用户体验,所以掌握几种对话框的实现方法还是非常有必要的.在看具体实例之前先对AlertDialog做一个简单介绍.AlertDialog是功能最 ...
随机推荐
- 29-main()的使用说明
* 1. main()方法作为程序的入口 * 2. main()方法也是一个普通的静态方法 * 3. main()方法可以作为我们与控制台交互的方式.(使用Scanner) 如何将控制台获取的数据传给 ...
- 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮
前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的 ...
- 《RabbitMQ》如何保证消息的可靠性
一条消费成功被消费经历了生产者->MQ->消费者,因此在这三个步骤中都有可能造成消息丢失. 一 消息生产者没有把消息成功发送到MQ 1.1 事务机制 AMQP协议提供了事务机制,在投递消息 ...
- Ubuntu定时执行任务(定时爬取数据)
cron是一个Linux下的后台进程,用来定期的执行一些任务.因为我用的是Ubuntu,所以这篇文章中的所有命令也只能保证在Ubuntu下有效. 1:编辑crontab文件,用来存放你要执行的命令 s ...
- Java实现短信验证码
前言 本人使用的是阿里短信服务,一开始尝试了许多不同的第三方短信服务平台,比如秒滴科技.梦网云通讯.当初开始为什么会选择这两个,首先因为,他们注册就送10元钱(#^.^#),但是后来却发现他们都需要认 ...
- ECS7天实践进阶训练营Day2:基于阿里云ECS部署MediaWiki
一.概述 MediaWiki是全球最著名的开源Wiki程序,运行于PHP+MySQL环境,MediaWiki从2002年被作为维基百科的系统软件,并由大量其他应用实例(例如萌娘百科),因此MediaW ...
- Vue 使用$createElement自定义文本
有时候弹窗或者一些特殊的区域需要自定义一些html元素来显示(snabbdom) const h = this.$createElement this.$msgbox({ title: '提示', m ...
- vue跳转页面问题记录
跳转到别的页面带参数 const space = this.pageHelperspace['search'] = this.searchconst query_params = Object.ass ...
- JS实例-DOM查询
<!DOCTYPE html><html lang="en"><head> <meta charset="utf-8" ...
- vue cli 中关于vue.config.js中chainWebpack的配置
Vue CLI 的官方文档上写:调整webpack配置最简单的方式就是在vue.config.js中的configureWebpack选项提供一个对象. Vue CLI 内部的 webpack 配置 ...