|
@@ -0,0 +1,403 @@
|
|
|
+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<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
|
|
|
+
|
|
|
+ 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<WifiP2pDevice> {
|
|
|
+ private List<WifiP2pDevice> items;
|
|
|
+ /**
|
|
|
+ * @param context
|
|
|
+ * @param textViewResourceId
|
|
|
+ * @param objects
|
|
|
+ */
|
|
|
+ public WiFiPeerListAdapter(Context context, int textViewResourceId,
|
|
|
+ List<WifiP2pDevice> 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<Void, Void, String> {
|
|
|
+ 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<Void, Void, Void> {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|