1. Give your activity an intent filter something like this. The prioritycan be anything from 1 to 4, since Setup Wizard is 5 and the "real"Home activity is 0.
<intent-filterandroid:priority="3">
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.HOME" />
<categoryandroid:name="android.intent.category.DEFAULT" />
</intent-filter>
2. As your activity finishes, do something like this:
// disableourselves so we won't ever get launched as a HOME activity again
PackageManagerpm = getPackageManager();
ComponentNamename = new ComponentName(this, ThisActivity.class);
pm.setComponentEnabledSetting(name,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
// Startthe real home activity (or the one with the next highest priority, anyway)
startActivity(newIntent(Intent.ACTION_MAIN, null)
.addCategory(Intent.CATEGORY_HOME)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED));
3. When Setup Wizard completes, it sets a flag that indicates to the restof the system that it's done, which enables certain phone functions thatwe don't want occurring during Setup Wizard, such as incoming phone calls.You might want to clear that flag again, just to prevent your activityfrom being interrupted. (This is not ideal, since there will be that briefsliver of time between our setting the flag and your clearing it wheremaybe an incoming call could slip in. We'll try to address this in thefuture.) Here's the code Setup Wizard uses to set the flag. If you decideto clear it at the start of your activity (by setting it to 0) make sureyou set it again before you exit!
Settings.Secure.putInt(getContentResolver(),Settings.Secure.DEVICE_PROVISIONED, 1);
4. Setup Wizard disables the entire status bar (with the possible exceptionof the Back key in some circumstances) during all the time it's running,so that nothing can appear there that might allow the user to leave SetupWizard and then not be able to get back to it. You should probably do thesame thing. Unfortunately, both of the possible ways of doing this arebased on hidden APIs, so you'll have to find them through reflection. Here'ssample code for one possible method that includes all the reflection stuff:
private static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
private static final int STATUS_BAR_DISABLE_EXPAND =0x00010000;
private static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS= 0x00020000;
private static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS= 0x00040000;
private static final int STATUS_BAR_DISABLE_SYSTEM_INFO= 0x00100000;
private static final int STATUS_BAR_DISABLE_HOME = 0x00200000;
private static final int STATUS_BAR_DISABLE_RECENT =0x01000000;
private static Method findMethod(Class c, String name,Class param) {
try {
if (c== null) {
returnnull;
}
returnc.getMethod(name, param);
} catch (NoSuchMethodExceptionunused) {
Log.i(GLSUser.TAG,"Method not found " + name);
}
return null;
}
private static final Method sViewSetSystemUiVisibility=
findMethod(View.class, "setSystemUiVisibility",
Integer.TYPE);
private static void viewSetSystemUiVisibility(FrameLayoutfl, int v) {
if (sViewSetSystemUiVisibility!= null) {
try {
sViewSetSystemUiVisibility.invoke(fl,v);
} catch(Throwable e) {
//ignore
}
}
}
View outerView = // get the outer view of your layout(Note: I see that what we're doing is creating this outer view dynamicallyin our onCreate() and then loading the layout into it. I'm not sure ifthis was required to make this status bar disabling technique work or ifit was done for other, unrelated reasons, but just be aware you might haveto do something like that yourself.)
viewSetSystemUiVisibility(outerView, STATUS_BAR_DISABLE_EXPAND
|STATUS_BAR_DISABLE_NOTIFICATION_ICONS
|STATUS_BAR_DISABLE_NOTIFICATION_ALERTS
|STATUS_BAR_DISABLE_SYSTEM_INFO
|STATUS_BAR_DISABLE_HOME
|STATUS_BAR_DISABLE_RECENT
|STATUS_BAR_DISABLE_BACK); // Note: if youneed the Back key for your activity, you can leave this out
If your activity is really multiple activities, you'll need to do thisfor each of them. Its effect only applies to the view it's done for.
If you don't want to mess with grabbing your outer view, you can also disablethe status bar directly through the status bar manager, though that's ahidden API, too. But you can use the same reflection tricks as above tocall it yourself. Here's the direct Setup Wizard code:
mStatusBarManager= (StatusBarManager)getSystemService(Context.STATUS_BAR_SERVICE);
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND
|StatusBarManager.DISABLE_NOTIFICATION_ICONS
|StatusBarManager.DISABLE_NOTIFICATION_ALERTS
|StatusBarManager.DISABLE_SYSTEM_INFO
|StatusBarManager.DISABLE_HOME
|StatusBarManager.DISABLE_RECENT
|StatusBarManager.DISABLE_BACK); // Note:if you need the Back key for your activity, you can leave this out
This one only needs to be done once, and it will remain in effect as longas your process is still running. In that respect, it's better than thefirst method. Also, it will also continue to keep the status bar disabledshould you launch some external activity you have no control of, sinceyour process will still be running underneath it at that point. (However,if the system decides to temporarily shut down your process for memorymanagement purposes, the status bar will be re-enabled. I think this isa bug we need to fix.) With the first method, once a view that hasn't disabledthe status bar appears on top of yours, the status bar will be re-enabled.
总结如下:manifest:
<intent-filter android:priority="3" >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
执行完成之后下次启动的时候不再执行本程序:
public void disableOurselves(){
// disable ourselves so we won't ever get launched as a HOME activity again
PackageManager pm = this.context.getPackageManager();
ComponentName name = new ComponentName(this.context, LenovoOOBEActivity.class);
pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
this.context.startActivity(new Intent(Intent.ACTION_MAIN, null)
.addCategory(Intent.CATEGORY_HOME)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED));
}