You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:20:42