• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Bluetooth Chat application

 
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have created bluetooth chat application
It acts as a sender and receiver of messages as needed

It includes 3 classes

1.DeviceFinder class....Enable the device and serach for devices around.
2.SendMessage...class for sending messages
3.GuiForms ...... class that exetnds Midlet,implents Runnable
message listening process implemented inside Run method



on start of application this starts new threads

1.Message listener Thread calling run method of this class
2. Device finder thread ie called via a Timer
3. sendMessage thread is created only once user hits a button to send a message.




The application performs following

1. Searches for devices in visibility range in frequent intervals and keeps a updated list of available online users after every search.
2. Simultaneously it starts listening for incoming messages and runs until application exits and process a message once it is received
3. If a user wants to send a message he have to select recipient from online users list and sent it. Once selected, recipient remains same until user makes another selection from the list.
4. Sent messages and received messages are shown in a text box;

The issues were in following cases


1.When running in emulators every thing was working correctly.But on real devices it caused problems

i used 2 textfields one named "history"-which displays sent and rcvd messages.It is higher width and length
just below that a smaller one "tosend "-where user can type messages to be send...

i used screen properties to set size of textfields ...Though it worked correctly in emulators....in devices it was shown in strange way...


2. The device searches was taking long time in real devices and also in emulators



3.Consider a case in which

1. A device “ABC" completed its routine search. found some valid devices. and is in active state and yet to start a new search after fixed time.
At the same time a new device “XYZ" arrived, detects the device "ABC” and sents it a message......But the recepient “ABC" will not be able to reply the sender as long as it have not detected
the sender "XYZ"..ie until its online list contains an entry related to XYZ. ie: Identification of sender from received connection couldn’t be done.


I will post entire code..So can any help me in optimizing this..and fixing the flaws...




GuiForms.java


public class GuiForms extends MIDlet implements CommandListener,Runnable{

public static List onlineusers;
public static Form chatWindow;


public static TextField history;
public static TextField tosend;

Command chat;
public Command exit;
public static Command send;
public static Command showfriends;


String currentrecipenturl;

public int screenWidth;
public int screenHeight;
public int txtlimit;
public String previous;

public StreamConnectionNotifier myNotifier;
StreamConnection conn ;
String recvdMessage;
private static final UUID SERVICE_ID = new UUID("BAE0D0C0B0A000955570605040302013", false);

Timer timer;
DeviceFinder findusers;
String[] friends;


public Displayable previousscreen=null; // keeps track of previous screen
public boolean firstrun;
public String recepient;

public GuiForms() {
chat = new Command("Chat",Command.OK,2);
exit = new Command("Exit",Command.EXIT,1);
onlineusers = new List("Online Users",List.IMPLICIT);
onlineusers.addCommand(chat);
onlineusers.addCommand(exit);
onlineusers.setCommandListener(this);
findusers=null;
firstrun=true;
// GuiForms.onlineusers=null;
}
public void startApp() {
try {

/*1.INITIALISING DEVICE PROPERTES
2.STARTING THE INCOMING MESSAGE MONITOR THREAD
3.STARTING EVICE SAERCH THREAD
*/


// Message Listener thread
Thread t1 = new Thread(this);
t1.start();




findusers = new DeviceFinder();

// Device Finder Thread
timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
// System.out.println("**********************************************************Starting from timer");
startDevicesearch();

}
},1000,40000);





/*GETTING SCREEN WIDTH AND HEIGHT OF CURRENT DEVICE*/

Alert tmp = new Alert("just getting screen size");
screenWidth = tmp.getWidth();
screenHeight = tmp.getHeight();
if (screenHeight < 274) {
txtlimit = 70;
} else {
// criteria when text box to be cleared
txtlimit = 160;
}
tmp = null;



// Showing a picture on load
Form j = new Form("");
j.setTicker(new Ticker("Searching Devices "));
Display.getDisplay(this).setCurrent(j);

} catch (Exception ex) {
ex.printStackTrace();
} }
public void destroyApp(boolean bn){}
public void pauseApp() {}



/*Other Methods used by the application*/

/* 1. Method to call the device searching method of DeviceFinder class .This is used in startApp function

2. create a window that can be used for chatting

3. run method for listening for incoming messages

4.process came messages

5.Populating the onlineusers list with string array.This is called from deviceFinder class


*/





