gpt4 book ai didi

java - XMPP 服务连接终止

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:09 24 4
gpt4 key购买 nike

我正在用 Java 开发一个 Android 聊天应用程序。现在我终于可以使用我的服务了,但是一旦我完全终止应用程序,我服务中的连接就会终止。

我正在使用 asmack 作为 XMPP 连接的库。目标是即使应用程序被用户终止(因此它不在后台)也能接收消息。

当我使用前台服务时,它确实工作,但我不想使用前台服务,因为内存使用率高,而且我不想在通知中心显示前台消息.

我的服务等级

public class MessagingService extends Service {

private final String TAG = "MessagingService";
private final IBinder mBinder = new MessagingBinder();
public Context context;
public XMPPConnection Connection;
public static Handler mHandler = new Handler();

private final int ONGOING_NOTIFICATION_ID = 2344;

@Override
public void onCreate() {
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return mBinder;
}

@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "onUnbind");
return true;
}

@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.d(TAG, "onRebind");
}

@Override
public void onDestroy() {
}


public class MessagingBinder extends Binder {

MessagingService getService() {
Log.d(TAG + " - MessagingBinder", "getService");
return MessagingService.this;
}

}

public Boolean isConnected() {
return (Connection != null);
}

public void Connect(final AuthorizeActivity authorize, final String username, final String password) {
Thread XMPPConnect = new Thread(new Runnable() {

public final String TAG = "XMPPConnect Thread";

@Override
public void run() {

AndroidConnectionConfiguration connConfig = new AndroidConnectionConfiguration(Configuration.HOST, Configuration.PORT, Configuration.SERVICE);

SmackConfiguration.setDefaultPingInterval(100);
connConfig.setReconnectionAllowed(true);
connConfig.setSASLAuthenticationEnabled(true);
connConfig.setRosterLoadedAtLogin(true);

Connection = new XMPPConnection(connConfig);

try {
Connection.connect();
Log.i(TAG, "Connected to " + Connection.getHost());
} catch (XMPPException ex) {
Log.e(TAG, "Failed to connect to " + Connection.getHost());
Log.e(TAG, ex.toString());
Connection = null;
}

if(authorize != null)
authorize.mServiceConnectCallback();

if(username != null && password != null)
Login(username, password, null);

}

});
XMPPConnect.start();
}

public void Login(final String username, final String password, final AuthorizeActivity authorize) {
Thread XMPPLogin = new Thread(new Runnable() {

public final String TAG = "XMPPConnect Thread";

@Override
public void run() {

try {
Connection.login(username, password);
Log.i(TAG, "Logged in as " + Connection.getUser());

Presence presence = new Presence(Presence.Type.available);
Connection.sendPacket(presence);

PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
Connection.addPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) {
final Message message = (Message) packet;
if (message.getBody() != null) {
final String fromName = StringUtils.parseName(message.getFrom());
Log.i(TAG, "Text Recieved " + message.getBody() + " from " + fromName );

mHandler.post(new Runnable() {
public void run() {
Receiver.recieveMessage(fromName, message.getBody());

if(!VisibilityHelper.IsVisible()) {
showNotification(fromName, message.getBody());
}

}
});
}
}

}, filter);

} catch (XMPPException ex) {
Log.e(TAG, "Failed to log in as " + "test");
Log.e(TAG, ex.toString());
Connection = null;
}

if(authorize != null)
authorize.mServiceLoginCallback();

}

});
XMPPLogin.start();
}

public void showNotification(String from, String message) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

CharSequence notiText = message;
long meow = System.currentTimeMillis();

Notification notification = new Notification(R.drawable.ic_launcher, notiText, meow);

Context context = getApplicationContext();
CharSequence contentTitle = from;
CharSequence contentText = message;
Intent notificationIntent = new Intent(context, MainActivity.class);

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notification.flags = Notification.DEFAULT_LIGHTS | Notification.FLAG_AUTO_CANCEL;

int SERVER_DATA_RECEIVED = 1;
notificationManager.notify(SERVER_DATA_RECEIVED, notification);
}

public void Logout() {
if(Connection.isConnected()) {
Log.i(TAG, "Logout");
Connection.disconnect();
}
}

