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 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 participantIds = (ArrayList)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. *

* 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 participants = session.getAllParticipantNames(); ArrayAdapter aAdapter = new ArrayAdapter(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 onResume() *

* Sets the retrieved intent (containing info about the new session selected by the user) as the current one, to make * onResume() 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). *

* 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 MicroRuntimeService * * @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. *

* 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 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 receivers) { theMsg = new ACLMessage(ACLMessage.INFORM); theMsg.setContent(content); theMsg.setOntology(MsnAgent.CHAT_ONTOLOGY); theMsg.setConversationId(convId); for(int i=0; i * Two cases are possible: *

    *
  1. incoming message is related to the current session and should be added to message list *
  2. incoming message is related to another session and a notification is to be shown *
* * @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); } } } }