我的代码中有一个无限循环,表示我的群组消息,BroadcastReceiver一遍又一遍地只接受数据库中的第一条消息,直到我停止运行应用程序。请注意,重复消息仅发生在客户端应用程序中,而不是在服务器数据库中。
有没有办法追踪BroadcastReceiver接收的意图?即。能够查看BroadcastReceiver正在采取行动的意图来找到这些行动的来源吗?
我发送和接收群组邮件的代码如果有帮助:( BroadcastReceiver靠近底部)
public class GroupMessaging extends Activity {
private static final int MESSAGE_CANNOT_BE_SENT = 0;
public String username;
public String groupname;
private EditText messageText;
private EditText messageHistoryText;
private Button sendMessageButton;
private Manager imService;
private InfoOfGroup group = new InfoOfGroup();
private StorageManipulater localstoragehandler;
private Cursor dbCursor;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((MessagingService.IMBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
Toast.makeText(GroupMessaging.this, R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.message); // messaging_screen);
messageHistoryText = (EditText) findViewById(R.id.messageHistory);
messageText = (EditText) findViewById(R.id.message);
messageText.requestFocus();
sendMessageButton = (Button) findViewById(R.id.sendMessageButton);
Bundle extras = this.getIntent().getExtras();
group.groupName = extras.getString(InfoOfGroup.GROUPNAME);
group.groupId = extras.getString(InfoOfGroup.GROUPID);
String msg = extras.getString(InfoOfGroupMessage.GROUP_MESSAGE_TEXT);
setTitle("Group: " + group.groupName);
// Retrieve the information
localstoragehandler = new StorageManipulater(this);
dbCursor = localstoragehandler.groupGet(group.groupId);
if (dbCursor.getCount() > 0) {
int noOfScorer = 0;
dbCursor.moveToFirst();
while ((!dbCursor.isAfterLast())
&& noOfScorer < dbCursor.getCount()) {
noOfScorer++;
// String 2: Username
// String 3: Message
this.appendToMessageHistory(dbCursor.getString(2),
dbCursor.getString(3));
dbCursor.moveToNext();
}
}
localstoragehandler.close();
if (msg != null) {
// Then friends username and message, not equal to null
this.appendToMessageHistory(group.groupId, msg);
((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
.cancel((group.groupId + msg).hashCode());
}
// The send button
sendMessageButton.setOnClickListener(new OnClickListener() {
CharSequence message;
Handler handler = new Handler();
public void onClick(View arg0) {
message = messageText.getText();
if (message.length() > 0) {
appendToMessageHistory(imService.getUsername(),
message.toString());
// *****************PROBLEM MAY BE
// HERE******************************
localstoragehandler.groupInsert(imService.getUsername(),
group.groupId, message.toString());
messageText.setText("");
Thread thread = new Thread() {
public void run() {
try {
if (imService.sendGroupMessage(group.groupId,
group.groupName, message.toString()) == null) {
handler.post(new Runnable() {
public void run() {
Toast.makeText(
getApplicationContext(),
R.string.message_cannot_be_sent,
Toast.LENGTH_LONG).show();
// showDialog(MESSAGE_CANNOT_BE_SENT);
}
});
}
} catch (UnsupportedEncodingException e) {
Toast.makeText(getApplicationContext(),
R.string.message_cannot_be_sent,
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
};
thread.start();
}
}
});
messageText.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == 66) {
sendMessageButton.performClick();
return true;
}
return false;
}
});
}
@Override
protected Dialog onCreateDialog(int id) {
int message = -1;
switch (id) {
case MESSAGE_CANNOT_BE_SENT:
message = R.string.message_cannot_be_sent;
break;
}
if (message == -1) {
return null;
} else {
return new AlertDialog.Builder(GroupMessaging.this)
.setMessage(message)
.setPositiveButton(R.string.OK,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
/* User clicked OK so do some stuff */
}
}).create();
}
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(groupMessageReceiver);
unbindService(mConnection);
ControllerOfGroup.setActiveGroup(null);
}
@Override
protected void onResume() {
super.onResume();
bindService(new Intent(GroupMessaging.this, MessagingService.class),
mConnection, Context.BIND_AUTO_CREATE);
IntentFilter i = new IntentFilter();
i.addAction(MessagingService.TAKE_GROUP_MESSAGE);
registerReceiver(groupMessageReceiver, i);
ControllerOfGroup.setActiveGroup(group.groupName);
}
// For receiving messages form other users...
public class GroupMessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extra = intent.getExtras();
String username = extra.getString(InfoOfGroupMessage.FROM_USER);
String groupId = extra.getString(InfoOfGroupMessage.TO_GROUP_ID);
String message = extra
.getString(InfoOfGroupMessage.GROUP_MESSAGE_TEXT);
// *************************OR HERE******************************
if (username != null && message != null) {
if (group.groupId.equals(groupId)) {
appendToMessageHistory(username, message);
localstoragehandler.groupInsert(username, groupId, message);
} else {
if (message.length() > 15) {
message = message.substring(0, 15);
}
Toast.makeText(GroupMessaging.this,
username + " says '" + message + "'",
Toast.LENGTH_SHORT).show();
}
}
}
};
// Build receiver object to accept messages
private GroupMessageReceiver groupMessageReceiver = new GroupMessageReceiver();
// Setting username and message to the message box
public void appendToMessageHistory(String username, String message) {
if (username != null && message != null) {
messageHistoryText.append(username + ":\n");
messageHistoryText.append(message + "\n");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (localstoragehandler != null) {
localstoragehandler.close();
}
if (dbCursor != null) {
dbCursor.close();
}
}
}
MessagingService类:
public class MessagingService extends Service implements Manager, Updater {
// private NotificationManager mNM;
public static String USERNAME;
public static final String TAKE_MESSAGE = "Take_Message";
public static final String FRIEND_LIST_UPDATED = "Take Friend List";
public static final String MESSAGE_LIST_UPDATED = "Take Message List";
public static final String TAKE_GROUP_MESSAGE = "Take_Group_Message";
public static final String GROUP_LIST_UPDATED = "Take Group List";
public static final String GROUP_MESSAGE_LIST_UPDATED = "Take Group Message List";
public ConnectivityManager conManager = null;
private final int UPDATE_TIME_PERIOD = 15000;
private String rawFriendList = new String();
private String rawMessageList = new String();
private String rawGroupList = new String();
private String rawGroupMessageList = new String();
SocketerInterface socketOperator = new Socketer(this);
private final IBinder mBinder = new IMBinder();
private String username;
private String password;
private String groupname;
private boolean authenticatedUser = false;
// timer to take the updated data from server
private Timer timer;
private StorageManipulater localstoragehandler;
private NotificationManager mNM;
public class IMBinder extends Binder {
public Manager getService() {
return MessagingService.this;
}
}
@Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
localstoragehandler = new StorageManipulater(this);
conManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
new StorageManipulater(this);
// Timer is used to take the friendList info every UPDATE_TIME_PERIOD;
timer = new Timer();
Thread thread = new Thread() {
@Override
public void run() {
Random random = new Random();
int tryCount = 0;
while (socketOperator.startListening(10000 + random
.nextInt(20000)) == 0) {
tryCount++;
if (tryCount > 10) {
// if it can't listen a port after trying 10 times, give
// up...
break;
}
}
}
};
thread.start();
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private void showNotification(String username, String msg) {
// Set the icon, scrolling text and TIMESTAMP
String title = "AndroidIM: You got a new Message! (" + username + ")";
String text = username + ": "
+ ((msg.length() < 5) ? msg : msg.substring(0, 5) + "...");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.notification)
.setContentTitle(title).setContentText(text);
Intent i = new Intent(this, IndividualMessaging.class);
i.putExtra(InfoOfFriend.USERNAME, username);
i.putExtra(InfoOfMessage.MESSAGETEXT, msg);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, i, 0);
mBuilder.setContentIntent(contentIntent);
mBuilder.setContentText("New message from " + username + ": " + msg);
// Send the notification.
// We use a layout id because it is a unique number. We use it later to
// cancel.
mNM.notify((username + msg).hashCode(), mBuilder.build());
}
public String getUsername() {
return this.username;
}
public String sendMessage(String username, String tousername, String message)
throws UnsupportedEncodingException {
String params = "username=" + URLEncoder.encode(this.username, "UTF-8")
+ "&password=" + URLEncoder.encode(this.password, "UTF-8")
+ "&to=" + URLEncoder.encode(tousername, "UTF-8") + "&message="
+ URLEncoder.encode(message, "UTF-8") + "&action="
+ URLEncoder.encode("sendMessage", "UTF-8") + "&";
Log.i("PARAMS", params);
return socketOperator.sendHttpRequest(params);
}
private String getFriendList() throws UnsupportedEncodingException {
// after authentication, server replies with friendList xml
// Has the friend and group and message(s) xml
rawFriendList = socketOperator
.sendHttpRequest(getAuthenticateUserParams(username, password));
if (rawFriendList != null) {
this.parseFriendInfo(rawFriendList);
}
return rawFriendList;
}
private String getMessageList() throws UnsupportedEncodingException {
rawMessageList = socketOperator
.sendHttpRequest(getAuthenticateUserParams(username, password));
if (rawMessageList != null) {
this.parseMessageInfo(rawMessageList);
}
return rawMessageList;
}
private String getGroupList() throws UnsupportedEncodingException {
rawGroupList = socketOperator
.sendHttpRequest(getAuthenticateUserParams(username, password));
if (rawGroupList != null) {
this.parseGroupInfo(rawGroupList);
}
return rawGroupList;
}
private String getGroupMessageList() throws UnsupportedEncodingException {
rawGroupMessageList = socketOperator
.sendHttpRequest(getAuthenticateUserParams(username, password));
if (rawGroupMessageList != null) {
this.parseGroupInfo(rawGroupMessageList);
}
return rawGroupMessageList;
}
public String authenticateUser(String usernameText, String passwordText)
throws UnsupportedEncodingException {
this.username = usernameText;
this.password = passwordText;
this.authenticatedUser = false;
String result = null;
result = this.getFriendList(); // socketOperator.sendHttpRequest(getAuthenticateUserParams(username,
// password));
if (result != null && !result.equals(LoggingIn.AUTHENTICATION_FAILED)) {
// if user is authenticated then return string from server is not
// equal to AUTHENTICATION_FAILED
this.authenticatedUser = true;
rawFriendList = result;
USERNAME = this.username;
// For Friends
Intent i = new Intent(FRIEND_LIST_UPDATED);
i.putExtra(InfoOfFriend.FRIEND_LIST, rawFriendList);
sendBroadcast(i);
// For Groups
Intent iG = new Intent(GROUP_LIST_UPDATED);
i.putExtra(InfoOfGroup.GROUP_LIST, rawGroupList);
sendBroadcast(iG);
timer.schedule(new TimerTask() {
public void run() {
try {
// rawFriendList = IMService.this.getFriendList();
// sending friend list
Intent i = new Intent(FRIEND_LIST_UPDATED);
Intent i2 = new Intent(MESSAGE_LIST_UPDATED);
Intent i3 = new Intent(GROUP_LIST_UPDATED);
Intent i4 = new Intent(GROUP_MESSAGE_LIST_UPDATED);
String tmp = MessagingService.this.getFriendList();
String tmp2 = MessagingService.this.getMessageList();
String tmp3 = MessagingService.this.getGroupList();
String tmp4 = MessagingService.this
.getGroupMessageList();
// For friends
if (tmp != null) {
i.putExtra(InfoOfFriend.FRIEND_LIST, tmp);
sendBroadcast(i);
Log.i("friend list broadcast sent ", "");
if (tmp2 != null) {
i2.putExtra(InfoOfMessage.MESSAGE_LIST, tmp2);
sendBroadcast(i2);
Log.i("friend list broadcast sent ", "");
}
} else {
Log.i("friend list returned null", "");
}
// Changed to i3 and i4 for the intents created...
if (tmp3 != null) {
i3.putExtra(InfoOfGroup.GROUP_LIST, tmp3);
sendBroadcast(i3);
Log.i("group list broadcast sent ", "");
if (tmp4 != null) {
i4.putExtra(
InfoOfGroupMessage.GROUP_MESSAGE_LIST,
tmp4);
sendBroadcast(i4);
Log.i("group list broadcast sent ", "");
}
} else {
Log.i("group list returned null", "");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, UPDATE_TIME_PERIOD, UPDATE_TIME_PERIOD);
}
return result;
}
public void messageReceived(String username, String message) {
// FriendInfo friend = FriendController.getFriendInfo(username);
InfoOfMessage msg = IndividualMessageController.checkMessage(username);
if (msg != null) {
Intent i = new Intent(TAKE_MESSAGE);
i.putExtra(InfoOfMessage.USERID, msg.userid);
i.putExtra(InfoOfMessage.MESSAGETEXT, msg.messagetext);
sendBroadcast(i);
String activeFriend = ControllerOfFriend.getActiveFriend();
if (activeFriend == null || activeFriend.equals(username) == false) {
localstoragehandler.insert(username, this.getUsername(),
message.toString());
showNotification(username, message);
}
Log.i("TAKE_MESSAGE broadcast sent by im service", "");
}
}
@Override
public void groupMessageReceived(String username, String groupId,
String message) {
// FriendInfo friend = FriendController.getFriendInfo(username);
InfoOfGroupMessage msg = GroupMessageController.checkMessage(username);
if (msg != null) {
Intent i = new Intent(TAKE_GROUP_MESSAGE);
i.putExtra(InfoOfGroupMessage.FROM_USER, msg.fromUser);
i.putExtra(InfoOfGroupMessage.TO_GROUP_ID, msg.toGroupId);
i.putExtra(InfoOfGroupMessage.GROUP_MESSAGE_TEXT, msg.messageText);
sendBroadcast(i);
}
Log.i("TAKE_GROUP_MESSAGE broadcast sent by im service", "");
}
private String getAuthenticateUserParams(String usernameText,
String passwordText) throws UnsupportedEncodingException {
String params = "username="
+ URLEncoder.encode(usernameText, "UTF-8")
+ "&password="
+ URLEncoder.encode(passwordText, "UTF-8")
+ "&action="
+ URLEncoder.encode("authenticateUser", "UTF-8")
+ "&port="
+ URLEncoder.encode(
Integer.toString(socketOperator.getListeningPort()),
"UTF-8") + "&";
return params;
}
public void setUserKey(String value) {
}
public boolean isNetworkConnected() {
return conManager.getActiveNetworkInfo().isConnected();
}
public boolean isUserAuthenticated() {
return authenticatedUser;
}
public String getLastRawFriendList() {
return this.rawFriendList;
}
@Override
public void onDestroy() {
Log.i("IMService is being destroyed", "...");
super.onDestroy();
}
public void exit() {
timer.cancel();
socketOperator.exit();
socketOperator = null;
this.stopSelf();
}
public String signUpUser(String usernameText, String passwordText,
String emailText) {
String params = "username=" + usernameText + "&password="
+ passwordText + "&action=" + "signUpUser" + "&email="
+ emailText + "&";
String result = socketOperator.sendHttpRequest(params);
// This is the output of the datastream from the server ie. <data>
// (bunch of data...etc) </data>
return result;
}
public String addNewFriendRequest(String friendUsername) {
String params = "username=" + this.username + "&password="
+ this.password + "&action=" + "addNewFriend"
+ "&friendUserName=" + friendUsername + "&";
String result = socketOperator.sendHttpRequest(params);
return result;
}
public String sendFriendsReqsResponse(String approvedFriendNames,
String discardedFriendNames) {
String params = "username=" + this.username + "&password="
+ this.password + "&action=" + "responseOfFriendReqs"
+ "&approvedFriends=" + approvedFriendNames
+ "&discardedFriends=" + discardedFriendNames + "&";
String result = socketOperator.sendHttpRequest(params);
return result;
}
private void parseFriendInfo(String xml) {
try {
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
sp.parse(new ByteArrayInputStream(xml.getBytes()), new HandlerXML(
MessagingService.this));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseMessageInfo(String xml) {
try {
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
sp.parse(new ByteArrayInputStream(xml.getBytes()), new HandlerXML(
MessagingService.this));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseGroupInfo(String xml) {
try {
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
sp.parse(new ByteArrayInputStream(xml.getBytes()), new HandlerXML(
MessagingService.this));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseGroupMessageInfo(String xml) {
try {
SAXParser sp = SAXParserFactory.newInstance().newSAXParser();
sp.parse(new ByteArrayInputStream(xml.getBytes()), new HandlerXML(
MessagingService.this));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void updateData(InfoOfMessage[] messages, InfoOfFriend[] friends,
InfoOfGroup[] groups, InfoOfGroupMessage[] groupMessages,
InfoOfFriend[] unApprovedFriends, String userKey) {
this.setUserKey(userKey);
// FriendController.
IndividualMessageController.setMessagesInfo(messages);
// Log.i("MESSAGEIMSERVICE","messages.length="+messages.length);
GroupMessageController.setMessagesInfo(groupMessages);
int i = 0;
while (i < messages.length) {
messageReceived(messages[i].userid, messages[i].messagetext);
i++;
}
int j = 0;
while (j < groupMessages.length) {
groupMessageReceived(groupMessages[i].fromUser,
groupMessages[i].toGroupId, groupMessages[i].messageText);
j++;
}
// For individual chat
ControllerOfFriend.setFriendsInfo(friends);
ControllerOfFriend.setUnapprovedFriendsInfo(unApprovedFriends);
// For group chat
ControllerOfGroup.setGroupsInfo(groups);
// ControllerOfGroup.setUnapprovedGroupsInfo(unapprovedGroups);
}
// ************GENERAL METHODS FOR THE GROUP CHAT************
@Override
public String createNewGroup(String userName, String groupName)
throws UnsupportedEncodingException {
String params = "username=" + URLEncoder.encode(this.username, "UTF-8")
+ "&password=" + URLEncoder.encode(this.password, "UTF-8")
+ "&action=" + "createGroup" + "&groupName=" + groupName + "&";
String result = socketOperator.sendHttpRequest(params);
return result;
}
@Override
public String addGroupMember() {
// TODO Auto-generated method stub
return null;
}
@Override
public String sendGroupMessage(String toGroupId, String toGroupName,
String messageText) throws UnsupportedEncodingException {
String params = "username=" + URLEncoder.encode(this.username, "UTF-8")
+ "&password=" + URLEncoder.encode(this.password, "UTF-8")
+ "&toGroupId=" + URLEncoder.encode(toGroupId, "UTF-8")
+ "&messageText=" + URLEncoder.encode(messageText, "UTF-8")
+ "&action=" + URLEncoder.encode("sendGroupMessage", "UTF-8")
+ "&";
Log.i("PARAMS", params);
return socketOperator.sendHttpRequest(params);
}
@Override
public String getGroupName() {
// TODO Auto-generated method stub
return this.groupname;
}
}
Websocket类
公共类Socketer实现了SocketerInterface {
Global ipAddress = new Global();
private final String AUTHENTICATION_SERVER_ADDRESS = "http://" + ipAddress.getIpAddress() + ":PRIVATE"; // change to your WebAPI Address
private int listeningPort = 0;
private static final String HTTP_REQUEST_FAILED = null;
private HashMap<InetAddress, Socket> sockets = new HashMap<InetAddress, Socket>();
private ServerSocket serverSocket = null;
private boolean listening;
private class ReceiveConnection extends Thread {
Socket clientSocket = null;
public ReceiveConnection(Socket socket)
{
this.clientSocket = socket;
Socketer.this.sockets.put(socket.getInetAddress(), socket);
}
@Override
public void run() {
try {
// PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
{
if (inputLine.equals("exit") == false) // as long as have noted exited yet, will continuing reading in
{
//appManager.messageReceived(inputLine);
}
else
{
clientSocket.shutdownInput();
clientSocket.shutdownOutput();
clientSocket.close();
Socketer.this.sockets.remove(clientSocket.getInetAddress());
}
}
} catch (IOException e) {
Log.e("ReceiveConnection.run: when receiving connection ","");
}
}
}
public Socketer(Manager appManager) {
}
public String sendHttpRequest(String params)
{
URL url;
String result = new String();
try
{
url = new URL(AUTHENTICATION_SERVER_ADDRESS);
HttpURLConnection connection;
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.println(params);
out.close();
BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
in.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
if (result.length() == 0) {
result = HTTP_REQUEST_FAILED;
}
// This is the output of the datastream from the server ie. <data> (bunch of data...etc) </data>
return result;
}
public int startListening(int portNo)
{
listening = true;
try {
serverSocket = new ServerSocket(portNo);
this.listeningPort = portNo;
} catch (IOException e) {
//e.printStackTrace();
this.listeningPort = 0;
return 0;
}
while (listening) {
try {
new ReceiveConnection(serverSocket.accept()).start();
} catch (IOException e) {
//e.printStackTrace();
return 2;
}
}
try {
serverSocket.close();
} catch (IOException e) {
Log.e("Exception server socket", "Exception when closing server socket");
return 3;
}
return 1;
}
public void stopListening()
{
this.listening = false;
}
public void exit()
{
for (Iterator<Socket> iterator = sockets.values().iterator(); iterator.hasNext();)
{
Socket socket = (Socket) iterator.next();
try {
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
} catch (IOException e)
{
}
}
sockets.clear();
this.stopListening();
}
public int getListeningPort() {
return this.listeningPort;
}
}