Compare commits

...

2 Commits

11 changed files with 474 additions and 83 deletions

View File

@ -189,7 +189,7 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
} else {
serviceTrackingDog.sendXmppCommandStopTrail();
}
} catch (XmppStringprepException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | InterruptedException | SmackException.NoResponseException e) {
} catch (XmppStringprepException e) {
e.printStackTrace();
}
}

View File

@ -0,0 +1,61 @@
package fr.chteufleur.mytrackingdog.models.beans;
import java.security.SecureRandom;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;
public class RandomString {
/**
* Generate a random string.
*/
public String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static final String lower = upper.toLowerCase(Locale.ROOT);
public static final String digits = "0123456789";
public static final String alphanum = upper + lower + digits;
private final Random random;
private final char[] symbols;
private final char[] buf;
public RandomString(int length, Random random, String symbols) {
if (length < 1) throw new IllegalArgumentException();
if (symbols.length() < 2) throw new IllegalArgumentException();
this.random = Objects.requireNonNull(random);
this.symbols = symbols.toCharArray();
this.buf = new char[length];
}
/**
* Create an alphanumeric string generator.
*/
public RandomString(int length, Random random) {
this(length, random, alphanum);
}
/**
* Create an alphanumeric strings from a secure generator.
*/
public RandomString(int length) {
this(length, new SecureRandom());
}
/**
* Create session identifiers.
*/
public RandomString() {
this(36);
}
}

View File

@ -0,0 +1,19 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jxmpp.jid.FullJid;
public abstract class SendCommand {
public static final String TAG = SendCommand.class.getName();
protected final FullJid to;
protected final AdHocCommandManager commandManager;
public SendCommand(AdHocCommandManager commandManager, FullJid to) {
this.commandManager = commandManager;
this.to = to;
}
public abstract void executeCommand() throws Exception;
}

View File

@ -0,0 +1,18 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jxmpp.jid.FullJid;
public abstract class SendLocationCommand extends SendCommand {
protected final double latitude;
protected final double longitude;
protected final long time;
public SendLocationCommand(AdHocCommandManager commandManager, FullJid to, double lat, double lon, long time) {
super(commandManager, to);
this.latitude = lat;
this.longitude = lon;
this.time = time;
}
}

View File

@ -0,0 +1,33 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import android.util.Log;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jivesoftware.smackx.commands.RemoteCommand;
import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.FullJid;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.ObjectGeolocCommand;
import fr.chteufleur.mytrackingdog.services.ServiceXmpp;
public class SendObjectLocationCommand extends SendLocationCommand {
public SendObjectLocationCommand(AdHocCommandManager commandManager, FullJid to, double lat, double lon, long time) {
super(commandManager, to, lat, lon, time);
}
@Override
public void executeCommand() throws Exception {
Log.i(TAG, "Send command object");
RemoteCommand command = commandManager.getRemoteCommand(to, ServiceXmpp.XMPP_NODE_OBJECT_GEOLOC);
command.execute();
if (command.getForm() == null) {
throw new Exception("Didn't get form back");
}
Form form = command.getForm().createAnswerForm();
form.setAnswer(ObjectGeolocCommand.FIELD_PARAM_LATITUDE, latitude);
form.setAnswer(ObjectGeolocCommand.FIELD_PARAM_LONGITUDE, longitude);
form.setAnswer(ObjectGeolocCommand.FIELD_PARAM_TIME, time);
command.next(form);
}
}

View File

@ -0,0 +1,34 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import android.util.Log;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jivesoftware.smackx.commands.RemoteCommand;
import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.FullJid;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.RealTimeModeCommand;
import fr.chteufleur.mytrackingdog.services.ServiceXmpp;
public class SendRealTimeModeCommand extends SendCommand {
private final boolean isRealTimeMode;
public SendRealTimeModeCommand(AdHocCommandManager commandManager, FullJid to, boolean isRealTimeMode) {
super(commandManager, to);
this.isRealTimeMode = isRealTimeMode;
}
@Override
public void executeCommand() throws Exception {
Log.i(TAG, "Send commande real time mode");
RemoteCommand command = commandManager.getRemoteCommand(to, ServiceXmpp.XMPP_NODE_REAL_TIME_MODE);
command.execute();
if (command.getForm() == null) {
throw new Exception("Didn't get form back");
}
Form form = command.getForm().createAnswerForm();
form.setAnswer(RealTimeModeCommand.FIELD_PARAM_IS_ACTIVE, isRealTimeMode);
command.next(form);
}
}

