Hello,
I'm working on a bluetooth chat application project called 'BlueChat'. I coded the server (BServer.java) and client (BClient.java) parts (2 separate threads). The visual part is called BlueChat.java and allowes the user to select to be the server or the client.

I wrote a lot of System.out.println("")'s to check WHY NO MESSAGE IS SEND (there are no errors or exceptions). So I detect that:
- On the server, when it reaches

con = notifier.acceptAndOpen();

part, loopes infinitely as it doesn't receive any join from a 'Client'
- On the client when it passes the 'inquiry' but it's waiting infinitely on the service detection:

serviceL.wait();

as it can never find a remote host device (the server)


Here are the classes:
The 'visual' class

public class BlueChat extends MIDlet implements CommandListener{


    /*******************************************************************************/

 
    private final Command EXIT_CMD = new Command("Exit", Command.EXIT, 2);


   

    Command RECEIVE_CMD = new Command("Receive", Command.ITEM, 2);
    Command SEND_CMD = new Command("Send", Command.ITEM, 2);
 
    

    /** value is true after creating the server/client */
    private boolean isInit = false;

    /*******************************************************************************/

   

    Display display;
    Form mainForm;
    boolean firstTime = true;

    StringItem status;


    //Bluetooth members


    LocalDevice local = null;
    DiscoveryAgent discoveryAgent = null;
    ServiceRecord SR = null;

    L2CAPConnectionNotifier notifier = null;
    L2CAPConnection con = null;
    String service_UUID = null;

    InputStream input = null;
    OutputStream output = null;


    
    String deviceName="",deviceAddress="";
    private boolean listening=true;
    private StringItem msg;


    //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">                      
    //</editor-fold>                    

    /**
     * The BlueChat constructor.
     */
    public BlueChat() {
       
    }


   protected void setAlert(String info) {
        Alert a = new Alert("INFO");
        a.setString(info);
        a.setTimeout(Alert.FOREVER);
        display.setCurrent(a);
    }
     
  ...
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {                                            
        // write pre-switch user code here
        Display display = getDisplay();                                               
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }                                             
        // write post-switch user code here
    }                                   
    //</editor-fold>                                 

    /**
     * Returns a display instance.
     * @return the display instance.
     */
    public Display getDisplay () {
        return Display.getDisplay(this);
    }

    /**
     * Exits MIDlet.
     */
    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */
    public void startApp() {

       firstTime = true;
       mainForm = new Form("BlueChat");

       if(firstTime)
       {
           display = Display.getDisplay(this);
           // vizual
           status = new StringItem("Status:", "...");
           mainForm.append(status);
           msg = new StringItem("Message:","...");
           mainForm.append(msg);

           //comenzi
           mainForm.addCommand(EXIT_CMD);
           mainForm.addCommand(SEND_CMD);
           mainForm.addCommand(RECEIVE_CMD);
         

           mainForm.setCommandListener(this);

            /////////////////
           firstTime = false;
       }

       display.setCurrent(mainForm);
       /* try {
            connect();
        } catch (IOException ex) {
            ex.printStackTrace();
        }*/
    }

    public void commandAction(Command c, Displayable d)
    {
        if(c == EXIT_CMD)
        {    
            this.destroyApp(true);
            this.notifyDestroyed();
            
        }
        else if(c == RECEIVE_CMD)
        {
           new BServer(this);
          
        }
        else if(c == SEND_CMD)
        {
           new BClient(this);
        }
       
            
        
    }

    /**
     * Called when MIDlet is paused.
     */
    public void pauseApp() {
        midletPaused = true;
    }

    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */
    public void destroyApp(boolean unconditional) {
    }



}

The SERVER class

public class BServer implements Runnable{
    private LocalDevice local;
    private DiscoveryAgent discoveryAgent;
    private String deviceName;
    private String deviceAddress;
   // final private StringItem status,msg;
    private String service_UUID="00000000000010008000006057028A06";
    private L2CAPConnectionNotifier notifier;
    private boolean listening;
    private L2CAPConnection con;

