summaryrefslogtreecommitdiff
path: root/app/src/main/java/no/topi/fiken/display/MainActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/no/topi/fiken/display/MainActivity.java')
-rw-r--r--app/src/main/java/no/topi/fiken/display/MainActivity.java335
1 files changed, 335 insertions, 0 deletions
diff --git a/app/src/main/java/no/topi/fiken/display/MainActivity.java b/app/src/main/java/no/topi/fiken/display/MainActivity.java
new file mode 100644
index 0000000..d9dc073
--- /dev/null
+++ b/app/src/main/java/no/topi/fiken/display/MainActivity.java
@@ -0,0 +1,335 @@
+package no.topi.fiken.display;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.ListActivity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.lang.String.valueOf;
+import static no.topi.fiken.display.DisplayService.IntentAction;
+import static no.topi.fiken.display.DisplayService.IntentExtra;
+import static no.topi.fiken.display.ExceptionHandler.EXCEPTION_HANDLER;
+
+public class MainActivity extends ListActivity {
+ private final static String TAG = MainActivity.class.getSimpleName();
+
+ // Stops scanning after 10 seconds.
+ private static final long SCAN_PERIOD = 3 * 1000;
+
+ private static final int REQUEST_ENABLE_BT = 1;
+
+ private DisplayListAdapter displayList;
+ private Handler handler;
+ private BluetoothAdapter mBluetoothAdapter;
+ private boolean mScanning;
+ private DisplayService displayService;
+ private String deviceToShow;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Log.i(TAG, "onCreate");
+ Thread.setDefaultUncaughtExceptionHandler(EXCEPTION_HANDLER);
+ super.onCreate(savedInstanceState);
+
+ ActionBar actionBar = getActionBar();
+ if (actionBar != null) {
+ actionBar.setTitle(R.string.title_devices);
+ }
+ handler = new Handler();
+
+ // Use this check to determine whether BLE is supported on the device. Then you can
+ // selectively disable BLE-related features.
+ if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+ Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
+ // BluetoothAdapter through BluetoothManager.
+ final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+ mBluetoothAdapter = bluetoothManager.getAdapter();
+
+ // Checks if Bluetooth is supported on the device.
+ if (mBluetoothAdapter == null) {
+ Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ ServiceConnection serviceConnection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder service) {
+ displayService = ((DisplayService.LocalBinder) service).getService();
+ if (!displayService.initialize()) {
+ finish();
+ }
+
+ startScan();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ stopScan();
+ displayService = null;
+ }
+ };
+
+ Intent displayServiceIntent = new Intent(this, DefaultDisplayService.class);
+ bindService(displayServiceIntent, serviceConnection, BIND_AUTO_CREATE);
+ }
+
+ @Override
+ protected void onResume() {
+ Log.i(TAG, "onResume");
+
+ super.onResume();
+
+ // Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
+ // fire an intent to display a dialog asking the user to grant permission to enable it.
+ if (!mBluetoothAdapter.isEnabled()) {
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+ }
+
+ registerReceiver(displayServiceBroadcastReceiver, IntentAction.ALL_FILTER);
+ }
+
+ @Override
+ protected void onPause() {
+ Log.i(TAG, "onPause");
+
+ super.onPause();
+ stopScan();
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ Log.i(TAG, "onActivityResult");
+
+ // User chose not to enable Bluetooth.
+ if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
+ finish();
+ return;
+ }
+
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ Log.i(TAG, "onCreateOptionsMenu");
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+
+ if (!mScanning) {
+ menu.findItem(R.id.menu_stop).setVisible(false);
+ menu.findItem(R.id.menu_scan).setVisible(true);
+ menu.findItem(R.id.menu_refresh).setActionView(null);
+ } else {
+ menu.findItem(R.id.menu_stop).setVisible(true);
+ menu.findItem(R.id.menu_scan).setVisible(false);
+ menu.findItem(R.id.menu_refresh).setActionView(R.layout.actionbar_indeterminate_progress);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ Log.i(TAG, "onOptionsItemSelected");
+
+ switch (item.getItemId()) {
+ case R.id.menu_scan:
+ startScan();
+ break;
+ case R.id.menu_stop:
+ stopScan();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void startScan() {
+ displayList = new DisplayListAdapter();
+ setListAdapter(displayList);
+
+ displayService.startScan();
+
+ // Stops scanning after a pre-defined scan period.
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ displayService.stopScan();
+ invalidateOptionsMenu();
+ }
+ }, SCAN_PERIOD);
+ }
+
+ private void stopScan() {
+ if (displayService != null) {
+ displayService.stopScan();
+ }
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ stopScan();
+
+ DisplayService.DeviceInfo state = displayList.getDevice(position);
+
+ if (!displayService.connect(state.address)) {
+ Toast.makeText(this, "Could not connect to " + state.address, Toast.LENGTH_SHORT).show();
+ } else {
+ deviceToShow = state.address;
+ }
+ }
+
+ private final BroadcastReceiver displayServiceBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ IntentAction action = IntentAction.valueOf(intent);
+
+ String deviceAddress = intent.getStringExtra(IntentExtra.DEVICE_ADDRESS.name());
+
+ if (action == IntentAction.DEVICE_UPDATE && deviceAddress != null) {
+ DisplayService.DeviceInfo device = displayList.getDevice(deviceAddress, true);
+
+ device.update(intent);
+
+ if (intent.hasExtra(IntentExtra.CONNECTED.name())) {
+ boolean connected = intent.getBooleanExtra(IntentExtra.CONNECTED.name(), false);
+
+ if (connected) {
+ if (deviceToShow != null && deviceToShow.equals(device.address)) {
+ Log.i(TAG, "connected to " + deviceToShow);
+ final Intent intent = new Intent(context, DisplayControlActivity.class);
+ intent.putExtra(IntentExtra.DEVICE_ADDRESS.name(), device.address);
+ intent.putExtra(IntentExtra.DEVICE_NAME.name(), device.name);
+ startActivity(intent);
+ }
+ }
+ }
+ displayList.notifyDataSetChanged();
+ }
+
+ if (intent.hasExtra(IntentExtra.SCANNING.name())) {
+ mScanning = intent.getBooleanExtra(IntentExtra.SCANNING.name(), false);
+ invalidateOptionsMenu();
+ }
+ }
+ });
+ }
+ };
+
+ static class ViewHolder {
+ final TextView deviceName;
+ final TextView deviceAddress;
+ final TextView rssi;
+ final TextView isDisplay;
+
+ ViewHolder(TextView deviceName, TextView deviceAddress, TextView rssi, TextView isDisplay) {
+ this.deviceName = deviceName;
+ this.deviceAddress = deviceAddress;
+ this.rssi = rssi;
+ this.isDisplay = isDisplay;
+ }
+ }
+
+ private class DisplayListAdapter extends BaseAdapter {
+ private List<DisplayService.DeviceInfo> devices = new ArrayList<DisplayService.DeviceInfo>();
+ private LayoutInflater inflater = MainActivity.this.getLayoutInflater();
+
+ public DisplayService.DeviceInfo getDevice(int position) {
+ return devices.get(position);
+ }
+
+ public DisplayService.DeviceInfo getDevice(String address, boolean create) {
+ for (DisplayService.DeviceInfo device : devices) {
+ if (device.address.equals(address)) {
+ return device;
+ }
+ }
+
+ DisplayService.DeviceInfo deviceInfo = null;
+ if (create) {
+ deviceInfo = new DisplayService.DeviceInfo(address, 0);
+ devices.add(deviceInfo);
+ }
+ return deviceInfo;
+ }
+
+ @Override
+ public int getCount() {
+ return devices.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return devices.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ ViewHolder viewHolder;
+
+ if (view == null) {
+ view = inflater.inflate(R.layout.listitem_device, null);
+ viewHolder = new ViewHolder(
+ (TextView) view.findViewById(R.id.device_name),
+ (TextView) view.findViewById(R.id.device_address),
+ (TextView) view.findViewById(R.id.device_rssi),
+ (TextView) view.findViewById(R.id.device_isDisplay));
+ view.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) view.getTag();
+ }
+
+ DisplayService.DeviceInfo state = devices.get(i);
+ if (state.name != null && state.name.length() > 0) {
+ viewHolder.deviceName.setText(state.name);
+ } else {
+ viewHolder.deviceName.setText(R.string.unknown_device);
+ }
+ viewHolder.deviceAddress.setText(state.address);
+
+ viewHolder.rssi.setText(getText(R.string.rssi) + ": " +
+ (state.rssi != 0 ? valueOf(state.rssi) : getText(R.string.rssi_unknown)));
+
+ viewHolder.isDisplay.setText("Is display: " +
+ (state.isDisplay != null ? state.isDisplay : "unknown"));
+ view.setClickable(state.isDisplay != null && state.isDisplay);
+
+ return view;
+ }
+ }
+}