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是功能最 ...
随机推荐
- Ubuntu环境下使用Jupyter Notebook查找桌面.csv文档的方法
这个问题困扰了我很久,最后在一个老师发来的完成结果里找到了答案.(奇怪的是教材里没有.老师也不讲.尤其是百度也没有啊啊啊啊) 好了进入正题.教材里的原话是这样的 这行代码实现的环境应该是在window ...
- 文档写作利器:Markdown
大佬的文章,写的很好,里面推荐的Markdown编辑工具很不错,值的推荐. 文档写作利器:Markdown_网络_xcbeyond|疯狂源自梦想,技术成就辉煌-CSDN博客https://blog.c ...
- 插槽slot使用方法
<slot>为vue的内置标签:用于给组件定义一个插槽,在这个插槽里传入内容(可以是模板代码或者组件),达到动态改变组件的目的. v-slot指令:绑定内容到指定插槽,v-slot 只能添 ...
- Linux安装配置PHPmyadmin
进官网下载zip安装包 wget https://files.phpmyadmin.net/phpMyAdmin/5.0.1/phpMyAdmin-5.0.1-all-languages.zip 安装 ...
- 配置JDK的环境变量
1.官网下载JDK安装包并进行安装,记住安装目录 2.安装完JDK后配置环境变量 计算机→属性→高级系统设置→高级→环境变量 3.系统变量→新建 JAVA_HOME 变量 .变量值填写jdk的安装目 ...
- docker找回构建时被删除的文件
设想这样一个场景:当一个docker镜像被多次引用构建,在某次构建中某个文件被删除,如何找回被删除的文件? 要想回答这么一个问题,首先得熟悉下docker镜像的分层存储结构,镜像每一层都是只读的: 那 ...
- ROS 八叉树地图构建 - 使用 octomap_server 建图过程总结!
构建语义地图时,最开始用的是 octomap_server,后面换成了 semantic_slam: octomap_generator,不过还是整理下之前的学习笔记. 一.增量构建八叉树地图步骤 为 ...
- Mysql Column 'xxxxx' in field list is ambiguous"
使用了关联查询,两张表有相同的字段,所以说取值含糊不清: 使用别名.列名解决: 如 a.description
- JAVA—继承及抽象类
继承的概念 在Java中,类的继承是指在一个现有类的基础上去构建一个新的类,构建出来的新类被称作子类,现有类被称作父类,子类会自动拥有父类所有可继承的属性和方法. 与css中继承父元素属性类似 继承的 ...
- Java的注解浅析
人的一生就像一篇文章,只有经过多次精心修改,才能不断完善 Java注解概念理解: Java注解又称为Java标注,是JDK5引入的一中注释机制,Java中大家熟悉的五种注解分别是:@Override, ...