title: Sending a constant rate data stream from Droid via TCP/IP
body: <p>in my quest to learn Java / Android development, I’m running into lots of roadblocks. Mainly because I don’t really know much about threading and communication between threads/processes. I’m trying to stream the IMU data from an android device to a python application on a computer. Whenever the sensor values change, a sensor listener saves the current values into a variable for the network handler to access. </p>
  
  <p>The network handler in turn is supposed to run on a timer, sending the values and a current timestamp at a more or less fixed rate of 33Hz (perhaps a bit fast? well, I’d be willing to accept as slow as 10Hz, but no slower than that). Anyway, when I tested this, I could see on the computer interface that the data isn’t nearly coming in at a steady pace of 30 per second, but rather comes in surges, sometimes not coming at all for a second, and overall accumulating quite the delay (ie. the later the values are, the more delayed they come in). I understand there might be some variability in the network and some lags, but I would at least like the overall pace to at least be correct, ie that it doesn’t get worse and worse the longer I’m sending.</p>
  
  <p>Considering the devices are both on a common wifi network, and I’m capable of streaming 1080p video without any lags over wifi, I’m fairly confident that the protocol should be able to handle a 64 Byte string every 30ms without troubles. To eliminate the sensor reader as an problem source, I made a minimum working example that simply sends a string every 30ms, without any sensor reading. I basically got this code from various stackoverflow posts, and modified it until it more or less did what I wanted. The problem is that the network interface runs in an AsynchronousTask, for which I am uncertain how to access it once it has been started. My theory is that it’s wasting resources to open a new socket for every new data packet, but I’m unsure how to open the socket once in the background and then pass the values to it on a timer and tell it to send. </p>
  
  <p>Here’s the basic activity I made to test this:</p>
  
  <pre><code>package com.jamesdoesntlikejava.motionlearning15;
  
  import android.support.v7.app.ActionBarActivity;
  import android.os.Bundle;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.widget.Toast;
  import java.util.Timer;
  import java.util.TimerTask;
  
  
  public class SendValuesActivity extends ActionBarActivity {
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_send_values);
          // creating timer task, timer
          final Timer timer = new Timer();
          TimerTask taskNew = new TimerTask() {
              @Override
              public void run() {
                  int counter = 0;
                  int numsteps = 333;
                  String params[] = new String[2];
                  if (counter &lt; numsteps) {
                      params[0] = "192.168.1.33";
                      long currentTime = System.currentTimeMillis();
                      params[1] = Long.toString(currentTime)+"blablabla";
                      new ServerCommunicationTask().execute(params);
                      counter++;
                  } else  {
                      timer.cancel();
                      timer.purge();
                  }
              }
          };
          // scheduling the task at fixed rate delay
          Toast.makeText(this, "Sending Values in 1s...", Toast.LENGTH_SHORT).show();
          timer.scheduleAtFixedRate(taskNew,1000,30);
      }
  
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.menu_send_values, menu);
          return true;
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          // Handle action bar item clicks here. The action bar will
          // automatically handle clicks on the Home/Up button, so long
          // as you specify a parent activity in AndroidManifest.xml.
          int id = item.getItemId();
  
          //noinspection SimplifiableIfStatement
          if (id == R.id.action_settings) {
              return true;
          }
  
          return super.onOptionsItemSelected(item);
      }
  }
  </code></pre>
  
  <p>And this is the class for doing the networking:</p>
  
  <pre><code>package com.jamesdoesntlikejava.motionlearning15;
  
  import android.os.AsyncTask;
  import java.io.BufferedWriter;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.net.Socket;
  import java.net.UnknownHostException;
  
  public class ServerCommunicationTask extends AsyncTask&lt;String, Void, String&gt; {
  
      public final static int TCP_SERVER_PORT = 13337;
      // params are 0: the target IP and 1: the message to send.
      @Override
      protected String doInBackground(String[] params) {
  
          String TCP_SERVER_IP = params[0];
          try {
              Socket s = new Socket(TCP_SERVER_IP, TCP_SERVER_PORT);
              BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
              //send output msg
              String outMsg = params[1];
              out.write(outMsg);
              out.flush();
              //close connection
              s.close();
          } catch (UnknownHostException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
          return "success";
      }
  
      @Override
      protected void onPostExecute(String response) {
      }
  }
  </code></pre>
  
  <p>Running on a Moto G LTE (updated 1st gen) with android 5.1. Any hints are appreciated, thanks!</p>