Android开发App全自动升级对于很多App开发者而言,是必不可少的一项功能。因为随着移动应用市场的日益发展,其竞争也与日俱增。因此,App开发者需要不断优化自己的软件,提高用户的满意度,进而获取更多的用户。因此,Android开发App全自动升级功能无疑是非常必要的。本篇文章将结合实际操作,为你介绍Android开发App全自动升级的原理和详细步骤。
一、升级方式
Android系统中有两种主要的应用升级方式:静默安装和动态下载。由于静默安装需要获得root权限才能实现,而且卸载的时候也不能够做到完全清除,所以一般情况下我们会选择使用动态下载的方式来更新应用。
二、升级原理
Android开发App全自动升级的原理就是通过网络下载apk文件,然后在后台进行安装的过程,从而达到实现应用升级的目的。具体的实现流程如下:
1.用户启动应用并且检测应用当前版本;
2.通过网络获取服务器上最新的apk文件版本,并与用户当前所使用的版本进行比较;
3.如果发现用户的应用版本过旧,则提示用户进行应用升级;
4.用户确认升级后,在后台下载最新的apk文件;
5.下载完成后进行安装覆盖,然后启动新的应用。
三、实现步骤
一、在工程中添加以下依赖
```java
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
implementation 'com.google.code.gson:gson:2.8.2'
```
二、创建更新工具类
```java
public class UpdateUtil {
private OkHttpClient mOkHttpClient;
private Context mContext;
//当前安装的版本名
private String currentVersionName;
//当前安装的版本号
private int currentVersionCode;
//从服务器上获取的最新版本名
private String latestVersionName;
//从服务器上获取的最新版本号
private int latestVersionCode;
//从服务器上获取的最新版本描述信息
private String latestVersionDesc;
//从服务器上获取的最新版本下载地址
private String latestVersionUrl;
//从服务器上获取的最新版本强制更新信息
private boolean latestVersionForceUpdate;
public UpdateUtil(Context context) {
mContext = context;
}
/**
* 获取当前app本地版本号和版本名称
*/
private void getCurrentVersion(Context context) {
PackageManager packageManager = context.getPackageManager();
try {
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
currentVersionName = packageInfo.versionName;
currentVersionCode = packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
/**
* 从服务器中获取最新版本信息
*/
public void getLatestVersion() {
mOkHttpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder()
.url("your url")
.build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()) {
String result = response.body().string();
Gson gson = new Gson();
VersionBean versionBean = gson.fromJson(result,VersionBean.class);
latestVersionName = versionBean.getVersionName();
latestVersionCode = versionBean.getVersionCode();
latestVersionDesc = versionBean.getDescription();
latestVersionUrl = versionBean.getDownloadUrl();
latestVersionForceUpdate = versionBean.getForceUpdate();
}
}
});
}
/**
* 检查更新
*/
public void checkUpdate() {
getCurrentVersion(mContext);
getLatestVersion();
if (currentVersionCode < latestVersionCode) { //可升级
showUpdateDialog();
} else {
Toast.makeText(mContext, "已经是最新版本", Toast.LENGTH_SHORT).show();
}
}
/**
* 显示更新对话框
*/
private void showUpdateDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.Theme_AppCompat_Dialog_Alert);
builder.setTitle("发现新版本");
builder.setMessage(latestVersionDesc);
builder.setPositiveButton("立即升级", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//如果是强制更新则不可取消进度框
if(latestVersionForceUpdate){
downloadApk(true);
}else { //否则可以取消进度框
downloadApk(false);
}
}
});
if(!latestVersionForceUpdate){
builder.setNegativeButton("暂不升级", null);
}
builder.setCancelable(false);
builder.show();
}
/**
* 下载apk
* @param isForceUpdate 是否强制更新
*/
private void downloadApk(boolean isForceUpdate) {
ProgressDialog progressDialog = new ProgressDialog(mContext);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
progressDialog.show();
mOkHttpClient = new OkHttpClient();
//创建下载请求
Request request = new Request.Builder().url(latestVersionUrl).build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
progressDialog.dismiss();
e.printStackTrace();
Toast.makeText(mContext,"下载失败",Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()) {
InputStream is = null;
byte[] buf = new byte[4096];
int len;
FileOutputStream fos = null;
//储存下载文件的目录
String savePath = Environment.getExternalStorageDirectory() + File.separator + "Download";
File dir = new File(savePath);
if (!dir.exists()) {
dir.mkdirs();
}
File apkFile = new File(dir, "update.apk");
try {
is = response.body().byteStream();
long total = response.body().contentLength();
fos = new FileOutputStream(apkFile);
long sum = 0;
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
sum += len;
int progress = (int) (sum * 1.0f / total * 100);
progressDialog.setProgress(progress);
}
progressDialog.dismiss();
installApk(apkFile,isForceUpdate);
} catch (Exception e) {
progressDialog.dismiss();
e.printStackTrace();
Toast.makeText(mContext,"安装失败",Toast.LENGTH_SHORT).show();
} finally {
if(is != null){
is.close();
}
if(fos != null){
fos.close();
}
}
}
}
});
}
/**
* 安装apk文件
* @param file 要安装的apk文件
* @param isForceUpdate 是否强制更新
*/
private void installApk(@NotNull File file,boolean isForceUpdate) {
Intent intent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(mContext, "com.example.fileprovider", file);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
if(isForceUpdate){ //如果是强制更新
mContext.startActivity(intent);
}else { //否则可以取消安装磁贴
mContext.startActivityForResult(intent,1);
}
}
/**
* 获取当前安装的版本名称
* @return 当前安装的版本名称
*/
public String getCurrentVersionName() {
return currentVersionName;
}
/**
* 获取当前安装的版本号
* @return 当前安装的版本号
*/
public int getCurrentVersionCode() {
return currentVersionCode;
}
}
```
三、创建bean类VersionBean
```java
public class VersionBean {
private int versionCode; //版本号
private String versionName; //版本名称
private String description; //版本描述信息
private String downloadUrl; //下载地址
private boolean forceUpdate; //强制更新
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
public boolean getForceUpdate() {
return forceUpdate;
}
public void setForceUpdate(boolean forceUpdate) {
this.forceUpdate = forceUpdate;
}
}
```
四、在manifest中添加provider配置
```xml
android:name="androidx.core.content.FileProvider" android:authorities="com.example.fileprovider" android:exported="false" android:grantUriPermissions="true"> android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
```
五、创建file_paths.xml文件
在res/xml/目录下创建file_paths.xml文件,内容如下:
```xml
name="download" path="Download/" /> ``` 六、MainActivity中使用updateutil ```java public class MainActivity extends AppCompatActivity { private final UpdateUtil mUpdateUtil = new UpdateUtil(this); private static final int PERMISSION_REQUEST_CODE = 10; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mUpdateUtil.checkUpdate(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == 1){ Toast.makeText(this,"取消了安装",Toast.LENGTH_SHORT).show(); } } } ``` 以上就是Android开发App全自动升级的原理和详细步骤了。相信通过以上的实现,你已经可以轻松的实现App全自动升级的功能了。