reworked account managment. now status display actually works
This commit is contained in:
parent
14a171b088
commit
0d80d88736
|
@ -35,16 +35,16 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="Status: "
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/account_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#669900"
|
||||
android:text="Online"
|
||||
android:text="unknown"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"/>
|
||||
android:textSize="16sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -18,11 +18,20 @@ public class Account extends AbstractEntity{
|
|||
|
||||
public static final int OPTION_USETLS = 0;
|
||||
|
||||
public static final int STATUS_OFFLINE = 0;
|
||||
public static final int STATUS_ONLINE = 1;
|
||||
public static final int STATUS_UNAUTHORIZED = 2;
|
||||
public static final int STATUS_NOINTERNET = 3;
|
||||
public static final int STATUS_TLS_ERROR = 4;
|
||||
public static final int STATUS_SERVER_NOT_FOUND = 5;
|
||||
|
||||
protected String username;
|
||||
protected String server;
|
||||
protected String password;
|
||||
protected int options;
|
||||
protected String rosterVersion;
|
||||
protected String resource;
|
||||
protected int status = 0;
|
||||
|
||||
protected boolean online = false;
|
||||
|
||||
|
@ -70,8 +79,16 @@ public class Account extends AbstractEntity{
|
|||
this.password = password;
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return online;
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getJid() {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package de.gultsch.chat.services;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
@ -10,7 +9,7 @@ import de.gultsch.chat.entities.Contact;
|
|||
import de.gultsch.chat.entities.Conversation;
|
||||
import de.gultsch.chat.entities.Message;
|
||||
import de.gultsch.chat.persistance.DatabaseBackend;
|
||||
import de.gultsch.chat.ui.ConversationActivity;
|
||||
import de.gultsch.chat.ui.OnAccountListChangedListener;
|
||||
import de.gultsch.chat.ui.OnConversationListChangedListener;
|
||||
import de.gultsch.chat.ui.OnRosterFetchedListener;
|
||||
import de.gultsch.chat.utils.UIHelper;
|
||||
|
@ -19,20 +18,15 @@ import de.gultsch.chat.xmpp.IqPacket;
|
|||
import de.gultsch.chat.xmpp.MessagePacket;
|
||||
import de.gultsch.chat.xmpp.OnIqPacketReceived;
|
||||
import de.gultsch.chat.xmpp.OnMessagePacketReceived;
|
||||
import de.gultsch.chat.xmpp.OnStatusChanged;
|
||||
import de.gultsch.chat.xmpp.XmppConnection;
|
||||
import android.R;
|
||||
import android.R.dimen;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
import android.util.Log;
|
||||
|
||||
public class XmppConnectionService extends Service {
|
||||
|
@ -48,6 +42,7 @@ public class XmppConnectionService extends Service {
|
|||
private Hashtable<Account, XmppConnection> connections = new Hashtable<Account, XmppConnection>();
|
||||
|
||||
private OnConversationListChangedListener convChangedListener = null;
|
||||
private OnAccountListChangedListener accountChangedListener = null;
|
||||
|
||||
private final IBinder mBinder = new XmppConnectionBinder();
|
||||
private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() {
|
||||
|
@ -79,6 +74,16 @@ public class XmppConnectionService extends Service {
|
|||
}
|
||||
}
|
||||
};
|
||||
private OnStatusChanged statusListener = new OnStatusChanged() {
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(Account account) {
|
||||
Log.d(LOGTAG,account.getJid()+" changed status to "+account.getStatus());
|
||||
if (accountChangedListener != null) {
|
||||
accountChangedListener.onAccountListChangedListener();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public class XmppConnectionBinder extends Binder {
|
||||
public XmppConnectionService getService() {
|
||||
|
@ -88,15 +93,10 @@ public class XmppConnectionService extends Service {
|
|||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
for (Account account : accounts) {
|
||||
if (!connections.containsKey(account)) {
|
||||
XmppConnection connection = new XmppConnection(account, pm);
|
||||
connection
|
||||
.setOnMessagePacketReceivedListener(this.messageListener);
|
||||
Thread thread = new Thread(connection);
|
||||
thread.start();
|
||||
this.connections.put(account, connection);
|
||||
|
||||
this.connections.put(account, this.createConnection(account));
|
||||
}
|
||||
}
|
||||
return START_STICKY;
|
||||
|
@ -108,74 +108,66 @@ public class XmppConnectionService extends Service {
|
|||
this.accounts = databaseBackend.getAccounts();
|
||||
}
|
||||
|
||||
public XmppConnection createConnection(Account account) {
|
||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
XmppConnection connection = new XmppConnection(account, pm);
|
||||
connection
|
||||
.setOnMessagePacketReceivedListener(this.messageListener);
|
||||
connection.setOnStatusChangedListener(this.statusListener );
|
||||
Thread thread = new Thread(connection);
|
||||
thread.start();
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
public void sendMessage(final Account account, final Message message) {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(LOGTAG, "sending message for " + account.getJid()
|
||||
+ " to: " + message.getCounterpart());
|
||||
databaseBackend.createMessage(message);
|
||||
MessagePacket packet = new MessagePacket();
|
||||
packet.setType(MessagePacket.TYPE_CHAT);
|
||||
packet.setTo(message.getCounterpart());
|
||||
packet.setFrom(account.getJid());
|
||||
packet.setBody(message.getBody());
|
||||
try {
|
||||
connections.get(account).sendMessagePacket(packet);
|
||||
message.setStatus(Message.STATUS_SEND);
|
||||
databaseBackend.updateMessage(message);
|
||||
} catch (IOException e) {
|
||||
Log.d(LOGTAG,
|
||||
"io exception during send. message is in database. will try again later");
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
Log.d(LOGTAG, "sending message for " + account.getJid() + " to: "
|
||||
+ message.getCounterpart());
|
||||
databaseBackend.createMessage(message);
|
||||
MessagePacket packet = new MessagePacket();
|
||||
packet.setType(MessagePacket.TYPE_CHAT);
|
||||
packet.setTo(message.getCounterpart());
|
||||
packet.setFrom(account.getJid());
|
||||
packet.setBody(message.getBody());
|
||||
connections.get(account).sendMessagePacket(packet);
|
||||
message.setStatus(Message.STATUS_SEND);
|
||||
databaseBackend.updateMessage(message);
|
||||
}
|
||||
|
||||
public void getRoster(final Account account,
|
||||
final OnRosterFetchedListener listener) {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
|
||||
Element query = new Element("query");
|
||||
query.setAttribute("xmlns", "jabber:iq:roster");
|
||||
query.setAttribute("ver", "");
|
||||
iqPacket.addChild(query);
|
||||
try {
|
||||
connections.get(account).sendIqPacket(iqPacket,
|
||||
new OnIqPacketReceived() {
|
||||
IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET);
|
||||
Element query = new Element("query");
|
||||
query.setAttribute("xmlns", "jabber:iq:roster");
|
||||
query.setAttribute("ver", "");
|
||||
iqPacket.addChild(query);
|
||||
connections.get(account).sendIqPacket(iqPacket,
|
||||
new OnIqPacketReceived() {
|
||||
|
||||
@Override
|
||||
public void onIqPacketReceived(Account account,
|
||||
IqPacket packet) {
|
||||
Element roster = packet.findChild("query");
|
||||
List<Contact> contacts = new ArrayList<Contact>();
|
||||
for (Element item : roster.getChildren()) {
|
||||
String name = item.getAttribute("name");
|
||||
String jid = item.getAttribute("jid");
|
||||
if (name == null) {
|
||||
name = jid.split("@")[0];
|
||||
}
|
||||
Contact contact = new Contact(account,
|
||||
name, jid, null);
|
||||
contacts.add(contact);
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onRosterFetched(contacts);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Log.d(LOGTAG, "io error during roster fetch");
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
@Override
|
||||
public void onIqPacketReceived(Account account,
|
||||
IqPacket packet) {
|
||||
Element roster = packet.findChild("query");
|
||||
List<Contact> contacts = new ArrayList<Contact>();
|
||||
for (Element item : roster.getChildren()) {
|
||||
String name = item.getAttribute("name");
|
||||
String jid = item.getAttribute("jid");
|
||||
if (name == null) {
|
||||
name = jid.split("@")[0];
|
||||
}
|
||||
Contact contact = new Contact(account, name, jid,
|
||||
null);
|
||||
contacts.add(contact);
|
||||
}
|
||||
if (listener != null) {
|
||||
listener.onRosterFetched(contacts);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addConversation(Conversation conversation) {
|
||||
|
@ -249,14 +241,32 @@ public class XmppConnectionService extends Service {
|
|||
|
||||
public void createAccount(Account account) {
|
||||
databaseBackend.createAccount(account);
|
||||
this.accounts.add(account);
|
||||
this.connections.put(account, this.createConnection(account));
|
||||
if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener();
|
||||
}
|
||||
|
||||
public void updateAccount(Account account) {
|
||||
databaseBackend.updateAccount(account);
|
||||
XmppConnection connection = this.connections.get(account);
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
this.connections.remove(account);
|
||||
}
|
||||
this.connections.put(account, this.createConnection(account));
|
||||
if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener();
|
||||
}
|
||||
|
||||
public void deleteAccount(Account account) {
|
||||
Log.d(LOGTAG,"called delete account");
|
||||
if (this.connections.containsKey(account)) {
|
||||
Log.d(LOGTAG,"found connection. disconnecting");
|
||||
this.connections.get(account).disconnect();
|
||||
this.connections.remove(account);
|
||||
this.accounts.remove(account);
|
||||
}
|
||||
databaseBackend.deleteAccount(account);
|
||||
if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener();
|
||||
}
|
||||
|
||||
public void setOnConversationListChangedListener(
|
||||
|
@ -267,4 +277,12 @@ public class XmppConnectionService extends Service {
|
|||
public void removeOnConversationListChangedListener() {
|
||||
this.convChangedListener = null;
|
||||
}
|
||||
|
||||
public void setOnAccountListChangedListener(OnAccountListChangedListener listener) {
|
||||
this.accountChangedListener = listener;
|
||||
}
|
||||
|
||||
public void removeOnAccountListChangedListener() {
|
||||
this.accountChangedListener = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import java.util.List;
|
|||
import de.gultsch.chat.R;
|
||||
import de.gultsch.chat.entities.Account;
|
||||
import de.gultsch.chat.ui.EditAccount.EditAccountListener;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -25,10 +24,29 @@ import android.widget.TextView;
|
|||
|
||||
public class ManageAccountActivity extends XmppActivity {
|
||||
|
||||
|
||||
protected List<Account> accountList = new ArrayList<Account>();
|
||||
protected ListView accountListView;
|
||||
protected ArrayAdapter<Account> accountListViewAdapter;
|
||||
protected OnAccountListChangedListener accountChanged = new OnAccountListChangedListener() {
|
||||
|
||||
@Override
|
||||
public void onAccountListChangedListener() {
|
||||
Log.d("xmppService", "ui on account list changed listener");
|
||||
accountList.clear();
|
||||
accountList.addAll(xmppConnectionService.getAccounts());
|
||||
runOnUiThread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (accountList.size() == 1) {
|
||||
startActivity(new Intent(getApplicationContext(),
|
||||
NewConversationActivity.class));
|
||||
}
|
||||
accountListViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -38,14 +56,39 @@ public class ManageAccountActivity extends XmppActivity {
|
|||
setContentView(R.layout.manage_accounts);
|
||||
|
||||
accountListView = (ListView) findViewById(R.id.account_list);
|
||||
accountListViewAdapter = new ArrayAdapter<Account>(getApplicationContext(), R.layout.account_row, this.accountList) {
|
||||
accountListViewAdapter = new ArrayAdapter<Account>(
|
||||
getApplicationContext(), R.layout.account_row, this.accountList) {
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
Account account = getItem(position);
|
||||
if (view == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = (View) inflater.inflate(R.layout.account_row, null);
|
||||
}
|
||||
((TextView) view.findViewById(R.id.account_jid)).setText(getItem(position).getJid());
|
||||
((TextView) view.findViewById(R.id.account_jid))
|
||||
.setText(account.getJid());
|
||||
TextView statusView = (TextView) view
|
||||
.findViewById(R.id.account_status);
|
||||
switch (account.getStatus()) {
|
||||
case Account.STATUS_ONLINE:
|
||||
statusView.setText("online");
|
||||
statusView.setTextColor(0xFF83b600);
|
||||
break;
|
||||
case Account.STATUS_OFFLINE:
|
||||
statusView.setText("offline");
|
||||
statusView.setTextColor(0xFFe92727);
|
||||
break;
|
||||
case Account.STATUS_UNAUTHORIZED:
|
||||
statusView.setText("unauthorized");
|
||||
statusView.setTextColor(0xFFe92727);
|
||||
break;
|
||||
case Account.STATUS_SERVER_NOT_FOUND:
|
||||
statusView.setText("server not found");
|
||||
statusView.setTextColor(0xFFe92727);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
@ -54,8 +97,8 @@ public class ManageAccountActivity extends XmppActivity {
|
|||
accountListView.setOnItemClickListener(new OnItemClickListener() {
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> arg0, View view, int position,
|
||||
long arg3) {
|
||||
public void onItemClick(AdapterView<?> arg0, View view,
|
||||
int position, long arg3) {
|
||||
EditAccount dialog = new EditAccount();
|
||||
dialog.setAccount(accountList.get(position));
|
||||
dialog.setEditAccountListener(new EditAccountListener() {
|
||||
|
@ -67,41 +110,27 @@ public class ManageAccountActivity extends XmppActivity {
|
|||
|
||||
@Override
|
||||
public void onAccountDelete(Account account) {
|
||||
|
||||
Log.d("gultsch","deleting account:"+account.getJid());
|
||||
|
||||
xmppConnectionService.deleteAccount(account);
|
||||
|
||||
//dont bother finding the right account in the frontend list. just reload
|
||||
accountList.clear();
|
||||
accountList.addAll(xmppConnectionService.getAccounts());
|
||||
|
||||
accountListViewAdapter.notifyDataSetChanged();
|
||||
|
||||
}
|
||||
});
|
||||
dialog.show(getFragmentManager(),"edit_account");
|
||||
dialog.show(getFragmentManager(), "edit_account");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (xmppConnectionServiceBound) {
|
||||
this.accountList.clear();
|
||||
this.accountList.addAll(xmppConnectionService
|
||||
.getAccounts());
|
||||
accountListViewAdapter.notifyDataSetChanged();
|
||||
if (this.accountList.size() == 0) {
|
||||
getActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
}
|
||||
xmppConnectionService.removeOnAccountListChangedListener();
|
||||
unbindService(mConnection);
|
||||
xmppConnectionServiceBound = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void onBackendConnected() {
|
||||
Log.d("gultsch","called on backend connected");
|
||||
xmppConnectionService.setOnAccountListChangedListener(accountChanged);
|
||||
this.accountList.clear();
|
||||
this.accountList.addAll(xmppConnectionService.getAccounts());
|
||||
accountListViewAdapter.notifyDataSetChanged();
|
||||
|
@ -141,19 +170,14 @@ public class ManageAccountActivity extends XmppActivity {
|
|||
@Override
|
||||
public void onAccountEdited(Account account) {
|
||||
xmppConnectionService.createAccount(account);
|
||||
accountList.add(account);
|
||||
accountListViewAdapter.notifyDataSetChanged();
|
||||
activity.getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
if (accountList.size() == 1) {
|
||||
activity.startActivity(new Intent(activity,NewConversationActivity.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountDelete(Account account) {
|
||||
//this will never be called
|
||||
// this will never be called
|
||||
}
|
||||
});
|
||||
dialog.show(getFragmentManager(),"add_account");
|
||||
dialog.show(getFragmentManager(), "add_account");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package de.gultsch.chat.ui;
|
||||
|
||||
public interface OnAccountListChangedListener {
|
||||
public void onAccountListChangedListener();
|
||||
}
|
|
@ -3,12 +3,37 @@ package de.gultsch.chat.xml;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class TagWriter {
|
||||
|
||||
OutputStreamWriter writer;
|
||||
private OutputStreamWriter outputStream;
|
||||
private LinkedBlockingQueue<String> writeQueue = new LinkedBlockingQueue<String>();
|
||||
private Thread writer = new Thread() {
|
||||
public boolean shouldStop = false;
|
||||
@Override
|
||||
public void run() {
|
||||
while(!shouldStop) {
|
||||
try {
|
||||
String output = writeQueue.take();
|
||||
outputStream.write(output);
|
||||
outputStream.flush();
|
||||
} catch (IOException e) {
|
||||
Log.d("xmppService", "error writing to stream");
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public TagWriter() {
|
||||
|
||||
|
@ -16,31 +41,29 @@ public class TagWriter {
|
|||
|
||||
public TagWriter(OutputStream out) {
|
||||
this.setOutputStream(out);
|
||||
writer.start();
|
||||
}
|
||||
|
||||
public void setOutputStream(OutputStream out) {
|
||||
this.writer = new OutputStreamWriter(out);
|
||||
this.outputStream = new OutputStreamWriter(out);
|
||||
if (!writer.isAlive()) writer.start();
|
||||
}
|
||||
|
||||
public TagWriter beginDocument() throws IOException {
|
||||
writer.write("<?xml version='1.0'?>");
|
||||
public TagWriter beginDocument() {
|
||||
writeQueue.add("<?xml version='1.0'?>");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TagWriter writeTag(Tag tag) throws IOException {
|
||||
writer.write(tag.toString());
|
||||
public TagWriter writeTag(Tag tag) {
|
||||
writeQueue.add(tag.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
writer.flush();
|
||||
public void writeString(String string) {
|
||||
writeQueue.add(string);
|
||||
}
|
||||
|
||||
public void writeString(String string) throws IOException {
|
||||
writer.write(string);
|
||||
}
|
||||
|
||||
public void writeElement(Element element) throws IOException {
|
||||
writer.write(element.toString());
|
||||
public void writeElement(Element element) {
|
||||
writeQueue.add(element.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package de.gultsch.chat.xmpp;
|
||||
|
||||
import de.gultsch.chat.entities.Account;
|
||||
|
||||
public interface OnStatusChanged {
|
||||
public void onStatusChanged(Account account);
|
||||
}
|
|
@ -39,7 +39,7 @@ public class XmppConnection implements Runnable {
|
|||
private boolean isTlsEncrypted = false;
|
||||
private boolean isAuthenticated = false;
|
||||
//private boolean shouldUseTLS = false;
|
||||
private boolean shouldReConnect = true;
|
||||
private boolean shouldConnect = true;
|
||||
private boolean shouldBind = true;
|
||||
private boolean shouldAuthenticate = true;
|
||||
private Element streamFeatures;
|
||||
|
@ -52,8 +52,7 @@ public class XmppConnection implements Runnable {
|
|||
private OnPresencePacketReceived presenceListener = null;
|
||||
private OnIqPacketReceived unregisteredIqListener = null;
|
||||
private OnMessagePacketReceived messageListener = null;
|
||||
|
||||
private String resource = null;
|
||||
private OnStatusChanged statusListener = null;
|
||||
|
||||
public XmppConnection(Account account, PowerManager pm) {
|
||||
this.account = account;
|
||||
|
@ -66,7 +65,6 @@ public class XmppConnection implements Runnable {
|
|||
protected void connect() {
|
||||
try {
|
||||
socket = new Socket(account.getServer(), 5222);
|
||||
Log.d(LOGTAG, "starting new socket");
|
||||
OutputStream out = socket.getOutputStream();
|
||||
tagWriter.setOutputStream(out);
|
||||
InputStream in = socket.getInputStream();
|
||||
|
@ -77,40 +75,54 @@ public class XmppConnection implements Runnable {
|
|||
while ((nextTag = tagReader.readTag()) != null) {
|
||||
if (nextTag.isStart("stream")) {
|
||||
processStream(nextTag);
|
||||
break;
|
||||
} else {
|
||||
Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (socket.isConnected()) {
|
||||
socket.close();
|
||||
}
|
||||
} catch (UnknownHostException e) {
|
||||
Log.d(LOGTAG,account.getJid()+": error during connect. unknown host");
|
||||
account.setStatus(Account.STATUS_SERVER_NOT_FOUND);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
Log.d(LOGTAG, account.getJid()+": error during connect. io exception. falscher port?");
|
||||
return;
|
||||
if (shouldConnect) {
|
||||
Log.d(LOGTAG,account.getJid()+": connection lost");
|
||||
account.setStatus(Account.STATUS_OFFLINE);
|
||||
if (statusListener!=null) {
|
||||
statusListener.onStatusChanged(account);
|
||||
}
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
Log.d(LOGTAG,"xml exception "+e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while(shouldReConnect) {
|
||||
shouldConnect = true;
|
||||
while(shouldConnect) {
|
||||
connect();
|
||||
try {
|
||||
Thread.sleep(30000);
|
||||
if (shouldConnect) {
|
||||
Thread.sleep(30000);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Log.d(LOGTAG,"end run");
|
||||
}
|
||||
|
||||
private void processStream(Tag currentTag) throws XmlPullParserException,
|
||||
IOException {
|
||||
Tag nextTag;
|
||||
while (!(nextTag = tagReader.readTag()).isEnd("stream")) {
|
||||
Tag nextTag = tagReader.readTag();
|
||||
while ((nextTag != null) && (!nextTag.isEnd("stream"))) {
|
||||
if (nextTag.isStart("error")) {
|
||||
processStreamError(nextTag);
|
||||
} else if (nextTag.isStart("features")) {
|
||||
|
@ -124,6 +136,12 @@ public class XmppConnection implements Runnable {
|
|||
tagReader.reset();
|
||||
sendStartStream();
|
||||
processStream(tagReader.readTag());
|
||||
break;
|
||||
} else if(nextTag.isStart("failure")) {
|
||||
Element failure = tagReader.readElement(nextTag);
|
||||
Log.d(LOGTAG,"read failure element"+failure.toString());
|
||||
account.setStatus(Account.STATUS_UNAUTHORIZED);
|
||||
tagWriter.writeTag(Tag.end("stream"));
|
||||
} else if (nextTag.isStart("iq")) {
|
||||
processIq(nextTag);
|
||||
} else if (nextTag.isStart("message")) {
|
||||
|
@ -134,6 +152,13 @@ public class XmppConnection implements Runnable {
|
|||
Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName()
|
||||
+ " as child of " + currentTag.getName());
|
||||
}
|
||||
nextTag = tagReader.readTag();
|
||||
}
|
||||
if (account.getStatus() == Account.STATUS_ONLINE) {
|
||||
account.setStatus(Account.STATUS_OFFLINE);
|
||||
if (statusListener!=null) {
|
||||
statusListener.onStatusChanged(account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,11 +215,11 @@ public class XmppConnection implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
private void sendStartTLS() throws XmlPullParserException, IOException {
|
||||
private void sendStartTLS() {
|
||||
Tag startTLS = Tag.empty("starttls");
|
||||
startTLS.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-tls");
|
||||
Log.d(LOGTAG,account.getJid()+": sending starttls");
|
||||
tagWriter.writeTag(startTLS).flush();
|
||||
tagWriter.writeTag(startTLS);
|
||||
}
|
||||
|
||||
private void switchOverToTls(Tag currentTag) throws XmlPullParserException,
|
||||
|
@ -213,6 +238,7 @@ public class XmppConnection implements Runnable {
|
|||
isTlsEncrypted = true;
|
||||
sendStartStream();
|
||||
processStream(tagReader.readTag());
|
||||
sslSocket.close();
|
||||
} catch (IOException e) {
|
||||
Log.d(LOGTAG, account.getJid()+": error on ssl '" + e.getMessage()+"'");
|
||||
}
|
||||
|
@ -227,7 +253,6 @@ public class XmppConnection implements Runnable {
|
|||
auth.setContent(saslString);
|
||||
Log.d(LOGTAG,account.getJid()+": sending sasl "+auth.toString());
|
||||
tagWriter.writeElement(auth);
|
||||
tagWriter.flush();
|
||||
}
|
||||
|
||||
private void processStreamFeatures(Tag currentTag)
|
||||
|
@ -249,12 +274,10 @@ public class XmppConnection implements Runnable {
|
|||
startSession.addChild(session);
|
||||
sendIqPacket(startSession, null);
|
||||
tagWriter.writeElement(startSession);
|
||||
tagWriter.flush();
|
||||
}
|
||||
Element presence = new Element("presence");
|
||||
|
||||
tagWriter.writeElement(presence);
|
||||
tagWriter.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,8 +289,12 @@ public class XmppConnection implements Runnable {
|
|||
this.sendIqPacket(iq, new OnIqPacketReceived() {
|
||||
@Override
|
||||
public void onIqPacketReceived(Account account, IqPacket packet) {
|
||||
resource = packet.findChild("bind").findChild("jid").getContent().split("/")[1];
|
||||
Log.d(LOGTAG,account.getJid()+": new resource is "+resource);
|
||||
String resource = packet.findChild("bind").findChild("jid").getContent().split("/")[1];
|
||||
account.setResource(resource);
|
||||
account.setStatus(Account.STATUS_ONLINE);
|
||||
if (statusListener!=null) {
|
||||
statusListener.onStatusChanged(account);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -276,7 +303,7 @@ public class XmppConnection implements Runnable {
|
|||
Log.d(LOGTAG, "processStreamError");
|
||||
}
|
||||
|
||||
private void sendStartStream() throws IOException {
|
||||
private void sendStartStream() {
|
||||
Tag stream = Tag.start("stream");
|
||||
stream.setAttribute("from", account.getJid());
|
||||
stream.setAttribute("to", account.getServer());
|
||||
|
@ -284,32 +311,29 @@ public class XmppConnection implements Runnable {
|
|||
stream.setAttribute("xml:lang", "en");
|
||||
stream.setAttribute("xmlns", "jabber:client");
|
||||
stream.setAttribute("xmlns:stream", "http://etherx.jabber.org/streams");
|
||||
tagWriter.writeTag(stream).flush();
|
||||
tagWriter.writeTag(stream);
|
||||
}
|
||||
|
||||
private String nextRandomId() {
|
||||
return new BigInteger(50, random).toString(32);
|
||||
}
|
||||
|
||||
public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) throws IOException {
|
||||
public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) {
|
||||
String id = nextRandomId();
|
||||
packet.setAttribute("id",id);
|
||||
tagWriter.writeElement(packet);
|
||||
if (callback != null) {
|
||||
iqPacketCallbacks.put(id, callback);
|
||||
}
|
||||
tagWriter.flush();
|
||||
Log.d(LOGTAG,account.getJid()+": sending: "+packet.toString());
|
||||
}
|
||||
|
||||
public void sendMessagePacket(MessagePacket packet) throws IOException {
|
||||
public void sendMessagePacket(MessagePacket packet){
|
||||
tagWriter.writeElement(packet);
|
||||
tagWriter.flush();
|
||||
}
|
||||
|
||||
public void sendPresencePacket(PresencePacket packet) throws IOException {
|
||||
public void sendPresencePacket(PresencePacket packet) {
|
||||
tagWriter.writeElement(packet);
|
||||
tagWriter.flush();
|
||||
}
|
||||
|
||||
public void setOnMessagePacketReceivedListener(OnMessagePacketReceived listener) {
|
||||
|
@ -323,4 +347,13 @@ public class XmppConnection implements Runnable {
|
|||
public void setOnPresencePacketReceivedListener(OnPresencePacketReceived listener) {
|
||||
this.presenceListener = listener;
|
||||
}
|
||||
|
||||
public void setOnStatusChangedListener(OnStatusChanged listener) {
|
||||
this.statusListener = listener;
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
shouldConnect = false;
|
||||
tagWriter.writeTag(Tag.end("stream"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue