Android Open Source - base-android-utils Wifi Waker






From Project

Back to project page base-android-utils.

License

The source code is released under:

Apache License

If you think the Android project base-android-utils listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package me.pc.mobile.helper.v14.net;
//from  www. j  a v  a  2 s.c o  m
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.util.Log;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/** Wake the radio up. You must provide a latch on which the wake methods await. */
public final class WifiWaker {

  private final static String TAG = WifiWaker.class.getSimpleName();
  private BroadcastReceiver mConnectionReceiver;
  private final AbordableLatch latch_;

  /**
   * Provide a latch with count 1 to have the methods of this class wait upon.
   *
   * @param latch
   *            the latch on which the methods wait - must have count one
   * @throws IllegalArgumentException
   *             if the latch does not have count 1
   */
  public WifiWaker(CountDownLatch latch) {
    this.latch_ = new AbordableLatch(latch);
  }

  /**
   * Tries to connect to wifi only if wifi is initially enabled. Will wait on
   * the class latch (with count one) till a connection is established or the
   * latch times out - in which case it returns false. DO NOT CALL THIS ON THE
   * MAIN THREAD. It registers a receiver which will receive the connection
   * event and will count the latch down, so the main thread must no block on
   * the latch for onReceive () to run. Anyway the main thread must not block.
   *
   * @param ctx
   *            the Context used to get the services and register the receiver
   * @param latchTimeout
   *            the timeout of the latch in milliseconds
   * @return true if wifi connected, false otherwise
   */
  public boolean wakeWifiUpIfEnabled(Context ctx, long latchTimeout) {
    WifiManager wm = (WifiManager) ctx
      .getSystemService(Context.WIFI_SERVICE);
    final int wifiState = wm.getWifiState();
    if (!wm.isWifiEnabled() || wifiState == WifiManager.WIFI_STATE_DISABLED
      || wifiState == WifiManager.WIFI_STATE_DISABLING) {
      // Make sure the Wi-Fi is enabled, required for some devices when
      // enable WiFi does not occur immediately
      // ******************* do not enable if not enabled ****************
      // ******************* d("!_wifiManager.isWifiEnabled()");
      // ******************* wm.setWifiEnabled(true);
      // ******************* return false instead ****************
      return false;
    }
    if (!NetworkUtil.isWifiConnectedOrConnecting(ctx)) {
      d("Wifi is NOT Connected Or Connecting - "
        + "wake it up and wait till is up");
      // Do not wait for the OS to initiate a reconnect to a Wi-Fi router
      wm.pingSupplicant();
      // if (wifiState == WifiManager.WIFI_STATE_ENABLED) { // DONT !!!!!!
      // try {
      // // Brute force methods required for some devices
      // _wifiManager.setWifiEnabled(false);
      // _wifiManager.setWifiEnabled(true);
      // } catch (SecurityException e) {
      // // Catching exception which should not occur on most
      // // devices. OS bug details at :
      // // https://code.google.com/p/android/issues/detail?id=22036
      // }
      // }
      // ////////////////// commented those out :
      // _wifiManager.disconnect();
      // _wifiManager.startScan();
      wm.reassociate();
      wm.reconnect();
      try {
        mConnectionReceiver = new WifiConnectionMonitor(latch_);
        startMonitoringConnection(ctx);
        w("I wait");
        // If the current count is zero then await returns immediately
        // with the value true. So no worries if the receiver
        // immediately counts down the latch
        final boolean await = latch_.await(latchTimeout,
          TimeUnit.MILLISECONDS);
        w("Woke up");
        // await should be false if latch timed out
        return await;
      } catch (InterruptedException e) {
        if (e instanceof AbordableLatch.AbordingException) {
          w("Interrupted while waiting for connection: "
            + e.getMessage());
        } else w("Interrupted while waiting for connection", e);
        return false;
      } finally {
        stopMonitoringConnection(ctx);
      }
    }
    return true;
  }

  private final static class WifiConnectionMonitor extends BroadcastReceiver {

    private final AbordableLatch latch_;
    private final static String TAG2 = WifiConnectionMonitor.class
      .getSimpleName();

