BluetoothSync.java 9.0 KB

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