package de.tudarmstadt.informatik.hostage.sync.p2p; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; import android.net.wifi.p2p.WifiP2pConfig; import android.net.wifi.p2p.WifiP2pDevice; import android.net.wifi.p2p.WifiP2pDeviceList; import android.net.wifi.p2p.WifiP2pGroup; import android.net.wifi.p2p.WifiP2pInfo; import android.net.wifi.p2p.WifiP2pManager; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import android.widget.ViewAnimator; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import de.tudarmstadt.informatik.hostage.R; public class P2PSyncActivity extends Activity implements WifiP2pManager.PeerListListener, WifiP2pManager.ChannelListener, AdapterView.OnItemClickListener, WifiP2pManager.ConnectionInfoListener { private WifiP2pManager mManager; private WifiP2pManager.Channel mChannel; private BroadcastReceiver mReceiver; private IntentFilter mIntentFilter; private List peers = new ArrayList(); private TextView mTxtP2PDeviceName; private TextView mTxtP2PDeviceStatus; private ViewAnimator mViewAnimator; private RelativeLayout mDevicesContainer; private TextView mTxtP2PSearchProgress; private ListView mLstP2PDevices; private RelativeLayout mWelcomeContainer; private TextView mTxtP2PNotAvailable; private TextView mTxtP2PChangeDeviceName; private WifiP2pDevice mDevice; private WifiP2pDevice mOtherDevice; private WifiP2pInfo mInfo; private final int OWNER_SERVER_PORT = 8988; private final int CLIENT_SERVER_PORT = 8989; private void extractFromView(){ mTxtP2PDeviceName = (TextView) findViewById(R.id.txt_p2p_device_name); mTxtP2PDeviceStatus = (TextView) findViewById(R.id.txt_p2p_device_status); mTxtP2PChangeDeviceName = (TextView) findViewById(R.id.txtP2PChangeDeviceName); //mTxtP2PHeader = (TextView) findViewById(R.id.txtP2PHeader); //mTxtP2PSubHeader = (TextView) findViewById(R.id.txtP2PSubheader); //mTxtP2PHelpBack = (TextView) findViewById(R.id.txtP2PHelpBack); mViewAnimator = (ViewAnimator) findViewById(R.id.viewAnimator); mDevicesContainer = (RelativeLayout) findViewById(R.id.devicesContainer); mWelcomeContainer = (RelativeLayout) findViewById(R.id.welcomeContainer); mTxtP2PSearchProgress = (TextView) findViewById(R.id.txtP2PSearchProgress); mLstP2PDevices = (ListView) findViewById(R.id.lstP2PDevices); //mBtnP2PSearch = (Button) findViewById(R.id.btnP2PSearch); mTxtP2PNotAvailable = (TextView) findViewById(R.id.txtP2PNotAvailable); } public void discoverPeers(){ mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { mViewAnimator.showNext(); mTxtP2PSearchProgress.setVisibility(View.VISIBLE); setWifiDirectAvailable(); } @Override public void onFailure(int reason) { if(reason == WifiP2pManager.P2P_UNSUPPORTED) { setWifiDirectNotAvailable(); } } }); } public void setWifiDirectNotAvailable(){ //mBtnP2PSearch.setVisibility(View.GONE); mTxtP2PNotAvailable.setVisibility(View.VISIBLE); } public void setWifiDirectAvailable(){ //mBtnP2PSearch.setVisibility(View.VISIBLE); mTxtP2PNotAvailable.setVisibility(View.GONE); } public void registerListeners(){ mTxtP2PChangeDeviceName.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Method method1 = null; try { method1 = mManager.getClass().getDeclaredMethod("setDeviceName", WifiP2pManager.Channel.class); method1.invoke(mManager, mChannel, "Android_fc546"); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_p2_psync); assert getActionBar() != null; getActionBar().setTitle("WifiDirect Synchronization"); this.extractFromView(); this.registerListeners(); this.mLstP2PDevices.setAdapter(new WiFiPeerListAdapter(this, R.layout.row_devices, peers)); this.mLstP2PDevices.setOnItemClickListener(this); mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(this, getMainLooper(), new WifiP2pManager.ChannelListener() { @Override public void onChannelDisconnected() { System.out.println("---------------------> CHannel disconnect!!!"); } }); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); this.discoverPeers(); } @Override protected void onResume() { super.onResume(); mReceiver = new P2PBroadcastReceiver(mManager, mChannel, this); registerReceiver(mReceiver, mIntentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mReceiver); } @Override public void onPeersAvailable(WifiP2pDeviceList peerList){ mTxtP2PSearchProgress.setVisibility(View.GONE); peers.clear(); peers.addAll(peerList.getDeviceList()); ((WiFiPeerListAdapter) mLstP2PDevices.getAdapter()).notifyDataSetChanged(); if (peers.size() == 0) { return; } } private static String getDeviceStatus(int deviceStatus) { switch (deviceStatus) { case WifiP2pDevice.AVAILABLE: return "Available"; case WifiP2pDevice.INVITED: return "Invited"; case WifiP2pDevice.CONNECTED: return "Connected"; case WifiP2pDevice.FAILED: return "Failed"; case WifiP2pDevice.UNAVAILABLE: return "Unavailable"; default: return "Unknown"; } } public void updateThisDevice(WifiP2pDevice device) { this.mDevice = device; mTxtP2PDeviceName.setText(device.deviceName); mTxtP2PDeviceStatus.setText(getDeviceStatus(device.status)); } @Override public void onChannelDisconnected() { } @Override public void onItemClick(AdapterView parent, View view, int position, long id) { final WifiP2pDevice device = (WifiP2pDevice) this.mLstP2PDevices.getAdapter().getItem(position); WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = device.deviceAddress; mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() { @Override public void onSuccess() { mOtherDevice = device; } @Override public void onFailure(int reason) { //mOtherDevice = null; Toast.makeText(P2PSyncActivity.this, "Could not connect to device. Retry.", Toast.LENGTH_LONG).show(); } }); } @Override public void onConnectionInfoAvailable(WifiP2pInfo info) { mInfo = info; //if(mOtherDevice == null) return; if(info.groupFormed && info.isGroupOwner){ new FileServerAsyncTask(this, OWNER_SERVER_PORT).execute(); //new FileTransferAsyncTask(this, mOtherDevice.deviceAddress, CLIENT_SERVER_PORT).execute(); } else if(info.groupFormed){ //new FileServerAsyncTask(this, CLIENT_SERVER_PORT).execute(); new FileTransferAsyncTask(this, mInfo.groupOwnerAddress.getHostAddress(), OWNER_SERVER_PORT).execute(); } } public void sendDatabase(boolean isOwner){ } /** * Array adapter for ListFragment that maintains WifiP2pDevice list. */ private class WiFiPeerListAdapter extends ArrayAdapter { private List items; /** * @param context * @param textViewResourceId * @param objects */ public WiFiPeerListAdapter(Context context, int textViewResourceId, List objects) { super(context, textViewResourceId, objects); items = objects; } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if (v == null) { LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.row_devices, null); } WifiP2pDevice device = items.get(position); if (device != null) { TextView top = (TextView) v.findViewById(R.id.device_name); TextView bottom = (TextView) v.findViewById(R.id.device_details); if (top != null) { top.setText(device.deviceName); } if (bottom != null) { if(device.status == WifiP2pDevice.CONNECTED){ mOtherDevice = device; } bottom.setText(getDeviceStatus(device.status)); } } return v; } } public static class FileServerAsyncTask extends AsyncTask { private Context context; private int port; /** * @param context */ public FileServerAsyncTask(Context context, int port) { this.context = context; this.port = port; } @Override protected String doInBackground(Void... params) { try { ServerSocket serverSocket = new ServerSocket(this.port); Socket client = serverSocket.accept(); /*final File f = new File(Environment.getExternalStorageDirectory() + "/" + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis() + ".txt"); File dirs = new File(f.getParent()); if (!dirs.exists()) dirs.mkdirs(); f.createNewFile();*/ InputStream inputstream = client.getInputStream(); readToToast(inputstream); client.getOutputStream().write(("HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am server").getBytes()); //copyFile(inputstream, new FileOutputStream(f)); serverSocket.close(); return ""; } catch (IOException e) { return null; } } public void readToToast(InputStream inputStream){ byte buf[] = new byte[1024]; StringBuffer bf = new StringBuffer(); int len; try { while ((len = inputStream.read(buf)) != -1) { bf.append(buf); } inputStream.close(); } catch (IOException e) { return; } Toast.makeText(context, "Received: " + bf.toString(), Toast.LENGTH_LONG).show(); } } public static class FileTransferAsyncTask extends AsyncTask { private Context context; private int port; private String host; private static final int SOCKET_TIMEOUT = 5000; /** * @param context */ public FileTransferAsyncTask(Context context, String host, int port) { this.context = context; this.host = host; this.port = port; } @Override protected Void doInBackground(Void... params) { Socket socket = new Socket(); try { socket.bind(null); socket.connect(new InetSocketAddress(host, port), SOCKET_TIMEOUT); OutputStream stream = socket.getOutputStream(); stream.write(("HELLO I HOPE THIS WILL REACH IT'S DESTINATION. I am " + host).getBytes()); } catch (IOException e) { e.printStackTrace(); } return null; } } public static boolean copyFile(InputStream inputStream, OutputStream out) { byte buf[] = new byte[1024]; int len; try { while ((len = inputStream.read(buf)) != -1) { out.write(buf, 0, len); } out.close(); inputStream.close(); } catch (IOException e) { return false; } return true; } }