简体   繁体   中英

I need to get data from sensor over WiFi-Direct. How do I send a command to the sensor?

I have been working on this project where I am supposed to connect my phone to a sensor using WiFi Direct. Then retrieve the sensor data and visualize it on a map. I have been able to connect the sensor to the phone with WiFi Direct and also visualize fake data in an infowindow on a map. The company that makes the sensor is supposed to make a command that gives me the data. I am stuck on the part where I need to establish a connection with the sensor and send a command.

I was looking at this demo app for WiFi-direct which is supposed to send an image between two devices. Can I maybe rewrite this in some way to instead send a command to the sensor from my phone instead of an image? If not, what's the easiest way to send a command to the sensor?

I appreciate any help I get.

Here is the code for the service of transfering an image.

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;
}
}

You cant just send a

command

However you can send a String, an int or even a char -simply data- and compare it with a switch or else if chain. If you want you could also write your own 'transmission' class and serialize it so you could send a bunch of information at a time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM