Selasa, 22 Mei 2012

Membuat Bluetooth Chat dengan J2ME NetBeans


Bluetooth Chat dengan J2ME NetBeans
Untuk membuat aplikasi Bluetooth Chat di Java ME NetBeans dapat digunakan library import javax.microedition.io.*. Langkah-langkah pembuatannya sebagai berikut :

1. Buka Netbeans. Klik menu File-New Project. Pilih Categories : Java ME, Projects : Mobile Application. Klik Next. Pada dialog berikutnya, isikan Project Name : BlueChat. Kemudian cek Set As Main Project dan hilangkan cek pada Create Hello Midlet. Klik Next. Klik Next. Klik Finish.


2. Pada Project TreeView klik kanan, pilih New –Midlet. Kemudian akan muncul dialog, isikan Class Name : ChatController, package : my.blue. Klik Finish. Akan ditampilkan MIDlet kosong, isikan kode program berikut ini :

package my.blue;

import java.util.Vector;

import java.io.IOException;

import javax.microedition.io.Connector;
import javax.microedition.io.ConnectionNotFoundException;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Choice;

import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DataElement;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.UUID;

import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.L2CAPConnectionNotifier;
import javax.bluetooth.L2CAPConnection;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.BluetoothConnectionException;
import javax.bluetooth.ServiceRegistrationException;

public class ChatController extends MIDlet implements CommandListener
{
 private Display display = null;
 private Form mainForm = null;
 private ChoiceGroup devices = null;
 private TextField inTxt = null;
 private TextField outTxt = null;
 private Command exit = null;
 private Command start = null;
 private Command connect = null;
 private Command send = null;
 private Command select = null;
 private StringItem status = null;

 private LocalDevice local = null;
 private RemoteDevice rDevices[];
 private ServiceRecord service = null;
 private DiscoveryAgent agent = null;
 private L2CAPConnectionNotifier notifier;
 private L2CAPConnection connection = null;

 private static final String UUID_STRING = "112233445566778899AABBCCDDEEFF";

 private boolean running = false;

 public ChatController()
      {
     super();
     display = Display.getDisplay(this);
       mainForm = new Form("CHAT");
       devices = new ChoiceGroup(null,Choice.EXCLUSIVE);
       inTxt = new TextField("incoming msg:","",256,TextField.ANY);
       outTxt = new TextField("outgoing msg:","",256,TextField.ANY);
       exit = new Command("EXIT",Command.EXIT,1);
       start = new Command("START",Command.SCREEN,2);
       connect = new Command("CONNECT",Command.SCREEN,2);
       send = new Command("SEND",Command.SCREEN,2);
       select = new Command("SELECT",Command.SCREEN,2);
       status = new StringItem("status : ",null);
       mainForm.append(status);
       mainForm.addCommand(exit);
       mainForm.setCommandListener(this);
      }


 protected void startApp() throws MIDletStateChangeException
      {
     running = true;
       mainForm.addCommand(start);
     mainForm.addCommand(connect);
       display.setCurrent(mainForm);
     try
       {
        local = LocalDevice.getLocalDevice();
          agent = local.getDiscoveryAgent();
       }
     catch(BluetoothStateException bse)
       {
        status.setText("BluetoothStateException unable to start:"+bse.getMessage());
            try
              {
               Thread.sleep(1000);
            }
            catch(InterruptedException ie)
              {}
        notifyDestroyed();
       }
    }

 protected void pauseApp()
      {
     running = false;
       releaseResources();
      }

 protected void destroyApp(boolean uncond) throws MIDletStateChangeException
      {
     running = false;
       releaseResources();
    }

