P2PSyncActivity.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. package de.tudarmstadt.informatik.hostage.sync.p2p;
  2. import android.app.Activity;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.IntentFilter;
  6. import android.net.wifi.p2p.WifiP2pConfig;
  7. import android.net.wifi.p2p.WifiP2pDevice;
  8. import android.net.wifi.p2p.WifiP2pDeviceList;
  9. import android.net.wifi.p2p.WifiP2pGroup;
  10. import android.net.wifi.p2p.WifiP2pInfo;
  11. import android.net.wifi.p2p.WifiP2pManager;
  12. import android.os.AsyncTask;
  13. import android.os.Build;
  14. import android.os.Bundle;
  15. import android.os.Environment;
  16. import android.view.LayoutInflater;
  17. import android.view.View;
  18. import android.view.ViewGroup;
  19. import android.widget.AdapterView;
  20. import android.widget.ArrayAdapter;
  21. import android.widget.Button;
  22. import android.widget.ListView;
  23. import android.widget.RelativeLayout;
  24. import android.widget.TextView;
  25. import android.widget.Toast;
  26. import android.widget.ViewAnimator;
  27. import java.io.File;
  28. import java.io.FileOutputStream;
  29. import java.io.IOException;
  30. import java.io.InputStream;
  31. import java.io.OutputStream;
  32. import java.lang.reflect.InvocationTargetException;
  33. import java.lang.reflect.Method;
  34. import java.net.InetSocketAddress;
  35. import java.net.ServerSocket;
  36. import java.net.Socket;
  37. import java.util.ArrayList;
  38. import java.util.List;
  39. import de.tudarmstadt.informatik.hostage.R;
  40. public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerListListener, WifiP2pManager.ChannelListener, AdapterView.OnItemClickListener, WifiP2pManager.ConnectionInfoListener {
  41. private WifiP2pManager mManager;
  42. private WifiP2pManager.Channel mChannel;
  43. private BroadcastReceiver mReceiver;
  44. private IntentFilter mIntentFilter;
  45. private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
  46. private TextView mTxtP2PDeviceName;
  47. private TextView mTxtP2PDeviceStatus;
  48. private ViewAnimator mViewAnimator;
  49. private RelativeLayout mDevicesContainer;
  50. private TextView mTxtP2PSearchProgress;
  51. private ListView mLstP2PDevices;
  52. private RelativeLayout mWelcomeContainer;
  53. private TextView mTxtP2PNotAvailable;
  54. private TextView mTxtP2PChangeDeviceName;
  55. private WifiP2pDevice mDevice;
  56. private WifiP2pDevice mOtherDevice;
  57. private WifiP2pInfo mInfo;
  58. private final int OWNER_SERVER_PORT = 8988;
  59. private final int CLIENT_SERVER_PORT = 8989;
  60. private void extractFromView(){
  61. mTxtP2PDeviceName = (TextView) findViewById(R.id.txt_p2p_device_name);
  62. mTxtP2PDeviceStatus = (TextView) findViewById(R.id.txt_p2p_device_status);
  63. mTxtP2PChangeDeviceName = (TextView) findViewById(R.id.txtP2PChangeDeviceName);
  64. //mTxtP2PHeader = (TextView) findViewById(R.id.txtP2PHeader);
  65. //mTxtP2PSubHeader = (TextView) findViewById(R.id.txtP2PSubheader);
  66. //mTxtP2PHelpBack = (TextView) findViewById(R.id.txtP2PHelpBack);
  67. mViewAnimator = (ViewAnimator) findViewById(R.id.viewAnimator);
  68. mDevicesContainer = (RelativeLayout) findViewById(R.id.devicesContainer);
  69. mWelcomeContainer = (RelativeLayout) findViewById(R.id.welcomeContainer);
  70. mTxtP2PSearchProgress = (TextView) findViewById(R.id.txtP2PSearchProgress);
  71. mLstP2PDevices = (ListView) findViewById(R.id.lstP2PDevices);
  72. //mBtnP2PSearch = (Button) findViewById(R.id.btnP2PSearch);
  73. mTxtP2PNotAvailable = (TextView) findViewById(R.id.txtP2PNotAvailable);
  74. }
  75. public void discoverPeers(){
  76. mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
  77. @Override
  78. public void onSuccess() {
  79. mViewAnimator.showNext();
  80. mTxtP2PSearchProgress.setVisibility(View.VISIBLE);
  81. setWifiDirectAvailable();
  82. }
  83. @Override
  84. public void onFailure(int reason) {
  85. if(reason == WifiP2pManager.P2P_UNSUPPORTED) {
  86. setWifiDirectNotAvailable();
  87. }
  88. }
  89. });
  90. }
  91. public void setWifiDirectNotAvailable(){
  92. //mBtnP2PSearch.setVisibility(View.GONE);
  93. mTxtP2PNotAvailable.setVisibility(View.VISIBLE);
  94. }
  95. public void setWifiDirectAvailable(){
  96. //mBtnP2PSearch.setVisibility(View.VISIBLE);
  97. mTxtP2PNotAvailable.setVisibility(View.GONE);
  98. }
  99. public void registerListeners(){
  100. mTxtP2PChangeDeviceName.setOnClickListener(new View.OnClickListener() {
  101. @Override
  102. public void onClick(View v) {
  103. Method method1 = null;
  104. try {
  105. method1 = mManager.getClass().getDeclaredMethod("setDeviceName", WifiP2pManager.Channel.class);
  106. method1.invoke(mManager, mChannel, "Android_fc546");
  107. } catch (NoSuchMethodException e) {
  108. e.printStackTrace();
  109. } catch (InvocationTargetException e) {
  110. e.printStackTrace();
  111. } catch (IllegalAccessException e) {
  112. e.printStackTrace();
  113. }
  114. }
  115. });
  116. }
  117. @Override
  118. protected void onCreate(Bundle savedInstanceState) {
  119. super.onCreate(savedInstanceState);
  120. setContentView(R.layout.activity_p2_psync);
  121. assert getActionBar() != null;
  122. getActionBar().setTitle("WifiDirect Synchronization");
  123. this.extractFromView();
  124. this.registerListeners();
  125. this.mLstP2PDevices.setAdapter(new WiFiPeerListAdapter(this, R.layout.row_devices, peers));
  126. this.mLstP2PDevices.setOnItemClickListener(this);
  127. mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
  128. mChannel = mManager.initialize(this, getMainLooper(), new WifiP2pManager.ChannelListener() {
  129. @Override
  130. public void onChannelDisconnected() {
  131. System.out.println("---------------------> CHannel disconnect!!!");
  132. }
  133. });
  134. mIntentFilter = new IntentFilter();
  135. mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
  136. mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
  137. mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
  138. mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
  139. this.discoverPeers();
  140. }
  141. @Override
  142. protected void onResume() {
  143. super.onResume();
  144. mReceiver = new P2PBroadcastReceiver(mManager, mChannel, this);
  145. registerReceiver(mReceiver, mIntentFilter);
  146. }
  147. @Override
  148. protected void onPause() {
  149. super.onPause();
  150. unregisterReceiver(mReceiver);
  151. }
  152. @Override
  153. public void onPeersAvailable(WifiP2pDeviceList peerList){
  154. mTxtP2PSearchProgress.setVisibility(View.GONE);
  155. peers.clear();
  156. peers.addAll(peerList.getDeviceList());
  157. ((WiFiPeerListAdapter) mLstP2PDevices.getAdapter()).notifyDataSetChanged();
  158. if (peers.size() == 0) {
  159. return;
  160. }
  161. }
  162. private static String getDeviceStatus(int deviceStatus) {
  163. switch (deviceStatus) {
  164. case WifiP2pDevice.AVAILABLE:
  165. return "Available";
  166. case WifiP2pDevice.INVITED:
  167. return "Invited";
  168. case WifiP2pDevice.CONNECTED:
  169. return "Connected";
  170. case WifiP2pDevice.FAILED:
  171. return "Failed";
  172. case WifiP2pDevice.UNAVAILABLE:
  173. return "Unavailable";
  174. default:
  175. return "Unknown";
  176. }
  177. }
  178. public void updateThisDevice(WifiP2pDevice device) {
  179. this.mDevice = device;
  180. mTxtP2PDeviceName.setText(device.deviceName);
  181. mTxtP2PDeviceStatus.setText(getDeviceStatus(device.status));
  182. }
  183. @Override
  184. public void onChannelDisconnected() {
  185. }
  186. @Override
  187. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  188. final WifiP2pDevice device = (WifiP2pDevice) this.mLstP2PDevices.getAdapter().getItem(position);
  189. WifiP2pConfig config = new WifiP2pConfig();
  190. config.deviceAddress = device.deviceAddress;
  191. mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
  192. @Override
  193. public void onSuccess() {
  194. mOtherDevice = device;
  195. }
  196. @Override
  197. public void onFailure(int reason) {
  198. //mOtherDevice = null;
  199. Toast.makeText(P2PSyncActivity.this, "Could not connect to device. Retry.", Toast.LENGTH_LONG).show();
  200. }
  201. });
  202. }
  203. @Override
  204. public void onConnectionInfoAvailable(WifiP2pInfo info) {
  205. mInfo = info;
  206. //if(mOtherDevice == null) return;
  207. if(info.groupFormed && info.isGroupOwner){
  208. new FileServerAsyncTask(this, OWNER_SERVER_PORT).execute();
  209. //new FileTransferAsyncTask(this, mOtherDevice.deviceAddress, CLIENT_SERVER_PORT).execute();
  210. } else if(info.groupFormed){
  211. //new FileServerAsyncTask(this, CLIENT_SERVER_PORT).execute();
  212. new FileTransferAsyncTask(this, mInfo.groupOwnerAddress.getHostAddress(), OWNER_SERVER_PORT).execute();
  213. }
  214. }
  215. public void sendDatabase(boolean isOwner){
  216. }
  217. /**
  218. * Array adapter for ListFragment that maintains WifiP2pDevice list.
  219. */
  220. private class WiFiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> {
  221. private List<WifiP2pDevice> items;
  222. /**
  223. * @param context
  224. * @param textViewResourceId
  225. * @param objects
  226. */
  227. public WiFiPeerListAdapter(Context context, int textViewResourceId,
  228. List<WifiP2pDevice> objects) {
  229. super(context, textViewResourceId, objects);
  230. items = objects;
  231. }
  232. @Override
  233. public View getView(int position, View convertView, ViewGroup parent) {
  234. View v = convertView;
  235. if (v == null) {
  236. LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  237. v = vi.inflate(R.layout.row_devices, null);
  238. }
  239. WifiP2pDevice device = items.get(position);
  240. if (device != null) {
  241. TextView top = (TextView) v.findViewById(R.id.device_name);
  242. TextView bottom = (TextView) v.findViewById(R.id.device_details);
  243. if (top != null) {
  244. top.setText(device.deviceName);
  245. }
  246. if (bottom != null) {
  247. if(device.status == WifiP2pDevice.CONNECTED){
  248. mOtherDevice = device;
  249. }
  250. bottom.setText(getDeviceStatus(device.status));
  251. }
  252. }
  253. return v;
  254. }
  255. }
  256. public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
  257. private Context context;
  258. private int port;
  259. /**
  260. * @param context
  261. */
  262. public FileServerAsyncTask(Context context, int port) {
  263. this.context = context;
  264. this.port = port;
  265. }
  266. @Override
  267. protected String doInBackground(Void... params) {
  268. try {
  269. ServerSocket serverSocket = new ServerSocket(this.port);
  270. Socket client = serverSocket.accept();
  271. /*final File f = new File(Environment.getExternalStorageDirectory() + "/"
  272. + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
  273. + ".txt");
  274. File dirs = new File(f.getParent());
  275. if (!dirs.exists())
  276. dirs.mkdirs();
  277. f.createNewFile();*/
  278. InputStream inputstream = client.getInputStream();
  279. readToToast(inputstream);
  280. client.getOutputStream().write(("HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am server").getBytes());
  281. //copyFile(inputstream, new FileOutputStream(f));
  282. serverSocket.close();
  283. return "";
  284. } catch (IOException e) {
  285. return null;
  286. }
  287. }
  288. public void readToToast(InputStream inputStream){
  289. byte buf[] = new byte[1024];
  290. StringBuffer bf = new StringBuffer();
  291. int len;
  292. try {
  293. while ((len = inputStream.read(buf)) != -1) {
  294. bf.append(buf);
  295. }
  296. inputStream.close();
  297. } catch (IOException e) {
  298. return;
  299. }
  300. Toast.makeText(context, "Received: " + bf.toString(), Toast.LENGTH_LONG).show();
  301. }
  302. }
  303. public static class FileTransferAsyncTask extends AsyncTask<Void, Void, Void> {
  304. private Context context;
  305. private int port;
  306. private String host;
  307. private static final int SOCKET_TIMEOUT = 5000;
  308. /**
  309. * @param context
  310. */
  311. public FileTransferAsyncTask(Context context, String host, int port) {
  312. this.context = context;
  313. this.host = host;
  314. this.port = port;
  315. }
  316. @Override
  317. protected Void doInBackground(Void... params) {
  318. Socket socket = new Socket();
  319. try {
  320. socket.bind(null);
  321. socket.connect(new InetSocketAddress(host, port), SOCKET_TIMEOUT);
  322. OutputStream stream = socket.getOutputStream();
  323. stream.write(("HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am " + host).getBytes());
  324. } catch (IOException e) {
  325. e.printStackTrace();
  326. }
  327. return null;
  328. }
  329. }
  330. public static boolean copyFile(InputStream inputStream, OutputStream out) {
  331. byte buf[] = new byte[1024];
  332. int len;
  333. try {
  334. while ((len = inputStream.read(buf)) != -1) {
  335. out.write(buf, 0, len);
  336. }
  337. out.close();
  338. inputStream.close();
  339. } catch (IOException e) {
  340. return false;
  341. }
  342. return true;
  343. }
  344. }