作者:程序员小冰,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开发必有功能,更新版本提示,检测是否有新版本更新。下载完成后进行安装。的更多相关文章

  1. 打造高质量Android应用:Android开发必知的50个诀窍

    打造高质量Android应用:Android开发必知的50个诀窍

  2. Android开发学习总结——搭建最新版本的Android开发环境

    原文出自:https://www.cnblogs.com/xdp-gacl/p/4322165.html#undefined 最近由于工作中要负责开发一款Android的App,之前都是做JavaWe ...

  3. android 开发必用的开源库

    LogReport:  https://github.com/wenmingvs/LogReport,   崩溃日志上传框架 wcl-permission-demo:Android 6.0 - 动态权 ...

  4. Android开发中Eclipse里的智能提示设置

    今天开始学习一下Android开发,直接在Android Developers下载的一个开发工具包,然后再下了一个JDK,配置完环境变量等一系列的工作后环境就搭建好了,在新建好第一个Android项目 ...

  5. Android开发之发送邮件功能的实现(源代码分享)

    Android开发中可能会碰到如何发送邮件的困扰,之前我也查了相关的文档,博友们也分享了不少的发送邮件的办法,总共有3种把,我仔细阅读了下,发现有的讲的太过复杂跟麻烦,不够清晰,我今天就来分享下我认为 ...

  6. Android开发之发送邮件功能的实现(源码分享)

    Android开发中可能会碰到怎样发送邮件的困扰,之前我也查了相关的文档,博友们也分享了不少的发送邮件的办法.总共同拥有3种把,我细致阅读了下,发现有的讲的太过复杂跟麻烦,不够清晰.我今天就来分享下我 ...

  7. Android开发中的OpenCV霍夫直线检测(Imgproc.HoughLines()&Imgproc.HoughLinesP())

    本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃   //2017-04-21更新: 很多网友希望能得到源码,由于在公司做的,所以不太方便传出来 ...

  8. Android开发必知--自定义Toast提示

    开发过Android的童鞋都会遇到一个问题,就是在打印Toast提示时,如果短时间内触发多个提示,就会造成Toast不停的重复出现,直到被触发的Toast全部显示完为止.这虽然不是什么大毛病,但在用户 ...

  9. Android开发必知--几种不同对话框的实现

    在开发过程中,与用户交互式免不了会用到对话框以实现更好的用户体验,所以掌握几种对话框的实现方法还是非常有必要的.在看具体实例之前先对AlertDialog做一个简单介绍.AlertDialog是功能最 ...

随机推荐

  1. Linux之iptables原理详解

    目录: 一.netfilter与iptables 二.filter.nat.mangle等规则表 三.INPUT.FORWARD等规则链和规则 四.Linux数据包路由原理 五.iptables编写规 ...

  2. [转]Maven类包冲突终极三大解决技巧

    举例 A依赖于B及C,而B又依赖于X.Y,而C依赖于X.M,则A除引B及C的依赖包下,还会引入X,Y,M的依赖包(一般情况下了,Maven可通过<scope>等若干种方式控制传递依赖).这 ...

  3. Springboot使用JdbcTemplate的使用

    在spring-boot-starter-jdbc这个依赖包中一共分成四个部分. core,JdbcTemplate等相关核心接口和类 datasource,数据源相关的辅助类 object,将基本的 ...

  4. Nginx一个server主机上80、433,http、https共存

    如果一站点既要80 http访问,又要443https访问. 要让https和http并存,不能在配置文件中使用ssl on,配置listen 443 ssl; 实例 server { listen ...

  5. 能动手绝不多说:开源评论系统remark42上手指南

    能动手绝不多说:开源评论系统 remark42 上手指南 前言 写博客嘛, 谁不喜欢自己倒腾一下呢. 从自建系统到 Github Page, 从 Jekyll 到 Hexo, 年轻的时候谁不喜欢多折腾 ...

  6. JS 模仿京东键盘输入内容

    css代码 .search { width: 300px; height: 80px; margin: 0 auto; position: relative; } .con { display: no ...

  7. JS DOM操作案例

    显示隐藏表单文本内容 <input type="text" value="手机"> var text = document.querySelecto ...

  8. OGG复制进程延迟高,优化方法一(使用索引)

    日常运维过程中,可能发现OGG同步进程延迟很高: 本篇介绍其中的一种方式. OGG复制进程,或者说同步进程及通过解析ogg trail文件,输出dml语句,在目标库执行dml操作,那么延迟高可能性其一 ...

  9. C# ASP response.write()弹出提示框后页面布局被打乱

    发现在使用了response.write后样式发生了变化,位置和字体都不正确.Response.Write("<script>alert(')</script>&qu ...

  10. BiLSTM:序列标注任务的标杆

    Bidirectional LSTM-CRF Models for Sequence Tagging. Zhiheng Huang. 2015 在2015年,本文第一个提出使用BiLSTM-CRF来做 ...