see_you/ChatActivity.java

624 lines
19 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.thinkname.ap.main;
import jade.android.ConnectionListener;
import jade.android.JadeGateway;
import jade.core.AID;
import jade.core.Profile;
import jade.core.behaviours.OneShotBehaviour;
import jade.imtp.leap.JICP.JICPProtocol;
import jade.lang.acl.ACLMessage;
import jade.util.Logger;
import jade.util.leap.Properties;
import java.util.ArrayList;
import java.util.List;
import org.thinkname.ap.R;
import org.thinkname.ap.contact.Contact;
import org.thinkname.ap.contact.ContactLocation;
import org.thinkname.ap.contact.ContactManager;
import org.thinkname.ap.map.MyMapActivity;
import org.thinkname.ap.menu.IconContextMenu;
import org.thinkname.ap.menu.IconContextMenu.IconContextItemSelectedListener;
import org.thinkname.ap.msn.MsnAgent;
import org.thinkname.ap.msn.MsnEvent;
import org.thinkname.ap.msn.MsnEventMgr;
import org.thinkname.ap.msn.MsnSession;
import org.thinkname.ap.msn.MsnSessionAdapter;
import org.thinkname.ap.msn.MsnSessionManager;
import org.thinkname.ap.msn.MsnSessionMessage;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Toast;
public class ChatActivity extends Activity implements ConnectionListener{
/** Instance of Jade Logger, for debugging purpose. */
private final Logger myLogger = Logger.getMyLogger(this.getClass().getName());
/** ListView showing participants to this chat session. */
private ListView partsList;
/** Button for sending data. */
//private ImageButton sendButton;
private Button sendButton;
/** Button for closing this activity and session. */
private Button closeButton;
/** List of already sent messages. */
private ListView messagesSentList;
/** Edit text for editing the message that must be sent. */
private EditText messageToBeSent;
/** Instance of jade gateway necessary to work with Jade add-on. */
private JadeGateway gateway;
/** Id of the session this activity is related to*/
private String sessionId;
/** Adapter used to fill up the message list */
private MsnSessionAdapter sessionAdapter;
private ChatActivityHandler activityHandler;
private Handler mylocHandler;//
private ImageButton btnAdd;
private IconContextMenu icm;
private ProgressDialog pdg;
private Button btnGoBack;
private String myaddress;
/**
* Retrieves the id of the chat session this activity refers to.
*
* @return Id of the session
*/
public String getMsnSession(){
return sessionId;
}
/**
* Initializes basic GUI components and listeners. Also performs connection to add-on's Jade Gateway.
*
* @param icicle Bundle of data if we are resuming a frozen state (not used)
*/
protected void onCreate(Bundle icicle) {
Thread.currentThread().getId();
myLogger.log(Logger.FINE, "onReceiveIntent called: My currentThread has this ID: " + Thread.currentThread().getId());
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_LEFT_ICON);
setContentView(R.layout.chat);
setFeatureDrawable(Window.FEATURE_LEFT_ICON, getResources().getDrawable(R.drawable.chat));
myLogger.log(Logger.FINE, "onCreate called ...");
sessionAdapter = new MsnSessionAdapter(getWindow().getLayoutInflater(), getResources());
sendButton = (Button) findViewById(R.id.sendBtn);
sendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String msgContent = messageToBeSent.getText().toString().trim();
myLogger.log(Logger.FINE,"onClick(): send message:" + msgContent);
MsnSession session = MsnSessionManager.getInstance().retrieveSession(sessionId);
List<String> receivers = session.getAllParticipantIds();
if(receivers.get(0).toString().equals("Tester"))
{
Toast.makeText(ChatActivity.this, "Tester用于离线测试不支持发送消息",
Toast.LENGTH_SHORT).show();
return;
}
if(msgContent.length()>0){
sendMessageToParticipants(msgContent);
}
messageToBeSent.setText("");
}
});
//retrieve the list
partsList = (ListView) findViewById(R.id.partsList);
messageToBeSent = (EditText)findViewById(R.id.edit);
messagesSentList = (ListView) findViewById(R.id.messagesListView);
closeButton = (Button) findViewById(R.id.closeBtn);
closeButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
ChatSessionNotificationManager.getInstance().removeSessionNotification(sessionId);
MsnSessionManager.getInstance().removeMsnSession(sessionId);
finish();
}
});
btnGoBack=(Button)findViewById(R.id.goBackBtn);
btnGoBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
activityHandler = new ChatActivityHandler();
//fill Jade connection properties
Properties jadeProperties = getJadeProperties();
//try to get a JadeGateway
try {
JadeGateway.connect(MsnAgent.class.getName(), jadeProperties, this, this);
} catch (Exception e) {
//troubles during connection
Toast.makeText(this,
getString(R.string.error_msg_jadegw_connection),
Integer.parseInt(getString(R.string.toast_duration))
).show();
myLogger.log(Logger.SEVERE, "Error in chatActivity", e);
e.printStackTrace();
}
//TODO:扩展菜单ADD
btnAdd=(ImageButton)findViewById(R.id.icon_add_btn);
icm=new IconContextMenu(ChatActivity.this, R.menu.add_menu);
icm.setOnIconContextItemSelectedListener(new IconContextItemSelectedListener() {
@Override
public void onIconContextItemSelected(MenuItem item, Object info) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.cmSMS2:
{
ArrayList<String> participantIds = (ArrayList<String>)MainActivity.contactsListView
.getAllSelectedItems();
String smsContacts="";
int size=1;
for(String s:participantIds)
{
//TODO:
Log.i("debug",s);
// if(s.contains("-"))
// {
// String[] ss= s.split("-");
// s=ss.toString();
// Log.i("debug","ss.toString()"+ss.toString());
// for(String temp:ss)
// {
// s=s+temp;
// }
// Log.i("debug",s);
//
// }
if(participantIds.size()>size)
{
smsContacts=smsContacts+s+";";
}
else if(participantIds.size()==size)
{
smsContacts=smsContacts+s;
}
size++;
}
System.out.println(smsContacts);
Uri smsToUri = Uri.parse("smsto:"+smsContacts);// 联系人地址
Intent i = new Intent(Intent.ACTION_SENDTO, smsToUri);
i.putExtra("sms_body", "");
startActivity(i);
}
break;
case R.id.cmQuickReply:
//TODO:
//messageToBeSent.setText("此条消息用于快速回复~");
icm.dismiss();
pdg=new ProgressDialog(ChatActivity.this);
pdg.setMessage("准备获取...");
pdg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pdg.setCancelable(true);
pdg.show();
new Thread(){
public void run()
{
Intent intent = new Intent();//创建Intent
intent.setClass(ChatActivity.this,MyMapActivity.class);
startActivityForResult(intent, 1); //启动activity并返回结果
//overridePendingTransition(R.anim.fade, R.anim.hold);//切换效果
handler.sendEmptyMessage(1);
}
}.start();
//overridePendingTransition(R.anim.fade, R.anim.hold);
break;
case R.id.cmMyLocation:
mylocHandler=new Handler(){
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
switch(msg.what)
{
case 1:
ContactLocation myCloc = ContactManager.getInstance().getMyContactLocation();
String address=Location.getAddressByLatLng(myCloc.getLatitude(), myCloc.getLongitude());
pdg.dismiss();
Toast.makeText(getApplicationContext() ,R.string.toast_chat_getMyLocation,
2000).show();
messageToBeSent.setText("Hi,我在:"+address);
break;
case 0:
pdg.dismiss();
Toast.makeText(getApplicationContext(),R.string.toast_chat_noMyLocation,
Toast.LENGTH_LONG).show();
break;
}
}
};
pdg=new ProgressDialog(ChatActivity.this);
pdg.setMessage("正在获取我的地理位置信息...");
pdg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pdg.setCancelable(true);
pdg.show();
//a new Thread to get the Loc
Thread t=new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ContactLocation myLoc=ContactManager.getInstance().getMyContactLocation();
double lat=myLoc.getLatitude();
double lng=myLoc.getLongitude();
if (lat!=Double.POSITIVE_INFINITY&&lng!=Double.POSITIVE_INFINITY)
{
mylocHandler.sendEmptyMessage(1);
//String address=Location.getAddressByLatLng(lat, lng);
}
else
{
mylocHandler.sendEmptyMessage(0);
}
}
});
t.start();
break;
case R.id.cmMyTrack:
if(MyTrack.myTrack.size()==0)
{
Toast.makeText(ChatActivity.this,R.string.Toast_noTrack,
Toast.LENGTH_LONG).show();
}else{
messageToBeSent.setText("我的足迹 :)\n"+MyTrack.myTrack);
}
break;
default:
break;
}
}
});
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
icm.show();
}
});
}
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==1)
{
pdg.dismiss();
}
if(msg.what==10)
{
messageToBeSent.setText("我的位置:\n"+myaddress);
}
super.handleMessage(msg);
}
};
private Properties getJadeProperties() {
//fill Jade connection properties
Properties jadeProperties = new Properties();
JChatApplication app = (JChatApplication)getApplication();
jadeProperties.setProperty(Profile.MAIN_HOST, app.getProperty(JChatApplication.JADE_DEFAULT_HOST));
jadeProperties.setProperty(Profile.MAIN_PORT, app.getProperty(JChatApplication.JADE_DEFAULT_PORT));
jadeProperties.setProperty(JICPProtocol.MSISDN_KEY, app.getProperty(JChatApplication.PREFERENCE_PHONE_NUMBER));
return jadeProperties;
}
/**
* Populates the GUI retrieving the sessionId from the intent that initiates the activity itself.
* The session Id is saved in the intent as an URI, whose fragment is the part we are interested in.
* <p>
* Please note that this method shall be called both when the activity is created for the first time and
* when it is resumed from the background (that is, when it is in the foreground and the user switches to a new session
* by clicking the status bar notifications)
*/
@Override
protected void onResume() {
myLogger.log(Logger.FINE, "onResume() was called!" );
Intent i = getIntent();
Uri sessionIdUri = i.getData();
sessionId = sessionIdUri.getFragment();
MsnSession session = MsnSessionManager.getInstance().retrieveSession(sessionId);
setTitle(session.toString());
List<String> participants = session.getAllParticipantNames();
ArrayAdapter<String> aAdapter = new ArrayAdapter<String>(this,R.layout.participant_layout, R.id.participantName, participants);
partsList.setAdapter(aAdapter);
ChatSessionNotificationManager.getInstance().addNewSessionNotification(sessionId);
messageToBeSent.setText("");
//Retrieve messages if the session already contains data
sessionAdapter.setNewSession(session);
messagesSentList.setAdapter(sessionAdapter);
MsnEventMgr.getInstance().registerEvent(MsnEvent.INCOMING_MESSAGE_EVENT, activityHandler);
super.onResume();
}
/**
* Called only when resuming an activity by clicking the status bar, just before <code> onResume() </code>
* <p>
* Sets the retrieved intent (containing info about the new session selected by the user) as the current one, to make
* <code> onResume() </code> able to populate the GUI with the new data.
*
* @param intent the intent launched when clicking on status bar notification (no new activity is created but the new intent is passed anyway)
*/
@Override
protected void onNewIntent(Intent intent) {
myLogger.log(Logger.FINE, "onNewIntent was called!! \n Intent received was: " + intent.toString());
setIntent(intent);
super.onNewIntent(intent);
}
/**
* Called only when destroying the chat activity when closing the chat window (both when clicking the close button or when going back
* in activity stack with the back arrow).
* <p>
* It basically performs a disconnection from the service, sends the closing message to the main activity and resets the ChatActivityUpdater
* to null (so the agent is aware that the chat activity is not visible).
*
* @param intent the intent launched when clicking on status bar notification (no new activity is created but the new intent is passed anyway)
*/
@Override
protected void onDestroy() {
super.onDestroy();
if (gateway != null){
gateway.disconnect(this);
myLogger.log(Logger.INFO, "ChatActivity.onDestroy() : disconnected from MicroRuntimeService");
}
}
/**
* Gets the instance to the add-on's JadeGateway to be able to send messages to be sent to the
* Jade agent. It's a callback, called after the connection to add-on's <code>MicroRuntimeService</code>
*
* @param gw Instance of the JadeGateway retrieved after the connection
* @see ConnectionListener
*/
public void onConnected(JadeGateway gw) {
this.gateway = gw;
myLogger.log(Logger.INFO, "onConnected(): SUCCESS!");
}
/**
* Dummy implementation for the ConnectionListener's onDisconnected
*
* @see ConnectionListener
*/
public void onDisconnected() {
}
/**
* Sends a message to all participants of this session.
* <p>
* Instantiates a new SenderBehaviour object and sends it to the agent, together with message contents and receiver list,
* then updates the message ListView.
*
* @param msgContent content of the message to be sent
*/
private void sendMessageToParticipants(String msgContent){
//set all participants as receivers
MsnSession session = MsnSessionManager.getInstance().retrieveSession(sessionId);
List<String> receivers = session.getAllParticipantIds();
try{
gateway.execute(new SenderBehaviour(session.getSessionId(), msgContent, receivers));
Contact myContact = ContactManager.getInstance().getMyContact();
MsnSessionMessage message = new MsnSessionMessage(msgContent,myContact.getName(),myContact.getPhoneNumber());
MsnSessionManager.getInstance().addMessageToSession(session.getSessionId(), message);
//Add a new view to the adapter
sessionAdapter.addMessageView(message);
//refresh the list
messagesSentList.setAdapter(sessionAdapter);
}catch(Exception e){
myLogger.log(Logger.WARNING, e.getMessage());
}
}
/**
* Contains the actual code executed by the agent to send the message.
*/
private class SenderBehaviour extends OneShotBehaviour {
/** ACLMessage to be sent */
private ACLMessage theMsg;
/**
* Instantiates a new sender behaviour. Fills up the ACLMessage with data provided.
*
* @param convId the conv id
* @param content the content
* @param receivers the receivers
*/
public SenderBehaviour(String convId, String content, List<String> receivers) {
theMsg = new ACLMessage(ACLMessage.INFORM);
theMsg.setContent(content);
theMsg.setOntology(MsnAgent.CHAT_ONTOLOGY);
theMsg.setConversationId(convId);
for(int i=0; i<receivers.size(); i++){
String cId = receivers.get(i);
theMsg.addReceiver(new AID(cId, AID.ISLOCALNAME));
}
}
/**
* Sends the message. Executed by JADE agent.
*/
public void action() {
myLogger.log(Logger.FINE, "Sending msg " + theMsg.toString());
myAgent.send(theMsg);
}
}
/**
* Defines an handler for UI events.
*
*/
private class ChatActivityHandler extends GuiEventHandler {
/**
* Performs the update of the GUI.
* It handles the arrival of a new message.
* <p>
* Two cases are possible:
* <ol>
* <li> incoming message is related to the current session and should be added to message list
* <li> incoming message is related to another session and a notification is to be shown
* </ol>
*
* @param event the event that shall be notified to this listener to be handled
*/
protected void processEvent(MsnEvent event) {
String eventName = event.getName();
//Handle case of new message
if (eventName.equals(MsnEvent.INCOMING_MESSAGE_EVENT)){
MsnSessionMessage msnMsg = (MsnSessionMessage) event.getParam(MsnEvent.INCOMING_MESSAGE_PARAM_MSG);
String sessionId = (String) event.getParam(MsnEvent.INCOMING_MESSAGE_PARAM_SESSIONID);
//check if the message is related to the same session we are currently in.
//If so, add a new message to session udapter and update it
if (sessionId.equals(ChatActivity.this.sessionId)){
sessionAdapter.addMessageView(msnMsg);
messagesSentList.setAdapter(sessionAdapter);
NotificationSound();
} else {
//if the incoming msg is not for our session, post a notification
ChatSessionNotificationManager.getInstance().addNewMsgNotification(sessionId, msnMsg);
Toast.makeText(ChatActivity.this, msnMsg.getSenderName() + " says: " + msnMsg.getMessageContent(), 3000).show();
//提示音提示:
NotificationSound();
}
}
}
private AudioManager audioManager;
private SoundPool soundPool;
private void NotificationSound()
{
//创建对象
//第一个参数声音音频流池的最大音频流的数目为10
//第三个参数指定声音品质为5
soundPool =new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
//从资源或者文件中载入音频
int hit=soundPool.load(getApplicationContext(), R.raw.msg,0);
float volumeNum=(float)getVolume()/7;
int streamID=soundPool.play(hit, 1, 1, 0, 0, (float)1.4);
soundPool.setVolume(streamID, volumeNum, volumeNum);
}
private int getVolume()
{
int volume=-1;
audioManager=(AudioManager) getSystemService(Context.AUDIO_SERVICE);
volume=audioManager.getStreamVolume(AudioManager.STREAM_RING);
Log.i("debug","getVolume");
return volume;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1)
{
if(resultCode == RESULT_OK){
Bundle bundle = data.getExtras();
double lon = bundle.getDouble("lon");
double lat = bundle.getDouble("lat");
myaddress=bundle.getString("myaddress");
handler.sendEmptyMessage(10);
}
}
}
}