624 lines
19 KiB
Java
624 lines
19 KiB
Java
|
||
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);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|