2017-04-06 74 views
1

我一直在研究这个项目,我应该使用WiFi Direct将我的手机连接到传感器。然后检索传感器数据并在地图上将其可视化。我已经能够使用WiFi Direct将传感器连接到手机,并在地图上的infowindow中将虚假数据可视化。制造传感器的公司应该提供给我数据的命令。我被卡在需要与传感器建立连接并发送命令的部分。我需要通过WiFi-Direct从传感器获取数据。如何向传感器发送命令?

我正在看这款适用于WiFi-direct的演示应用程序,该应用程序应该在两个设备之间发送图像。我是否可以用某种方式改写它,而不是通过手机发送命令给我的手机而不是图像?如果不是,发送命令到传感器的最简单方法是什么?

我很感激我得到的任何帮助。

以下是传送图像的服务代码。

FileTransferService:

public class FileTransferService extends IntentService { 

private static final int SOCKET_TIMEOUT = 5000; 
public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE"; 
public static final String EXTRAS_FILE_PATH = "file_url"; 
public static final String EXTRAS_ADDRESS = "go_host"; 
public static final String EXTRAS_PORT = "go_port"; 

public FileTransferService(String name) { 
    super(name); 
} 

public FileTransferService() { 
    super("FileTransferService"); 
} 

/* 
* (non-Javadoc) 
* @see android.app.IntentService#onHandleIntent(android.content.Intent) 
*/ 
@Override 
protected void onHandleIntent(Intent intent) { 

    Context context = getApplicationContext(); 
    if (intent.getAction().equals(ACTION_SEND_FILE)) { 
     String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH); 
     String host = intent.getExtras().getString(EXTRAS_ADDRESS); 
     Socket socket = new Socket(); 
     int port = intent.getExtras().getInt(EXTRAS_PORT); 

     try { 
      Log.d(WiFiDirectActivity.TAG, "Opening client socket - "); 
      socket.bind(null); 
      socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT); 

      Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected()); 
      OutputStream stream = socket.getOutputStream(); 
      ContentResolver cr = context.getContentResolver(); 
      InputStream is = null; 
      try { 
       is = cr.openInputStream(Uri.parse(fileUri)); 
      } catch (FileNotFoundException e) { 
       Log.d(WiFiDirectActivity.TAG, e.toString()); 
      } 
      DeviceDetailFragment.copyFile(is, stream); 
      Log.d(WiFiDirectActivity.TAG, "Client: Data written"); 
     } catch (IOException e) { 
      Log.e(WiFiDirectActivity.TAG, e.getMessage()); 
     } finally { 
      if (socket != null) { 
       if (socket.isConnected()) { 
        try { 
         socket.close(); 
        } catch (IOException e) { 
         // Give up 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 

    } 
} 
} 

DeviceDetailFragment

public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener { 

public static final String IP_SERVER = "192.168.49.1"; 
public static int PORT = 8988; 
private static boolean server_running = false; 

protected static final int CHOOSE_FILE_RESULT_CODE = 20; 
private View mContentView = null; 
private WifiP2pDevice device; 
private WifiP2pInfo info; 
ProgressDialog progressDialog = null; 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    mContentView = inflater.inflate(R.layout.device_detail, null); 
    mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      WifiP2pConfig config = new WifiP2pConfig(); 
      config.deviceAddress = device.deviceAddress; 
      config.wps.setup = WpsInfo.PBC; 
      if (progressDialog != null && progressDialog.isShowing()) { 
       progressDialog.dismiss(); 
      } 
      progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel", 
        "Connecting to :" + device.deviceAddress, true, true 
        //      new DialogInterface.OnCancelListener() { 
        // 
        //       @Override 
        //       public void onCancel(DialogInterface dialog) { 
        //        ((DeviceActionListener) getActivity()).cancelDisconnect(); 
        //       } 
        //      } 
      ); 
      ((DeviceActionListener) getActivity()).connect(config); 

     } 
    }); 

    mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
      new View.OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        ((DeviceActionListener) getActivity()).disconnect(); 
       } 
      }); 

    mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
      new View.OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        // Allow user to pick an image from Gallery or other 
        // registered apps 
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
        intent.setType("image/*"); 
        startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE); 
       } 
      }); 

    return mContentView; 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    String localIP = Utils.getLocalIPAddress(); 
    // Trick to find the ip in the file /proc/net/arp 
    String client_mac_fixed = new String(device.deviceAddress).replace("99", "19"); 
    String clientIP = Utils.getIPFromMac(client_mac_fixed); 

    // User has picked an image. Transfer it to group owner i.e peer using 
    // FileTransferService. 
    Uri uri = data.getData(); 
    TextView statusText = (TextView) mContentView.findViewById(R.id.status_text); 
    statusText.setText("Sending: " + uri); 
    Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri); 
    Intent serviceIntent = new Intent(getActivity(), FileTransferService.class); 
    serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE); 
    serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString()); 

    if(localIP.equals(IP_SERVER)){ 
     serviceIntent.putExtra(FileTransferService.EXTRAS_ADDRESS, clientIP); 
    }else{ 
     serviceIntent.putExtra(FileTransferService.EXTRAS_ADDRESS, IP_SERVER); 
    } 

    serviceIntent.putExtra(FileTransferService.EXTRAS_PORT, PORT); 
    getActivity().startService(serviceIntent); 
} 

