如何简单实现安卓app自动更新功能
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何简单实现安卓app自动更新功能相关的知识,希望对你有一定的参考价值。
app自动更新程序可以参考如下代码:第一步 服务器端:
服务端提供一个借口,或者网址,我这里就用的服务器是tomcat,这里提供一个网址如下:
//也就是一个json数据接口
public static final String UPDATE_URL = "http://192.168.1.103:8080/update.json";
我们来看下json数据参数:
//app名字
appname: "爱新闻1.1",
//服务器版本号
serverVersion: "2",
//服务器标志
serverFlag: "1",
//是否强制更新
lastForce: "1",
//apk下载地址,这里我已经下载了官方的apk,放到了服务器里面
updateurl: "http://192.168.1.103:8080/36Kr.apk",
//版本的更新的描述
upgradeinfo: "V1.1版本更新,你想不想要试一下哈!!!"
好了以上的是服务器端的信息,在这里不需要多说了,我们来看下客户端的吧。
第二步 客户端需要实现:
首先我们要去解析服务端给的json,那么我们就要来创建一个model类了(代码过多,这里只有字段,getter和setter方法自己创建):
//app名字
private String appname;
//服务器版本
private String serverVersion;
//服务器标志
private String serverFlag;
//强制升级
private String lastForce;
//app最新版本地址
private String updateurl;
//升级信息
private String upgradeinfo;
在这里使用了一个辅助类,基本和model字段差不多:
public class UpdateInformation
public static String appname = MyApplication.getInstance()
.getResources().getString(R.string.app_name);
public static int localVersion = 1;// 本地版本
public static String versionName = ""; // 本地版本名
public static int serverVersion = 1;// 服务器版本
public static int serverFlag = 0;// 服务器标志
public static int lastForce = 0;// 之前强制升级版本
public static String updateurl = "";// 升级包获取地址
public static String upgradeinfo = "";// 升级信息
public static String downloadDir = "wuyinlei";// 下载目录
我们知道,我们在进入app的时候,这个时候如果检测到服务器端有了新的版本,就回弹出提示框,提示我们更新。这个我们在MainActivity里面处理逻辑(onCreate()方法里面):
OkhttpManager.getAsync(Config.UPDATE_URL, new OkhttpManager.DataCallBack()
@Override
public void requestFailure(Request request, Exception e)
@Override
public void requestSuccess(String result)
try
Log.d("wuyiunlei",result);
JSONObject object = new JSONObject(result);
UpdateInfoModel model = new UpdateInfoModel();
model.setAppname(object.getString("appname"));
model.setLastForce(object.getString("lastForce"));
model.setServerFlag(object.getString("serverFlag"));
model.setServerVersion(object.getString("serverVersion"));
model.setUpdateurl(object.getString("updateurl"));
model.setUpgradeinfo(object.getString("upgradeinfo"));
tmpMap.put(DeliverConsts.KEY_APP_UPDATE, model);
catch (JSONException e)
e.printStackTrace();
//发送广播
sendBroadcast(new Intent(UpdateReceiver.UPDATE_ACTION));
);
当然了,我们也要注册和结束广播:
/**
* 广播注册
*/
private void registerBroadcast()
mUpdateReceiver = new UpdateReceiver(false);
mIntentFilter = new IntentFilter(UpdateReceiver.UPDATE_ACTION);
this.registerReceiver(mUpdateReceiver, mIntentFilter);
/**
* 广播卸载
*/
private void unRegisterBroadcast()
try
this.unregisterReceiver(mUpdateReceiver);
catch (Exception e)
e.printStackTrace();
好了,接下来我们看下我们自定义的广播接收者UpdateReceiver .java:
/**
* 版本更新升级 广播接受者
*
*/ 参考技术A 360手机助手→设置→下载安装及流量设置。打开里面的零流量更新和下载完成后开始秒装
MAUI自动更新功能的安卓App
自动更新功能的安卓App
自动更新主要下面4个步骤
1、获取最新版本号
2、提示用户发现更新,等待用户确认更新
3、下载最新的apk包
4、安装apk包
更新服务
为简单示例:直接在android平台文件夹下新建静态类:UpgradeService.cs
包含:
- 检查更新
- 下载文件
- 安装apk包
因为存在命名空间冲突问题,故需改下命名空间。
public static class UpgradeService
readonly static HttpClient _client;
static UpgradeService()
_client = new HttpClient();
public static async Task<Dictionary<string, string>> CheckUpdatesAsync(string url)
var result = new Dictionary<string, string>();
// 获取当前版本号
var currentVersion = VersionTracking.CurrentVersion;
var latestVersion = await _client.GetStringAsync(url);
result.Add("CurrentVersion", currentVersion);
result.Add("LatestVersion", latestVersion);
return result;
public static void InstallNewVersion()
var file = $"FileSystem.AppDataDirectory/"com.shez.addressbook-Signed.apk"";
var apkFile = new Java.IO.File(file);
var intent = new Intent(Intent.ActionView);
// 判断Android版本
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
//给临时读取权限
intent.SetFlags(ActivityFlags.GrantReadUriPermission);
var uri = FileProvider.GetUriForFile(Android.App.Application.Context, "com.shez.addressbook.fileprovider", apkFile);
// 设置显式 MIME 数据类型
intent.SetDataAndType(uri, "application/vnd.android.package-archive");
else
intent.SetDataAndType(Android.Net.Uri.FromFile(new Java.IO.File(file)), "application/vnd.android.package-archive");
//指定以新任务的方式启动Activity
intent.AddFlags(ActivityFlags.NewTask);
//激活一个新的Activity
Android.App.Application.Context.StartActivity(intent);
public static async Task DownloadFileAsync(string url, Action<long, long> action)
var req = new HttpRequestMessage(new HttpMethod("GET"), url);
var response = _client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead).Result;
var allLength = response.Content.Headers.ContentLength;
var stream = await response.Content.ReadAsStreamAsync();
var file = $"FileSystem.AppDataDirectory/"com.shez.addressbook-Signed.apk"";
await using var fileStream = new FileStream(file, FileMode.Create);
fileStream.Flush();
await using (stream)
var buffer = new byte[10240];
var readLength = 0;
int length;
while ((length = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
readLength += length;
action(readLength, allLength!.Value);
// 写入到文件
fileStream.Write(buffer, 0, length);
这里需要使用到 FileProvider,在Android 7之后出于安全考虑不再支持content://URL 或file:///URL这种文件访问方式,可参考FileProvider | Android Developers,我们先添加一下对应配置
在Platforms/Android/Resources下面新建xml文件夹,并添加provider_paths.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<root-path name="root" path="" />
<files-path name="files" path="" />
<cache-path name="cache" path="" />
<external-path name="camera_photos" path="" />
<external-files-path name="external_file_path" path="" />
<external-cache-path name="external_cache_path" path="" />
</paths>
</resources>
修改Platforms / Android下面的AndroidManifest.xml文件,在application下添加provider,再添加一个安卓安装的权限“REQUEST_INSTALL_PACKAGES”
通过WebApi请求获取发布的最新版本号。为简单示例,API读取配置文件获取。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.masa.mauidemo.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
</manifest>
其中com.shez.addressbook-Signed.apk为apk的文件名称。
测试页面:MainPage.xaml
<HorizontalStackLayout Margin="0,20,0,0" Spacing="10">
<Button x:Name="UpdateBtn" Margin="20,10" Text="检查更新" VerticalOptions="Fill" CornerRadius="25" WidthRequest="200" Clicked="OnUpdateClicked" />
</HorizontalStackLayout>
<HorizontalStackLayout Margin="0,20,0,0" Spacing="10">
<Label x:Name="lblCurrentVersion" Margin="20,10" Text="" FontSize="16" HorizontalTextAlignment="Center" />
</HorizontalStackLayout>
<HorizontalStackLayout Margin="0,20,0,0" Spacing="10">
<Label x:Name="lblPross" Margin="20,10" Text="" FontSize="16" HorizontalTextAlignment="Center" />
</HorizontalStackLayout>
cs代码:
为简单测试版本,Webapi接口直接读取配置文件版本。
直接文本显示百分比和下载字节数。
public MainPage()
InitializeComponent();
lblCurrentVersion.Text ="当前版本:"+ VersionTracking.CurrentVersion;
private async void OnReLoginClicked(object sender, EventArgs e)
await Shell.Current.GoToAsync("//LoginPage");
private async void OnExitClicked(object sender, EventArgs e)
Environment.Exit(0);
/// <summary>
/// 更新
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void OnUpdateClicked(object sender, EventArgs e)
var result = await UpgradeService.CheckUpdatesAsync($" Operator.BaseUrl/api/File/AddressBookVer");
if (result["CurrentVersion"] != result["LatestVersion"])
var confirm = await Shell.Current.DisplayAlert("问题?", $"检测到新版本,是否升级,版本号为:" + result["LatestVersion"], "确定", "取消");
if (confirm)
await UpgradeService.DownloadFileAsync($"Operator.BaseUrl/api/File/AddressBook", DownloadProgressChanged);//https://你的域名/com.masa.mauidemo.apk
UpgradeService.InstallNewVersion();
UpdateBtn.IsEnabled = true;
else
await Shell.Current.DisplayAlert("提示",$"当前版本已经是最新版,版本号为:" + result["LatestVersion"],"确定");
private void DownloadProgressChanged(long readLength, long allLength)
UpdateBtn.IsEnabled = false;
var c = (int)(readLength * 100 / allLength);
if (c > 0 && c % 5 == 0) //刷新进度为每5%更新一次,过快的刷新会导致页面显示数值与实际不一致
var BytesReceived = readLength / 1024; //当前已经下载的Kb
var TotalBytesToReceive = allLength / 1024; //文件总大小Kb
lblPross.Text =$"正在下载中c% BytesReceived/TotalBytesToReceive...";
if (c == 100)
UpdateBtn.IsEnabled = true;
测试
参考:https://blog.csdn.net/sunday866/article/details/126405322
并得到老师的指导,感谢!
以上是关于如何简单实现安卓app自动更新功能的主要内容,如果未能解决你的问题,请参考以下文章