I’m developing an app which is going to use the Estimote beacons to retrieve information about the environment and have them sent to a server using a REST service. In order to verify how the communication would work, I firstly created a “mock” of the data that would be sent to the server, using a button on my application to trigger it. Then, once this was working, I introduced the beacons, and tried to do the same, but this time, once the beacons were discovered, the data gathered would be sent to the server. Even though the code is the same, using the beacons does not work, throwing the error “connect failed: EHOSTUNREACH (No route to host)”, and I cannot figure out why.
Class that finds the beacons
public class MainActivity extends AppCompatActivity { private static final String ESTIMOTE_PROXIMITY_UUID = "B9407F30-F5F8-466E-AFF9-25556B57FE6D"; private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", ESTIMOTE_PROXIMITY_UUID, null, null); private static final String TAG = "MainActivity"; private BeaconManager beaconManager; private String host; private JSONInterface jsonInterface; @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); jsonInterface = new JSONInterface(); setContentView(R.layout.activity_main); beaconManager = new BeaconManager(this); final TextView view = (TextView) findViewById(R.id.text);
Button button = (Button) findViewById(R.id.sendRequest); button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v){ EditText ip = (EditText) findViewById(R.id.ip); host = ip.getText().toString(); EditText id = (EditText) findViewById(R.id.id); } });
beaconManager.setRangingListener(new BeaconManager.RangingListener() { @Override public void onBeaconsDiscovered(Region region, final List<Beacon> beacons) { Log.d("Estimote", "Ranged beacons: " + beacons); JSONObject root = null; try {
Handler handler = new Handler(); handler.post(new Runnable() { @Override public void run() { jsonInterface.sendJson(beacons); } });
} catch(Exception e ) { e.printStackTrace(); }
} });
} private void setHost(String host) { this.host = host; }
@Override protected void onStart() { super.onStart(); beaconManager.connect(new BeaconManager.ServiceReadyCallback() { @Override public void onServiceReady() { try { beaconManager.startRanging(ALL_ESTIMOTE_BEACONS); } catch (Exception e) { e.printStackTrace(); } } }); }
@Override protected void onStop() { super.onStop(); try{ beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS); }catch(Exception e) { e.printStackTrace(); } finally{ super.onStop(); } }
@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_main, 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); }
}
Class that sends the requests
public class JSONInterface {
public JSONObject sendJson(List<Beacon> beacons)
{
JSONObject root = new JSONObject();
JSONObject json = new JSONObject();
JSONArray jsonArray = new JSONArray();
try {
//for (Beacon beacon : beacons) {
for(int i=0;i<3;i++){
json.put("id", 4);
json.put("controller_id", i);
json.put("proximity", "FAR");
jsonArray.put(json);
json = new JSONObject();
}
root.put("controllers", jsonArray);
Log.d("JSONInterface ", root.toString());
String retorno = new JSONCall().execute(root).get();
return root;
}catch(Exception e)
{
e.printStackTrace();
while(true){}
}
}
private class JSONCall extends AsyncTask<JSONObject,Void,String> {
@Override
protected String doInBackground(JSONObject... jsons)
{
String ret = "Success!";
HttpPost httpPost=null;
try {
JSONObject json = (JSONObject) jsons[0];
Log.d("JSONInterface ", json.toString());
String host = "192.168.0.13:3002";
URL url = new URL("http://"+host+"/controller/addagent");
Log.d("JSONInterface ",json.toString());
HttpClient httpClient = new DefaultHttpClient();
httpPost = new HttpPost(url .toURI());
httpPost.setEntity(new StringEntity(json.toString(), "UTF-8"));
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Accept-Encoding", "application/json");
httpPost.setHeader("Accept-Language", "en-US");
httpClient.execute(httpPost);
httpPost.abort();
} catch (Exception e) {
e.printStackTrace();
httpPost.abort();
ret = e.toString();
}
finally{
return ret;
}
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
Exception:
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ org.apache.http.conn.HttpHostConnectException:
Connection to http://192.168.0.13:3002 refused 09-26 16:00:03.313
29064-30218/tccii.fernando.tccii_agentsmonitoring W/System.err﹕ at
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:183)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:670)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
tccii.fernando.tccii_agentsmonitoring.JSONInterface$JSONCall.doInBackground(JSONInterface.java:79)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
tccii.fernando.tccii_agentsmonitoring.JSONInterface$JSONCall.doInBackground(JSONInterface.java:53)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
java.util.concurrent.FutureTask.run(FutureTask.java:237) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at java.lang.Thread.run(Thread.java:841) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ Caused by: java.net.ConnectException: failed to connect
to /192.168.0.13 (port 3002): connect failed: EHOSTUNREACH (No route
to host) 09-26 16:00:03.313
29064-30218/tccii.fernando.tccii_agentsmonitoring W/System.err﹕ at
libcore.io.IoBridge.connect(IoBridge.java:114) 09-26 16:00:03.313
29064-30218/tccii.fernando.tccii_agentsmonitoring W/System.err﹕ at
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:460) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at java.net.Socket.connect(Socket.java:833) 09-26
16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at
org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
09-26 16:00:03.313 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ … 14 more 09-26 16:00:03.313
29064-30218/tccii.fernando.tccii_agentsmonitoring W/System.err﹕ Caused
by: libcore.io.ErrnoException: connect failed: EHOSTUNREACH (No route
to host) 09-26 16:00:03.323
29064-30218/tccii.fernando.tccii_agentsmonitoring W/System.err﹕ at
libcore.io.Posix.connect(Native Method) 09-26 16:00:03.323
29064-30218/tccii.fernando.tccii_agentsmonitoring W/System.err﹕ at
libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85) 09-26
16:00:03.323 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
09-26 16:00:03.323 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ at libcore.io.IoBridge.connect(IoBridge.java:112) 09-26
16:00:03.323 29064-30218/tccii.fernando.tccii_agentsmonitoring
W/System.err﹕ … 19 more
EDIT 1
The part of the code that does not work, when I add the beacons, is the method “doInBackground” from the private class JSONCall.
This is the flow :
-
MainActivity → looks for beacons around and creates a list, called “beacons”
-
MainActivity → calls the sendJSON method, from JSONInterface, and sends the “beacons” list to it
-
JSONInterface → creates the JSON request based on the list provided by MainActivity
-
JSONInterface → sends the JSON object to the JSONCall class, which is responsible for calling the REST service that was exposed this is the point where it fails when I add the beacons, if I just use a hard coded request, sent whenever I press a button, it works.
EDIT 2
This code works (I just commented out the part where I look for the beacons)
public class MainActivity extends AppCompatActivity {
private static final String ESTIMOTE_PROXIMITY_UUID = "B9407F30-F5F8-466E-AFF9-25556B57FE6D";
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId", ESTIMOTE_PROXIMITY_UUID, null, null);
private static final String TAG = "MainActivity";
private BeaconManager beaconManager;
private String host;
private JSONInterface jsonInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
jsonInterface = new JSONInterface();
setContentView(R.layout.activity_main);
beaconManager = new BeaconManager(this);
final TextView view = (TextView) findViewById(R.id.text);
Button button = (Button) findViewById(R.id.sendRequest);
button.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
EditText ip = (EditText) findViewById(R.id.ip);
host = ip.getText().toString();
EditText id = (EditText) findViewById(R.id.id);
jsonInterface.sendJson(null);
}
});
/* beaconManager.setRangingListener(new BeaconManager.RangingListener() {
@Override
public void onBeaconsDiscovered(Region region, final List<Beacon> beacons) {
Log.d("Estimote", "Ranged beacons: " + beacons);
JSONObject root = null;
try {
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
jsonInterface.sendJson(beacons);
}
});
}
catch(Exception e )
{
e.printStackTrace();
}
}
});*/
}
private void setHost(String host)
{
this.host = host;
}
@Override
protected void onStart() {
super.onStart();
/* beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
@Override
public void onServiceReady() {
try {
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS);
} catch (Exception e) {
e.printStackTrace();
}
}
});*/
}
@Override
protected void onStop()
{
super.onStop();
/*try{
beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS);
}catch(Exception e)
{
e.printStackTrace();
}
finally{
super.onStop();
}*/
}
@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_main, 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);
}
}
EDIT 3
After going through the code, we found out that the line below makes this error happen
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS);
If we keep it commented, then it works. We have changed the code so we could control the requests made by hard coding them and having a button trigger them.