Android アプリケーションのコンポーネントには、 アクティビティ、 サービス、 コンテンツ プロバイダ、 ブロードキャスト レシーバーの 4 種類があります。アクティビティは画面を持つコンポーネント、 サービスはバックグランドで動作するコンポーネントです。
アプリケーションの形態によっては、 バックグランドで動作しているサービスからアクティビティを開始して画面表示をしたい、 といったことがあります。
startActivity
メソッドでインテントを送信することでアクティビティを開始する方法が良く知られていますが、 実はこの方法には状況によって 5 秒程度の時間がかかるという落とし穴があります。
インテントを送信してアクティビティを開始する例
Android ではインテントを送信することでアクティビティを開始することができます。はじめにアクティビティを開始するコード例を紹介しておきます。
たとえば、 マップ (Google Maps) を開始する場合は以下のようなコードを書きます。
マップ(Google Maps)を開始する例Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName(
"com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
context.startActivity(intent);
基本的にはこれで問題ないのですが、 このコードには HOME ボタンを押した直後は制限を受けるという問題があります。
HOMEボタンを押下後はアクティビティ開始が制限される
Android には HOME ボタンを押下してホーム画面に戻った直後 (5 秒間) は、 サービスからのアクティビティ開始が制限されるという仕様があります。
- ユーザーがタッチ操作によってアプリを起動しようとした場合にはこのような制限はかかりません。
この制限を回避する方法についてインターネット上のコミュニティ各所で様々な議論がされており、 以前から android.permission.STOP_APP_SWITCHES
パーミッションを付与すれば、 この 5 秒制限を受けなくなることは知られていました。
しかし、 android.permission.STOP_APP_SWITCHES
の保護レベルは signatureOrSystem
となっており、 このパーミッションを付与するために、 アプリにプラットフォーム署名をしたり、 root 権限を取得してアプリを /system/app/
に配置することが必要でした。事実上、 一般アプリでは android.permission.STOP_APP_SWITCHES
パーミッションを付与することはできないといえます。
議論の中では他にも…
- 必要な機能をアクティビティではなくサービスだけで実装すべきだ
- アプリ自身をホームアプリにしてしまえばよい
といった意見も多いのですが、 これでは根本的な解決にはならないですよね。
PendingIntentならアクティビティ開始制限を受けない
どういった理由なのか分かりませんが、 PendingIntent
を使うと HOME ボタン押下直後 5 秒間のアクティビティ開始制限を受けなくなります。
PendingIntent
を使ってマップ (Google Maps) を開始するように書き換えたコードは以下の通りです。
PendingIntentを使ってマップ(Google Maps)を開始する例Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName(
"com.google.android.apps.maps", "com.google.android.maps.MapsActivity");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
pendingIntent.send();
従来通りにアクティビティ開始用のインテントを作成して、 startActivity
で送信する代わりに PendingIntent
でラップして send
メソッドで送信します。たったこれだけです。
このとても簡単なコードの書き換えによって、 長年、 私達を悩ませ続けてきたアクティビティ開始制限を回避できてしまうなんて驚きですね。