Android Open Source - beaconbrowser Browse Activity






From Project

Back to project page beaconbrowser.

License

The source code is released under:

MIT License

If you think the Android project beaconbrowser 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 org.waded.beaconbrowser;
/* w  ww  . j a  v a2 s  .c o m*/
import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.google.common.collect.Ordering;
import com.radiusnetworks.ibeacon.IBeacon;
import com.radiusnetworks.ibeacon.IBeaconConsumer;
import com.radiusnetworks.ibeacon.IBeaconManager;
import com.radiusnetworks.ibeacon.RangeNotifier;
import com.radiusnetworks.ibeacon.Region;

import java.util.Collection;
import java.util.List;

public class BrowseActivity extends Activity implements IBeaconConsumer
{
  private static final String TAG = BrowseActivity.class.getName();

  private IBeaconManager iBeaconManager = IBeaconManager.getInstanceForApplication(this);
  private List<Entry> entryCache;
  private String currentEntryId;
  // Wildcard uuid, major, and minor to be notified of range of all of them
  private static final Region region = new Region(TAG, null, null, null);


  Ordering<IBeacon> byDistance = new Ordering<IBeacon>() {
    public int compare(IBeacon l, IBeacon r) {
      // accuracy means distance, but accurate it is not
      return Double.compare(l.getAccuracy(), r.getAccuracy());
    }
  };


  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    // Bind for beacon ranging notifications. We won't start just yet to
    // avoid interfering with wifi, which we need to get the beacon info,
    // and later to load content.
    iBeaconManager.bind(this);

    // Start beacon sync
    startBeaconSync();

    // Set up layout, particularly the webview
    setContentView(R.layout.activity_browse);
    WebView webView = (WebView) findViewById(R.id.webView);
    webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    webView.setWebChromeClient(new WebChromeClient());
    webView.setWebViewClient(new WebViewClient()
    {
      public void onPageFinished(WebView view, String url)
      {
        startRanging();
      }

      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
      {
        startRanging();
      }
    });
    WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setMediaPlaybackRequiresUserGesture(false);
    settings.setUserAgentString(TAG);
  }

  @Override
  protected void onPause()
  {
    stopRanging();
    super.onPause();
  }

  @Override
  protected void onResume()
  {
    startRanging();
    super.onResume();
  }

  @Override
  protected void onDestroy()
  {
    stopRanging();
    iBeaconManager.unBind(this);
    super.onDestroy();
  }

  private void startBeaconSync()
  {
    Log.i(TAG, "Starting refresh of entries");
    BeaconSyncTask task = new BeaconSyncTask()
    {
      @Override
      public void onPostExecute(List<Entry> result)
      {
        entryCache = result;
        Log.i(TAG, "Refreshed " + entryCache.size() + " entries.");

        // OK to start now, we got the entryCache updated.
        startRanging();
      }
    };

    // We can make the WordPress site feed URL configurable later
    task.execute("http://waded-dci.azurewebsites.net/feed/atom");
  }

  /**
   * Navigate the webview to the @param entry's link with debouncing on the entry's id,
   * since this will be called often by ranging notifications.
   */
  public void startLoadUrlForEntry(final Entry entry)
  {
    if (!entry.id.equals(currentEntryId))
    {
      stopRanging();

      currentEntryId = entry.id;
      runOnUiThread(new Runnable()
      {
        @Override
        public void run()
        {
          Log.i(TAG, "Switching to new entry " + currentEntryId);
          WebView webView = (WebView) findViewById(R.id.webView);
          webView.loadUrl(entry.link);
        }
      });
    }
    else
    {
      Log.i(TAG, "We're already at " + currentEntryId);
    }
  }

  /**
   * @return only an entry from entryCache that fully matches the given @param beacon.
   * Quite unforgiving for now. Returns null if no match.
   */
  private Entry getBestEntry(IBeacon beacon)
  {
    for (Entry e : entryCache)
    {
      if (beacon.getProximityUuid().equals(e.beacon.uuid) &&
        beacon.getMajor() == e.beacon.major &&
        beacon.getMinor() == e.beacon.minor)
      {
        return e;
      }
    }
    return null;
  }

  @Override
  public void onIBeaconServiceConnect()
  {
    iBeaconManager.setRangeNotifier(new RangeNotifier()
    {
      @Override
      public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region)
      {
        if (iBeacons.size() > 0)
        {
          if (entryCache != null)
          {
            IBeacon nearestBeacon = byDistance.min(iBeacons);
            Entry bestEntry = getBestEntry(nearestBeacon);
            if (bestEntry != null) startLoadUrlForEntry(bestEntry);
          }
        }
      }
    });
  }

  /**
   * See https://code.google.com/p/android/issues/detail?id=41631 before considering
   * calling this.
   */
  private void startRanging()
  {
    // We do not start if the entryCache is not established because there's
    // simply no reason to do so; we'll only interfere with getting it.
    // TODO: when we actually persist entryCache we'll want something more sensitive.
    if (entryCache == null) return;

    try
    {
      iBeaconManager.startRangingBeaconsInRegion(region);
    }
    catch (RemoteException e)
    {
      Log.e(TAG, "startRanging: " + e.getLocalizedMessage());
    }
  }

  private void stopRanging()
  {
    try
    {
      iBeaconManager.stopRangingBeaconsInRegion(region);
    }
    catch (RemoteException e)
    {
      Log.e(TAG, "stopRanging: " + e.getLocalizedMessage());
    }
  }
}




Java Source Code List

org.waded.beaconbrowser.BeaconSyncEntryExtension.java
org.waded.beaconbrowser.BeaconSyncTask.java
org.waded.beaconbrowser.BrowseActivity.java
org.waded.beaconbrowser.Entry.java