    WifiConnectionMonitor(AbordableLatch latch) {
      super();
      this.latch_ = latch;
    }

    // http://stackoverflow.com/a/4504110/281545
    // http://stackoverflow.com/questions/5276032/
    @Override
    public void onReceive(Context context, Intent in) {
      String action = in.getAction();
      if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
        NetworkInfo networkInfo = in
          .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        d("NETWORK_STATE_CHANGED_ACTION :" + networkInfo);
        if (networkInfo.isConnected()) {
          d("Wifi is connected!");
          latch_.succeed(); // COUNT DOWN HERE
        }
      } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
        @SuppressWarnings("deprecation")
        final String extraNetInfo = ConnectivityManager.EXTRA_NETWORK_INFO;
        NetworkInfo networkInfo = in.getParcelableExtra(extraNetInfo);
        // boolean noConnectivity = intent.getBooleanExtra(
        // ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI
        /* && !networkInfo.isConnected() */) {
          d("CONNECTIVITY_ACTION - " + networkInfo);
        }
      } else if (WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION
        .equals(action)) {
        d("SUPPLICANT_CONNECTION_CHANGE_ACTION - "
          + "EXTRA_SUPPLICANT_CONNECTED :"
          + in.getBooleanExtra(
            WifiManager.EXTRA_SUPPLICANT_CONNECTED, false));
      } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION
        .equals(action)) {
        d("SUPPLICANT_STATE_CHANGED_ACTION - EXTRA_NEW_STATE: "
          + in.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)
          + " - EXTRA_SUPPLICANT_ERROR: "
          + in.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, -1));
      } else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
        d("WIFI_STATE_CHANGED_ACTION - EXTRA_WIFI_STATE: "
          + wifiState(in, WifiManager.EXTRA_WIFI_STATE)
          + " - EXTRA_PREVIOUS_WIFI_STATE: "
          + wifiState(in, WifiManager.EXTRA_PREVIOUS_WIFI_STATE));
        final int intExtra = in.getIntExtra(
          WifiManager.EXTRA_WIFI_STATE, -1);
        String msg = null;
        if (intExtra == WifiManager.WIFI_STATE_DISABLING) msg = "Wireless disabling";
        else if (intExtra == WifiManager.WIFI_STATE_DISABLED)
          msg = "Wireless disabled";
        if (msg != null) latch_.abort(msg);
      }
    }

    /**
     * Returns a string describing the state of the Wifi. Meant to be used
     * with an intent received by a BroadcastReceiver whose action is
     * WifiManager.WIFI_STATE_CHANGED_ACTION
     *
     * @param in
     *            an intent received by a BR whose action is
     *            WifiManager.WIFI_STATE_CHANGED_ACTION
     * @param key
     *            must be either WifiManager.EXTRA_WIFI_STATE OR
     *            WifiManager.EXTRA_PREVIOUS_WIFI_STATE. NOTHING else
     * @return a string for the state instead of an int
     */
    private static String wifiState(Intent in, String key) {
      switch (in.getIntExtra(key, -1)) {
      case WifiManager.WIFI_STATE_DISABLED:
        return "WIFI_STATE_DISABLED";
      case WifiManager.WIFI_STATE_DISABLING:
        return "WIFI_STATE_DISABLING";
      case WifiManager.WIFI_STATE_ENABLED:
        return "WIFI_STATE_ENABLED";
      case WifiManager.WIFI_STATE_ENABLING:
        return "WIFI_STATE_ENABLING";
      case WifiManager.WIFI_STATE_UNKNOWN:
        return "WIFI_STATE_UNKNOWN";
      }
      throw new RuntimeException("Forgot Wifi State");
    }

    private static void d(String string) {
      Log.d(TAG2, string);
    }
  }

  private synchronized void startMonitoringConnection(Context ctx) {
    IntentFilter aFilter = new IntentFilter(
      ConnectivityManager.CONNECTIVITY_ACTION);
    // aFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
    aFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    // aFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
    // aFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); // !!!!
    aFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
    aFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
    aFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    ctx.registerReceiver(mConnectionReceiver, aFilter);
  }

  private synchronized void stopMonitoringConnection(Context ctx) {
    ctx.unregisterReceiver(mConnectionReceiver);
  }

  // helpers
  private static void w(String string) {
    Log.w(TAG, string);
  }

  private static void w(String string, Throwable e) {
    Log.w(TAG, string, e);
  }

  private static void d(String string) {
    Log.d(TAG, string);
  }

  /**
   * Latch wrapper to be able throw an exception instead just counting down.
   * See <a href="http://stackoverflow.com/a/10453959/281545">here</a> for the
   * idea and variations. Must have count of one, otherwise
   * IllegalArgumentException is thrown on construction.
   */
  private static final class AbordableLatch {

    public class AbordingException extends InterruptedException {

      private static final long serialVersionUID = 6999070510289378029L;

      public AbordingException(String message) {
        super(message);
      }
    }

    private final CountDownLatch latch;
    private boolean aborted;
    private String message = "";

    public AbordableLatch(CountDownLatch latch) {
      if (latch.getCount() != 1)
        throw new IllegalArgumentException(
          "The latch must have count 1");
      this.latch = latch; // no copy cstor
    }

    boolean await(long latchTimeout, TimeUnit milliseconds)
        throws InterruptedException {
      final boolean notTimedOut = latch.await(latchTimeout, milliseconds);
      if (aborted) {
        throw new AbordingException(message);
      }
      return notTimedOut;
    }

    void abort(String msg) {
      message = msg;
      aborted = true;
      latch.countDown();
    }

    void succeed() {
      latch.countDown();
    }
  }
}




