BluetoothSyncActivity.java 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package de.tudarmstadt.informatik.hostage.sync.bluetooth;
  2. import java.util.UUID;
  3. import android.util.Log;
  4. import android.app.Activity;
  5. import android.bluetooth.BluetoothAdapter;
  6. import android.bluetooth.BluetoothDevice;
  7. import android.bluetooth.BluetoothSocket;
  8. import android.content.BroadcastReceiver;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.IntentFilter;
  12. import android.os.Bundle;
  13. import android.os.Handler;
  14. import android.os.Message;
  15. import android.view.View;
  16. import android.widget.AdapterView;
  17. import android.widget.ArrayAdapter;
  18. import android.widget.LinearLayout;
  19. import android.widget.ListView;
  20. import android.widget.TextView;
  21. import android.widget.AdapterView.OnItemClickListener;
  22. import de.tudarmstadt.informatik.hostage.R;
  23. /**
  24. * Activity that allows the user to choose a bluetooth device to
  25. * synchronize with and informs about the status of the synchronization.
  26. *
  27. * @author Lars Pandikow
  28. */
  29. public class BluetoothSyncActivity extends Activity{
  30. public static final int CONNECTING = 0x0;
  31. public static final int CONNECTION_ESTABLISHED = 0x1;
  32. public static final int CONNECTION_FAILED = 0x2;
  33. public static final int SYNC_SUCCESSFUL = 0x3;
  34. public static final int SYNC_FAILED = 0x4;
  35. public static UUID serviceUUID;
  36. private BluetoothAdapter mBluetoothAdapter;
  37. private ArrayAdapter<String> arrayAdapter;
  38. private ServerThread serverThread;
  39. private ClientThread clientThread;
  40. private CommunicationThread commThread;
  41. private TextView mInfoText;
  42. private ListView listView;
  43. private LinearLayout layout;
  44. @Override
  45. public void onCreate(Bundle savedInstanceState){
  46. super.onCreate(savedInstanceState);
  47. setContentView(R.layout.activity_bluetooth);
  48. serviceUUID = UUID.fromString(getResources().getString(R.string.UUID));
  49. mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  50. arrayAdapter = new ArrayAdapter<String>(this, R.layout.list_view_bluetooth_devices);
  51. setLayoutElement();
  52. registerBroadcastReceiver();
  53. if (mBluetoothAdapter == null) {
  54. // Device does not support Bluetooth
  55. mInfoText.setText("Bluetooth is not available on this device.");
  56. }
  57. else if (!mBluetoothAdapter.isEnabled()) {
  58. mInfoText.setText("Enable Bluetooth before synchronizing.");
  59. Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  60. startActivity(enableBtIntent);
  61. } else {
  62. startConnectionListener();
  63. chooseDevice();
  64. }
  65. }
  66. @Override
  67. public void onDestroy(){
  68. super.onDestroy();
  69. if(mRecieverRegistered){
  70. unregisterBroadcastReceiver();
  71. }
  72. if(commThread != null) {
  73. commThread.cancel();
  74. }
  75. if(clientThread != null){
  76. clientThread.cancel();
  77. }
  78. if(serverThread != null){
  79. serverThread.cancel();
  80. }
  81. }
  82. /**
  83. * Starts discorvry of bluetooth devices.
  84. */
  85. private void chooseDevice(){
  86. arrayAdapter.clear();
  87. if (!mBluetoothAdapter.startDiscovery())
  88. return;
  89. mInfoText.setText("Choose Device for synchronizing:\n");
  90. layout.addView(listView);
  91. setContentView(layout);
  92. }
  93. /**
  94. * Start a ServerThread to listen for incomming connections
  95. * @see ServerThread
  96. */
  97. private void startConnectionListener() {
  98. Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  99. discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  100. startActivity(discoverableIntent);
  101. serverThread = new ServerThread(mHandler, getResources().getString(R.string.app_name));
  102. serverThread.start();
  103. }
  104. /**
  105. * Called when a connection has been established.
  106. * Starts a {@link CommunicationThread} for communication.
  107. * @param socket The socket of the connection.
  108. */
  109. protected void manageConnectedSocket(BluetoothSocket socket) {
  110. mBluetoothAdapter.cancelDiscovery();
  111. unregisterBroadcastReceiver();
  112. layout.removeView(listView);
  113. String deviceName = socket.getRemoteDevice().getName();
  114. mInfoText.setText("Synchronizing with " + deviceName + "...");
  115. commThread = new CommunicationThread(this, socket, mHandler);
  116. commThread.start();
  117. }
  118. /**
  119. * BroadcastReciever listens for state changes of bluetooth and discovery of new devices.
  120. */
  121. private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
  122. @Override
  123. public void onReceive(Context context, Intent intent) {
  124. String action = intent.getAction();
  125. // When discovery finds a device
  126. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  127. // Get the BluetoothDevice object from the Intent
  128. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  129. // Add the name and address to an array adapter to show in a ListView
  130. arrayAdapter.add(device.getName() + "\n" + device.getAddress());
  131. arrayAdapter.notifyDataSetChanged();
  132. }else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
  133. int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
  134. Log.i("BluetoothSync", state + "");
  135. if(state == BluetoothAdapter.STATE_ON){
  136. startConnectionListener();
  137. chooseDevice();
  138. }else if(state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF){
  139. mInfoText.setText("Enable Bluetooth before synchronizing.");
  140. layout.removeView(listView);
  141. }
  142. }
  143. }
  144. };
  145. private boolean mRecieverRegistered = false;
  146. /**
  147. * Register the BroadcastReceiver
  148. */
  149. private void registerBroadcastReceiver() {
  150. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  151. filter.addAction(BluetoothAdapter. ACTION_STATE_CHANGED);
  152. registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
  153. mRecieverRegistered = true;
  154. }
  155. /**
  156. * Unregister the BroadcastReceiver
  157. */
  158. private void unregisterBroadcastReceiver(){
  159. unregisterReceiver(mReceiver);
  160. mRecieverRegistered = false;
  161. }
  162. /**
  163. * Creates the list of bluetooth devices.
  164. * Starts a {@link ClientThread} to establish connection when a device is clicked.
  165. */
  166. private void setLayoutElement(){
  167. mInfoText = (TextView) findViewById(R.id.bluetoothInfoText);
  168. layout = (LinearLayout) findViewById(R.id.bluetoothLayout);
  169. listView = new ListView(this);
  170. listView.setAdapter(arrayAdapter);
  171. listView.setOnItemClickListener(new OnItemClickListener() {
  172. @Override
  173. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  174. String deviceInfo = arrayAdapter.getItem(position);
  175. String mac = deviceInfo.substring(deviceInfo.indexOf("\n") + 1);
  176. String name = deviceInfo.substring(0, deviceInfo.indexOf("\n"));
  177. mHandler.obtainMessage(CONNECTING, name).sendToTarget();
  178. clientThread = new ClientThread(mBluetoothAdapter.getRemoteDevice(mac), mHandler);
  179. clientThread.start();
  180. }
  181. });
  182. }
  183. /**
  184. * Handles message sent from the background threads and updates UI.
  185. */
  186. private Handler mHandler = new Handler() {
  187. @Override
  188. public void handleMessage(Message msg) {
  189. switch(msg.what){
  190. case CONNECTING:
  191. layout.removeView(listView);
  192. mInfoText.setText("Connecting to " + (String)msg.obj + "!");
  193. break;
  194. case CONNECTION_ESTABLISHED:
  195. BluetoothSocket socket = (BluetoothSocket) msg.obj;
  196. manageConnectedSocket(socket);
  197. break;
  198. case CONNECTION_FAILED:
  199. mInfoText.setText("Failed to connect to device!");
  200. break;
  201. case SYNC_SUCCESSFUL:
  202. mInfoText.setText("Synchronization successfull!");
  203. break;
  204. case SYNC_FAILED:
  205. mInfoText.setText("Synchronization failed!");
  206. break;
  207. }
  208. }
  209. };
  210. }