 public void commandAction(Command cmd,Displayable disp)
      {
     if(cmd==exit)
            {
           running = false;
             releaseResources();
             notifyDestroyed();
          }
     else if(cmd==start)
               {
              new Thread()
                     {
                      public void run()
                           {
                            startServer();
                           }
                     }.start();
               }
          else if(cmd==connect)
                     {
                      status.setText("searching for devices...");
                          mainForm.removeCommand(connect);
                          mainForm.removeCommand(start);
                          mainForm.append(devices);

                          DeviceDiscoverer discoverer = new DeviceDiscoverer(ChatController.this);
                          try
                             {
                                agent.startInquiry(DiscoveryAgent.GIAC,discoverer);
                             }

                          catch(IllegalArgumentException iae)
                             {
                      status.setText("BluetoothStateException :"+iae.getMessage());
                             }
                          catch(NullPointerException npe)
                             {
                      status.setText("BluetoothStateException :"+npe.getMessage());
                             }
                          catch(BluetoothStateException bse1)
                             {
                      status.setText("BluetoothStateException :"+bse1.getMessage());
                             }
                  }
                else if(cmd==select)
                          {
                               status.setText("searching devices for service...");
                                 int index = devices.getSelectedIndex();
                                 mainForm.delete(mainForm.size()-1);//deletes choiceGroup
                                 mainForm.removeCommand(select);

                                 ServiceDiscoverer serviceDListener = new ServiceDiscoverer(ChatController.this);
                                 int attrSet[] = {0x0100}; //returns service name attribute
                       UUID[] uuidSet = {new UUID(UUID_STRING,false)};

                                 try
                                    {
                                       agent.searchServices(attrSet,uuidSet,rDevices[index],serviceDListener);
                                    }
                                  catch(IllegalArgumentException iae1)
                                  {
                           status.setText("BluetoothStateException :"+iae1.getMessage());
                                  }
                                catch(NullPointerException npe1)
                                  {
                           status.setText("BluetoothStateException :"+npe1.getMessage());
                                  }
                                catch(BluetoothStateException bse11)
                                  {
                           status.setText("BluetoothStateException :"+bse11.getMessage());
                                  }
                               }
                      else if(cmd==send)
                                 {
                                        new Thread()
                                                 {
                                                public void run()
                                                       {
                                                      sendMessage();
                                                     }
                                               }.start();
                                           }

       }

//this method is called from DeviceDiscoverer when device inquiry finishes
 public void deviceInquiryFinished(RemoteDevice[] rDevices,String message)
      {
     this.rDevices = rDevices;
       String deviceNames[] = new String[rDevices.length];
       for(int k=0;k<rDevices.length;k++)
            {
           try
             {
           deviceNames[k] = rDevices[k].getFriendlyName(false);
             }
           catch(IOException ioe)
             {
              status.setText("IOException :"+ioe.getMessage());
               }
          }
     for(int l=0;l<deviceNames.length;l++)
            {
           devices.append(deviceNames[l],null);
          }
     mainForm.addCommand(select);
       status.setText(message);
    }

//called by ServiceDiscoverer when service search gets completed
 public void serviceSearchFinished(ServiceRecord service,String message)
      {
       String url = "";
     this.service = service;
       status.setText(message);
       try
         {
          url = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT,false);
         }
       catch (IllegalArgumentException iae1)
         {}
     try
       {
     connection = (L2CAPConnection)Connector.open(url);
            status.setText("connected...");
            new Thread()
               {
                public void run()
                     {
                      startReciever();
                     }
               }.start();
       }
     catch(IOException ioe1)
       {
        status.setText("IOException :"+ioe1.getMessage());
       }
      }

 // this method starts L2CAPConnection chat server from server mode
 public void startServer()
      {
     status.setText("server starting...");
       mainForm.removeCommand(connect);
       mainForm.removeCommand(start);
       try
         {
            local.setDiscoverable(DiscoveryAgent.GIAC);

            notifier = (L2CAPConnectionNotifier)Connector.open("btl2cap://localhost:"+UUID_STRING+";name=L2CAPChat");

            ServiceRecord record = local.getRecord(notifier);
            String conURL = record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT,false);
            status.setText("server running...");

            connection = notifier.acceptAndOpen();
            new Thread()
               {
                public void run()
                     {
                      startReciever();
                     }
               }.start();
         }
       catch(IOException ioe3)
         {
        status.setText("IOException :"+ioe3.getMessage());
         }
    }

 //starts a message reciever listening for incomming message
 public void startReciever()
      {
     mainForm.addCommand(send);
     mainForm.append(inTxt);
       mainForm.append(outTxt);
       while(running)
            {
           try
              {
            if(connection.ready())
                        {
                       int receiveMTU = connection.getReceiveMTU();
                         byte[] data = new byte[receiveMTU];
                         int length = connection.receive(data);

                         String message = new String(data,0,length);
                         inTxt.setString(message);
                      }
              }
           catch(IOException ioe4)
              {
              status.setText("IOException :"+ioe4.getMessage());
                  }
          }
     }

 //sends a message over L2CAP
 public void sendMessage()
      {
     try
       {
     String message = outTxt.getString();
            byte[] data = message.getBytes();
            int transmitMTU = connection.getTransmitMTU();
            if(data.length <= transmitMTU)
             {
              connection.send(data);
             }
        else
             {
              status.setText("message ....");
             }
       }
     catch (IOException ioe5)
       {
        status.setText("IOException :"+ioe5.getMessage());
       }
    }

 //closes L2CAP connection
 public void releaseResources()
      {
     try
       {
     if(connection != null)
                  connection.close();
            if(notifier != null)
                   notifier.close();
       }
     catch(IOException ioe6)
       {
        status.setText("IOException :"+ioe6.getMessage());
         }
    }
}

