package com.michaelfotiadis.eventtriggeredskypecaller.activities;
import java.util.Calendar;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.IBeaconDevice;
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import com.github.johnpersano.supertoasts.SuperActivityToast;
import com.michaelfotiadis.eventtriggeredskypecaller.R;
import com.michaelfotiadis.eventtriggeredskypecaller.containers.BluetoothLeDeviceStore;
import com.michaelfotiadis.eventtriggeredskypecaller.containers.CustomConstants;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.BluetoothLeScanner;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.BluetoothUtils;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.Logger;
import com.michaelfotiadis.eventtriggeredskypecaller.utils.ToastUtils;
public class BluetoothLEActivity extends FragmentActivity {
public class ResponseReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Logger.d(TAG, "On Receiver Result");
if (intent.getAction().equalsIgnoreCase(
CustomConstants.Broadcasts.BROADCAST_1.getString())) {
removeReceivers();
onPostScan();
}
}
}
// BlueTooth Fields
private BluetoothLeDeviceStore mDeviceStore;
private BluetoothLeScanner mScanner;
private BluetoothUtils mBluetoothUtils;
// Scan Variables
private int mCountScans = 0;
private Long mScanStartTime = null;
private Long mScanDuration = null;
// Scan Final Fields
private final int TARGET_SCAN_DURATION = 5000;
private final int TARGET_COUNT_SCANS_FALLBACK = 200;
private final String TAG = "IBEACON_BLUETOOTH";
private SuperActivityToast mSuperActivityToast;
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
final BluetoothLeDevice deviceLe = new BluetoothLeDevice(device,
rssi, scanRecord, System.currentTimeMillis());
runOnUiThread(new Runnable() {
@Override
public void run() {
if (IBeaconUtils.isThisAnIBeacon(deviceLe)) {
mDeviceStore.addDevice(deviceLe);
mCountScans++;
Logger.i(TAG, "Found an iBeacon");
}
mScanDuration = Calendar.getInstance().getTimeInMillis()
- mScanStartTime;
Logger.i(TAG, "Scan Duration : " + mScanDuration.toString());
/*
* addTextToTextView(reportTextView, "Scan Time " +
* mScanDuration.toString() + ". Performed " + mCountScans
* + " scans.");
*/
if ((mScanDuration >= TARGET_SCAN_DURATION || mCountScans >= TARGET_COUNT_SCANS_FALLBACK)
&& mDeviceStore.getDeviceList().size() >= 1) {
mScanner.scanLeDevice(-1, false);
onPostScan();
}
}
});
}
};
private ResponseReceiver mReceiver;
public void initialiseBluetoothScan() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mBluetoothUtils.askUserToEnableBluetoothIfNeeded();
if (mBluetoothUtils.isBluetoothOn()
&& mBluetoothUtils.isBluetoothLeSupported()) {
mCountScans = 0;
mScanStartTime = Calendar.getInstance().getTimeInMillis();
Logger.i(TAG, "Start Time is " + mScanStartTime);
mDeviceStore.clear();
if (mBluetoothUtils.isBluetoothOn()
&& mBluetoothUtils.isBluetoothLeSupported()) {
Logger.i(TAG, "Starting Scan");
mScanner.scanLeDevice(TARGET_SCAN_DURATION, true);
}
} else {
sendResult(null);
}
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_le);
startScan();
}
/**
* Called when activity gets invisible
*/
@Override
protected void onPause() {
super.onPause();
removeReceivers();
}
private void onPostScan() {
Logger.i(TAG, "Dismissing Toast");
ToastUtils.dismissToast(mSuperActivityToast);
removeReceivers();
if (mDeviceStore.getDeviceList() != null
&& mDeviceStore.getDeviceList().size() > 0) {
showChoiceDialog();
} else {
Logger.d(TAG, "No LE Devices Found");
ToastUtils.makeInfoToast(this, "No Devices Found");
startScan();
}
}
protected void removeReceivers() {
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mReceiver);
Logger.d(TAG, "Receiver Unregistered Successfully");
} catch (Exception e) {
Logger.d(
TAG,
"Receiver Already Unregistered. Exception : "
+ e.getLocalizedMessage());
}
}
/**
* Method which broadcasts the activity result
*
* @param result
* String value of the result
*/
private void sendResult(String result) {
Logger.d(TAG, "Sending Result: " + result);
Intent returnIntent = new Intent();
returnIntent.putExtra(CustomConstants.EXTRA_RESULT, result);
// if a device has not been selected, set result cancelled
if (result == null || result.length() < 1) {
setResult(RESULT_CANCELED);
} else {
setResult(RESULT_OK, returnIntent);
}
finish();
}
protected void showChoiceDialog() {
String[] results = new String[mDeviceStore.getDeviceList().size()];
int i = 0;
IBeaconDevice iDevice;
// Generate the selection string
for (BluetoothLeDevice d : mDeviceStore.getDeviceList()) {
iDevice = new IBeaconDevice(d);
results[i] = "Device Name: " + iDevice.getName()
+ CustomConstants.LINE_SEPARATOR + "Device ID: "
+ iDevice.getDevice().getAddress()
+ CustomConstants.LINE_SEPARATOR + "Signal Strength: "
+ iDevice.getRunningAverageRssi()
+ CustomConstants.LINE_SEPARATOR + "Distance Descriptor: "
+ iDevice.getDistanceDescriptor()
+ CustomConstants.LINE_SEPARATOR;
i++;
}
// Show a dialog which allows for the selection of a device
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a Device");
builder.setItems(results, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int position) {
Logger.d(TAG, "Selected " + position);
IBeaconDevice iDevice = new IBeaconDevice(mDeviceStore
.getDeviceList().get(position));
sendResult(iDevice.getDevice().getAddress());
}
});
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
sendResult(null);
}
});
builder.show();
}
protected void startScan() {
Logger.i(TAG, "Registering the Broadcast Receiver");
IntentFilter mIntentFilter = new IntentFilter(
CustomConstants.Broadcasts.BROADCAST_1.getString());
mReceiver = new ResponseReceiver();
Logger.d(TAG, "Registering Receiver");
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
mIntentFilter);
mDeviceStore = new BluetoothLeDeviceStore();
mBluetoothUtils = new BluetoothUtils(this);
mScanner = new BluetoothLeScanner(this, mLeScanCallback,
mBluetoothUtils);
mSuperActivityToast = ToastUtils.makeProgressToast(this,
mSuperActivityToast, "Scanning...");
initialiseBluetoothScan();
}
}