Service
This commit is contained in:
parent
04a2acf5a1
commit
656939390d
4 changed files with 159 additions and 110 deletions
|
@ -1,55 +1,29 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuAdapter.OnContextMenuClick;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.Version;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.activities.SettingsActivity;
|
||||
import net.osmand.plus.views.MonitoringInfoControl;
|
||||
import net.osmand.plus.views.MonitoringInfoControl.MonitoringInfoControlServices;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.Settings.Secure;
|
||||
|
||||
public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlServices {
|
||||
|
||||
private OsmandApplication app;
|
||||
public static final String ID = "osmand.osmo";
|
||||
private static final Log log = PlatformUtil.getLog(OsMoPlugin.class);
|
||||
private OsMoService service;
|
||||
private OsMoTracker tracker;
|
||||
|
||||
|
@ -113,45 +87,11 @@ public class OsMoPlugin extends OsmandPlugin implements MonitoringInfoControlSer
|
|||
|
||||
@Override
|
||||
protected Exception doInBackground(Void... params) {
|
||||
return registerOsmoDeviceKey();
|
||||
return service.registerOsmoDeviceKey();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Exception registerOsmoDeviceKey() {
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth");
|
||||
try {
|
||||
// Add your data
|
||||
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
|
||||
nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID));
|
||||
nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL));
|
||||
nameValuePairs.add(new BasicNameValuePair("imei", "0"));
|
||||
nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT));
|
||||
nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app)));
|
||||
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
|
||||
|
||||
// Execute HTTP Post Request
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
InputStream cm = response.getEntity().getContent();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(cm));
|
||||
String r = reader.readLine();
|
||||
reader.close();
|
||||
log.info("Authorization key : " + r);
|
||||
final JSONObject obj = new JSONObject(r);
|
||||
if(obj.has("error")) {
|
||||
return new RuntimeException(obj.getString("error"));
|
||||
}
|
||||
app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key"));
|
||||
return null;
|
||||
} catch (ClientProtocolException e) {
|
||||
return e;
|
||||
} catch (IOException e) {
|
||||
return e;
|
||||
} catch (JSONException e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,16 +1,38 @@
|
|||
package net.osmand.plus.osmo;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.os.Build;
|
||||
import android.provider.Settings.Secure;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.Version;
|
||||
|
||||
public class OsMoService {
|
||||
private OsMoThread thread;
|
||||
private List<OsMoSender> listSenders = new java.util.concurrent.CopyOnWriteArrayList<OsMoSender>();
|
||||
private List<OsMoReactor> listReactors = new java.util.concurrent.CopyOnWriteArrayList<OsMoReactor>();
|
||||
private OsmandApplication app;
|
||||
private static final Log log = PlatformUtil.getLog(OsMoService.class);
|
||||
|
||||
public interface OsMoSender {
|
||||
|
||||
|
@ -38,7 +60,7 @@ public class OsMoService {
|
|||
}
|
||||
thread.stopConnection();
|
||||
}
|
||||
thread = new OsMoThread(app, listSenders, listReactors);
|
||||
thread = new OsMoThread(this, listSenders, listReactors);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,4 +91,95 @@ public class OsMoService {
|
|||
}
|
||||
|
||||
|
||||
public Exception registerOsmoDeviceKey() {
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
HttpPost httppost = new HttpPost("http://api.osmo.mobi/auth");
|
||||
try {
|
||||
// Add your data
|
||||
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
|
||||
nameValuePairs.add(new BasicNameValuePair("android_id", Secure.ANDROID_ID));
|
||||
nameValuePairs.add(new BasicNameValuePair("android_model", Build.MODEL));
|
||||
nameValuePairs.add(new BasicNameValuePair("imei", "0"));
|
||||
nameValuePairs.add(new BasicNameValuePair("android_product", Build.PRODUCT));
|
||||
nameValuePairs.add(new BasicNameValuePair("osmand", Version.getFullVersion(app)));
|
||||
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
|
||||
|
||||
// Execute HTTP Post Request
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
InputStream cm = response.getEntity().getContent();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(cm));
|
||||
String r = reader.readLine();
|
||||
reader.close();
|
||||
log.info("Authorization key : " + r);
|
||||
final JSONObject obj = new JSONObject(r);
|
||||
if(obj.has("error")) {
|
||||
return new RuntimeException(obj.getString("error"));
|
||||
}
|
||||
app.getSettings().OSMO_DEVICE_KEY.set(obj.getString("key"));
|
||||
return null;
|
||||
} catch (ClientProtocolException e) {
|
||||
return e;
|
||||
} catch (IOException e) {
|
||||
return e;
|
||||
} catch (JSONException e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SessionInfo {
|
||||
public String hostName;
|
||||
public String port;
|
||||
public String token;
|
||||
}
|
||||
|
||||
|
||||
public SessionInfo getSessionToken() throws IOException {
|
||||
String deviceKey = app.getSettings().OSMO_DEVICE_KEY.get();
|
||||
HttpClient httpclient = new DefaultHttpClient();
|
||||
HttpPost httppost = new HttpPost("http://api.osmo.mobi/prepare");
|
||||
try {
|
||||
// Add your data
|
||||
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
|
||||
nameValuePairs.add(new BasicNameValuePair("key", deviceKey));
|
||||
nameValuePairs.add(new BasicNameValuePair("protocol", "1"));
|
||||
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
|
||||
|
||||
// Execute HTTP Post Request
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
InputStream cm = response.getEntity().getContent();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(cm));
|
||||
String r = reader.readLine();
|
||||
reader.close();
|
||||
log.info("Authorization key : " + r);
|
||||
final JSONObject obj = new JSONObject(r);
|
||||
if(obj.has("error")) {
|
||||
throw new RuntimeException(obj.getString("error"));
|
||||
}
|
||||
if(!obj.has("port")) {
|
||||
throw new RuntimeException("Port not specified");
|
||||
}
|
||||
if(!obj.has("address")) {
|
||||
throw new RuntimeException("Host name not specified");
|
||||
}
|
||||
if(!obj.has("token")) {
|
||||
throw new RuntimeException("Token not specified");
|
||||
}
|
||||
SessionInfo si = new SessionInfo();
|
||||
si.hostName = obj.getString("address");
|
||||
si.port = obj.getString("port");
|
||||
si.token = obj.getString("token");
|
||||
return si;
|
||||
} catch (ClientProtocolException e) {
|
||||
throw new IOException(e);
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (JSONException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void showErrorMessage(String string) {
|
||||
app.showToastMessage(app.getString(R.string.osmo_io_error) + string);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,13 +13,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.osmo.OsMoService.OsMoReactor;
|
||||
import net.osmand.plus.osmo.OsMoService.OsMoSender;
|
||||
import net.osmand.plus.osmo.OsMoService.SessionInfo;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONException;
|
||||
|
@ -28,25 +26,21 @@ import org.json.JSONObject;
|
|||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Message;
|
||||
import android.provider.Settings.Secure;
|
||||
|
||||
public class OsMoThread {
|
||||
private static String TRACKER_SERVER = "srv.osmo.mobi";
|
||||
private static int TRACKER_PORT = 4242;
|
||||
// private static String TRACKER_SERVER = "srv.osmo.mobi";
|
||||
// private static int TRACKER_PORT = 3245;
|
||||
|
||||
protected final static Log log = PlatformUtil.getLog(OsMoThread.class);
|
||||
private static final long HEARTBEAT_DELAY = 100;
|
||||
private static final long HEARTBEAT_FAILED_DELAY = 10000;
|
||||
private static final long LIMIT_OF_FAILURES_RECONNECT = 10;
|
||||
private static final long CONNECTION_DELAY = 25000;
|
||||
private static final long SELECT_TIMEOUT = 500;
|
||||
private static int HEARTBEAT_MSG = 3;
|
||||
private Handler serviceThread;
|
||||
|
||||
private int failures = 0;
|
||||
private int activeConnectionId = 0;
|
||||
// -1 means connected, 0 needs to reconnect, > 0 when connection initiated
|
||||
private long connectionStarted = 0;
|
||||
private boolean stopThread;
|
||||
private Selector selector;
|
||||
|
||||
|
@ -54,7 +48,8 @@ public class OsMoThread {
|
|||
private List<OsMoReactor> listReactors;
|
||||
|
||||
private boolean authorized;
|
||||
private OsmandApplication ctx;
|
||||
private OsMoService service;
|
||||
private SessionInfo token = null;
|
||||
private String authorizationCommand = null;
|
||||
private SocketChannel activeChannel;
|
||||
private ByteBuffer pendingSendCommand;
|
||||
|
@ -62,9 +57,10 @@ public class OsMoThread {
|
|||
private ByteBuffer pendingReadCommand = ByteBuffer.allocate(2048);
|
||||
private LinkedList<String> queueOfMessages = new LinkedList<String>();
|
||||
|
||||
|
||||
|
||||
public OsMoThread(OsmandApplication ctx, List<OsMoSender> listSenders, List<OsMoReactor> listReactors) {
|
||||
this.ctx = ctx;
|
||||
public OsMoThread(OsMoService service, List<OsMoSender> listSenders, List<OsMoReactor> listReactors) {
|
||||
this.service = service;
|
||||
this.listSenders = listSenders;
|
||||
this.listReactors = listReactors;
|
||||
// start thread to receive events from OSMO
|
||||
|
@ -90,19 +86,22 @@ public class OsMoThread {
|
|||
}
|
||||
|
||||
protected void initConnection() throws IOException {
|
||||
try {
|
||||
authorized = false;
|
||||
authorizationCommand = getAuthorizationCmd();
|
||||
selector = Selector.open();
|
||||
connectionStarted = System.currentTimeMillis();
|
||||
activeChannel = SocketChannel.open();
|
||||
activeChannel.configureBlocking(false);
|
||||
SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
|
||||
key.attach(new Integer(++activeConnectionId));
|
||||
activeChannel.connect(new InetSocketAddress(TRACKER_SERVER, TRACKER_PORT));
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
if (token == null) {
|
||||
token = service.getSessionToken();
|
||||
}
|
||||
authorized = false;
|
||||
selector = Selector.open();
|
||||
SocketChannel activeChannel = SocketChannel.open();
|
||||
activeChannel.configureBlocking(true);
|
||||
activeChannel.connect(new InetSocketAddress(token.hostName, Integer.parseInt(token.port)));
|
||||
activeChannel.configureBlocking(false);
|
||||
SelectionKey key = activeChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
|
||||
if (this.activeChannel != null) {
|
||||
stopChannel();
|
||||
}
|
||||
this.activeChannel = activeChannel;
|
||||
key.attach(new Integer(++activeConnectionId));
|
||||
|
||||
}
|
||||
|
||||
public String format(String cmd, Map<String, Object> params) {
|
||||
|
@ -120,13 +119,6 @@ public class OsMoThread {
|
|||
}
|
||||
}
|
||||
|
||||
private String getAuthorizationCmd() {
|
||||
Map<String, Object> params = new TreeMap<String, Object>();
|
||||
params.put("protocol_version", 1);
|
||||
params.put("key", ctx.getSettings().OSMO_DEVICE_KEY.get());
|
||||
return format("AUTH", params);
|
||||
}
|
||||
|
||||
public void scheduleHeartbeat(long delay) {
|
||||
Message msg = serviceThread.obtainMessage();
|
||||
msg.what = HEARTBEAT_MSG;
|
||||
|
@ -139,7 +131,7 @@ public class OsMoThread {
|
|||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return connectionStarted == -1;
|
||||
return activeChannel != null;
|
||||
}
|
||||
|
||||
protected void checkAsyncSocket() {
|
||||
|
@ -148,12 +140,7 @@ public class OsMoThread {
|
|||
if (selector == null) {
|
||||
stopThread = true;
|
||||
} else {
|
||||
if (activeChannel != null && connectionStarted != -1 && !activeChannel.isConnectionPending()) {
|
||||
// connection ready
|
||||
connectionStarted = -1;
|
||||
}
|
||||
if ((connectionStarted != -1 && System.currentTimeMillis() - connectionStarted > CONNECTION_DELAY)
|
||||
|| activeChannel == null) {
|
||||
if(activeChannel == null) {
|
||||
initConnection();
|
||||
} else {
|
||||
checkSelectedKeys();
|
||||
|
@ -265,16 +252,20 @@ public class OsMoThread {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(cmd.equalsIgnoreCase("AUTH")) {
|
||||
if(obj != null && !obj.has("error")) {
|
||||
try {
|
||||
ctx.showToastMessage(ctx.getString(R.string.osmo_io_error) + obj.getString("error"));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
boolean error = false;
|
||||
if(obj != null && !obj.has("error")) {
|
||||
error = true;
|
||||
try {
|
||||
service.showErrorMessage(obj.getString("error"));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if(cmd.equalsIgnoreCase("TOKEN")) {
|
||||
if(!error){
|
||||
authorized = true;
|
||||
ctx.showToastMessage("OSMo authorization successfull");
|
||||
// TODO delete
|
||||
service.showErrorMessage("OSMo authorization successfull");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ import net.osmand.Location;
|
|||
import net.osmand.plus.osmo.OsMoService.OsMoSender;
|
||||
|
||||
public class OsMoTracker implements OsMoSender {
|
||||
private LinkedList<Location> bufferOfLocations = new LinkedList<Location>();
|
||||
private LinkedList<Location> bufferOfLocations = new LinkedList<Location>();
|
||||
private boolean start;
|
||||
|
||||
public OsMoTracker(OsMoService service) {
|
||||
service.registerSender(this);
|
||||
|
@ -14,6 +15,10 @@ public class OsMoTracker implements OsMoSender {
|
|||
|
||||
@Override
|
||||
public String nextSendCommand(OsMoThread thread) {
|
||||
if(!start) {
|
||||
start = true;
|
||||
return "TRACKER_SESSION_OPEN";
|
||||
}
|
||||
if(!bufferOfLocations.isEmpty()){
|
||||
Location loc = bufferOfLocations.poll();
|
||||
StringBuilder cmd = new StringBuilder("T|");
|
||||
|
|
Loading…
Reference in a new issue