Android apk版本更新

Android OTA升级后,APK版本信息未更新问题 在build/make/core/version_defaults.mk中,如果BUILD_NUMBER为空,则随机分配:BUILD_NUMBER := eng.$(shell echo $${BUILD_USERNAME:0:6}).$(shell $(DATE) +%Y%m%d.%H%M%S);读取vendor/mediatek/proprietary/buildinfo_vnd/label.ini中的MTK_INTERNAL_BUILD_VERNO内容,使得BUILD_NUMBER为空, 阅读详情

说到android的版本更新,要写一个出来还是需要耗费一点时间的,这次我们来写一个版本更新服务,用户进入app后有新版本需要更新则提示用户确认更新,更新在后台运行,不影响用户的正常操作,用户体验相对较好。


Android版本更新的步骤:

1、获取当前app版本号,代码如下

public String getAppVersion() {
try {
PackageInfo packinfo = pm.getPackageInfo(context.getPackageName(),0);
return packinfo.versionName;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return "1.0";
}


2、从服务器获取版本号,并与当前版本进行对比,如果相同则不更新,如果服务器版本号大于当前版本号,弹出更新对话框,提示用户进行更新升级。弹出对话框今天就不在这里写了,这部分代码相对还是比较简单的,当然如果我们需要一个比较好看的对话框,系统提供的原生对话框是不能满足我们的需求的,需要自定义对话框,读者可以自己去研究这方面的代码。

3、用户确认进行版本更新后,将从服务器下载更新的apk并进行自动升级。此处就用到了我们今天说到的版本更新服务,具体代码如下,部分代码已经做了注释,就不详细说明了。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import com.ygwaimai.manage.R;
import com.ygwaimai.manage.util.AppInfo;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.widget.RemoteViews;
import android.widget.Toast;

public class UpdateService extends Service {

	private NotificationManager nm;
	private Notification notification;
	private File tempFile = null;
	private boolean cancelUpdate = false;
	private MyHandler myHandler;
	private int download_precent = 0;
	private RemoteViews views;
	private int notificationId = 1234;

	private int appicon;

	public static final int TIME_OUT_MILL = 50000;// 超时毫秒数
	private static final String DOWNLOAD_APK_PATH = "APK_UPDATE";
	
	//更新进度标记
	private static final int UPDATE_DOWNLOAD_PRECENCE = 3;
	//下载完成标记
	private static final int DOWNLOAD_FINISH = 2;
	//下载APK失败标记
	private static final int DOWNLOAD_FAIL = 4;
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		notification = new Notification();
		notification.icon = android.R.drawable.stat_sys_download;
		// notification.icon=android.R.drawable.stat_sys_download_done;
		// notification.tickerText=getString(R.string.app_name)+"更新";
		notification.tickerText = "版本更新";
		notification.when = System.currentTimeMillis();
		notification.defaults = Notification.DEFAULT_LIGHTS;

		// 设置任务栏中下载进程显示的views
		views = new RemoteViews(getPackageName(), R.layout.update);
		notification.contentView = views;

		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				new Intent(), 0);
		notification.setLatestEventInfo(this, "", "", contentIntent);

		// 将下载任务添加到任务栏中
		nm.notify(notificationId, notification);

		myHandler = new MyHandler(Looper.myLooper(), this);

		// 初始化下载任务内容views,初始化进度为 0
		Message message = myHandler.obtainMessage(UPDATE_DOWNLOAD_PRECENCE, 0);
		myHandler.sendMessage(message);

		// 启动线程开始执行下载任务
		String url = intent.getStringExtra("DOWNLOAD_URL");
		downFile(url);
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// 停止掉当前的服务
		stopSelf();
		super.onDestroy();
	}

	// 下载更新文件
	private void downFile(final String url) {
		new Thread() {
			public void run() {
				try {
					HttpClient client = new DefaultHttpClient();
					// params[0]代表连接的url
					System.out.println("下载url======" + url);
					HttpGet request = new HttpGet(url);
					HttpResponse response = client.execute(request);
					// 请求超时
					client.getParams().setParameter(
							CoreConnectionPNames.CONNECTION_TIMEOUT,
							TIME_OUT_MILL);
					// 读取超时
					client.getParams().setParameter(
							CoreConnectionPNames.SO_TIMEOUT, TIME_OUT_MILL);
					client.getParams().setIntParameter("http.socket.timeout",
							TIME_OUT_MILL);

					HttpEntity entity = response.getEntity();
					long length = entity.getContentLength();
					InputStream is = entity.getContent();
					if (is != null) {
						File rootFile = new File(
								Environment.getExternalStorageDirectory(),
								"/" + DOWNLOAD_APK_PATH);
						if (!rootFile.exists() && !rootFile.isDirectory())
							rootFile.mkdir();

						tempFile = new File(
								Environment.getExternalStorageDirectory(),

								"/"+DOWNLOAD_APK_PATH + "/"
										+ url.substring(url.lastIndexOf("/") + 1));
						if (tempFile.exists())
							tempFile.delete();
						tempFile.createNewFile();

						// 已读出流作为参数创建一个带有缓冲的输出流
						BufferedInputStream bis = new BufferedInputStream(is);

						// 创建一个新的写入流,讲读取到的图像数据写入到文件中
						FileOutputStream fos = new FileOutputStream(tempFile);
						// 已写入流作为参数创建一个带有缓冲的写入流
						BufferedOutputStream bos = new BufferedOutputStream(fos);

						int read;
						long count = 0;
						int precent = 0;
						byte[] buffer = new byte[1024];
						while ((read = bis.read(buffer)) != -1 && !cancelUpdate) {
							bos.write(buffer, 0, read);
							count += read;
							precent = (int) (((double) count / length) * 100);

							// 每下载完成5%就通知任务栏进行修改下载进度
							if (precent - download_precent >= 5) {
								download_precent = precent;
								Message message = myHandler.obtainMessage(UPDATE_DOWNLOAD_PRECENCE,precent);
								myHandler.sendMessage(message);
							}
						}
						bos.flush();
						bos.close();
						fos.flush();
						fos.close();
						is.close();
						bis.close();
					}

					if (!cancelUpdate) {
						Message message = myHandler.obtainMessage(DOWNLOAD_FINISH, tempFile);
						myHandler.sendMessage(message);
					} else {
						tempFile.delete();
					}
				} catch (ClientProtocolException e) {
					e.printStackTrace();
					Message message = myHandler.obtainMessage(DOWNLOAD_FAIL, "下载更新文件失败");
					myHandler.sendMessage(message);
				} catch (IOException e) {
					e.printStackTrace();
					Message message = myHandler.obtainMessage(DOWNLOAD_FAIL, "下载更新文件失败");
					myHandler.sendMessage(message);
				} catch (Exception e) {
					e.printStackTrace();
					Message message = myHandler.obtainMessage(DOWNLOAD_FAIL, "下载更新文件失败");
					myHandler.sendMessage(message);
				}
			}
		}.start();
	}

	/**
	 * 安装下载后的apk文件
	 * @param file
	 * @param context
	 */
	private void Instanll(File file, Context context) {
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setAction(android.content.Intent.ACTION_VIEW);
		intent.setDataAndType(Uri.fromFile(file),
				"application/vnd.android.package-archive");
		context.startActivity(intent);
	}

	/* 事件处理类 */
	class MyHandler extends Handler {
		private Context context;

		public MyHandler(Looper looper, Context c) {
			super(looper);
			this.context = c;
			// 获取应用图标
			AppInfo appinfo = new AppInfo(c);
			appicon = appinfo.getAppIcon2();
		}

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (msg != null) {
				switch (msg.what) {
				
				case DOWNLOAD_FINISH:

					// 下载完成后清除所有下载信息,执行安装提示
					download_precent = 0;
					nm.cancel(notificationId);
					Instanll((File) msg.obj, context);

					// 停止掉当前的服务
					stopSelf();
					break;
				case UPDATE_DOWNLOAD_PRECENCE:

					// 更新状态栏上的下载进度信息
					views.setImageViewResource(R.id.ivLogo, appicon);
					views.setTextViewText(R.id.tvProcess, "已下载"
							+ download_precent + "%");
					views.setProgressBar(R.id.pbDownload, 100,
							download_precent, false);
					notification.contentView = views;
					nm.notify(notificationId, notification);
					break;
				case DOWNLOAD_FAIL:
					nm.cancel(notificationId);
					break;
				}
			}
		}
	}

}

Notification使用到的布局文件update.xml文件

<?xml version="1.0" encoding="utf-8"?>
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:orientation="vertical"
       android:background="#f2f2f2" >
       <RelativeLayout
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:orientation="horizontal">
          <ImageView
              android:id="@+id/ivLogo"
              android:layout_width="45dip"
              android:layout_height="45dip"
              android:layout_margin="10dip"
              android:layout_alignParentLeft="true" 
              android:layout_centerVertical="true"/>
          <LinearLayout
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical"
              android:layout_toRightOf="@+id/ivLogo"
              android:layout_marginRight="10dip"
              android:layout_alignParentRight="true" 
              android:layout_centerVertical="true">
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:textColor="@color/textgray"
                  android:text="版本更新"
                  android:textSize="18dip"
                  android:textStyle="bold"/>
              <ProgressBar
                  android:id="@+id/pbDownload"
                  android:layout_width="fill_parent"
                  android:layout_height="12dip"
                  android:progress="0"
                  android:max="100"
                  style="?android:attr/progressBarStyleHorizontal" />
              <TextView
                  android:id="@+id/tvProcess"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:textColor="#6a6a6a"
                  android:text="已下载0%"
                  android:textSize="12dip"
                 android:textStyle="bold" />
         </LinearLayout>
      </RelativeLayout>

    </LinearLayout>