    private BlueChat chat;

    BServer(BlueChat chat)
    {
          
            this.chat = chat;
            
            Thread t = new Thread(this);
            t.start();
    }

    public void run() {
  try {
       System.out.println("Server thread started");
        local = LocalDevice.getLocalDevice();//initializare  pt gazda
        local.setDiscoverable(DiscoveryAgent.LIAC);
        discoveryAgent = local.getDiscoveryAgent();
        deviceName = local.getFriendlyName();
        deviceAddress = local.getBluetoothAddress();

       /* status.setText(deviceName+"\nAddress="+deviceAddress+
                "\nDiscovery agent="+discoveryAgent.toString());
*/



       String url = "btl2cap://localhost:"+service_UUID+";name="+deviceName;

            notifier = (L2CAPConnectionNotifier) Connector.open(url);
            // con = (L2CAPConnection)Connector.open(url);

       System.out.println("advertising the connection");
/**************************************************************
                                                       WAITING INFINETELY HERE
*******************************************************/
       con = notifier.acceptAndOpen();///////////////////////////////
        System.out.println("advertising finished");
       while(listening){

        if(con.ready()){
             System.out.println("server READY to receive data");
            // primim in bytes data de la client apoi o trecem intr-un String
            byte[] buff  = new byte[1000];
            con.receive(buff);

            String s = new String(buff,0, buff.length);
          //  msg.setText("a");
            //daca am primit mesaj alertam interfata vizuala
            System.out.println("Recieved from client: " + s.trim());
            chat.setAlert(s.trim());

            //asa trimitem
            sendMessage("Hello client, my name is: " + local.getFriendlyName());

            listening = false;
        }
       }


               } catch (IOException ex) {
                   System.out.println("Eroare la SERVER\n");
            ex.printStackTrace();
        }



    }


    private void sendMessage(String msg)
    {
        byte[] buff = msg.getBytes();
                try {
            con.send(buff);
        } catch(IOException e){
            System.out.println(e);
        }
    }

}

The client class

public class BClient implements Runnable{

    String s;
    private LocalDevice local;
    private DiscoveryAgent discoveryAgent;
    private String deviceName;
    private String deviceAddress;
    
    private String service_UUID="00000000000010008000006057028A06";
    private L2CAPConnectionNotifier notifier;
    private L2CAPConnection con;

    private BlueChat chat;
    private InquiryListener inquiryL;
    private ServiceListener serviceL;
    private boolean listening=true;

    BClient(BlueChat chat)
    {
       this.chat = chat;

        Thread t = new Thread(this);
        t.start();
    }

