Androidアプリを作製していると、外部からIntent呼び出しに対応させたりと考える開発者は多いと思うのですが、一方、ずらずらずらーとアプリ一覧が出るのは結構いやなので、対応を躊躇する方もいると思います。

特にいつも使うんじゃなくて、特定の状況下のみで使用するアプリの場合は、自分の作ったソフトが一覧に出てくるのがじゃまだったりするので、うーんという状況になります。

そのようなアプリの場合、設定画面で、Intent呼び出しに対応できると便利です。

一言で説明すると、COMPONENT_ENABLED_STATE_ENABLED使うとできるよ
なのですが、そんなやり方の解説です。

仕様

良く見かける、どのブラウザを使用するかの選択画面

tcalpturebrowser

ブラウザアプリを、作ってみた。Intent対応して、以下のように表示させるようにした。

tcalpturebrowser

でも、いつも表示させるのは、いやなので、アプリケーション内の以下のような設定画面で設定できるようにしたい。(URLを開くときに使うで制御)

tcalpturebrowser

技術概要

PacakageManagerクラスに、setComponentEnableSettingというメソッドがあります。このメソッドを使用する事でActivityをEnable/Disableに切り替え可能です。

他のアプリケーションの設定は権限が必要になりますが、自分自身であれば可能です。


<activity android:name=".lib.MainActivityDummy"
android:enabled="false"
>

setComponentEnableSettingは、Manifest.xmlの「android:enable」の部分に対応します。ここにfalseと記載すると外部から参照はされなくなりますが、setComponetEnableDettingを使用すると上記の「android:enable」が書き変わります。

もちろん、直接インストールしたファイルが書き変わるわけではなく、システムが管理するpackage.xmlの方の記載が変更になり、disableにした場合は呼び出されなくなります。

Android Manifest.xml


<activity android:name=".lib.MainActivity"
android:label="@string/app_name"
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 内部の設定でブラウザ選択画面に出すか出さないかを決められるようにする-->
<activity android:name=".lib.MainActivityDummy"
android:enabled="false"
>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:scheme="about" />
</intent-filter>
</activity>

ホームアプリから、アイコンをタップして起動されるActivityは、「.lib.MainActivity」です。

ブラウザの選択画面から起動されるときは、「.lib.MainActivityDummy」(以降DammyActivity)となります。

上記Manifestでは、DammyActivityの方は、android:enabled=”false”にしてありますので、インストール直後は
ブラウザ一覧画面にでてこない仕様です。

アプリ内の設定画面にて、「使用する」とすると、DammyActivityのandroid:enabledがtrueになり、アプリ一覧に表示されるようになるという仕組みです。

何故、呼び出し用Activityとホームから呼ばれる2つのActivityに分けているかというと、ホームアプリから呼ばれるActivityをfalseにしてしまうと二度と起動しなくなってしまうので、false/trueを切り替え可能なように呼び出し専用のActivityを作製してあります。

DammyActivity

この機能を実現するために、呼び出し専用のActivityを作ります。

といっても、そんなに難しくはありません


package jp.co.taosoftware.android.devbrowser.lib;
/**
* インテントフィルタのON/OFFを設定から利用する為に利用する
* MainActivityを継承するのみ
*/
public class MainActivityDummy extends MainActivity {
}

作製するアプリの種類にもよると思いますが、継承して終わりです。

パラメータを解析がここだけであれば、onCreateをOverrideして、このクラスのみで処理をすると、ソースが綺麗になるかと思います。

設定

shared prefrenceに使うか使わないかがtrue/falseで入っているのが前提ですが、true/falseのサンプルコードとなります。

PrefrenceActivityのonSharedPreferenceChangedあたりで使用すればうまく動作します。


PackageManager pm = mContext.getPackageManager();
// リストの設定状態を取得
Boolean check = sharedPreferences.getBoolean(key, false);
// URLをクリックした際に、ブラウザ一覧に表示するかどうかを切り替える
if(check){
// チェックが有る場合は一覧に表示にする
// 設定した瞬間にアプリケーションを終了したくないのでDONT_KILL_APPを指定
pm.setComponentEnabledSetting(new ComponentName(mContext, MainActivityDummy.class),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}else{
// チェックが無い場合は一覧に表示しない
pm.setComponentEnabledSetting(new ComponentName(mContext, MainActivityDummy.class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}

まとめ

Twitterの方でつぶやかれている方がいたので、急遽記事にしたため、かなり早足になりましたが、その代わりコピーペーストで行けるように記載をしまいた。

しかし、設定画面に表示させる、「有効にする無効にする」を表現する言葉って良い表現ないものでしょうか?

ブログ内の関連する記事