Android Custom Launcher startActivity() blocks BOO

2020-05-28 18:15发布

问题:

I am currently working on a custom ROM (based on CyanogenMod 11.0), which aims to implement a custom "Kiosk Mode". To do this, I have three components in one application (with system privileges): The service, which handles modifications to the status/navigationbar and disables the power key. The receiver, which only starts the service after the BOOT_COMPLETED signal is received. The HomeIntentWrapper works as the launcher, and only starts one custom activity.

The problem I am currently facing is that the startActivity(...) command in the HomeIntentWrapper somehow blocks the system from booting any further, and the BOOT_COMPLETED intent is never sent.

I verifed this with the adb shell dumpsys activity command, which tells me:

mStartedUsers:
  User #0: mState=BOOTING

It also does not show the BOOT_COMPLETED broadcast ever sent.

Now, if the user presses the Home-Button, the BOOT_COMPLETED intent is sent, and the mState switches to RUNNING.

If I do not start an activity in the HomeIntentWrapper, the intent is sent. What am I doing wrong here?

AndroidManifest.xml:

<manifest coreApp="true">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />    

    <application android:allowBackup="true"
                 android:persistent="true" >

        <service android:name="Service" 
                 android:process=":service" >
            </intent-filter>
        </service>

        <receiver android:name="Receiver" 
                  android:process=":receiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <activity android:name="HomeIntentWrapper"
                  android:process=":launcher" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Receiver:

public class Receiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.startService(new Intent(context, Service.class));
    }
} 

HomeIntentWrapper:

public class HomeIntentWrapper extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startApp();
    }

    @Override
    protected void onResume() {
        super.onResume();
        startApp();
    }

    private void startApp() {
        SharedPreferences sharedPrefs = getSharedPreferences(getString(R.string.settings_file), Context.MODE_MULTI_PROCESS);
        String customAppIntentString = sharedPrefs.getString(getString(R.string.settings_custom_intent), "");

        if(customAppIntentString.equals("") == false) {
            try {
                Intent intent = Intent.getIntent(customAppIntentString);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
            } catch(java.net.URISyntaxException e) {
                // Intentionally
            }
        }
    }
}

回答1:

Root cause: finishBooting() is not called because Home Activity is not on top of stack.

http://androidxref.com/4.4.4_r1/xref/frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java

Line: 1811 Line: 1883-1886 Line: 1934-1940

Solution:

Do not call start Activity Until Boot_Completed is received.