package tmay.bluetoothbacon.blescanner.fragments;
import android.app.ListFragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.SystemService;
import org.androidannotations.annotations.UiThread;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import tmay.bluetoothbacon.MainMenuActivity_;
import tmay.bluetoothbacon.blescanner.adapters.BleScannerAdapter;
/**
* Created by Terry on 10/4/14.
*/
@EFragment
public class BleScannerFragment extends ListFragment {
private static final String SERVICE_UUID = "service_uuid";
private static final String KNOWN_ADDRESS = "known_address";
private static final int SCAN_TIMEOUT = 10*1000;
private static final int REQUEST_ENABLE_BT = 0x01;
public static BleScannerFragment newInstance(String deviceAddress, ParcelUuid serviceId) {
BleScannerFragment fragment = new BleScannerFragment_();
Bundle args = new Bundle();
args.putString(KNOWN_ADDRESS, deviceAddress);
args.putParcelable(SERVICE_UUID, serviceId);
fragment.setArguments(args);
return fragment;
}
public interface OnBleDeviceSelectionListener {
public void onBleDeviceSelection(BluetoothDevice device);
}
@Bean
BleScannerAdapter adapter;
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private OnBleDeviceSelectionListener listener;
private String knownAddress;
private UUID serviceID;
private Timer timer;
private MenuItem scanMenuItem;
BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] bytes) {
if (knownAddress == null)
updateAdapter(device, rssi);
else if (device.getAddress().equals(knownAddress))
updateAdapter(device, rssi);
}
};
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
scanMenuItem = menu.add("Stop Scan").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
stopScan();
return false;
}
});
scanMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
scanMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
@AfterViews
void onAfterViews() {
this.setHasOptionsMenu(true);
this.setListAdapter(adapter);
this.knownAddress = this.getArguments().getString(KNOWN_ADDRESS);
ParcelUuid puuid = (ParcelUuid) this.getArguments().get(SERVICE_UUID);
if (puuid != null)
this.serviceID = puuid.getUuid();
initScan();
}
@Override
public void onPause() {
super.onPause();
stopScan();
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
stopScan();
listener.onBleDeviceSelection(adapter.getItem(position));
}
public void setSelectionListener(OnBleDeviceSelectionListener listener) {
this.listener = listener;
}
@UiThread
void initScan() {
if (checkForBluetooth()) {
if (serviceID == null) scan();
else scanForService(serviceID);
} else {
showBluetoothSettings();
}
}
private void scan() {
getActivity().setProgressBarIndeterminateVisibility(true);
adapter.clear();
bluetoothAdapter.startLeScan(leScanCallback);
startScanTimer();
}
private void scanForService(UUID serviceId) {
UUID[] uuids = new UUID[1];
uuids[0] = serviceId;
getActivity().setProgressBarIndeterminateVisibility(true);
adapter.clear();
bluetoothAdapter.startLeScan(uuids, leScanCallback);
startScanTimer();
}
@UiThread
void updateAdapter(BluetoothDevice device, int rssi) {
adapter.addDevice(device, rssi);
}
private void startScanTimer() {
if (timer != null)
timer.cancel();
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
timer.cancel();
stopScan();
}
}, SCAN_TIMEOUT, 1);
}
@UiThread
void stopScan() {
bluetoothAdapter.stopLeScan(leScanCallback);
if (getActivity() != null)
getActivity().setProgressBarIndeterminateVisibility(false);
if (timer != null)
timer.cancel();
scanMenuItem.setTitle("Start Scan").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
initScan();
return false;
}
});
}
private boolean checkForBluetooth() {
bluetoothManager = (BluetoothManager) getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetoothManager == null) {
Log.e("BLEService", "Unable to initialize BluetoothManager.");
}
bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
return false;
}
return true;
}
private void showBluetoothSettings() {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}