@Override 
public void onConnectionInfoAvailable(final WifiP2pInfo info) { 
    if (progressDialog != null && progressDialog.isShowing()) { 
     progressDialog.dismiss(); 
    } 
    this.info = info; 
    this.getView().setVisibility(View.VISIBLE); 

    // The owner IP is now known. 
    TextView view = (TextView) mContentView.findViewById(R.id.group_owner); 
    view.setText(getResources().getString(R.string.group_owner_text) 
      + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes) 
        : getResources().getString(R.string.no))); 

    // InetAddress from WifiP2pInfo struct. 
    view = (TextView) mContentView.findViewById(R.id.device_info); 
    view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress()); 

    mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE); 

    if (!server_running){ 
     new ServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text)).execute(); 
     server_running = true; 
    } 

    // hide the connect button 
    mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE); 
} 

/** 
* Updates the UI with device data 
* 
* @param device the device to be displayed 
*/ 
public void showDetails(WifiP2pDevice device) { 
    this.device = device; 
    this.getView().setVisibility(View.VISIBLE); 
    TextView view = (TextView) mContentView.findViewById(R.id.device_address); 
    view.setText(device.deviceAddress); 
    view = (TextView) mContentView.findViewById(R.id.device_info); 
    view.setText(device.toString()); 

} 

/** 
* Clears the UI fields after a disconnect or direct mode disable operation. 
*/ 
public void resetViews() { 
    mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE); 
    TextView view = (TextView) mContentView.findViewById(R.id.device_address); 
    view.setText(R.string.empty); 
    view = (TextView) mContentView.findViewById(R.id.device_info); 
    view.setText(R.string.empty); 
    view = (TextView) mContentView.findViewById(R.id.group_owner); 
    view.setText(R.string.empty); 
    view = (TextView) mContentView.findViewById(R.id.status_text); 
    view.setText(R.string.empty); 
    mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE); 
    this.getView().setVisibility(View.GONE); 
} 

/** 
* A simple server socket that accepts connection and writes some data on 
* the stream. 
*/ 
public static class ServerAsyncTask extends AsyncTask<Void, Void, String> { 

    private final Context context; 
    private final TextView statusText; 

