Alternative

僕はHHKキーボードを愛してやまないのだが、自分の手に慣れ親しんだツールにこだわるのは何もエンジニアだけではない。和田先生のアメリカ西部のカウボーイ話ではないが、自分の使いたい道具、インタフェースを使うよろこびは誰にでもあるだろう。

僕は、ブラウジングIEではなくFirefoxを使いたいし、テキスト編集はviよりもemacsを使いたい。そう、UNIXのEDITOR環境変数や、Debainのalternativesのようなものは、Androidに置いてもほしい機能である。

前置きはさておき、このAlternativeな仕掛けっぽいことをAndroidで実現できないか調べてみると、android.intent.category.ALTERNATIVEカテゴリを利用することで「やんわり」と実現できる。「やんわり」とは、完全に僕のイメージを満たすものではないが、まぁ、ギリギリセーフかもしれないけれど、やっぱりアウトかな。というニュアンスを表現してみた。

The offering application

The application offering the service must include an element in the manifest, inside the tag of the offering Activity. The intent filter includes all the details describing what it can do, such as a element that describes the MIME type of data that it can handle, a custom value that describes what your handling application can do (this is so that when it receives the Intent on opening it knows what it is expected to do), and most important, include a filter with the value android.intent.category.ALTERNATIVE and/or android.intent.category.SELECTED_ALTERNATIVE (SELECTED_ALTERNATIVE is used to handle only the currently selected element on the screen, rather than the whole Activity intent.

Android Developers  |  Android Developersより引用

これは、Activityを呼び出すときに複数のActivityから1つを選択できる機能である。例えば、VimとEmacsの2つのエディタがインストールされており、ユーザがテキスト編集したいときにどちらか好きなエディタを選択する。というような場合に使えるのではないだろうか。

ここで、EditorLauncher, AndroidEmacs, AndroidVimという3つのActivityを例にあげて説明する。EditorLauncherは、文字通りエディタを起動するActivityでLunchボタンを持っている。このLaunchボタンを押下すると、使いたいエディタ(AndroidEmacs or AndroidVim)をユーザが選択し、どちらかを起動するというものである。

まず、AndroidEmacsとAndroidVimのAndroidManifests.xmlを見てほしい。

  • AndroidEmacsのマニフェスト
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mamezou.android.editors.emacs">
    <application>
        <activity android:name=".AndroidEmacs"
            android:label="AndroidEmacs">
            <intent-filter>
                <action android:name="android.intent.action.EDITOR" />
                <category android:name="android.intent.category.DEFAULT" />
                <category
                    android:name="android.intent.category.ALTERNATIVE" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  • AndroidVimのマニフェスト
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mamezou.android.editors.vim">
    <application>
        <activity android:name=".AndroidVim"
            android:label="AndroidVim">
            <intent-filter>
                <action android:name="android.intent.action.EDITOR" />
                <category
                    android:name="android.intent.category.DEFAULT" />
                <category
                    android:name="android.intent.category.ALTERNATIVE" />
            </intent-filter>
        </activity>
    </application>
</manifest>

このように、android.intent.category.ALTERNATIVEカテゴリを両方に設定することで、次のようにIntentがブロードキャストしたときにフィルタ条件が一致するActivityの選択画面ダイアログをAndroidが自動的に表示してくれるのである。

public class EditorLauncher extends Activity {
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        Button le = (Button) findViewById(R.id.launch_editor);
        le.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent("android.intent.action.EDITOR");
                startActivity(intent);
            }
        });
    }
}

僕はこんな機能があることは知らなかったし、ググっても案外でてこないので書いてみた。