用到的工具类AppInfo.java

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;

public class AppInfo {
	private Context context;
	private PackageManager pm;

	public AppInfo(Context context) {
		this.context = context;
		pm = context.getPackageManager();
	}

	/*
	 * 获取程序 图标
	 */
	public Drawable getAppIcon() {
		Drawable dr = null;
		try {
			ApplicationInfo info = pm.getApplicationInfo(
					context.getPackageName(), 0);
			dr = info.loadIcon(pm);
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		}
		return dr;
	}

	/*
	 * 获取程序 图标
	 */
	public int getAppIcon2() {
		int icon = 0;
		try {
			ApplicationInfo info = pm.getApplicationInfo(
					context.getPackageName(), 0);
			icon = info.icon;
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		}
		return icon;
	}

	/*
	 * 获取程序的版本号
	 */
	public String getAppVersion() {

		try {
			PackageInfo packinfo = pm.getPackageInfo(context.getPackageName(),
					0);
			return packinfo.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();

		}
		return "1.0";
	}

	/*
	 * 获取程序的名字
	 */
	public String getAppName(String packname) {
		try {
			ApplicationInfo info = pm.getApplicationInfo(packname, 0);
			return info.loadLabel(pm).toString();
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		}
		return null;
	}

	/*
	 * 获取程序的权限
	 */
	public String[] getAppPremission(String packname) {
		try {
			PackageInfo packinfo = pm.getPackageInfo(packname,
					PackageManager.GET_PERMISSIONS);
			// 获取到所有的权限
			return packinfo.requestedPermissions;

		} catch (NameNotFoundException e) {
			e.printStackTrace();

		}
		return null;
	}

	/*
	 * 获取程序的签名
	 */
	public String getAppSignature(String packname) {
		try {
			PackageInfo packinfo = pm.getPackageInfo(packname,
					PackageManager.GET_SIGNATURES);
			// 获取到所有的权限
			return packinfo.signatures[0].toCharsString();

		} catch (NameNotFoundException e) {
			e.printStackTrace();

		}
		return null;
	}

