始终保留我的 MainActivity(启动器应用程序)的单个实例

发布于 2025-01-09 11:58:56 字数 4983 浏览 1 评论 0原文

我目前正在开发一个应用程序,该应用程序应该取代设备的整个用户界面。因此,我使用 以便在按下主页按钮时调用它,从而替换设备启动器。 此应用程序应始终仅运行其 MainActivity 的一个实例,并且当按下主页按钮时,它不应启动新的 Activity,而应恢复到现有的 Activity。

我已经尝试过不同的 launchModes 了,看起来 singleInstance 是最好的选择。但由于某种原因,主页按钮变得毫无用处,我无法返回启动器。有时它偶尔会起作用,当它起作用时,它就像我预期的那样起作用。

每当我按下主页按钮时,标准启动模式都会启动启动器的新实例,这会导致几个问题,因为启动器应该执行一些操作,例如打开其他应用程序并恢复到启动器,只要MainActivity 已创建。这会导致一个循环:启动器启动应用程序 ->通过创建一个新的 Activity 来恢复启动器 ->启动器启动应用程序... 这种行为可以通过某种方式得到修复,但仍然无法解决其根源,因为

singleTop 也会这样做。

singleTask 的作用相同。

singleInstance 保留 Activity,每当我按下主页按钮时,启动器就会恢复到最后的状态。但由于某种原因,主页按钮有时不起作用。这意味着该应用程序不会进入前台。即使关闭所有应用程序也不会让我返回启动器 ->由于您无能为力,因此设备会变砖

编辑: 实在找不到解决办法。我很确定这是谷歌方面的一个错误。我找不到原因,但我已经找到了解决方法。

我创建了一个名为“LoadingActivity”的新活动,它实际上只加载该活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_loading);
}

@Override
protected void onResume() {
    super.onResume();
    startActivity(new Intent(LoadingActivity.this,MainActivity.class));
}

LoadingActivitys launchMode 是“standard”,而“MainActivity”仍然是“singleInstance”。这暂时修复了一切。如果将来我找到更好的解决方案,我可以简单地删除该 Activity 并使 MainActivity 再次成为主要 Activity。

Edit2,根据请求,这是解决方法之前的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="[package]">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.READ_LOGS" tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/logo"
        android:label="@string/app_name"
        android:roundIcon="@drawable/logo"
        android:supportsRtl="false"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/AppTheme">
        <activity
          android:name="[package].MainActivity"
          android:launchMode="singleInstance"
          android:excludeFromRecents="true"
          android:alwaysRetainTaskState="true"
          android:configChanges="uiMode|fontScale">
          <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>


        <service android:name=".MediaServiceBrowser">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
                <action android:name="android.media.AUDIO_BECOMING_NOISY" />
                <action android:name="android.media.browse.MediaBrowserService" />
            </intent-filter>
        </service>

        <service android:name=".LocationService" />

        <service
            android:name=".NotificationListener"
            android:enabled="true"
            android:exported="true" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
            <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                 android:resource="@xml/provider_paths" />
        </provider>
    </application>

</manifest>

I'm currently working on an app that is supposed to replace the devices whole UI. Therefore I'm using <category android:name="android.intent.category.HOME"/> in order to call it whenever I press the home button, replacing the devices launcher.
This app should always have just one instance of its MainActivity running and when the home button is pressed, it shouldn't start a new Activity but resume to the existing one.

I've played with the different launchModes a bit and it looks like singleInstance is by best bet. But for some reason the home button gets rendered useless and I'm unabled to return the launcher. Sporadically sometimes it works and when it works, it works just like I've intended it to be.

standard launchmode starts a new instance of the launcher whenever I press the home button, which leads to several issues, since the launcher is supposed to do some things, like opening other apps and resuming to the launcher, whenever the MainActivity is created. This leads to a loop: launcher starts apps -> resumes to launcher by creating a new Activity -> launcher starts apps...
That behaviour could be fixed somehow, but still it doesn't solve the root of its cause

singleTop does the same.

singleTask does the same.

singleInstance retains the Activity and whenever I press the home button, the launcher just resumes with its last state. BUT for some reason, the home button sometimes doesn't work. Meaning that the App won't come to the foreground. Even closing all apps doesn't return me to the launcher -> the device kind of gets bricked since you can't do anything

Edit:
Couldn't really find a solution. I'm pretty sure it's a bug on googles side. I couldn't find the cause, but I've settled with a workaround.

I've created a new activitiy called "LoadingActivity" which literally only loads the activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_loading);
}

@Override
protected void onResume() {
    super.onResume();
    startActivity(new Intent(LoadingActivity.this,MainActivity.class));
}

The LoadingActivitys launchMode is "standard" while the "MainActivity" remains "singleInstance". This fixes everything for now. If I find a better solution in the future, I can simply delete the Activity and make the MainActivity the main activity again.

Edit2, per request, here's the manifest prior to the workaround:

<?xml version="1.0" encoding="utf-8"?>
<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="[package]">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.READ_LOGS" tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/logo"
        android:label="@string/app_name"
        android:roundIcon="@drawable/logo"
        android:supportsRtl="false"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/AppTheme">
        <activity
          android:name="[package].MainActivity"
          android:launchMode="singleInstance"
          android:excludeFromRecents="true"
          android:alwaysRetainTaskState="true"
          android:configChanges="uiMode|fontScale">
          <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>


        <service android:name=".MediaServiceBrowser">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_BUTTON" />
                <action android:name="android.media.AUDIO_BECOMING_NOISY" />
                <action android:name="android.media.browse.MediaBrowserService" />
            </intent-filter>
        </service>

        <service android:name=".LocationService" />

        <service
            android:name=".NotificationListener"
            android:enabled="true"
            android:exported="true" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
            <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                 android:resource="@xml/provider_paths" />
        </provider>
    </application>

</manifest>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文