View File

@ -0,0 +1,23 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import android.util.Log;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jivesoftware.smackx.commands.RemoteCommand;
import org.jxmpp.jid.FullJid;
import fr.chteufleur.mytrackingdog.services.ServiceXmpp;
public class SendStartTrailCommand extends SendCommand {
public SendStartTrailCommand(AdHocCommandManager commandManager, FullJid to) {
super(commandManager, to);
}
@Override
public void executeCommand() throws Exception {
Log.i(TAG, "Send command start");
RemoteCommand command = commandManager.getRemoteCommand(to, ServiceXmpp.XMPP_NODE_START_TRAIL_GEOLOC);
command.execute();
}
}

View File

@ -0,0 +1,23 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import android.util.Log;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jivesoftware.smackx.commands.RemoteCommand;
import org.jxmpp.jid.FullJid;
import fr.chteufleur.mytrackingdog.services.ServiceXmpp;
public class SendStopTrailCommand extends SendCommand {
public SendStopTrailCommand(AdHocCommandManager commandManager, FullJid to) {
super(commandManager, to);
}
@Override
public void executeCommand() throws Exception {
Log.i(TAG, "Send command stop");
RemoteCommand command = commandManager.getRemoteCommand(to, ServiceXmpp.XMPP_NODE_STOP_TRAIL_GEOLOC);
command.execute();
}
}

View File

@ -0,0 +1,34 @@
package fr.chteufleur.mytrackingdog.models.xmpp.commands.send;
import android.util.Log;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jivesoftware.smackx.commands.RemoteCommand;
import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.FullJid;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.ObjectGeolocCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.TrailGeolocCommand;
import fr.chteufleur.mytrackingdog.services.ServiceXmpp;
public class SendTrailLocationCommand extends SendLocationCommand {
public SendTrailLocationCommand(AdHocCommandManager commandManager, FullJid to, double lat, double lon, long time) {
super(commandManager, to, lat, lon, time);
}
@Override
public void executeCommand() throws Exception {
Log.i(TAG, "Send command location");
RemoteCommand command = commandManager.getRemoteCommand(to, ServiceXmpp.XMPP_NODE_TRAIL_GEOLOC);
command.execute();
if (command.getForm() == null) {
throw new Exception("Didn't get form back");
}
Form form = command.getForm().createAnswerForm();
form.setAnswer(TrailGeolocCommand.FIELD_PARAM_LATITUDE, latitude);
form.setAnswer(TrailGeolocCommand.FIELD_PARAM_LONGITUDE, longitude);
form.setAnswer(TrailGeolocCommand.FIELD_PARAM_TIME, time);
command.next(form);
}
}

View File

@ -69,7 +69,7 @@ public class ServiceTrackingDog implements Observer {
this.serviceGps.addObserver(this);
ServiceXmpp sx;
try {
sx = new ServiceXmpp(resources);
sx = new ServiceXmpp(preferences, resources);
sx.addObserver(this);
} catch (UnknownHostException | XmppStringprepException ex) {
sx = null;
@ -395,12 +395,12 @@ public class ServiceTrackingDog implements Observer {
return ret;
}
//<editor-fold defaultstate="collapsed" desc="Commands">
public void sendXmppCommandStartTrail() throws XmppStringprepException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
public void sendXmppCommandStartTrail() throws XmppStringprepException {
if (serviceXmpp != null) {
serviceXmpp.sendCommandStartTrail();
}
}
public void sendXmppCommandStopTrail() throws XmppStringprepException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
public void sendXmppCommandStopTrail() throws XmppStringprepException {
if (serviceXmpp != null) {
serviceXmpp.sendCommandStopTrail();
}

View File

@ -1,5 +1,6 @@
package fr.chteufleur.mytrackingdog.services;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Environment;
import android.os.StrictMode;
@ -9,7 +10,9 @@ import com.google.zxing.WriterException;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.PresenceEventListener;
@ -19,36 +22,46 @@ import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.commands.AdHocCommandManager;
import org.jivesoftware.smackx.commands.LocalCommand;
import org.jivesoftware.smackx.commands.LocalCommandFactory;
import org.jivesoftware.smackx.commands.RemoteCommand;
import org.jivesoftware.smackx.filetransfer.FileTransfer;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer;
import org.jivesoftware.smackx.xdata.Form;
import org.jivesoftware.smackx.iqregister.AccountManager;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Localpart;
import org.jxmpp.jid.parts.Resourcepart;
import org.jxmpp.stringprep.XmppStringprepException;
import java.io.File;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Random;
import fr.chteufleur.mytrackingdog.QRCodeGeneratorActivity;
import fr.chteufleur.mytrackingdog.models.Notification;
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
import fr.chteufleur.mytrackingdog.models.beans.RandomString;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.ObjectGeolocCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.RealTimeModeCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.StartTrailGeolocCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.StopTrailGeolocCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.TrailGeolocCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.send.SendCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.send.SendObjectLocationCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.send.SendRealTimeModeCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.send.SendStartTrailCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.send.SendStopTrailCommand;
import fr.chteufleur.mytrackingdog.models.xmpp.commands.send.SendTrailLocationCommand;
public class ServiceXmpp extends Observable implements PresenceEventListener, FileTransferListener {
public class ServiceXmpp extends Observable implements Runnable, ConnectionListener, PresenceEventListener, FileTransferListener {
public static final String TAG = ServiceXmpp.class.getName();
@ -67,31 +80,47 @@ public class ServiceXmpp extends Observable implements PresenceEventListener, Fi
public static final String NOTIF_NEW_PRESENCE_RECEIVED_VALUE_JID = NOTIF_NEW_PRESENCE_RECEIVED+".value.jid";
public static final String NOTIF_NEW_REAL_TIME_MODE_VALUE = NOTIF_NEW_REAL_TIME_MODE+".value";
private static final String XMPP_NODE_TRAIL_GEOLOC = "trail_geoloc";
private static final String XMPP_NODE_OBJECT_GEOLOC = "object_geoloc";
private static final String XMPP_NODE_START_TRAIL_GEOLOC = "start_trail_geoloc";
private static final String XMPP_NODE_STOP_TRAIL_GEOLOC = "stop_trail_geoloc";
private static final String XMPP_NODE_REAL_TIME_MODE = "real_time_mode";
public static final String XMPP_NODE_TRAIL_GEOLOC = "trail_geoloc";
public static final String XMPP_NODE_OBJECT_GEOLOC = "object_geoloc";
public static final String XMPP_NODE_START_TRAIL_GEOLOC = "start_trail_geoloc";
public static final String XMPP_NODE_STOP_TRAIL_GEOLOC = "stop_trail_geoloc";
public static final String XMPP_NODE_REAL_TIME_MODE = "real_time_mode";
private static final String XMPP_IP_SERVER = "51.254.205.203";
private static final String XMPP_DOMAIN_SERVER = "anon.xmpp.kingpenguin.tk";
// private static final String XMPP_DOMAIN_SERVER = "anon.xmpp.kingpenguin.tk";
// private static final String XMPP_DOMAIN_SERVER = "dog.xmpp.kingpenguin.tk";
private static final String XMPP_DOMAIN_SERVER = "kingpenguin.tk";
private static final int XMPP_PORT = 5222;
//<editor-fold defaultstate="collapsed" desc="Preferences">
private final SharedPreferences preferences;
private static final String PREF_XMPP_USER = "PREF_XMPP_USER";
private static final String PREF_XMPP_PASSWORD = "PREF_XMPP_PASSWORD";
private static final String PREF_XMPP_ACCOUNT_REGISTERED = "PREF_XMPP_ACCOUNT_REGISTERED";
private String prefXmppUser;
private String prefXmppPassword;
private boolean prefAccountRegistered;
//</editor-fold>
private String appName = "";
private final Resources resources;
private final XMPPTCPConnectionConfiguration configuration;
private AdHocCommandManager commandManager;
private FileTransferManager fileManager;
private AccountManager accountManager;
private AbstractXMPPConnection connection;
private String jid;
private String otherJid;
private final ServiceXmpp thsi;
private boolean run = false;
private boolean isEnable = false;
private boolean isRealTimeMode = false;
public ServiceXmpp(Resources resources) throws UnknownHostException, XmppStringprepException {
public ServiceXmpp(SharedPreferences preferences, Resources resources) throws UnknownHostException, XmppStringprepException {
this.preferences = preferences;
this.resources = resources;
this.configuration = XMPPTCPConnectionConfiguration.builder()
.setSecurityMode(ConnectionConfiguration.SecurityMode.ifpossible)
@ -99,56 +128,59 @@ public class ServiceXmpp extends Observable implements PresenceEventListener, Fi
.setPort(XMPP_PORT)
.setXmppDomain(XMPP_DOMAIN_SERVER)
.setDebuggerEnabled(true)
.performSaslAnonymousAuthentication()
// .performSaslAnonymousAuthentication()
.setKeystoreType(null)
.build();
if (!preferences.contains(PREF_XMPP_USER)) {
RandomString random = new RandomString();
prefXmppUser = random.nextString();
SharedPreferences.Editor editor = preferences.edit();
editor.putString(PREF_XMPP_USER, prefXmppUser);
editor.commit();
} else {
prefXmppUser = preferences.getString(PREF_XMPP_USER, "");
}
if (!preferences.contains(PREF_XMPP_PASSWORD)) {
RandomString random = new RandomString();
prefXmppPassword = random.nextString();
SharedPreferences.Editor editor = preferences.edit();
editor.putString(PREF_XMPP_PASSWORD, prefXmppPassword);
editor.commit();
} else {
prefXmppPassword = preferences.getString(PREF_XMPP_PASSWORD, "");
}
prefAccountRegistered = preferences.getBoolean(PREF_XMPP_ACCOUNT_REGISTERED, false);
this.thsi = this;
new Thread(this).start();
}
public void setAppName(String appName) {
this.appName = appName;
}
public boolean connect() throws InterruptedException, XMPPException, SmackException, IOException {
public void connect() throws InterruptedException, XMPPException, SmackException, IOException {
if (!isEnable) {
return false;
return;
}
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
boolean isConnected;
connection = new XMPPTCPConnection(configuration);
connection.addConnectionListener(this);
commandManager = AdHocCommandManager.getAddHocCommandsManager(connection);
fileManager = FileTransferManager.getInstanceFor(connection);
connection.connect();
connection.login();
registerCommands();
fileManager.addFileTransferListener(this);
Roster roster = Roster.getInstanceFor(connection);
roster.addPresenceEventListener(this);
isConnected = connection.isConnected();
if (isConnected) {
jid = connection.getUser().asFullJidIfPossible().toString();
Log.i(TAG, "JID: "+jid);
setPresenceAvailable();
}
Runnable r = new Runnable() {
@Override
public void run() {
try {
QRCodeGeneratorActivity.textToImageEncode(jid, resources);
} catch (WriterException ex) {
Log.e(TAG, "Failed to generate QR Code");
}
}
};
new Thread(r).start();
return isConnected;
}
public void close() {
disconnect();
run = false;
}
private void disconnect() {
if (otherJid != null) {
try {
sendPresenceUnavailable(otherJid);
@ -168,7 +200,30 @@ public class ServiceXmpp extends Observable implements PresenceEventListener, Fi
public void disable() {
this.isEnable = false;
close();
disconnect();
}
@Override
public void run() {
run = true;
while (run) {
if (connection != null && connection.isAuthenticated()) {
SendCommand command = getNextCommand();
if (command != null) {
try {
command.executeCommand();
} catch (Exception e) {
e.printStackTrace();
sendCommandFirst(command);
}
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public boolean isEnabled() {
@ -183,6 +238,103 @@ public class ServiceXmpp extends Observable implements PresenceEventListener, Fi
return this.isRealTimeMode;
}
//<editor-fold defaultstate="collapsed" desc="Connection listener">
@Override
public void connected(XMPPConnection _connection) {
if (!prefAccountRegistered) {
accountManager = AccountManager.getInstance(connection);
try {
if (accountManager.supportsAccountCreation()) {
accountManager.createAccount(Localpart.from(prefXmppUser), prefXmppPassword);
}
} catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | InterruptedException | XmppStringprepException e) {
e.printStackTrace();
}
}
try {
connection.login(prefXmppUser, prefXmppPassword, Resourcepart.from("MyTrackingDog"));
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (InterruptedException | IOException | SmackException | XMPPException e) {
e.printStackTrace();
}
registerCommands();
fileManager.addFileTransferListener(this);
Roster roster = Roster.getInstanceFor(connection);
roster.addPresenceEventListener(this);
}
@Override
public void authenticated(XMPPConnection connection, boolean resumed) {
jid = connection.getUser().asFullJidIfPossible().toString();
Log.i(TAG, "JID: "+jid);
prefAccountRegistered = true;
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(PREF_XMPP_ACCOUNT_REGISTERED, prefAccountRegistered);
editor.commit();
try {
setPresenceAvailable();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Runnable r = new Runnable() {
@Override
public void run() {
try {
QRCodeGeneratorActivity.textToImageEncode(jid, resources);
} catch (WriterException ex) {
Log.e(TAG, "Failed to generate QR Code");
}
}
};
new Thread(r).start();
}
@Override
public void connectionClosed() {
Log.i(TAG, "connectionClosed");
}
@Override
public void connectionClosedOnError(Exception e) {
Log.i(TAG, "connectionClosedOnError");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10_000);
connection.connect();
} catch (SmackException | IOException | XMPPException | InterruptedException e1) {
e1.printStackTrace();
}
}
}).start();
}
@Override
public void reconnectionSuccessful() {
Log.i(TAG, "reconnectionSuccessful");
}
@Override
public void reconnectingIn(int seconds) {
Log.i(TAG, "reconnectingIn");
}
@Override
public void reconnectionFailed(Exception e) {
Log.i(TAG, "reconnectionFailed");
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Presence">
public void sendPresenceAvailable() throws SmackException.NotConnectedException, InterruptedException, XmppStringprepException {
if (otherJid != null) {
@ -258,6 +410,7 @@ public class ServiceXmpp extends Observable implements PresenceEventListener, Fi
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Commands">
private final LinkedList<SendCommand> listSendCommand = new LinkedList<>();
private void registerCommands() {
commandManager.registerCommand(XMPP_NODE_TRAIL_GEOLOC, XMPP_NODE_TRAIL_GEOLOC, new LocalCommandFactory() {
@Override
@ -324,70 +477,63 @@ public class ServiceXmpp extends Observable implements PresenceEventListener, Fi
notifyObservers(new Notification(NOTIF_NEW_REAL_TIME_MODE).addExtra(NOTIF_NEW_REAL_TIME_MODE_VALUE, isRealTimeMode));
}
public void sendCommandStartTrail() throws XmppStringprepException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
public void sendCommandStartTrail() throws XmppStringprepException {
if (isOtherJidSet() && isRealTimeMode) {
Log.i(TAG, "Send command start");
RemoteCommand command = commandManager.getRemoteCommand(JidCreate.fullFrom(otherJid), XMPP_NODE_START_TRAIL_GEOLOC);
command.execute();
sendCommand(new SendStartTrailCommand(commandManager, JidCreate.fullFrom(otherJid)));
}
}
public void sendCommandStopTrail() throws XmppStringprepException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
public void sendCommandStopTrail() throws XmppStringprepException {
if (isOtherJidSet() && isRealTimeMode) {
Log.i(TAG, "Send command stop");
RemoteCommand command = commandManager.getRemoteCommand(JidCreate.fullFrom(otherJid), XMPP_NODE_STOP_TRAIL_GEOLOC);
command.execute();
sendCommand(new SendStopTrailCommand(commandManager, JidCreate.fullFrom(otherJid)));
}
}
public void sendCommandObjectTrail(double lat, double lon, long time) throws Exception {
if (isOtherJidSet() && isRealTimeMode) {
Log.i(TAG, "Send command object");
RemoteCommand command = commandManager.getRemoteCommand(JidCreate.fullFrom(otherJid), XMPP_NODE_OBJECT_GEOLOC);
command.execute();
if (command.getForm() == null) {
throw new Exception("Didn't get form back");
}
Form form = command.getForm().createAnswerForm();
form.setAnswer(ObjectGeolocCommand.FIELD_PARAM_LATITUDE, lat);
form.setAnswer(ObjectGeolocCommand.FIELD_PARAM_LONGITUDE, lon);
form.setAnswer(ObjectGeolocCommand.FIELD_PARAM_TIME, time);
command.next(form);
sendCommand(new SendObjectLocationCommand(commandManager, JidCreate.fullFrom(otherJid), lat, lon, time));
}
}
public void sendCommandLocationTrail(double lat, double lon, long time) throws Exception {
if (isOtherJidSet() && isRealTimeMode) {
Log.i(TAG, "Send command location");
RemoteCommand command = commandManager.getRemoteCommand(JidCreate.fullFrom(otherJid), XMPP_NODE_TRAIL_GEOLOC);
command.execute();
if (command.getForm() == null) {
throw new Exception("Didn't get form back");
}
Form form = command.getForm().createAnswerForm();
form.setAnswer(TrailGeolocCommand.FIELD_PARAM_LATITUDE, lat);
form.setAnswer(TrailGeolocCommand.FIELD_PARAM_LONGITUDE, lon);
form.setAnswer(TrailGeolocCommand.FIELD_PARAM_TIME, time);
command.next(form);
sendCommand(new SendTrailLocationCommand(commandManager, JidCreate.fullFrom(otherJid), lat, lon, time));
}
}
public void sendCommandeRealTimeMode() throws Exception {
if (isOtherJidSet()) {
Log.i(TAG, "Send commande real time mode");
RemoteCommand command = commandManager.getRemoteCommand(JidCreate.fullFrom(otherJid), XMPP_NODE_REAL_TIME_MODE);
command.execute();
if (command.getForm() == null) {
throw new Exception("Didn't get form back");
sendCommand(new SendRealTimeModeCommand(commandManager, JidCreate.fullFrom(otherJid), isRealTimeMode));
}
Form form = command.getForm().createAnswerForm();
form.setAnswer(RealTimeModeCommand.FIELD_PARAM_IS_ACTIVE, isRealTimeMode);
command.next(form);
}
private void sendCommand(SendCommand command) {
if (command != null) {
synchronized (listSendCommand) {
listSendCommand.addLast(command);
}
}
}
private void sendCommandFirst(SendCommand command) {
if (command != null) {
synchronized (listSendCommand) {
listSendCommand.addFirst(command);
}
}
}
private SendCommand getNextCommand() {
SendCommand ret = null;
synchronized (listSendCommand) {
if (!listSendCommand.isEmpty()) {
ret = listSendCommand.removeFirst();
}
}
return ret;
}
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="File transfert">
// Example: https://github.com/igniterealtime/Smack/blob/master/documentation/extensions/filetransfer.md
public void sendFile(File file) throws XmppStringprepException, SmackException {