3. Pada Project TreeView klik kanan, pilih New –Midlet. Kemudian akan muncul dialog, isikan Class Name : DeviceDiscoverer, package : my.blue. Klik Finish. Akan ditampilkan MIDlet kosong, isikan kode program berikut ini :

package my.blue;

import java.util.Vector;

import javax.bluetooth.RemoteDevice;
import javax.bluetooth.DeviceClass;

import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.ServiceRecord;

public class DeviceDiscoverer implements DiscoveryListener
{
 private ChatController controller = null;
 private Vector devices = null;
 private RemoteDevice[] rDevices = null;

 public DeviceDiscoverer(ChatController controller)
      {
     super();
     this.controller = controller;
       devices = new Vector();
      }

 public void deviceDiscovered(RemoteDevice remote,DeviceClass dClass)
      {
     devices.addElement(remote);
      }

 public void inquiryCompleted(int descType)
      {
       String message = "";

     switch(descType)
            {
           case DiscoveryListener.INQUIRY_COMPLETED:
                       message = "INQUIRY_COMPLETED";
                     break;
           case DiscoveryListener.INQUIRY_TERMINATED:
                       message = "INQUIRY_TERMINATED";
                     break;
           case DiscoveryListener.INQUIRY_ERROR:
                       message = "INQUIRY_ERROR";
                     break;
          }

      rDevices = new RemoteDevice[devices.size()];
        for(int i=0;i<devices.size();i++)
             rDevices[i] = (RemoteDevice)devices.elementAt(i);

        controller.deviceInquiryFinished(rDevices,message);//call of a method from ChatController class
        devices.removeAllElements();

        controller = null;
      devices = null;
      }

 public void servicesDiscovered(int transId,ServiceRecord[] services)
      {}

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

}

4. Pada Project TreeView klik kanan, pilih New –Midlet. Kemudian akan muncul dialog, isikan Class Name : ServiceDiscoverer, package : my.blue. Klik Finish. Akan ditampilkan MIDlet kosong, isikan kode program berikut ini : 

package my.blue;

import javax.bluetooth.RemoteDevice;
import javax.bluetooth.DataElement;
import javax.bluetooth.DeviceClass;

import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.ServiceRecord;

public class ServiceDiscoverer implements DiscoveryListener
{
 private static final String SERVICE_NAME = "L2CAPChat";
 private ChatController controller = null;
 private ServiceRecord service = null;

 public ServiceDiscoverer(ChatController controller)
      {
     super();
       this.controller = controller;
      }

 public void deviceDiscovered(RemoteDevice remote,DeviceClass dClass)
      {}

 public void inquiryCompleted(int descType)
      {}

 public void servicesDiscovered(int transId,ServiceRecord[] services)
      {
     for(int j=0;j<services.length;j++)
            {
           DataElement dataElementName = services[j].getAttributeValue(0x0100);

             String serviceName = (String)dataElementName.getValue();

             if(serviceName.equals(SERVICE_NAME))
                           service = services[j];

             break;
          }
      }

 public void serviceSearchCompleted(int transId,int respCode)
      {
     String message = "";

       switch(respCode)
            {
           case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
                         message = "SERVICE_SEARCH_COMPLETED";
                       break;
           case DiscoveryListener.SERVICE_SEARCH_ERROR:
                         message = "SERVICE_SEARCH_ERROR";
                       break;
           case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
                         message = "SERVICE_SEARCH_TERMINATED";
                       break;
           case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
                         message = "SERVICE_SEARCH_NO_RECORDS";
                       break;
           case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
                         message = "SERVICE_SEARCH_DEVICE_NOT_REACHABLE";
                       break;
          }

       controller.serviceSearchFinished(service,message);//calling a method from ChatController class

     controller = null;
       service = null;
      }
}

5. Klik Run untuk menjalankan aplikasi. Kemudian sebagai client Klik Run lagi untuk menjalankan aplikasi kedua. Kemudian coba aplikasi Bluetooth Chat untuk berkomunikasi antar keduanya :