	public String getAppPackageName() {
		PackageInfo info;
		try {
			info = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
			// 当前应用的版本名称
			String versionName = info.versionName;
			// 当前版本的版本号
			int versionCode = info.versionCode;
			// 当前版本的包名
			String packageNames = info.packageName;
			return packageNames;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

}


在Activity中使用,我们只要传入版本更新的url就可以了,相关的下载和安装操作都在UpdateService 里面实现了,
用起来是不是很简单。

Intent intent = new Intent(ctx,UpdateService.class);
intent.putExtra("DOWNLOAD_URL", version_url);
startService(intent);

最后不要忘了在配置文件在AndroidManifest.mxl中中添加网络和SD卡读写权限,还有注册Service

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

<service android:name ="com.ygwaimai.manage.service.UpdateService" />

这样一个简单的版本更新服务就写好了,当然这只是比较简单的实现,具体做起来我们还要考虑很多问题,这只能看具体需求了,比如我们还可以加一些逻辑,判断sd卡里面有没有apk安装包,并和当前版本比较,看是否已经下载有新版本了,我们没有安装,这时就不必要再去下载一次了,浪费时间还浪费流量。还可以在下载的部分添加增量更新功能,这是现在比较流行的一种更新方法,这部分内容比较多,今天就不在这里介绍了,有兴趣的朋友可以自己去研究,一个版本更新的功能要做得比较好还是需要蛮多东西要考虑的,这篇文章就写到这里,夜了,晚安。





Android 应用程序适配和更新:APK 安装指南 首先,我们准备 APK 文件,并添加相应的安装权限。然后,创建 APK 安装 Intent,并添加 FileProvider 支持。最后,在应用程序中触发相应事件,即可调起 APK 安装界面。APK 安装是指通过安装 APK 文件来更新或安装应用程序。本文将介绍如何通过 APK 安装来实现应用程序的适配更新,并提供相应的源代码示例。通过触发相应的事件,即可调用 APK 安装 Intent,实现应用程序的适配更新。在你的应用程序中,创建一个 Intent 对象,用于触发 APK 安装。 阅读详情

相关推荐

Mixly米思齐——超声波测距控制LED灯

为了更加地贴近中小学信息技术的课程,我们用米思齐做了一个实验——根据距离的远近开启警报灯(利用超声波测出距离)。 实验硬件准备 arduino uno R3 、USB 数据线、YFROBOT UNO I/O扩展板、YFROBOT超声波传感器模块、模块3P连接线x1、LED灯x1 硬件连接图如下: 在arduino uno R3 上再接一个LED灯,实物图如下: 在本次实验中,LE...

Janise_的博客 9978

Android开发 应用APK更新升级安装全部流程(适用于api12--api30)(使用DownloadManager实现下载)

--增加根目录配置,特别注意:此处的path要为空字符串-->--需要访问的文件路径,name属性可以自定义,path属性必须写为download,因为我们安装apk时需要访问的是下载apk的文件路径,download实际上是一个常量值-->

Chenyile161616的博客 1万+

不带DDR的ZYNQ使用OCM加载程序运行的方法

软件版本:Vivado Vitis2019.2 第一步: 在Vivado的ZYNQ Block Design时候不配置DDR 第二步: 在Vitis中: 1、 在Vitis中新建Platform,选择xsa文件: 2、 在xparameters.h中添加DDR的地址空间定义,如下: 3、 修改链接文件,修改每个段都到ram_0,因为ram_1空间全部给到应用程序 4、 修改fsbl工程的main.c,增加XPAR_PS7_DDR_0条件编译 5、 修改fsbl.h,重定义DDR_EN

hpf247的博客 5535

Android 本地更新APK(无需添加运行时权限)

Android本地更新APK(不需要获取系统的存储权限)

woai6116110的博客 1046

微信小程序 - 最新详细实现 “餐厅食堂外卖点餐“ 全屏左右联动菜单列表功能界面,附带搜索框、购物车功能、商品加减计算金额、折扣等,左侧商品分类,右侧列表数据,仿美团饿了么外卖点餐页面,饭店扫码点餐!

微信小程序,vue2,vue3,左右联动菜单,商品分类页面,点餐界面,美团外卖点餐,左右布局界面,饿了么点餐页面,左分类右列表,小程序实现左侧菜单,外卖点餐联动,锚点,点击左侧大类后侧列表跟着变跟着刷新,菜单左右联动效果,左菜单右边列表数据,uniapp,左侧菜单,右侧列表双向联动效果,右侧商品滑动时,右侧列表双向联动效果,侧边菜单和右边滚动条,电商项目,购物车,商品加减计算,外卖选餐页面带购物车计算,自动计算金额,微信小程序外卖点餐界面源码,店铺页面滑动左右联动,点餐类小程序界面,堂食,扫码点餐,餐饮行业

🏆 前端领域优质创作者 5160

Python爬虫实战:美团商家数据采集系统

本文将详细介绍如何使用Python最新技术栈构建高效的美团商家信息采集系统。内容涵盖异步爬虫、反爬对抗、数据存储、可视化分析等完整流程,提供可落地的代码方案和工程实践。

2201_76125261的博客 2660

如何用Kotlin和Jetpack Compose实现Android APK版本自动升级功能

这个过程展示了如何使用Kotlin和Jetpack Compose来实现APK的自动更新机制。实际情况可能更复杂,因为你需要处理多种错误情况和边缘情况。这只是一个基本的框架。在实现自动更新功能时,始终关注用户体验和应用安全性。

weixin_39183462的博客 2378

STM32CubeMX之emWin移植

“前面两章介绍了SDRAM和LTDC的使用,本篇文章将介绍emWin移植到STM32。”硬件环境:STM32F429IGT6软件环境:STM32CubeMX v5.5.0...

zhang062061的专栏 2826

Android APP 自动更新实现(适用Android9.0)

安卓程序在线检查更新

moon2000boy的博客 3030

[QMT量化交易小白入门]-104、QMT平台运行深度学习模型,预测期货价格

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 485

备赛电赛学习硬件篇(二):电源板电路设计

1、输入接口要准备各种接口,如2p端子,锂电池接口,typec等,提供多种电源供电方案2、输出接口3、自由拓展。

m0_61022809的博客 3215

Android安装更新 apk,适用于android6.0及以上安卓版本。

Android应用中apk下载更新,适用于android 9及以下安卓版本。 直接上代码: 一、在主配置文件中写权限。 <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.INTERN...

weixin_42075821的博客 2万+

OpenGL ES 3.0 开发(一):绘制一个三角形

该原创文章首发于微信公众号:字节流动 什么是 OpenGLES OpenGLES 全称 OpenGL for Embedded Systems ,是三维图形应用程序接口 OpenGL 的子集,本质上是一个跨编程语言、跨平台的编程接口规范,主要应用于嵌入式设备,如手机、平板等。由科纳斯(Khronos)组织定义和推广,科纳斯是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。 O...

字节流动 8万+

WSABuilds包管理:Android应用的APK安装与版本更新方法

WSABuilds是一款能让你在Windows 10和Windows 11电脑上运行Android应用的强大工具,它预集成了Google Play商店和Magisk等功能,让你轻松体验Android生态。本文将详细介绍如何在WSABuilds中安装APK文件以及更新应用版本的实用方法,帮助你充分利用这一工具的潜力。 ## 一、APK安装的四种实用方法 ### 1. 通过文件应用安装(适用于WS

gitblog_01125的博客 933

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

unity 调用android 的 aar包 在安卓版本7.0 以上 安装覆盖更新版本 apk

此博客在于解决unity开发人员 android7.0权限 不能覆盖安装apk问题 直接上代码 直接附上项目下载地址 这是unity 调用android 的 aar包 可以在安卓版本7.0 上安装覆盖更新版本。 附网址 https://download.youkuaiyun.com/download/qq_39735878/11183662 ...

qq_39735878的博客 775

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

android apk版本切换,Node.js实现android的apk版本更新

以下内容仅为android程序员自己测试时搭建的简单测试服务器。根据一般apk升级步骤:1. 请求服务器versionCode和本地apk的versionCode比对,如果服务器versionCode大于apk的versionCode,则执行2),否则结束;2. 弹出对话框,告知用户有新的版本可以更新,用户点击更新,则执行3)开始下载apk,否则结束;3. 后台下载最新版本的apk。第一步:判断v...

