无Google Play Store时Android Studio-Java应用远程自动更新咨询
Android 应用远程自动更新实现(Java)
核心流程(版本校验完成后)
已完成版本与服务器校验后,只需三步即可实现自动更新:下载APK文件 → 申请安装权限 → 触发安装流程
1. 用系统DownloadManager下载APK
系统API稳定支持断点续传,适配性更强,适合APK这类大文件下载。
private void downloadApk(String apkUrl, String apkFileName) { DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl)); // 设置通知栏提示 request.setTitle("应用更新"); request.setDescription("正在下载新版本"); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // 指定下载到公共下载目录,避免权限问题 File apkFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), apkFileName); request.setDestinationUri(Uri.fromFile(apkFile)); // 发起下载请求并保存任务ID DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); if (downloadManager != null) { long downloadId = downloadManager.enqueue(request); saveDownloadId(downloadId); registerDownloadCompleteReceiver(); } } // 保存下载任务ID到SharedPreferences,用于后续校验 private void saveDownloadId(long downloadId) { SharedPreferences sp = getSharedPreferences("update_prefs", MODE_PRIVATE); sp.edit().putLong("download_id", downloadId).apply(); }
2. 监听下载完成广播
下载完成后自动触发安装,需要注册广播接收器监听下载状态:
private BroadcastReceiver downloadCompleteReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (!DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { return; } long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); SharedPreferences sp = getSharedPreferences("update_prefs", MODE_PRIVATE); long savedId = sp.getLong("download_id", -1); // 确认是当前应用发起的下载任务 if (downloadId == savedId) { DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); if (downloadManager == null) return; DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); Cursor cursor = downloadManager.query(query); if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); if (status == DownloadManager.STATUS_SUCCESSFUL) { String apkPath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); installApk(Uri.parse(apkPath)); } } cursor.close(); unregisterReceiver(this); } } }; private void registerDownloadCompleteReceiver() { IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); registerReceiver(downloadCompleteReceiver, filter); }
3. 申请安装权限并启动安装
Android 8.0(API 26)及以上需要动态申请REQUEST_INSTALL_PACKAGES权限,低于该版本可直接启动安装:
private static final int REQUEST_INSTALL_PERMISSION = 1001; private void installApk(Uri apkUri) { Intent installIntent = new Intent(Intent.ACTION_VIEW); installIntent.setDataAndType(apkUri, "application/vnd.android.package-archive"); installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 处理Android 8.0+安装权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { boolean hasPermission = getPackageManager().canRequestPackageInstalls(); if (!hasPermission) { Intent permissionIntent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + getPackageName())); startActivityForResult(permissionIntent, REQUEST_INSTALL_PERMISSION); return; } } // 启动安装流程 try { startActivity(installIntent); } catch (ActivityNotFoundException e) { Toast.makeText(this, "安装失败,请手动打开下载的APK文件", Toast.LENGTH_LONG).show(); e.printStackTrace(); } } // 处理权限申请结果 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_INSTALL_PERMISSION && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { boolean hasPermission = getPackageManager().canRequestPackageInstalls(); if (hasPermission) { // 权限获取成功,重新触发安装 SharedPreferences sp = getSharedPreferences("update_prefs", MODE_PRIVATE); long downloadId = sp.getLong("download_id", -1); if (downloadId != -1) { DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); if (downloadManager != null) { DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); Cursor cursor = downloadManager.query(query); if (cursor.moveToFirst()) { String apkPath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); installApk(Uri.parse(apkPath)); } cursor.close(); } } } else { Toast.makeText(this, "未获取安装权限,无法自动更新", Toast.LENGTH_LONG).show(); } } }
4. 清单文件权限配置
在AndroidManifest.xml中添加必要权限:
<!-- 网络权限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 外部存储权限(仅针对Android 9及以下) --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" /> <!-- Android 8.0+安装未知来源应用权限 --> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
关键注意事项
- 服务器上的APK必须和当前应用签名一致,否则会安装失败。
- 建议在下载前弹出确认对话框,让用户选择是否更新,避免强制更新引起反感。
- 测试时覆盖Android 8.0+、Android 6.0+等不同版本,重点验证权限逻辑。
内容的提问来源于stack exchange,提问作者TripMedia
相关产品推荐
相关产品推荐

