BluetoothSync.java 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package de.tudarmstadt.informatik.hostage.sync;
  2. import java.io.IOException;
  3. import java.io.ObjectInputStream;
  4. import java.io.ObjectOutputStream;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.UUID;
  8. import de.tudarmstadt.informatik.hostage.R;
  9. import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler;
  10. import android.app.AlertDialog;
  11. import android.bluetooth.BluetoothAdapter;
  12. import android.bluetooth.BluetoothDevice;
  13. import android.bluetooth.BluetoothServerSocket;
  14. import android.bluetooth.BluetoothSocket;
  15. import android.content.BroadcastReceiver;
  16. import android.content.Context;
  17. import android.content.DialogInterface;
  18. import android.content.Intent;
  19. import android.content.IntentFilter;
  20. import android.util.Log;
  21. import android.widget.ArrayAdapter;
  22. public class BluetoothSync{
  23. private final UUID serviceUUID;
  24. private final int SERVER = 0;
  25. private final int CLIENT = 1;
  26. private BluetoothAdapter mBluetoothAdapter;
  27. private Context context;
  28. private ArrayAdapter<String> arrayAdapter;
  29. private ServerThread serverThread;
  30. private AlertDialog ad;
  31. public BluetoothSync(Context context){
  32. this.context = context;
  33. serviceUUID = UUID.fromString(context.getResources().getString(R.string.UUID));
  34. mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  35. }
  36. public boolean syncData(){
  37. if(!bluetoothAvaible())
  38. return false;
  39. syncDataPassive();
  40. return syncDataActive();
  41. }
  42. private boolean syncDataActive() {
  43. registerBroadcastReceiver();
  44. arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
  45. //Start scanning for devices
  46. if(!mBluetoothAdapter.startDiscovery())
  47. return false;
  48. deviceDialog();
  49. return true;
  50. }
  51. private void syncDataPassive(){
  52. Intent discoverableIntent = new
  53. Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  54. discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  55. context.startActivity(discoverableIntent);
  56. serverThread = new ServerThread();
  57. serverThread.start();
  58. }
  59. private void manageConnectedSocket(BluetoothSocket socket, int identifier){
  60. if(identifier == SERVER){
  61. ad.dismiss();
  62. }
  63. mBluetoothAdapter.cancelDiscovery();
  64. context.unregisterReceiver(mReceiver);
  65. CommunicationThread commThread = new CommunicationThread(socket, identifier);
  66. commThread.start();
  67. }
  68. private boolean bluetoothAvaible(){
  69. if (mBluetoothAdapter == null) {
  70. // Device does not support Bluetooth
  71. return false;
  72. }
  73. if (!mBluetoothAdapter.isEnabled()) {
  74. Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  75. context.startActivity(enableBtIntent);
  76. //TODO CHECK
  77. // if(!mBluetoothAdapter.isEnabled())
  78. // return false;
  79. }
  80. return true;
  81. }
  82. // Create a BroadcastReceiver for ACTION_FOUND
  83. private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
  84. public void onReceive(Context context, Intent intent) {
  85. String action = intent.getAction();
  86. // When discovery finds a device
  87. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  88. // Get the BluetoothDevice object from the Intent
  89. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  90. // Add the name and address to an array adapter to show in a ListView
  91. arrayAdapter.add(device.getName() + "\n" + device.getAddress());
  92. arrayAdapter.notifyDataSetChanged();
  93. }
  94. }
  95. };
  96. // Register the BroadcastReceiver
  97. private void registerBroadcastReceiver(){
  98. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  99. context.registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
  100. }
  101. private void deviceDialog() {
  102. AlertDialog.Builder builder = new AlertDialog.Builder(context);
  103. builder.setTitle(R.string.delete_dialog_title);
  104. builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
  105. public void onClick(DialogInterface dialog, int position) {
  106. String deviceInfo = arrayAdapter.getItem(position);
  107. String mac = deviceInfo.substring(deviceInfo.indexOf("\n") + 1);
  108. ClientThread clientThread = new ClientThread(mBluetoothAdapter.getRemoteDevice(mac));
  109. clientThread.start();
  110. }
  111. });
  112. // builder.create();
  113. ad = builder.show();
  114. }
  115. private class ServerThread extends Thread {
  116. private final BluetoothServerSocket serverSocket;
  117. public ServerThread() {
  118. BluetoothServerSocket tmp = null;
  119. try {
  120. tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(context.getResources().getString(R.string.app_name), serviceUUID);
  121. } catch (IOException e) { }
  122. serverSocket = tmp;
  123. }
  124. public void run() {
  125. BluetoothSocket socket = null;
  126. while(true){
  127. try {
  128. socket = serverSocket.accept();
  129. } catch (IOException e) {
  130. e.printStackTrace();
  131. break;
  132. }
  133. if (socket != null) {
  134. // Do work to manage the connection (in a separate thread)
  135. manageConnectedSocket(socket, SERVER);
  136. try {
  137. serverSocket.close();
  138. } catch (IOException e) {
  139. e.printStackTrace();
  140. }
  141. break;
  142. }
  143. }
  144. }
  145. /** Will cancel the listening socket, and cause the thread to finish */
  146. public void cancel() {
  147. try {
  148. serverSocket.close();
  149. } catch (IOException e) { }
  150. }
  151. }
  152. private class ClientThread extends Thread {
  153. private final BluetoothSocket socket;
  154. public ClientThread(BluetoothDevice device) {
  155. BluetoothSocket tmp = null;
  156. try {
  157. tmp = device.createRfcommSocketToServiceRecord(serviceUUID);
  158. } catch (IOException e) { }
  159. socket = tmp;
  160. }
  161. public void run() {
  162. try {
  163. socket.connect();
  164. } catch (IOException connectException) {
  165. // Unable to connect; close the socket and get out
  166. try {
  167. socket.close();
  168. } catch (IOException closeException) { }
  169. return;
  170. }
  171. manageConnectedSocket(socket, CLIENT);
  172. }
  173. /** Will cancel an in-progress connection, and close the socket */
  174. public void cancel() {
  175. try {
  176. socket.close();
  177. } catch (IOException e) { }
  178. }
  179. }
  180. private class CommunicationThread extends Thread {
  181. private final BluetoothSocket mmSocket;
  182. private final ObjectInputStream objectInput;
  183. private final ObjectOutputStream objectOuput;
  184. private final int identifier;
  185. public CommunicationThread(BluetoothSocket socket, int identifier) {
  186. mmSocket = socket;
  187. ObjectInputStream tmpIn = null;
  188. ObjectOutputStream tmpOut = null;
  189. // Get the input and output streams, using temp objects because
  190. // member streams are final
  191. try {
  192. tmpOut = new ObjectOutputStream(socket.getOutputStream());
  193. tmpIn = new ObjectInputStream(socket.getInputStream());
  194. } catch (IOException e) { e.printStackTrace();}
  195. objectInput = tmpIn;
  196. objectOuput = tmpOut;
  197. this.identifier = identifier;
  198. }
  199. public void run() {
  200. // Keep listening to the InputStream until an exception occurs
  201. // while (true) {
  202. try {
  203. DatabaseHandler dbh = new DatabaseHandler(context);
  204. ArrayList<HashMap<String, Object>> localNetworkInformation = dbh.getNetworkInformation();
  205. if(identifier == SERVER){
  206. // Read from the InputStream
  207. Object object = objectInput.readObject();
  208. ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) object;
  209. dbh.updateNetworkInformation(remoteNetworkInformation);
  210. objectOuput.writeObject(localNetworkInformation);
  211. }else{
  212. objectOuput.writeObject(localNetworkInformation);
  213. // Read from the InputStream
  214. Object object = objectInput.readObject();
  215. ArrayList<HashMap<String, Object>> remoteNetworkInformation = (ArrayList<HashMap<String, Object>>) object;
  216. dbh.updateNetworkInformation(remoteNetworkInformation);
  217. mmSocket.close();
  218. }
  219. } catch (ClassNotFoundException e) {
  220. e.printStackTrace();
  221. } catch (IOException e) {
  222. e.printStackTrace();
  223. }
  224. // }
  225. }
  226. /* Call this from the main activity to send data to the remote device */
  227. public void write(ArrayList<HashMap<String, Object>> networkInformation) {
  228. try {
  229. objectOuput.writeObject(networkInformation);
  230. } catch (IOException e) {
  231. e.printStackTrace();
  232. }
  233. }
  234. /* Call this from the main activity to shutdown the connection */
  235. public void cancel() {
  236. try {
  237. mmSocket.close();
  238. } catch (IOException e) { }
  239. }
  240. }
  241. }