public void startDevicesearch(){

boolean bv= findusers.FindDevices();
synchronized(this)
{
if(bv&&onlineusers!=null&&firstrun&&onlineusers.size()>0)
{
try {
// System.out.println(onlineusers.size() +"changing display" + bv);
// onlineusers.addCommand(chat);
//onlineusers.addCommand(exit);
//onlineusers.setCommandListener(this);
Display.getDisplay(this).setCurrent(GuiForms.onlineusers);

//Display.getDisplay(this).getCurrent().addCommand(chat);
// Display.getDisplay(this).getCurrent().addCommand(exit);
// Display.getDisplay(this).getCurrent(). setCommandListener(this);
firstrun = false;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
// System.out.println("end of start service searchmethod");
}
//Displays the chatwindow with two textboxes
public Form getChatwindow()
{

chatWindow = new Form("Chat Window");
history = new TextField(null," ",600,TextField.ANY);
tosend = new TextField("Type Your message Here",null,100,TextField.ANY);
send = new Command("send",Command.OK,1);
showfriends= new Command("Friends Online ",Command.OK,2);
chatWindow.append(history);
chatWindow.append(tosend);
chatWindow.addCommand(exit);
chatWindow.addCommand(showfriends);
chatWindow.addCommand(send);
chatWindow.setCommandListener(this);

if(screenWidth>=240)
{
history.setPreferredSize(230,200);
tosend.setPreferredSize(175,60);
}
else
{
history.setPreferredSize(170,90);
tosend.setPreferredSize(100,50);
}
return chatWindow;
}
// Registering the service in the database and waiting for incoming message
public void run()
{
try {

// System.out.println("............................................Starting Message listener thread");
String url = "btspp://localhost:" + SERVICE_ID.toString() + ";name=ChattingService;authorize=false";
myNotifier = (StreamConnectionNotifier) Connector.open(url);
while(true)
{
conn = myNotifier.acceptAndOpen();
if(conn!=null)
{
recvdMessage = processRequest(conn);
// System.out.println(findusers.getIndex(RemoteDevice.getRemoteDevice(conn))+"recvd message is"+ recvdMessage);

/*code to handle when msg is recieved from a user not list after search is deleted from here*/


}
if(history==null||!chatWindow.isShown())
{
chatWindow =getChatwindow();
Display.getDisplay(this).setCurrent(chatWindow);
history.setString(recvdMessage);
}
else if(chatWindow.isShown())
{
previous = history.getString()+"\n";
if((previous.length()+recvdMessage.length())>=txtlimit)
previous ="";
history.setString(previous+recvdMessage);
}
if(firstrun)
firstrun=false;

}
} catch (IOException ex) {
ex.printStackTrace();
}


}

// process the arrived message
private String processRequest(StreamConnection conn) {
String rcvdString="";
try {

DataInputStream dis = null;

String previous = "";
dis = conn.openDataInputStream();
if(RemoteDevice.getRemoteDevice(conn).getFriendlyName(false)!=null)
rcvdString ="From "+RemoteDevice.getRemoteDevice(conn).getFriendlyName(false)+": "+ dis.readUTF();
else
rcvdString ="From "+RemoteDevice.getRemoteDevice(conn).getBluetoothAddress()+": "+ dis.readUTF();
dis.close();

} catch (Exception e) {
e.printStackTrace();

}
return rcvdString;
}

// populate the list
public static void setOnlineList(String a[])
{
//onlineusers = new List("Online Users",List.IMPLICIT,a,null);
onlineusers.deleteAll();
for(int i=0;i<a.length;i++)
onlineusers.append(a[i],null);


}





/* *Actions for Buttons* */

public void commandAction(Command cmd,Displayable disp)
{

if(cmd==chat )
{
// System.out.println(onlineusers.getString(onlineusers.getSelectedIndex()));
// System.out.println(onlineusers.getString(onlineusers.getSelectedIndex()));
recepient= onlineusers.getString(onlineusers.getSelectedIndex());

if(chatWindow==null)
chatWindow = getChatwindow();

Display.getDisplay(this).setCurrent(chatWindow);

currentrecipenturl= DeviceFinder.getConnectionURL(onlineusers.getString(onlineusers.getSelectedIndex())).toString();

}
else if(cmd==showfriends )
{

//onlineusers.addCommand(chat);
//onlineusers.addCommand(exit);
Display.getDisplay(this).setCurrent(onlineusers);
// Display.getDisplay(this).getCurrent().setCommandListener(this);
//Display.getDisplay(this).getCurrent().addCommand(chat);
// Display.getDisplay(this).getCurrent().addCommand(exit);
}
else if(cmd == send )
{
int length=history.getString().length()+tosend.getString().length();
if(length>=txtlimit)//220)
{
// System.out.println("**********************************************String limit reached"+length);
history.setString("");
}
if(tosend.getString().length()<1)
{
tosend.setString("No message found\n Please type message to be sent");
}
else if(currentrecipenturl==null||currentrecipenturl.length()<1)
{
tosend.setString("\nPlease choose a person form online list");
}
else
{
Thread msgSendThread = new Thread(new SendMessage(tosend.getString(),currentrecipenturl));
msgSendThread.start();

if(onlineusers!=null&&onlineusers.getSelectedIndex()>-1)
{
//System.out.println("Selected Index is"+online.getSelectedIndex());
history.setString(history.getString()+"\n"+"To "+recepient+": "+tosend.getString());
}

}



}
else if(cmd==exit)
{

timer.cancel();
destroyApp(false) ;
notifyDestroyed();
}


else
{}

}
}






DeviceFinder class







public class DeviceFinder implements DiscoveryListener,Runnable{

private DiscoveryAgent DAgent;
private LocalDevice currentDevice;

// Holds the list of devices
private Vector devicesFound;
public Vector validDevices;
public static Hashtable htable_connectionUrl;
public int deviceIndex;

//Id used for the service we are using
private UUID[] uuidSet;
private static final UUID SERVICE_ID = new UUID("BAE0D0C0B0A000955570605040302013", false);



// Misc variables
public boolean searchDone; // flag for completeion of service search on a particular device
public static boolean fullservicesearch;
// public boolean cmpltd;


public String userlist[];

//Constructor:Make the device discoverable by others

public DeviceFinder() {
//System.out.println("From constructior");
try {

uuidSet = new UUID[1];
uuidSet[0] = SERVICE_ID;
devicesFound = new Vector();
validDevices = new Vector();
htable_connectionUrl = new Hashtable();
currentDevice = LocalDevice.getLocalDevice();
DAgent = currentDevice.getDiscoveryAgent();
currentDevice.setDiscoverable(DiscoveryAgent.GIAC);
DeviceFinder.fullservicesearch = true;
}
catch (BluetoothStateException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}

}


// Method called when a new thread starts

public synchronized void run()
{
try{
// System.out.println("............................................Starting Device finder thread");
FindDevices();
}
catch(Exception ex){
ex.printStackTrace();
}

}




/* ************** All other Needed Methods ***************************** */




public synchronized boolean FindDevices()
{
// System.out.println("From find devices");
try {
devicesFound.removeAllElements();
validDevices.removeAllElements();
// htable_connectionUrl.clear();
if(DeviceFinder.fullservicesearch)
{
DeviceFinder.fullservicesearch =false;
boolean enquiryOver = DAgent.startInquiry(DiscoveryAgent.GIAC, this);
//System.out.println("Device enquiry status is"+enquiryOver);
}

} catch (BluetoothStateException ex) {
ex.printStackTrace();
}
return true;
}


// Methods in interface which are implemented
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
{
// adds the device to a list when it is founded and has not been added before
if(devicesFound.indexOf(btDevice)<0)
devicesFound.addElement(btDevice) ;
}

public void inquiryCompleted(int param)
{
// System.out.println("*********************************** Device Inquiry completed method");

/* We should give the user an alert based on the inquiry status code */
switch (param) {
case DiscoveryListener.INQUIRY_COMPLETED:
// Inquiry completed normally, add appropriate code here.
{
//System.out.println("No of devices found are"+devicesFound.size());
if(devicesFound.size()>0)
{
//call find service method on this list of devices

this.findServices();
break;
}
else
{
DeviceFinder.fullservicesearch = true;
break;
}

}
case DiscoveryListener.INQUIRY_ERROR:
// Error during inquiry, add appropriate code here.
{
break;
}
case DiscoveryListener.INQUIRY_TERMINATED: /*Inquiry terminated, caused by agent.cancelInquiry()*/
{
break;
}
}// end of if check
}



/*performs service search on device list*/
public synchronized void findServices()
{
// System.out.println("From find services");

/* 1. Take each device in list Search for service in it.
2. Each Service search on a device should take place only after service search on a particular device have been completed
*/
// indicates whole service search status.set to true once whole search complete
for (int deviceCount=0;deviceCount<devicesFound.size();deviceCount++)
{
//System.out.println(deviceCount+"************************is Device count Devices found*********************"+devicesFound.size());
uuidSet[0] = SERVICE_ID;


try {
RemoteDevice rt =(RemoteDevice)devicesFound.elementAt(deviceCount);
deviceIndex =deviceCount;
int transid=DAgent.searchServices(null,uuidSet,rt,this);
// System.out.println(deviceCount+"Searching for service in"+rt.getBluetoothAddress()+" "+transid);
waitForSearchEnd(transid); // To ensure that a particular service search completed
} catch (BluetoothStateException ex) {
ex.printStackTrace();
}
}
if(deviceIndex==devicesFound.size()-1)
fullservicesearch=true;
if(fullservicesearch)
{
GuiForms.setOnlineList(getChatFriends()); //populates string array once entire search is completed
}

//if(devicesFound.size()>0)
// devicesFound.removeAllElements();
// devicesFound = validDevices;

}


// wait for the current service search to finish
private void waitForSearchEnd(int trans)
{
searchDone = false;
while (!searchDone) {
synchronized (this)
{try {this.wait();
}catch (Exception e)
{}}}
}



/* Methods in interface which are implemented
* 1. called when a service is discovered
* 2.called when search is complete
*/


/*
* This method performs following function
1.Add device to the list of valid devices
2.Add its conncetion URL to a list
* case in which we are searching on a particaular device ie direct call to search service is not handled here *
*/
public void servicesDiscovered(int transid,ServiceRecord bn[])
{
try {
String url = bn[0].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
//System.out.println("Connection url is"+url);
// System.out.println(devicesFound.size()+""+deviceIndex);
RemoteDevice rt = (RemoteDevice)devicesFound.elementAt(deviceIndex);
validDevices.addElement(rt);
if(rt.getFriendlyName(false)!=null)
htable_connectionUrl.put(rt.getFriendlyName(false),url);
else
htable_connectionUrl.put(rt.getBluetoothAddress(),url);

} catch (Exception ex) {
ex.printStackTrace();
}
}


/*Notify the service searching process that it completed its current search and new search can be started*/
public void serviceSearchCompleted(int param1,int param2)
{
// System.out.println("Completed Search method");
searchDone = true;
synchronized (this)
{this.notifyAll(); }

}

/*After Device search and Service search the Valid device list and hash table will be populated with device name,URL pair*/

// To be done
/* Remove invalid devices from founded device list
1. delete entire content of present founded device list. Assign it to validdevices list
devicesFound.removeAllElements();
devicesFound = validDevices;
*
* 2. On beginning of search remove all entries in all lists so as to refersh it to add new entries

*/


// Method to return the index of the Remote device passed as argument in the list of valid devices

public int getIndex(RemoteDevice rm)
{
return(validDevices.indexOf(rm));
}




public synchronized String [] getChatFriends()
{
try
{
// System.out.println(" get chat friends break point");
if(userlist!=null)
userlist=null;
userlist = new String[validDevices.size()];
int i;
for(i=0;i<validDevices.size();i++)
{
RemoteDevice rn =(RemoteDevice)validDevices.elementAt(i);
if(rn.getFriendlyName(false)!=null)
userlist[i]=rn.getFriendlyName(false);
else
userlist[i]=rn.getBluetoothAddress();
}
//System.out.println("getChatFriends");
// System.out.println("No of devices found are get chat are"+validDevices.size());
}
catch (Exception ex) {
ex.printStackTrace();
}
this.notify();
return userlist;
}


public static Object getConnectionURL(String username)
{
// System.out.println("Line 302 in device Finder class connection url got is"+username+""+htable_connectionUrl.get(username));
return htable_connectionUrl.get(username);
}


// searches for service on a specified Remote Device
public synchronized int specificservciesearch(RemoteDevice device){
int serviceId =0;
try {
serviceId = DAgent.searchServices(null, uuidSet, device, this);

} catch (BluetoothStateException ex) {
ex.printStackTrace();
}
return serviceId;
}


/* public static void main(String args[])
{

DeviceFinder df = new DeviceFinder();
Thread t1 = new Thread(new MessageListener());
Thread t2 = new Thread(df);
t1.start();
t2.start();





}*/

















}// end of class

























































 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, I tried you code but there is no the class sendMessage. Have you this class? Thanks. Valter
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please edit your post to UseCodeTags. It's unnecessarily hard to read the code as it is, making it less likely that people will bother to do so.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic