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

Android使用<activity-alias>切换应用图标触发ActivityNotFoundException

问题描述

我在Android应用里做了会员图标切换逻辑:用户是premium或semi-premium会员时调用changeIconToPremium()切换金色图标,非会员调用changeIconToDefault()切回默认图标。但运行时一直抛出ActivityNotFoundException,提示找不到com.fireframe.noxwallpapers.MainActivity。我的应用启动页是SplashScreen,切换图标后还是要以它作为启动页,求修复。

错误信息

FATAL EXCEPTION: main
Process: com.fireframe.noxwallpapers, PID: 18833
android.content.ActivityNotFoundException: Unable to find explicit activity class {com.fireframe.noxwallpapers/com.fireframe.noxwallpapers.MainActivity}; have you declared this activity in your AndroidManifest.xml, or does your intent not match its declared <intent-filter>?
    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2249)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1878)
    at android.app.Activity.startActivityForResult(Activity.java:5743)
    at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:780)
    at android.app.Activity.startActivityForResult(Activity.java:5701)
    at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:761)
    at android.app.Activity.startActivity(Activity.java:6199)
    at android.app.Activity.startActivity(Activity.java:6166)
    at com.fireframe.noxwallpapers.SplashScreen.endSplash$lambda$0(SplashScreen.kt:151)
    at com.fireframe.noxwallpapers.SplashScreen.$r8$lambda$L59SC2q6eERHvWVIWOUzibvW7Lg(Unknown Source:0)
    at com.fireframe.noxwallpapers.SplashScreen$$ExternalSyntheticLambda0.run(Unknown Source:2)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8893)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)

原Manifest配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="android.permission.SET_WALLPAPER" />
    <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
    <uses-permission android:name="com.android.vending.BILLING" />
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.NoxWallpapers"
        tools:replace="android:fullBackupContent"
        tools:targetApi="31">

        <!-- Launcher activity -->
        <activity
            android:name=".SplashScreen"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- MainActivity -->
        <activity
            android:name="com.fireframe.noxwallpapers.MainActivity"
            android:exported="false"
            android:label="@string/app_name"
            android:screenOrientation="portrait">
            <!-- No need for category DEFAULT in the intent-filter -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>

        <!-- MainActivityPremium alias -->
        <activity-alias
            android:name="com.fireframe.noxwallpapers.MainActivityPremium"
            android:enabled="false"
            android:exported="false"
            android:icon="@mipmap/ic_golden_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_golden_launcher_round"
            android:targetActivity="com.fireframe.noxwallpapers.MainActivity">
            <!-- No need for category DEFAULT in the intent-filter -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity-alias>

        <!-- 其他Activity和Service配置省略 -->
    </application>
</manifest>

原MainActivity相关代码

//Admob
//initializing
if ((subPerfHelper.getStatus() == "premium") || (subPerfHelper.getStatus() == "semi-premium")) {
    binding.bannerAd1.visibility = View.GONE
    if (subPerfHelper.getIconStatus() == "default"){
        changeIconToPremium()
        subPerfHelper.setIconStatus("premium")
    }
} else {
    if (subPerfHelper.getIconStatus() == "premium"){
        changeIconToDefault()
        subPerfHelper.setIconStatus("default")
    }
    MobileAds.initialize(this) {}
    // banner ads
    val adRequest = AdRequest.Builder().build()
    binding.bannerAd1.loadAd(adRequest)
    binding.bannerAd1.adListener = object : AdListener() {
        override fun onAdFailedToLoad(adError: LoadAdError) {
            binding.bannerAd1.visibility = View.GONE
        }
        override fun onAdLoaded() {
            binding.bannerAd1.visibility = View.VISIBLE
        }
    }
}


private fun changeIconToPremium() {
    //Disable default icon
    val packageManager = packageManager
    packageManager.setComponentEnabledSetting(
        ComponentName(this,"com.fireframe.noxwallpapers.MainActivity"),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP
    )

    //Enable golden icon
    packageManager.setComponentEnabledSetting(
        ComponentName(this,"com.fireframe.noxwallpapers.MainActivityPremium"),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

private fun changeIconToDefault() {
    //Disable golden icon
    val packageManager = packageManager
    packageManager.setComponentEnabledSetting(
        ComponentName(this,"com.fireframe.noxwallpapers.MainActivityPremium"),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP
    )

    //Enable default icon
    packageManager.setComponentEnabledSetting(
        ComponentName(this,"com.fireframe.noxwallpapers.MainActivity"),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

修复方案

问题根源

你之前错误地把图标切换逻辑绑定到了MainActivity上,切换时直接禁用了MainActivity组件,导致SplashScreen跳转时找不到MainActivity。而且Android的应用图标对应的是带有LAUNCHER intent-filter的组件,正确的做法是给启动页SplashScreen创建别名,而不是后续的MainActivity。

步骤1:修改AndroidManifest.xml

给SplashScreen创建两个activity-alias,分别对应默认图标和金色会员图标,把原SplashScreen的LAUNCHER过滤移到默认别名中:

<!-- 基础启动页Activity,不带LAUNCHER过滤 -->
<activity
    android:name=".SplashScreen"
    android:exported="true"/>

<!-- 默认图标启动别名(默认启用) -->
<activity-alias
    android:name=".SplashScreenDefault"
    android:enabled="true"
    android:exported="true"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:targetActivity=".SplashScreen">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

<!-- 金色会员图标启动别名(默认禁用) -->
<activity-alias
    android:name=".SplashScreenPremium"
    android:enabled="false"
    android:exported="true"
    android:icon="@mipmap/ic_golden_launcher"
    android:roundIcon="@mipmap/ic_golden_launcher_round"
    android:targetActivity=".SplashScreen">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

<!-- MainActivity保持原样,移除多余的intent-filter -->
<activity
    android:name="com.fireframe.noxwallpapers.MainActivity"
    android:exported="false"
    android:label="@string/app_name"
    android:screenOrientation="portrait">
</activity>

步骤2:修改MainActivity中的图标切换方法

现在操作SplashScreen的两个别名,不再动MainActivity:

private fun changeIconToPremium() {
    val packageManager = packageManager
    // 禁用默认图标别名
    packageManager.setComponentEnabledSetting(
        ComponentName(this, "com.fireframe.noxwallpapers.SplashScreenDefault"),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP
    )
    // 启用金色会员图标别名
    packageManager.setComponentEnabledSetting(
        ComponentName(this, "com.fireframe.noxwallpapers.SplashScreenPremium"),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

private fun changeIconToDefault() {
    val packageManager = packageManager
    // 禁用金色会员图标别名
    packageManager.setComponentEnabledSetting(
        ComponentName(this, "com.fireframe.noxwallpapers.SplashScreenPremium"),
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP
    )
    // 启用默认图标别名
    packageManager.setComponentEnabledSetting(
        ComponentName(this, "com.fireframe.noxwallpapers.SplashScreenDefault"),
        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP
    )
}

步骤3:验证SplashScreen跳转逻辑

确保SplashScreen跳转到MainActivity的代码正常,示例:

// SplashScreen.kt中跳转代码
private fun endSplash() {
    Handler(Looper.getMainLooper()).postDelayed({
        startActivity(Intent(this, MainActivity::class.java))
        finish()
    }, 2000) // 根据你的需求调整延迟时间
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:42:32