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是功能最 ...
随机推荐
- Hadoop学习问题记录之基础篇
目的 记录学习hadoop过程中遇到的基础问题,无关大小.无关困扰时间长短. 问题一 全分布式环境中运行mapred程序,报异常:java.net.NoRouteToHostException: 没有 ...
- 谈谈Spring中都用到了那些设计模式?
以下文章来源于微信公众号JavaGuide ,作者:JavaGuide JDK 中用到了那些设计模式?Spring 中用到了那些设计模式?这两个问题,在面试中比较常见.我在网上搜索了一下关于 Spri ...
- Echarts图表随浏览器大小,模块大小,位置实时更新
1.图表位置随浏览器大小改变 2.图表位置随模块的改变而改变 只需要在事件函数中添加:
- 新浪、腾讯、淘宝为何如此重视Web前端?前端入门容易吗?
为什么新浪.搜狐.网易.腾讯.淘宝等在内的各种规模的IT企业,都对web前端越来越重视了呢?小编为您揭晓答案! web前端的由来 以前会Photoshop和Dreamweaver就可以制作网页.随着时 ...
- 面经手册 · 第2篇《数据结构,HashCode为什么使用31作为乘数?》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在面经手册的前两篇介绍了<面试官都问我啥>和<认知自己的技术栈盲区 ...
- CRF
- Canal v1.1.4版本避坑指南
前提 在忍耐了很久之后,忍不住爆发了,在掘金发了条沸点(下班时发的): 这是一个令人悲伤的故事,这条情感爆发的沸点好像被屏蔽了,另外小水渠(Canal意为水道.管道)上线一段时间,不出坑的时候风平浪静 ...
- SSH config语法关键字
1.SSH config 语法关键字 host 别名 HostName 主机名(ip) User 用户(root就是一个用户) Port 端口(默认22) IdentityFile 密钥文件的路 ...
- 基于索引的QA问答对匹配流程梳理
知识库(主要是标准的QA信息)匹配需求是对已经梳理出的大量标准QA对信息进行匹配,找出最符合用户问题的QA对进行回复,拆分主要的处理流程主要为如下两点: 标准QA信息入库索引: 通过对用户提出的问题进 ...
- MnasNet:Mobile Neural Architecture Search(MNAS)