AlarmManagerによってトリガーされるBroadcastReceiverを実装しました。 AlarmManagerはBOOT_COMPLETEDで初期化されます。だから私はマニフェストで受信者を宣言する必要があります。
私の問題は、BroadcastReceiverに、自分のアクティビティがフォアグラウンドにないとき(つまり、ユーザーがアプリケーションと対話していないとき)にのみ何かをさせたいということです。リモートサーバーから情報を取得しますが、ユーザーが現在自分のアプリケーションにいる場合はユーザーに通知したくありません。
これまでのところ、アプリケーションがフォアグラウンドにあるかどうかを判断する方法を見つけることができませんでした。そのようなことをする方法はありますか? ActivityManagerは、アプリケーションが実行されているかどうかを通知しますが、フォアグラウンドにあるかどうかは通知しません。
問題はここで説明したものとほとんど同じです。 BroadcastReceiverからのアクティビティをフォアグラウンドにある場合にのみ通知する
ソリューション:
いくつかのソリューションを評価した後、バックグラウンド/フォアグラウンドでのアクティビティに対処するための最良の方法であると思うものをすばやく概説します。
推奨される方法は、アクティビティのonResumeメソッドでブロードキャストレシーバを登録し、onPauseのアクティビティで登録解除することです。サービスまたはその他のバックグラウンド要素は、アクティビティがインターセプトする特定のアクションを含むブロードキャストインテントを送信する必要があります。
アクティビティがフォアグラウンドにある場合、インテントレシーバーが登録され、サービスから送信されたインテントを直接処理できます。フォアグラウンドにない場合、インテントを受信しませんが、ブロードキャストを呼び出したサービスは、誰もブロードキャストインテントをインターセプトせず、それ自体を処理できることを認識します。たとえば、目的のアクティビティを起動したり、通知を表示したりできます。
次の答え:「 アプリケーションはバックグラウンドで実行されています 」は、バックグラウンド/フォアグラウンドのチェックに利用可能なソリューションをまとめたものです。
注:
以前、この回答はActivityManager.getRunningAppProcesses()
を使用することを提案していましたが、その方法は完全に信頼できるものではないようで、その使用は推奨されません。詳細については上記のリンクを確認してください。
アクティビティは、フォアグラウンドにあるかどうかに関する独自の状態を追跡できます(onStart()
でtrue
に、onStop()
でfalse
にbooleanを設定します) 。残念ながら、そのブール値はActivity
によって自動的に提供されません。
ActivityManager#getRunningAppProcesses()
は、RunningAppProcessInfo
のリストを返します。各RunningAppProcessInfo
には、重要度と呼ばれるフィールドがあります。重要度が_RunningAppProcessInfo.IMPORTANCE_FOREGROUND
_の場合、どのアクティビティがユーザーによってアクティブに監視されているかを示しているようです。 _RunningAppProcessInfo.IMPORTANCE_VISIBLE
_もありますが、これは低いですが、チェックする価値があります。
アクティビティがフォアグラウンドにあるかどうかを判断するためのソリューションを確認してください: http://www.mannaz.at/codebase/Android-activity-foreground-surveillance/
ロジックを「フォアグラウンド」から「フォアグラウンドではない」に簡単に戻すことができるはずです。
AlarmManagerによってトリガーされるBroadcastReceiverを実装しました。 AlarmManagerはBOOT_COMPLETEDで初期化されます。だから私はマニフェストで受信者を宣言する必要があります。
私の問題は、BroadcastReceiverに、自分のアクティビティがフォアグラウンドにないとき(つまり、ユーザーがアプリケーションと対話していないとき)にのみ何かをさせたいということです。リモートサーバーから情報を取得しますが、ユーザーが現在自分のアプリケーションにいる場合はユーザーに通知したくありません。
これまでのところ、アプリケーションがフォアグラウンドにあるかどうかを判断する方法を見つけることができませんでした。そのようなことをする方法はありますか? ActivityManagerは、アプリケーションが実行されているかどうかを通知しますが、フォアグラウンドにあるかどうかは通知しません。
アクティビティの1つが現在実行中のフォアグラウンドアクティビティであるかどうかを判断する直接的な方法はないようです。ただし、順序付けられたブロードキャストと2つのブロードキャストレシーバーを使用することで、目的の効果を得ることができます。 1つのブロードキャストレシーバーをOnResume()で登録し、OnPause()で登録解除する必要があります。 2番目のブロードキャストレシーバーは、既に行ったようにマニフェストで宣言されます。受信者のAndroid:priorityを設定して、動的に登録された受信者が登録された場合、最初にインテントを受信し、マニフェストに登録したブロードキャスト受信者に通知されないようにインテントを食べることができます。
ActivityLifecycleCallbacks を使用して、よりクリーンなソリューションを取得します。
canは安全ではなく、以下の例を実稼働で使用することにする前に this を読んでください。私のデバイスとOSバージョンの「ホーム開発」で動作します。
public class App extends Application implements Application.ActivityLifecycleCallbacks {
private boolean inForeground;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
@Override
public void onActivityResumed(Activity activity) {
inForeground = activity instanceof YourActivity;
}
public boolean isInForeground() {
return inForeground;
}
App
にAndroidManifest
を登録します。
<application
Android:name=".App" />
そしてパズルの最後のピース:
public class YourReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
App app = (App) context.getApplicationContext();
if(app.isInForeground()){
// do some stuff
}
}
}
ウィンドウにフォーカスがあるかどうかをテストする -しかし、dev docsで述べられているように、これはアクティビティがフォアグラウンドにある場合と同じではありません。