1 year ago

#219264

test-img

Mumbira

Always retain a single instance of my MainActivity (launcher app)

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>

java

android

android-launcher

launchmode

0 Answers

Your Answer

Accepted video resources