从 Java 中的 Google Talk 中检索离线消息和聊天历史记录
Posted
技术标签:
【中文标题】从 Java 中的 Google Talk 中检索离线消息和聊天历史记录【英文标题】:Retrieve Offline Messages and Chat History From Google Talk in Java 【发布时间】:2014-08-29 07:00:54 【问题描述】:我必须从 Google Talk 中检索与我有过对话的特定客户(朋友/XMPP 客户)的离线消息。
另外,我想找回聊天记录。
现在,我正在使用 Hash Map 来跟踪对话并且无法获得离线消息。
我已与“talk.google.com”建立了 XMPP 连接。我目前能够通过我的控制台向客户端发送消息。我已经实现了消息侦听器接口,因此可以在我的控制台本身中接收消息。
我有另一个实现(使用 OfflineMessageManager),我尝试提取离线消息头作为开始,不幸的是,它失败并出现 Null 异常。
我使用过 smack-tcp 版本 4.0.3 和 smackx 3.1.0。
请在下面找到我到目前为止尝试过的内容...
工作实施:
公共类 StartChatImpl 实现 startChat、MessageListener
static XMPPConnection myXMPPConnection;
static ArrayList<String> myFriends = new ArrayList<String>();
ArrayList<Msg> messages;
HashMap<String,ArrayList> conversation = new HashMap<String, ArrayList>();
OfflineMessageManager offlineMessages;
@Override
public void engageChat(ChatRequest chatRequest) throws XMPPException
ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
//config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setSendPresence(true);
myXMPPConnection = new XMPPTCPConnection(config);
try
System.out.println("Connecting to talk.google.com");
myXMPPConnection.connect();
System.out.println("Logging you in...");
myXMPPConnection.login(chatRequest.getUsername(),chatRequest.getPassword());
Presence pres = new Presence(Presence.Type.unavailable);
myXMPPConnection.sendPacket(pres);
offlineMessages = new OfflineMessageManager(myXMPPConnection);
System.out.println("You have been successfully connected.");
catch (SmackException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
public void send (String message, String to) throws XMPPException
Chat chat = ChatManager.getInstanceFor(myXMPPConnection).createChat(to, this);
//System.out.println("********************************************");
//System.out.println("CHAT ID: "+ chat.getThreadID());
//System.out.println("Participant: "+chat.getParticipant());
//System.out.println("********************************************");
try
chat.sendMessage(message);
String friendName = myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName();
if(conversation.containsKey(friendName))
messages = conversation.get(friendName);
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
message = "bot says: "+message;
Msg actualMsg = new Msg(currentTimestamp,message,"bot");
messages.add(actualMsg);
//messages.add("bot says: "+message);
else
messages = new ArrayList<Msg>();
//messages.add("Bot initiated the conversation on: "+new Date());
//messages.add("bot says: "+message);
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
message = "bot says: "+message;
Msg actualMsg = new Msg(currentTimestamp,message,"bot");
messages.add(actualMsg);
conversation.put(friendName,messages);
catch (SmackException.NotConnectedException e)
e.printStackTrace();
System.out.println("You said "+"'"+message+"'"+" to "+myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName());
PacketListener myPacketListener = new PacketListener()
@Override
public void processPacket(Packet p)
if (p instanceof Message)
Message msg = (Message) p;
;
public void displayMyFriends()
Roster roster = myXMPPConnection.getRoster();
Collection entries = roster.getEntries();
System.out.println("You currently have: "+entries.size()+" friends available to chat.");
int counter = 0;
Iterator i = entries.iterator();
while(i.hasNext())
RosterEntry r = (RosterEntry) i.next();
Presence.Type entryPresence;
entryPresence = roster.getPresence(r.getUser()).getType();
System.out.println((counter+1)+" . "+r.getName() +" is "+entryPresence);
//System.out.println("id:..."+r.getUser());
myFriends.add(r.getUser());
counter++;
public void disconnectMe()
try
System.out.println("Disconnection in progress...");
myXMPPConnection.disconnect();
System.out.println("You have been successfully disconnected.");
catch (SmackException.NotConnectedException e)
e.printStackTrace();
@Override
public void processMessage(Chat chat, Message message)
if((message.getType() == Message.Type.chat) && (message.getBody()!= null))
System.out.println(myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName() + " says: " + message.getBody());
String myMsg = myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName() + " says: " + message.getBody();
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
Msg actualMsg = new Msg(currentTimestamp,myMsg,"customer");
conversation.get(myXMPPConnection.getRoster().getEntry(chat.getParticipant()).getName()).
add(actualMsg);
public void receiveMessage()
myXMPPConnection.addPacketListener(myPacketListener, null);
public void retrieveUnservicedMessagesForSpecificPerson(String clientName)
ArrayList<Msg> myMessages = conversation.get(clientName);
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
java.sql.Timestamp currentTimestamp = new java.sql.Timestamp(now.getTime());
System.out.println("Unserviced messages from: "+ clientName);
if(!myMessages.isEmpty())
int counter = myMessages.size()-1;
System.out.println("Size of array list: "+counter);
boolean found = false;
java.sql.Timestamp lastBotTimestamp = null;
while (counter != 0 && found == false)
if(myMessages.get(counter).getOwner()=="bot")
lastBotTimestamp = myMessages.get(counter).getTimestamp();
found = true;
else
counter = counter-1;
for(Msg msg:myMessages)
if(msg.getTimestamp().before(currentTimestamp) &&
msg.getTimestamp().after(lastBotTimestamp))
System.out.println("---------------------------");
System.out.println("-"+msg.getActualMessage());
System.out.println("-"+msg.getTimestamp());
System.out.println("---------------------------");
public void returnConversation(String name)
System.out.println("Name of participant entered: "+ name);
System.out.println("Conversation history is: ");
ArrayList<Msg> m = conversation.get(name);
for(Msg msg:m)
System.out.println(msg.getActualMessage());
System.out.println("on: "+msg.getTimestamp());
public void returnAllUnservicedMessagesHistory()
for(String name: conversation.keySet())
System.out.println("History of unserviced messages for: "+ name);
retrieveUnservicedMessagesForSpecificPerson(name);
public void getOfflineMessagesCount()
try
System.out.println("Number of offline messages: "+ offlineMessages.getMessageCount());
catch (XMPPException e)
e.printStackTrace();
我的主类实现:
公共类 MainGoogleChatApp
public static void main(String[] args)
//Step 1: need to make a chat request with your username and password.
Scanner input = new Scanner(System.in);
System.out.println("Please enter your username to start: ");
String myUsername = input.next();
System.out.println("Please enter your password to continue: ");
String myPassword = input.next();
ChatRequest myChatRequest = new ChatRequest();
myChatRequest.setUsername(myUsername);
myChatRequest.setPassword(myPassword);
//Step 2: Need to initiate a connection to talk.google.com
StartChatImpl convo = new StartChatImpl();
try
convo.engageChat(myChatRequest);
catch (XMPPException e)
e.printStackTrace();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String myMessage;
System.out.println("Friend list.");
convo.displayMyFriends();
convo.receiveMessage();
try
while(true)
System.out.println("Input Which friend you want to chat with '0 to sign out' : ");
int num = input.nextInt() -1;
if (num == -1)
break;
String chatWith = StartChatImpl.myFriends.get(num);
System.out.print("Type your message: ");
myMessage=br.readLine();
try
convo.send(myMessage,chatWith);
catch (XMPPException e)
e.printStackTrace();
convo.displayMyFriends();
catch (IOException e)
e.printStackTrace();
System.out.println("Enter participant name to get specific chat...");
String yourName = null;
try
yourName = br.readLine();
catch (IOException e)
e.printStackTrace();
System.out.println("/./././././././././././././..//.");
if(yourName!=null)
System.out.println("Your name is not null...ok");
convo.returnConversation(yourName);
System.out.println("Enter another participant's name to get specific chat...");
String yourName1 = null;
try
yourName1 = br.readLine();
catch (IOException e)
e.printStackTrace();
System.out.println("/./././././././././././././..//.");
if(yourName1!=null)
System.out.println("Your name is not null...ok");
convo.returnConversation(yourName1);
System.out.println("Select a client name for whom you want to view unserviced messages: ");
String yourClientName = null;
try
yourClientName = br.readLine();
catch (IOException e)
e.printStackTrace();
if(yourClientName!=null)
System.out.println("...........................................");
convo.retrieveUnservicedMessagesForSpecificPerson(yourClientName);
System.out.println("...........................................");
convo.returnAllUnservicedMessagesHistory();
System.out.println("You have chosen to disconnect yourself from talk.google.com");
convo.disconnectMe();
System.exit(0);
尝试检索离线消息标头:
公共类 TestOfflineService
XMPPConnection xmppConnection = null;
//OfflineMessageManager offlineMessageManager = null;
public void makeConnection()
ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
//config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setSendPresence(true);
xmppConnection = new XMPPTCPConnection(config);
try
System.out.println("Connecting to talk.google.com");
xmppConnection.connect();
System.out.println("Logging you in...");
xmppConnection.login("*******.*@***.com", "*****");
System.out.println("You have been successfully connected.");
catch (SmackException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (XMPPException e)
e.printStackTrace();
public void makeMeUnavailable()
try
xmppConnection.sendPacket(new Presence(Presence.Type.unavailable));
catch (SmackException.NotConnectedException e)
e.printStackTrace();
public void getOfflineMessages()
OfflineMessageManager offlineMessageManager1 = new OfflineMessageManager(xmppConnection);
try
Iterator<OfflineMessageHeader> headers = offlineMessageManager1.getHeaders();
if(headers.hasNext())
System.out.println("Messages found");
catch (XMPPException e)
e.printStackTrace();
public static void main(String[] args)
TestOfflineService test = new TestOfflineService();
test.makeConnection();
test.makeMeUnavailable();
System.out.println("Enter messages");
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
System.out.println("Getting offline messages.....");
test.getOfflineMessages();
【问题讨论】:
【参考方案1】:OfflineMessageManager
尝试使用XEP-0013 检索离线消息。这个 XEP 不是由 GTalk 实现的。另请注意,启动环聊意味着您将永远不会再收到离线消息,因为环聊实例永远不会离线。
GTalk 也没有用于检索聊天记录的 XMPP API,例如 XEP-0136 或 XEP-0313。
【讨论】:
以上是关于从 Java 中的 Google Talk 中检索离线消息和聊天历史记录的主要内容,如果未能解决你的问题,请参考以下文章
从 Google App Engine 设置 Google Talk 状态(带身份验证)
从 Android 以编程方式更改 Google Talk 在线状态
如何使用 smack API 从 Google Talk 获取我的个人资料图片?