    public void run() {
       try{
          byte[] buff = "SAALUT".getBytes();

          System.out.println("Client thread started");
        //date dispozitiv
        local = LocalDevice.getLocalDevice();//initializare  pt gazda
        local.setDiscoverable(DiscoveryAgent.LIAC);
        discoveryAgent = local.getDiscoveryAgent();
        deviceName = local.getFriendlyName();
        deviceAddress = local.getBluetoothAddress();

        //cautare dispozitive bluetooth apoi serviciile fiecaruia
        inquiryL = new InquiryListener();
        
        synchronized(inquiryL){
            System.out.println("inainte de cautare inquiry");
            discoveryAgent.startInquiry(DiscoveryAgent.LIAC, inquiryL);
            try{
                System.out.println("in asteptare");
                inquiryL.wait();
            }catch(InterruptedException e){ }


            System.out.println("asteptare inquiry terminata");
        }
        
        //dispozitive gasite - in obiectul de cautare de mai sus
        Enumeration devices = inquiryL.cached_devices.elements();

        UUID[] u = new UUID[]{ new UUID("00000000000010008000006057028A06", false) };
        int attributes[]= { 0x0100 };

        //acum serviciile aferente FIECARUI ELEMENT... deic traversam vectorul de elemente
        serviceL = new ServiceListener();
        while(devices.hasMoreElements()){
            synchronized(serviceL){
                System.out.println("inainte de cautare servicii");
                discoveryAgent.searchServices(attributes, u, (RemoteDevice)devices.nextElement(), inquiryL);
                try{
                    System.out.println("in asteptare");
/**************************************************************
                                                       WAITING INFINETELY HERE
*******************************************************/
                    serviceL.wait();///////////
                }catch(InterruptedException e){}

                System.out.println("asteptare servicii terminata");
            }

 
         if (serviceL.service!=null){
            try {
                String url;
                url = serviceL.service.getConnectionURL(0, false);
                deviceName = LocalDevice.getLocalDevice().getFriendlyName();
                con = (L2CAPConnection) Connector.open( url );
                sendMessage("Hello server, my name is: " + deviceName);

                byte[] b = new byte[1000];

                 System.out.println("IN SERVICIU");

                while (listening) {
                    if (con.ready()){
                         System.out.println("GATA DE PRIMIRE");

                        con.receive(b);
                        String str = new String(b, 0, b.length);
                        System.out.println("Received from server: " + str.trim());
                        chat.setAlert(str.trim());
                        listening = false;
                    }
                }
            } catch (IOException g) {System.out.println(g);}
        }


        }


         } catch (IOException ex) {
              System.out.println("Eroare la CLIENT\n");
            ex.printStackTrace();
        }
    }




   /********* TRIMITE *****************/

   private void sendMessage(String msg)
    {
        byte[] buff = msg.getBytes();
                try {
            con.send(buff);
        } catch(IOException e){
            System.out.println(e);
        }
    }



   /*********** CLASA PENTRU CAUTARE DISPOZITIVE*******/
    class InquiryListener implements DiscoveryListener{

        public Vector cached_devices;

        InquiryListener(){
             cached_devices = new Vector();
        }

        public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
           if( ! cached_devices.contains( btDevice ) )	{
            cached_devices.addElement( btDevice );
          }
        }

        public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
        }

        public void serviceSearchCompleted(int transID, int respCode) {  
        }

        public void inquiryCompleted(int discType) {
             synchronized(this){ this.notify();System.out.println("inquiry terminata"); }
        }

    }



    /*********** CLASA PENTRU CAUTARE SERVICII ale dispozitivelor*******/
    class ServiceListener implements DiscoveryListener{

        public ServiceRecord service;

        public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
                   service = servRecord[0];
                    System.out.println("foundService");
        }

        public void serviceSearchCompleted(int transID, int respCode) {
           synchronized( this ){	this.notify();}
        }


        public void inquiryCompleted(int discType) {
        }

        public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        }

    }


}