Java Source Code List

me.pc.mobile.helper.v14.BuildConfig.java
me.pc.mobile.helper.v14.base.BaseActivity.java
me.pc.mobile.helper.v14.base.BaseApp.java
me.pc.mobile.helper.v14.base.BaseFrag.java
me.pc.mobile.helper.v14.base.abs.BaseJsonParser.java
me.pc.mobile.helper.v14.crypt.AES7Padding.java
me.pc.mobile.helper.v14.crypt.AES.java
me.pc.mobile.helper.v14.crypt.Base64.java
me.pc.mobile.helper.v14.crypt.CheckUtils.java
me.pc.mobile.helper.v14.crypt.ConfigureEncryptAndDecrypt.java
me.pc.mobile.helper.v14.crypt.RSA.java
me.pc.mobile.helper.v14.files.ExternalStorage.java
me.pc.mobile.helper.v14.files.FileUtils.java
me.pc.mobile.helper.v14.files.Reader.java
me.pc.mobile.helper.v14.files.Writer.java
me.pc.mobile.helper.v14.http.AsyncHttpUtil.java
me.pc.mobile.helper.v14.net.Addresses.java
me.pc.mobile.helper.v14.net.NetworkUtil.java
me.pc.mobile.helper.v14.net.WifiWaker.java
me.pc.mobile.helper.v14.receiver.BatteryStateReceiver.java
me.pc.mobile.helper.v14.receiver.NetworkStateChangeReceiver.java
me.pc.mobile.helper.v14.ui.image.RoundedDrawable.java
me.pc.mobile.helper.v14.ui.image.RoundedImageView.java
me.pc.mobile.helper.v14.util.AppInstallUtil.java
me.pc.mobile.helper.v14.util.BitDrawableUtil.java
me.pc.mobile.helper.v14.util.DeviceIdentifier.java
me.pc.mobile.helper.v14.util.DisplayUtils.java
me.pc.mobile.helper.v14.util.IntentUtil.java
me.pc.mobile.helper.v14.util.IoUtils.java
me.pc.mobile.helper.v14.util.LogUtil.java
me.pc.mobile.helper.v14.util.PackageUtil.java
me.pc.mobile.helper.v14.util.PermissionAssertUtils.java
me.pc.mobile.helper.v14.util.RegexUtil.java
me.pc.mobile.helper.v14.util.SharedPrefUtil.java
me.pc.mobile.helper.v14.util.StorageUtils.java