weixin_32325225的博客 729

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Android apk版本检测及更新

很多Android应用都具有版本检测自动更新功能,用户一键就可以完成软件的升级更新。这得益于Android系统的软件包管理和安装机制,这一功能实现起来也很简单。   Android的apk版本信息的获取: 定义在androidmanifest.xml里       package="com.huazi.updateapksamples"       android:versionCo

jonemill的专栏 1474

android apk 自动更新,android 自动更新apk版本

packagecom.update.apk;importjava.io.BufferedReader;importjava.io.File;importjava.io.FileOutputStream;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.net.HttpURLConnection;importja...

weixin_39685674的博客 522

android 版本更新 apk,Android 版本升级(APK下载和安装)

将手机上应用版本号等相关信息发送到服务器,服务器检测是否有新版本。如果有新版本,将返回客户端版本号、版本名称、下载地址、版本更新说明等信息。客户端获取到此信息后,将询问用户是否下载,确定后,开始下载。下载完成后开始提示安装。调用系统DownloadManager实现下载:DownloadManager downloadManager = (DownloadManager) getSystemSer...

weixin_34620780的博客 4344

android最新版apk,Android apk版本检测及更新

很多Android应用都具有版本检测自动更新功能,用户一键就可以完成软件的升级更新。这得益于Android系统的软件包管理和安装机制,这一功能实现起来也很简单。Android的apk版本信息的获取:定义在androidmanifest.xml里xmlns:android="http://schemas.android.com/apk/res/android"package="com.huazi.u...

