2013年3月29日金曜日

[Android]セットアップウィザードってどうやって実装してるの

初回起動時のウィザードとかナビゲーションバーが消えてホームボタンが押せないでござる…
っていう体験した人いるじゃない。
あれ不思議だったんだけど、実装方法大体わかったよ!

1.ナビゲーションバーを消す
com.android.settings.CryptKeeper見たらあった
import android.app.StatusBarManager;
StatusBarManager mSbm = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
// Disable the status bar
mSbm.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);
// Enable the status bar
mSbm.disable(StatusBarManager.DISABLE_NONE);

StatusBarManagerはステータスバーを開いたりできるんだけど、
disable()でナビゲーションバーのパーツを個別ですこともできるよ。
disable()で指定しているのDISABLE_hogeオプションで一通り全部消せるんだけど、DISABLE_MASKでもいいかも。

注意点として、使い終わったら解除しないと消えっぱなしだよ!
戻すときはdisableでDISABLE_NONE指定したら戻るよ。
ポイントは、消す時も戻すときも同じインスタンスで実行してね。
消さないでインスタンス破棄⇒別インスタンス取得して戻すだと消えないよ!
こうなるとアプリが強制終了するまで消え続けるよ!

StatusBarManagerはhideでリフレクションで実装しないといけないから、
上のコードのままでビルド通らないんだけどねω・`)

あと、消しただけでキーボードでHOME押したらふつうに利くよ!
HOMEキーも利かないようにしないといけないわけなんだけど、
解決策は簡単

2.HOMEアプリとして実装する
そりゃHOMEアプリで実装したらHOMEキー押しても自分が呼ばれるんだけど、一工夫してるんです。
対象のActivityのAndroidManifestをこんな感じに実装してね。
        <activity
            android:name=".HogeActivity"
            android:label="@string/app_name">
            <intent-filter android:priority="1">
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>;
これの元ネタはSetupWizard.apkだよ。

ポイントはandroid:priorityのところ。
android:priority自体はこちらの説明がとてもわかりやすかったです。
初回起動時はデフォルトホーム設定されてないからHOMEのintent持ってるアプリを探すんだけど、
android:priorityが高いものから実行されていくんだね。
で、android:priority=1が自分しかいなかったら、自分神様なんでHOMEキー押しても自分が呼ばれる!
ってことです。

普通のHOMEアプリはandroid:priorityがデフォルトの0になってるわけで、
セットアップウィザードとかprovisonとかは1以上になってるんだね。
そうすると面白いのが、デフォルト未設定時には0に設定されたHOMEアプリ選択ダイアログが出るように、
1以上でも同じ値のアプリが複数あったらそれだけをより集めたダイアログが出るんだね。
初回起動時にそんなダイアログ出さないで済ませたい人は、
android:priorityが被らないようにインクリメントしつつ実装したらいいわけだね。

3.後処理
セットアップウィザードとか一通り処理が終わったらIntentで呼び出されないようにするっす
            PackageManager pm = getPackageManager();
            ComponentName name = new ComponentName(this, hogeActivity.class);
            pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);
これでこのActivityはHOMEキー押されてもスルーされるようになると。


セットアップウィザードは初期設定用の特殊な何かがあると思ってただけに、
こんな工夫で乗り越えたことを知ったときの驚愕たるや…。

0 件のコメント:

コメントを投稿