So please help me on detection between devices if you can. I just don't know why the don't detect each other. I use NetBeans with Mobile Simulator and I even tested it on two real mobile phones - nothing happened :(

Recommended Answers

All 7 Replies

Sorry, I cannot help right know (little busy at the moment), but you can have look at Beginning J2ME: From Novice to Professional Chapter 12 that should help with device discovery

Nice book, I read something.... it's just it uses other type of connection and things that doesn't match my case (L2CAPConnection is more flexible than StreamConnection).
However thanks for interest and I will wait your and others help... while continously trying to find 'the bug'....

Hello,
I'm a novice in J2ME but i started developing a bluetooth chat aplication. I managed to find some samples of btooth chat aplications but i'm not satisfied with it. Can you provide some help(i mean source code )? if i can help you with your problem i'll send you a solution.
Thank you

Hello,
I'm working on a bluetooth chat application project called 'BlueChat'. I coded the server (BServer.java) and client (BClient.java) parts (2 separate threads). The visual part is called BlueChat.java and allowes the user to select to be the server or the client.

I wrote a lot of System.out.println("")'s to check WHY NO MESSAGE IS SEND (there are no errors or exceptions). So I detect that:
- On the server, when it reaches

con = notifier.acceptAndOpen();

part, loopes infinitely as it doesn't receive any join from a 'Client'
- On the client when it passes the 'inquiry' but it's waiting infinitely on the service detection:

serviceL.wait();

as it can never find a remote host device (the server)


Here are the classes:
The 'visual' class

public class BlueChat extends MIDlet implements CommandListener{


    /*******************************************************************************/

 
    private final Command EXIT_CMD = new Command("Exit", Command.EXIT, 2);


   

    Command RECEIVE_CMD = new Command("Receive", Command.ITEM, 2);
    Command SEND_CMD = new Command("Send", Command.ITEM, 2);
 
    

    /** value is true after creating the server/client */
    private boolean isInit = false;

    /*******************************************************************************/

   

    Display display;
    Form mainForm;
    boolean firstTime = true;

    StringItem status;


    //Bluetooth members


    LocalDevice local = null;
    DiscoveryAgent discoveryAgent = null;
    ServiceRecord SR = null;

    L2CAPConnectionNotifier notifier = null;
    L2CAPConnection con = null;
    String service_UUID = null;

    InputStream input = null;
    OutputStream output = null;


    
    String deviceName="",deviceAddress="";
    private boolean listening=true;
    private StringItem msg;


    //<editor-fold defaultstate="collapsed" desc=" Generated Fields ">                      
    //</editor-fold>                    

    /**
     * The BlueChat constructor.
     */
    public BlueChat() {
       
    }


   protected void setAlert(String info) {
        Alert a = new Alert("INFO");
        a.setString(info);
        a.setTimeout(Alert.FOREVER);
        display.setCurrent(a);
    }
     
  ...
    public void switchDisplayable(Alert alert, Displayable nextDisplayable) {                                            
        // write pre-switch user code here
        Display display = getDisplay();                                               
        if (alert == null) {
            display.setCurrent(nextDisplayable);
        } else {
            display.setCurrent(alert, nextDisplayable);
        }                                             
        // write post-switch user code here
    }                                   
    //</editor-fold>                                 

    /**
     * Returns a display instance.
     * @return the display instance.
     */
    public Display getDisplay () {
        return Display.getDisplay(this);
    }

    /**
     * Exits MIDlet.
     */
    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */
    public void startApp() {

       firstTime = true;
       mainForm = new Form("BlueChat");

       if(firstTime)
       {
           display = Display.getDisplay(this);
           // vizual
           status = new StringItem("Status:", "...");
           mainForm.append(status);
           msg = new StringItem("Message:","...");
           mainForm.append(msg);

           //comenzi
           mainForm.addCommand(EXIT_CMD);
           mainForm.addCommand(SEND_CMD);
           mainForm.addCommand(RECEIVE_CMD);
         

           mainForm.setCommandListener(this);

            /////////////////
           firstTime = false;
       }

       display.setCurrent(mainForm);
       /* try {
            connect();
        } catch (IOException ex) {
            ex.printStackTrace();
        }*/
    }

    public void commandAction(Command c, Displayable d)
    {
        if(c == EXIT_CMD)
        {    
            this.destroyApp(true);
            this.notifyDestroyed();
            
        }
        else if(c == RECEIVE_CMD)
        {
           new BServer(this);
          
        }
        else if(c == SEND_CMD)
        {
           new BClient(this);
        }
       
            
        
    }

    /**
     * Called when MIDlet is paused.
     */
    public void pauseApp() {
        midletPaused = true;
    }

    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */
    public void destroyApp(boolean unconditional) {
    }



}

The SERVER class

public class BServer implements Runnable{
    private LocalDevice local;
    private DiscoveryAgent discoveryAgent;
    private String deviceName;
    private String deviceAddress;
   // final private StringItem status,msg;
    private String service_UUID="00000000000010008000006057028A06";
    private L2CAPConnectionNotifier notifier;
    private boolean listening;
    private L2CAPConnection con;

    private BlueChat chat;

    BServer(BlueChat chat)
    {
          
            this.chat = chat;
            
            Thread t = new Thread(this);
            t.start();
    }

    public void run() {
  try {
       System.out.println("Server thread started");
        local = LocalDevice.getLocalDevice();//initializare  pt gazda
        local.setDiscoverable(DiscoveryAgent.LIAC);
        discoveryAgent = local.getDiscoveryAgent();
        deviceName = local.getFriendlyName();
        deviceAddress = local.getBluetoothAddress();

       /* status.setText(deviceName+"\nAddress="+deviceAddress+
                "\nDiscovery agent="+discoveryAgent.toString());
*/



       String url = "btl2cap://localhost:"+service_UUID+";name="+deviceName;

            notifier = (L2CAPConnectionNotifier) Connector.open(url);
            // con = (L2CAPConnection)Connector.open(url);

       System.out.println("advertising the connection");
/**************************************************************
                                                       WAITING INFINETELY HERE
*******************************************************/
       con = notifier.acceptAndOpen();///////////////////////////////
        System.out.println("advertising finished");
       while(listening){

        if(con.ready()){
             System.out.println("server READY to receive data");
            // primim in bytes data de la client apoi o trecem intr-un String
            byte[] buff  = new byte[1000];
            con.receive(buff);

            String s = new String(buff,0, buff.length);
          //  msg.setText("a");
            //daca am primit mesaj alertam interfata vizuala
            System.out.println("Recieved from client: " + s.trim());
            chat.setAlert(s.trim());

            //asa trimitem
            sendMessage("Hello client, my name is: " + local.getFriendlyName());

            listening = false;
        }
       }


               } catch (IOException ex) {
                   System.out.println("Eroare la SERVER\n");
            ex.printStackTrace();
        }



    }


    private void sendMessage(String msg)
    {
        byte[] buff = msg.getBytes();
                try {
            con.send(buff);
        } catch(IOException e){
            System.out.println(e);
        }
    }

}

The client class

public class BClient implements Runnable{

    String s;
    private LocalDevice local;
    private DiscoveryAgent discoveryAgent;
    private String deviceName;
    private String deviceAddress;
    
    private String service_UUID="00000000000010008000006057028A06";
    private L2CAPConnectionNotifier notifier;
    private L2CAPConnection con;

    private BlueChat chat;
    private InquiryListener inquiryL;
    private ServiceListener serviceL;
    private boolean listening=true;

    BClient(BlueChat chat)
    {
       this.chat = chat;

        Thread t = new Thread(this);
        t.start();
    }

    public void run() {
       try{
          byte[] buff = "SAALUT".getBytes();

          System.out.println("Client thread started");
        //date dispozitiv
        local = LocalDevice.getLocalDevice();//initializare  pt gazda
        local.setDiscoverable(DiscoveryAgent.LIAC);
        discoveryAgent = local.getDiscoveryAgent();
        deviceName = local.getFriendlyName();
        deviceAddress = local.getBluetoothAddress();

        //cautare dispozitive bluetooth apoi serviciile fiecaruia
        inquiryL = new InquiryListener();
        
        synchronized(inquiryL){
            System.out.println("inainte de cautare inquiry");
            discoveryAgent.startInquiry(DiscoveryAgent.LIAC, inquiryL);
            try{
                System.out.println("in asteptare");
                inquiryL.wait();
            }catch(InterruptedException e){ }


            System.out.println("asteptare inquiry terminata");
        }
        
        //dispozitive gasite - in obiectul de cautare de mai sus
        Enumeration devices = inquiryL.cached_devices.elements();

        UUID[] u = new UUID[]{ new UUID("00000000000010008000006057028A06", false) };
        int attributes[]= { 0x0100 };

        //acum serviciile aferente FIECARUI ELEMENT... deic traversam vectorul de elemente
        serviceL = new ServiceListener();
        while(devices.hasMoreElements()){
            synchronized(serviceL){
                System.out.println("inainte de cautare servicii");
                discoveryAgent.searchServices(attributes, u, (RemoteDevice)devices.nextElement(), inquiryL);
                try{
                    System.out.println("in asteptare");
/**************************************************************
                                                       WAITING INFINETELY HERE
*******************************************************/
                    serviceL.wait();///////////
                }catch(InterruptedException e){}

                System.out.println("asteptare servicii terminata");
            }

 
         if (serviceL.service!=null){
            try {
                String url;
                url = serviceL.service.getConnectionURL(0, false);
                deviceName = LocalDevice.getLocalDevice().getFriendlyName();
                con = (L2CAPConnection) Connector.open( url );
                sendMessage("Hello server, my name is: " + deviceName);

                byte[] b = new byte[1000];

                 System.out.println("IN SERVICIU");

                while (listening) {
                    if (con.ready()){
                         System.out.println("GATA DE PRIMIRE");

                        con.receive(b);
                        String str = new String(b, 0, b.length);
                        System.out.println("Received from server: " + str.trim());
                        chat.setAlert(str.trim());
                        listening = false;
                    }
                }
            } catch (IOException g) {System.out.println(g);}
        }


        }


         } catch (IOException ex) {
              System.out.println("Eroare la CLIENT\n");
            ex.printStackTrace();
        }
    }




   /********* TRIMITE *****************/

   private void sendMessage(String msg)
    {
        byte[] buff = msg.getBytes();
                try {
            con.send(buff);
        } catch(IOException e){
            System.out.println(e);
        }
    }



   /*********** CLASA PENTRU CAUTARE DISPOZITIVE*******/
    class InquiryListener implements DiscoveryListener{

        public Vector cached_devices;

        InquiryListener(){
             cached_devices = new Vector();
        }

        public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
           if( ! cached_devices.contains( btDevice ) )	{
            cached_devices.addElement( btDevice );
          }
        }

        public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
        }

        public void serviceSearchCompleted(int transID, int respCode) {  
        }

        public void inquiryCompleted(int discType) {
             synchronized(this){ this.notify();System.out.println("inquiry terminata"); }
        }

    }



    /*********** CLASA PENTRU CAUTARE SERVICII ale dispozitivelor*******/
    class ServiceListener implements DiscoveryListener{

        public ServiceRecord service;

        public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
                   service = servRecord[0];
                    System.out.println("foundService");
        }

        public void serviceSearchCompleted(int transID, int respCode) {
           synchronized( this ){	this.notify();}
        }


        public void inquiryCompleted(int discType) {
        }

        public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        }

    }


}

So please help me on detection between devices if you can. I just don't know why the don't detect each other. I use NetBeans with Mobile Simulator and I even tested it on two real mobile phones - nothing happened :(

Hello,
I'm a novice in J2ME but i started developing a bluetooth chat aplication. I managed to find some samples of btooth chat aplications but i'm not satisfied with it. Can you provide some help(i mean source code )? if i can help you with your problem i'll send you a solution.
Thank you

You better post your issue in new thread instead of trying to bargaining in style "give me what you have, maybe I will give you what I have.."

Just download the wirelesss development kit for java and, after you install it ouy'll find a folder with a lot of examples there. As for my problem, I abandoned L2CAP connection and used StreamConnection. Good Luck. In fact, this is an old unsolved thread.

Just download the wirelesss development kit for java and, after you install it ouy'll find a folder with a lot of examples there. As for my problem, I abandoned L2CAP connection and used StreamConnection. Good Luck. In fact, this is an old unsolved thread.

So on the end you went with my original suggestion :D

kind of... L2CAP connection is more reliable but I just can't make it work. Thanks :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.