public HashMap<String, String> getVCard(String user) {
Log.d(TAG, "getVCard");

//String email = user + "@" + Configuration.HOST;
String email = user;

VCard card = new VCard();

ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());

try {
card.load(MainActivity.mService.Connection, email);

String jabber_id = card.getJabberId();
String firstname = card.getFirstName();
String middlename = card.getMiddleName();
String lastname = card.getLastName();

HashMap<String, String> vcard = new HashMap<String, String>();

vcard.put("jabber_id", jabber_id);
vcard.put("firstname", firstname);
vcard.put("middlename", middlename);
vcard.put("lastname", lastname);

return vcard;
} catch (XMPPException e) {
e.printStackTrace();
}

return null;
}

public void retrieveContactsFromList() {
if(this.isConnected()) {
Roster roster = Connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();

for(RosterEntry entry : entries) {
Receiver.onRetrieveContactFromList(entry);
}
}
}

}

我启动服务的 Activity

public class ConnectionBinder extends FragmentActivity {

private final String TAG = "ConnectionBinder";
public static MessagingService mService;
public boolean mBound = false;

public Database DB;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if(!this.messagingServiceIsRunning())
{
startService(new Intent(this, MessagingService.class));
}
}

private boolean messagingServiceIsRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MessagingService.class.getName().equals( service.service.getClassName())) {
return true;
}
}

return false;
}

@Override
protected void onResume() {
super.onResume();
doBindService();
}

@Override
protected void onPause() {
super.onPause();
doUnbindService();
}

private void doBindService() {
Intent intent = new Intent(this, MessagingService.class);
bindService(intent, mMessagingService, Context.BIND_AUTO_CREATE);
}

private void doUnbindService() {
if (mBound) {
unbindService(mMessagingService);
}
}

private void doXMPPLogin() {
HashMap<String, String> user = DB.getUser();

mService.Connect(null, user.get("username"), user.get("password"));
}

private ServiceConnection mMessagingService = new ServiceConnection() {

public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(TAG, "mMessagingService.onServiceConnected()");
MessagingBinder binder = (MessagingBinder) service;
mService = binder.getService();
mBound = true;

if(!mService.isConnected()) {
doXMPPLogin();
}

mService.retrieveContactsFromList();
}

public void onServiceDisconnected(ComponentName arg0) {
Log.d(TAG, "mMessagingService.onServiceDisconnected()");
mBound = false;
}

};

}

最佳答案

传统的 XMPP 实现(和 XMPP RFC)没有定义在客户端断开连接时维持持久用户“ session ”的方法——当底层 TCP/IP 或 HTTP 连接丢失时,它们都会关闭用户 session 。另一方面,典型的 Android 环境具有“始终连接”的 Google 云服务,即使未连接,它也可以为您的应用程序传递消息。事实上,大多数聊天和社交网络应用程序都使用 GCM通知用户有关新消息的信息。因此,根据您的需要,您需要在聊天应用程序的服务器端进行一些更改:

  1. 大多数 XMPP 服务器实现都能够存储用户“离线”时收到的消息,并在用户再次连接时传送这些消息。您可以“ Hook ”离线消息接收并通过 Google Cloud Messaging 通知用户新消息的可用性,用户将在再次打开您的应用程序时收到它,并且您的 XMPPConnection 将建立。
  2. 使用 XMPP Stream Management扩展 - 如果您需要在多个用户重新连接之间共享同一 session - 并在用户再次打开您的应用程序时“恢复”上一个 session 。您仍然应该通过 GCM 通知用户有关其“ session ”中的新事件。
  3. 您的服务器端 XMPP 软件应为每个用户设备保留 GCM 注册 ID,因此当用户设备在 GCM 中注册时 - 您需要将新注册的 ID 通知您的服务器 - 这可以通过发送自定义 数据包来实现使用您的 GCM id 服务器。

一些商业 XMPP 产品已经实现了上述步骤,并将向您出售“支持推送的 XMPP 服务”,正如我所描述的,它实际上是具有 GCM 后端的 XMPP 服务器。

关于java - XMPP 服务连接终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22281279/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com