    /** 
    * @param context 
    * @param statusText 
    */ 
    public ServerAsyncTask(Context context, View statusText) { 
     this.context = context; 
     this.statusText = (TextView) statusText; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 
     try { 
      ServerSocket serverSocket = new ServerSocket(PORT); 
      Log.d(WiFiDirectActivity.TAG, "Server: Socket opened"); 
      Socket client = serverSocket.accept(); 
      Log.d(WiFiDirectActivity.TAG, "Server: connection done"); 
      final File f = new File(Environment.getExternalStorageDirectory() + "/" 
        + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis() 
        + ".jpg"); 

      File dirs = new File(f.getParent()); 
      if (!dirs.exists()) 
       dirs.mkdirs(); 
      f.createNewFile(); 

      Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString()); 
      InputStream inputstream = client.getInputStream(); 
      copyFile(inputstream, new FileOutputStream(f)); 
      serverSocket.close(); 
      server_running = false; 
      return f.getAbsolutePath(); 
     } catch (IOException e) { 
      Log.e(WiFiDirectActivity.TAG, e.getMessage()); 
      return null; 
     } 
    } 

    /* 
    * (non-Javadoc) 
    * @see android.os.AsyncTask#onPostExecute(java.lang.Object) 
    */ 
    @Override 
    protected void onPostExecute(String result) { 
     if (result != null) { 
      statusText.setText("File copied - " + result); 
      Intent intent = new Intent(); 
      intent.setAction(android.content.Intent.ACTION_VIEW); 
      intent.setDataAndType(Uri.parse("file://" + result), "image/*"); 
      context.startActivity(intent); 
     } 

    } 

    /* 
    * (non-Javadoc) 
    * @see android.os.AsyncTask#onPreExecute() 
    */ 
    @Override 
    protected void onPreExecute() { 
     statusText.setText("Opening a server socket"); 
    } 

} 

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) { 
     Log.d(WiFiDirectActivity.TAG, e.toString()); 
     return false; 
    } 
    return true; 
} 

} 

utils的:

public class Utils { 

private final static String p2pInt = "p2p-p2p0"; 

public static String getIPFromMac(String MAC) { 
    /* 
    * method modified from: 
    * 
    * http://www.flattermann.net/2011/02/android-howto-find-the-hardware-mac-address-of-a-remote-host/ 
    * 
    * */ 
    BufferedReader br = null; 
    try { 
     br = new BufferedReader(new FileReader("/proc/net/arp")); 
     String line; 
     while ((line = br.readLine()) != null) { 

      String[] splitted = line.split(" +"); 
      if (splitted != null && splitted.length >= 4) { 
       // Basic sanity check 
       String device = splitted[5]; 
       if (device.matches(".*" +p2pInt+ ".*")){ 
        String mac = splitted[3]; 
        if (mac.matches(MAC)) { 
         return splitted[0]; 
        } 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      br.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    return null; 
} 


public static String getLocalIPAddress() { 
    /* 
    * modified from: 
    * 
    * http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/ 
    * 
    * */ 
    try { 
     for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { 
      NetworkInterface intf = en.nextElement(); 
      for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { 
       InetAddress inetAddress = enumIpAddr.nextElement(); 

       String iface = intf.getName(); 
       if(iface.matches(".*" +p2pInt+ ".*")){ 
        if (inetAddress instanceof Inet4Address) { // fix for Galaxy Nexus. IPv4 is easy to use :-) 
         return getDottedDecimalIP(inetAddress.getAddress()); 
        } 
       } 
      } 
     } 
    } catch (SocketException ex) { 
     Log.e("AndroidNetworkAddressFactory", "getLocalIPAddress()", ex); 
    } catch (NullPointerException ex) { 
     Log.e("AndroidNetworkAddressFactory", "getLocalIPAddress()", ex); 
    } 
    return null; 
} 

private static String getDottedDecimalIP(byte[] ipAddr) { 
    /* 
    * ripped from: 
    * 
    * http://stackoverflow.com/questions/10053385/how-to-get-each-devices-ip-address-in-wifi-direct-scenario 
    * 
    * */ 
    String ipAddrStr = ""; 
    for (int i=0; i<ipAddr.length; i++) { 
     if (i > 0) { 
      ipAddrStr += "."; 
     } 
     ipAddrStr += ipAddr[i]&0xFF; 
    } 
    return ipAddrStr; 
} 
} 

回答

0

你不能只是发送

命令

但是,您可以发送一个字符串,一个int或甚至一个char -simply数据,并将其与交换机或链接进行比较。如果你想要的话,你还可以编写自己的'传输'类并将其序列化,以便一次发送大量信息。