web-dev-qa-db-ja.com

アプリがフォアグラウンドにあるときにAndroid 7.0Nougatで接続の変更を検出する

Nougatは、CONNECTIVITY_CHANGEDインテントの処理方法を変更したため(基本的には無視し、開発者にジョブスケジューラの使用を強制します)、これは私に疑問を残します。

一部のデータを取得している最中のアプリがある場合(リクエストを行ったときに電話がオンラインであったかどうかを確認しましたが、ユーザーが移動中で、電話が別のWi-Fiアクセスポイントに接続している場合など) )失敗した場合、接続が復元されたことを検出し、データの取得を再試行するにはどうすればよいですか?

したがって、この場合、私のアプリはフォアグラウンドにあり、Chrome(Androidの場合)にも同様の機能があると思います。

自分でポーリングする必要がありますか?それとも、その時に許可されているイベントはありますか?

9
REJH

実行中のアプリは、BroadcastReceiverで通知を要求した場合でも、メインスレッドでCONNECTIVITY_CHANGEをリッスンできます。

https://developer.Android.com/about/versions/nougat/Android-7.0-changes.html

4
Andromeda

アンドロメダの答えを使用することはできますが、その解決策はGoogleの意図した選択ではありません。あなたの質問は、接続が失われたときにどうするかであり、ネットワークサービスが戻ったときに操作を再開する必要があります。

CONNECTIVITY_CHANGEは技術的には機能しますが、この特定のニーズに対するハックであり、アプリがバックグラウンドに移行するとすぐにNougatで機能しなくなります。実際に使用する必要があるのは、ジョブスケジューラAPIです。 Googleは、さまざまな要件と機能を備えた多くのオプションを提供してきました。

  1. JobScheduler

JobSchedulerがLollipopに追加され、ネットワーク接続を待機してジョブをスケジュールできるスケジューラーが追加されました。接続の種類に依存して、従量制または非ローミング接続をチェックすることもできます。このオプションには下位互換性はありませんが、GooglePlay開発者サービスがなくても機能します。

  1. GCMネットワークマネージャー

GcmNetworkManagerは、JobScheduler機能をLollipopより前のバージョンに直接移植したものですが、GooglePlay開発者サービスが必要です。 GcmNetworkManagerは、Firebase JobDispatcherによってほとんど非推奨になりました。

  1. Firebase Job Dispatcher

Firebase JobDispatcherは、Lollipopより前のバージョンのジョブをスケジュールする別の手段を提供します。これはデフォルトでGoogle Play開発者サービスを使用しますが、この依存関係を必要としないように構成できます。

  1. WorkManager

私はこの投稿を編集して、Googleが以前の3つのジョブスケジューラすべてをWorkManagerに置き換えたことを追加しました。これは、ほとんどすべての点で他のスケジューラよりも優れています。ジョブを実行するために必要なネットワークタイプを設定できます。ジョブを次々にチェーンすることもできます。

これらのオプションはすべて、バッテリーに優しい方法でニーズを満たし、デバイスがDozeモードから短時間ウェイクアップした場合でも、ジョブはスケジュールされます。

Googleが提供する例を使用して、さまざまなオプションの詳細を以下に示します。

https://developer.Android.com/topic/performance/scheduling.htmlhttps://developer.Android.com/topic/performance/background-optimization.html#sched-ジョブ

10
colintheshots

doc によると:

Android 7.0(APIレベル24)以降を対象とするアプリは、マニフェストでブロードキャストレシーバーを宣言した場合、_CONNECTIVITY_ACTION_ブロードキャストを受信しません。アプリは_CONNECTIVITY_ACTION_ブロードキャストを受信します。彼らはBroadcastReceiverContext.registerReceiver()に登録し、そのコンテキストはまだ有効です。

6
Amir Rezazadeh

私の場合、サービスでCONNECTIVITY_CHANGEフィルターを使用してブロードキャストをサブスクライブしましたが、機能しています。

Serviceを存続させる方法は別の話です:)

3
Penzzz
public class ConnectivityReceiver
{

public static boolean getWifiStatus(Context context)
{
    // To get System Connectivity status
    ConnectivityManager cm = (ConnectivityManager) context
            .getSystemService(Context.CONNECTIVITY_SERVICE);


    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (null != activeNetwork)
    {
        // Check For Wifi Status
        if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
            return true;
        else
            return false;
    }

    return false;
}

public class NetworkMgr extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    ConnectivityReceiver cf = new ConnectivityReceiver();
    boolean status = cf.getWifiStatus(context);

    if(status)
    {
        Toast.makeText(context,"Wifi Connection is On.", Toast.LENGTH_SHORT).show();
    }
    else
    {
        Toast.makeText(context,"Wifi Connection is Off.", Toast.LENGTH_SHORT).show();
    }
  }
}