You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android应用内更新安装后自动启动的实现需求及代码咨询

解决Android应用更新安装完成后自动启动的问题

嘿,我来帮你搞定更新后自动启动App的问题!首先得明确几个关键点:不同Android版本对后台启动Activity的限制差异很大,而且你当前用的ACTION_VIEW安装方式没办法获取安装完成的回调,所以咱们得换用官方推荐的PackageInstaller API来实现这个需求。

核心思路

通过PackageInstaller执行APK安装,它能提供安装结果的回调通知。当安装成功时,我们在回调里触发App主Activity的启动。同时要注意系统权限和版本适配的问题。

步骤1:添加必要权限

AndroidManifest.xml里添加安装权限:

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

步骤2:替换原有安装方法为PackageInstaller实现

把你原来的installApkToDevice方法替换成下面的代码,用PackageInstaller来处理安装流程:

private void installApkWithPackageInstaller(Uri apkUri, int requestCode) {
    PackageInstaller packageInstaller = mActivity.getPackageManager().getPackageInstaller();
    PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
            PackageInstaller.SessionParams.MODE_FULL_INSTALL);
    // 设置当前App的包名,确保是更新当前应用
    params.setAppPackageName(mActivity.getPackageName());

    try {
        int sessionId = packageInstaller.createSession(params);
        PackageInstaller.Session session = packageInstaller.openSession(sessionId);
        
        // 将APK文件写入安装会话
        OutputStream outputStream = session.openWrite("apk", 0, -1);
        InputStream inputStream = mActivity.getContentResolver().openInputStream(apkUri);
        byte[] buffer = new byte[1024 * 1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }
        // 确保写入完成
        session.fsync(outputStream);
        inputStream.close();
        outputStream.close();

        // 创建安装完成的回调PendingIntent
        Intent intent = new Intent(mActivity, InstallResultReceiver.class);
        intent.setAction("com.your.package.INSTALL_COMPLETE"); // 替换成你的包名前缀
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                mActivity,
                sessionId,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
        
        // 提交安装请求
        session.commit(pendingIntent.getIntentSender());
        session.close();
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(mActivity, "安装准备失败", Toast.LENGTH_SHORT).show();
    }
}

步骤3:创建安装结果广播接收器

新建一个广播接收器类,用来接收安装完成的通知,并在成功时启动App:

public class InstallResultReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        int resultCode = getResultCode();
        if (resultCode == Activity.RESULT_OK) {
            // 安装成功,启动主Activity
            Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
            if (launchIntent != null) {
                // 添加标记确保启动的是最新的实例,且清除栈顶
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                context.startActivity(launchIntent);
            }
        } else {
            // 安装失败,可根据需要做错误提示
            Toast.makeText(context, "应用更新失败", Toast.LENGTH_SHORT).show();
        }
    }
}

步骤4:在Manifest中注册广播接收器

把刚才创建的接收器注册到AndroidManifest.xml里:

<receiver
    android:name=".InstallResultReceiver"
    android:exported="false">
    <intent-filter>
        <action android:name="com.your.package.INSTALL_COMPLETE" /> <!-- 和之前的Action保持一致 -->
    </intent-filter>
</receiver>

关键注意事项

  • Android 10+(API 29)限制:后台启动Activity需要满足系统条件,比如用户最近主动交互过你的App(更新流程是用户触发的,此时App一般在前台,满足条件)。如果App在后台闲置过久,系统会阻止启动,这是系统安全限制,无法绕过。
  • Android 12+(API 31)适配PendingIntent必须指定FLAG_IMMUTABLEFLAG_MUTABLE,这里用FLAG_IMMUTABLE即可,因为我们不需要修改回调Intent。
  • Uri权限问题:确保你传递的APK Uri是通过FileProvider生成的,避免出现文件访问权限被拒绝的问题。

内容的提问来源于stack exchange,提问作者Itay Feldman

火山引擎 最新活动