weixin_36156209的博客 2962

android apk版本更新

android apk版本更新 版本号获取等等...

随意而然的专栏 2426

Android APK版本更新下载

今天做了下APK版本更新的功能。其实关于APK版本更新相关的文章网上挺多的,功能实现上也并不难。基本思路就是讲当前APK的版本号和服务器上保存的最新APK包的版本号进行对比,如果当前版本小于最新版本,则进行下载更新。流程图如下:                引用的第三方jar包有okhttp,okio(为了支持okhttp)和gson: compile 'com.squareu

卡小基的博客 1万+

Cocos Creator 3.x APK热更新全流程:版本检测、下载与安卓原生安装实战

在移动应用开发中,热更新机制是保障应用持续迭代和用户体验的关键技术。其核心原理是通过网络请求获取服务器上的最新版本信息,与客户端本地版本进行比对,从而触发资源或安装包的更新流程。这项技术的价值在于能够快速修复线上问题、发布新功能,而无需用户重新下载整个应用,极大地提升了产品迭代效率和用户留存率。在游戏开发领域,尤其是使用Cocos Creator等跨平台引擎时,实现APK的静默或引导式更新是常见的工程实践需求。这涉及到前端版本号管理、网络资源下载、以及调用安卓原生API进行安装等多个技术环节的串联。本文将结

weixin_34195142的博客 362

Android本地Apk自动更新 (包含8.0等高版本和低版本)

参考博客: https://blog.youkuaiyun.com/qq_29405933/article/details/82862679 1.从服务器获取版本信息: (可参考我上一篇博客:https://blog.youkuaiyun.com/qq_30297763/article/details/87875072) private void upapk(){ OkGo.&lt;String&gt;get(Ur...

Android之旅 5400

android apk 版本更新

待续···· 文献参考: Android APK版本更新下载 https://blog.youkuaiyun.com/bit_kaki/article/details/72427928

Venus 的博客 1460

android apk u盘升级_Android App内检测更新新版本APK

Rayland主板虽然作为一块基于Android的工控板,但是很多设备厂商并不想让用户看到Android系统信息。所以APK默认设置为开机启动项、img去除了Android头部和底部菜单。但是随之带来了APK更新的问题,传统的插入u盘,sd卡手动安装新版本APK的方式已经不够用了。所以我们需要点自动的东西。App内检测更新新版本APK检测新版本APK我们使用 四大组件之一的BroadcastRec...

weixin_39611725的博客 668
上一篇: Android获取View的宽高
下一篇: android Popupwindow被弹出软键盘挡住
大漠-孤烟
博客等级 码龄11年 2粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值