Phone Midlet

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

Phone Midlet

Postby hassenplug » Mon Mar 03, 2008 7:48 pm

Has anyone posted code for a phone midlet? I searched the forum, and have not found any. (sorry if I'm missing it)

Thanks
Steve
hassenplug
New User
 
Posts: 2
Joined: Mon Mar 03, 2008 7:43 pm

Postby lawrie » Thu Mar 06, 2008 4:04 pm

Here is some code for a very simple phone midlet that I posted a while ago:

Code: Select all
import java.util.Vector;
import javax.bluetooth.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.io.*;
import java.io.IOException;
import java.io.*;


public class BlueDisc extends MIDlet implements CommandListener,
DiscoveryListener {

private LocalDevice local = null;
private DiscoveryAgent agent = null;

private Vector devicesFound = null;
private ServiceRecord[] servicesFound = null;
private Alert a;
StreamConnection con;

public void startApp() {

/* Add your MIDlet specific code here.
* You probably want to show the user
* a welcome screen.
* The call to doDeviceDiscovery() is
* here for the example's sake. You
* should call doDeviceDiscovery() when
* the user actively asks for it.
*/

//infoAlert("Discovering Services");

doDeviceDiscovery();
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void commandAction(Command c, Displayable d) {

}

private void infoAlert(String msg) {
a = new Alert("Info",msg, null, AlertType.INFO);
a.setTimeout(Alert.FOREVER);
Display.getDisplay(this).setCurrent(a);
}


public void deviceDiscovered(RemoteDevice remoteDevice,
DeviceClass deviceClass) {

infoAlert("Device discovered: " + deviceClass.getMajorDeviceClass());

devicesFound.addElement(remoteDevice);
}

public void inquiryCompleted(int param) {

/*We should give the user an alert based on the
*inquiry status code
*/

// infoAlert("Inquiry Completed");

switch (param) {

case DiscoveryListener.INQUIRY_COMPLETED:

//Inquiry completed normally, add appropriate code here

// infoAlert("Inquiry Completed Normally");

for(int i=0;i<devicesFound.size();i++) {

RemoteDevice rd = (RemoteDevice) devicesFound.elementAt(i);

//try {
//infoAlert("Searching for " + rd.getFriendlyName(false));
//} catch (IOException ioe) {}

doServiceSearch(rd);
}

break;

case DiscoveryListener.INQUIRY_ERROR:

//Error during inquiry, add appropriate code here

infoAlert("Inquiry Completed with error");

break;

case DiscoveryListener.INQUIRY_TERMINATED:

/*
* Inquiry terminated, caused by agent.cancelInquiry()
* Add appropriate code here
*/

infoAlert("Inquiry Terminated");

break;
}
}

public void serviceSearchCompleted(int transID, int respCode) {

switch(respCode) {

case DiscoveryListener.SERVICE_SEARCH_COMPLETED:

/*
* Service search completed successfully
* Add appropriate code here
*/

//infoAlert("Service completed OK");

break;

case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:

// device not reachable, add appropriate code here

infoAlert("Device not reachable");

break;

case DiscoveryListener.SERVICE_SEARCH_ERROR:

// Error during service search, add appropriate code here

infoAlert("Service Search Error");

break;

case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:

// No records found, add appropriate code here

infoAlert("No Services");

break;

case DiscoveryListener.SERVICE_SEARCH_TERMINATED:

/*
* Search terminated, caused by agent.cancelServiceSearch(..)
* Add appropriate code here
*/

infoAlert("Service Search Terminated");

break;
}

}

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

//Services discovered, keep a reference to the ServiceRecord array

//infoAlert("Services Discovered");

servicesFound = serviceRecord;

String url = serviceRecord[0].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);

//infoAlert(url);

try{

byte[] b = new byte[4];
byte[] r = new byte[7];

b[0] = 2;
b[1] = 0;
b[2] = 0;
b[3] = 0x0B;


con = (StreamConnection) Connector.open(url);


OutputStream os = con.openOutputStream();
os.write(b);
os.flush();

InputStream is = con.openInputStream();
is.read(r);

infoAlert("Battery: " + ((r[5] & 0xFF) + ((r[6] & 0xFF) << 8)));

is.close();
os.close();

}
catch(IOException e){
infoAlert("" + e.getMessage());
}

}

private void doDeviceDiscovery() {

try {
local = LocalDevice.getLocalDevice();
}catch (BluetoothStateException bse) {

// Error handling code here

infoAlert("No local device");
}

agent = local.getDiscoveryAgent();

// infoAlert((agent == null ? "No agent" : "Got agent"));

devicesFound = new Vector();

try {

if(!agent.startInquiry(DiscoveryAgent.GIAC,this)) {

//Inquiry not started, error handling code here

infoAlert("Inqiry not started");
}
}catch(BluetoothStateException bse) {

//Error handling code here

infoAlert("Inquiry Exception");
}
}

private void doServiceSearch(RemoteDevice device) {

/*
* Service search will always give the default attributes:
* ServiceRecordHandle (0x0000), ServiceClassIDList (0x0001),
* ServiceRecordState (0x0002), ServiceID (0x0003) and
* ProtocolDescriptorList (0x004).
*
* We want additional attributes, ServiceName (0x100),
* ServiceDescription (0x101) and ProviderName (0x102).
*
* These hex-values must be supplied through an int array
*/

int[] attributes = {0x100,0x101,0x102};

/*
* Supplying UUIDs in an UUID array enables searching for specific
* services. PublicBrowseRoot (0x1002) is used in this example. This
* will return any services that are public browsable. When searching
* for a specific service, the service's UUID should be supplied here.
*/

UUID[] uuids = new UUID[1];
//uuids[0] = new UUID(0x1002);
uuids[0] = new UUID("1101",true); // Serial Port

try {
agent.searchServices(attributes,uuids,device,this);
} catch (BluetoothStateException e) {

infoAlert("Service Search Exception");

infoAlert( "" + e);
// Error handling code here
}
}
}
lawrie
leJOS Team Member
 
Posts: 922
Joined: Mon Feb 05, 2007 1:27 pm

Postby bbagnall » Thu Mar 06, 2008 8:52 pm

Hey Steve, I was wondering if anyone in the LEGO community had any ideas for a mobile phone API? It seems like people generally want to use their cell phone as a remote control. If appropriate, it would be nice to have some sort of easy to use API for this so users could jump right in with mobile phone development.

I'm not too familiar with mobile phone MIDLETs, but I assume you would need to write a highly custom MIDLET on the cell phone which might make an API sort of moot.
User avatar
bbagnall
Site Admin
 
Posts: 392
Joined: Fri Aug 04, 2006 4:03 pm

Postby hassenplug » Fri Mar 07, 2008 4:46 am

Thanks for the code, lawrie

bbagnall wrote:I'm not too familiar with mobile phone MIDLETs, but I assume you would need to write a highly custom MIDLET on the cell phone which might make an API sort of moot.


Personally, I'd be as interested in a well-documented example (see above). :)

I'm actually not sure what functionality I'm looking for, so I don't really know what the API should do.

Steve
hassenplug
New User
 
Posts: 2
Joined: Mon Mar 03, 2008 7:43 pm

Postby bbagnall » Sun Mar 09, 2008 5:14 pm

The example above runs on your mobile phone. You wouldn't have to run anything on the NXT brick since it's using LCP, so either standard LEGO firmware or leJOS NXJ firmware will work (sitting at the main menu).
User avatar
bbagnall
Site Admin
 
Posts: 392
Joined: Fri Aug 04, 2006 4:03 pm

Postby peg » Wed Dec 03, 2008 2:16 pm

Hello everyone!

I'm trying to modify lawrie's example to work with something very similar to the BTReceive example but i ran into some trouble.

Here's the code on my NXT:

Code: Select all
*snip*
      BTConnection btc = Bluetooth.waitForConnection();
      btc.setIOMode(0);
      
      input  = btc.openDataInputStream();
      output = btc.openDataOutputStream();

      System.out.println(">bt connected");

      while( true )
      {
         try
         {
            if( input.available() > 0)
            {
               byte b = input.readByte();
               System.out.println(">bt: " + Message.getSpelling(b));
               publish(b);               
            }
         }
*snap*


And the important part from my midlet:

Code: Select all
*snip*
   /**
    * Start the service search for a specified device.
    */
   public void doServiceSearch(RemoteDevice device)
   {
      UUID [] uuid = new UUID[1];
      uuid[0]      = new UUID("1101", true);
      int[] attributes = {0x100,0x101,0x102};

      try
      {
         agent.searchServices(attributes, uuid, device, this);
      }
      catch (BluetoothStateException e)
      {
         e.printStackTrace();
      }
   }

   /**
    * Called if a service is discovered.
    */
   public void servicesDiscovered(int transID, ServiceRecord[] record)
   {
      service = record;
   }

   /**
    * Called if the service search is completed.
    * Creates a connection to the service of the device,if the service search was successful.
    * Otherwise it will be create an error message for the user.
    */
   public void serviceSearchCompleted(int tID, int responseCode)
   {
      switch (responseCode)
      {
         case DiscoveryListener.SERVICE_SEARCH_COMPLETED:

            String url = service[0].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
            try
            {
               connection = (StreamConnection) Connector.open(url);
               outStream = connection.openDataOutputStream();
               int i = 0;
               while (i < 10)
               {
                  outStream.write(Message.FORWARD);
                  i++;
               }               
               outStream.flush();
            }
            catch (Exception e)
            {
               e.printStackTrace();
               NXTMIDlet.infoScreen("Connection to service failed");
            }
            break;
         case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
            NXTMIDlet.infoScreen("Device not reachable");
            break;
         case DiscoveryListener.SERVICE_SEARCH_ERROR:
            NXTMIDlet.infoScreen("Service Search Error");
            break;
         case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
            NXTMIDlet.infoScreen("No Services");
            break;
         case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
            NXTMIDlet.infoScreen("Service Search Terminated");
            break;
      }
*snap*


The midlet seems to connect to the NXT just fine because it outputs ">bt connected" - the problem is that it doesn't seem to be able to read the 10 bytes i send though no exception is thrown on the midlet-side.

Any hints?
peg
New User
 
Posts: 5
Joined: Wed Nov 19, 2008 5:28 pm

Postby gloomyandy » Wed Dec 03, 2008 3:04 pm

I assume that whatever "publish" does it will end with a flush on the output stream?


One other note in general it is not a good idea to rely on available() in this way. It will work on the nxt but it will not work with the PC side leJOS classes...

See my post in these threads for some of the gory details....

http://lejos.sourceforge.net/forum/viewtopic.php?t=1165&highlight=available
http://lejos.sourceforge.net/forum/viewtopic.php?t=1066&highlight=available

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4119
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby peg » Wed Dec 03, 2008 3:12 pm

I'm using the publisher/subscriber pattern on my brick and the class that handles all the BT stuff is a publisher.
publish() should simply relays the received byte to all subscribers.
peg
New User
 
Posts: 5
Joined: Wed Nov 19, 2008 5:28 pm

Postby gloomyandy » Wed Dec 03, 2008 3:37 pm

What version of leJOS are you using? The arguments to setIOMode changed in 0.7, to bring Bluetooth and USB into line... You should probably either change the call to be....
Code: Select all
btc.setIOMode(NXTConnection.RAW);


or probably better still delete the setIOMode call and change waitForConnection to...
Code: Select all
Bluetooth.waitForConnection(0, NXTConnection.RAW);


The zero in the above is a timeout value (which in this case means wait for ever), you may want to change that....

Andy

PS If you are not using 0.7 then you probably need to tell us more about what is happening...
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4119
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby lawrie » Wed Dec 03, 2008 5:43 pm

What you are doing looks like it ought to work. Are you using version 0.7?
lawrie
leJOS Team Member
 
Posts: 922
Joined: Mon Feb 05, 2007 1:27 pm

Postby gloomyandy » Wed Dec 03, 2008 5:51 pm

PS I should have added that if you are using 0.7 the setIOMOde(0) will definitely not do the same as it did, in 0.6. In 0.6 that would in effect set the connection into RAW mode (no packet headers), in 0.7 that sets the default (Lego compatible) mode for that transport (which in the case of Bluetooth is to have 2 byte packet headers). Since your phone is unlikely to be sending these headers it is likely that this is causing the problem....
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4119
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby peg » Wed Dec 03, 2008 9:09 pm

The problem was indeed the (missing) header, fixed by using NXTConnection.RAW. Thanks for your help! :)
peg
New User
 
Posts: 5
Joined: Wed Nov 19, 2008 5:28 pm

Postby LudDjur » Tue Jan 20, 2009 11:03 pm

Hi,

im new in this forum. I try to do the same as peg but I'm having problems running his code.

At first: he is Using a Message.Forward static attribute where is the Message "Object"? Which package should be imported / how should the Message class look like.

@ peg: would it be possible to see your complete code?

thanks
LudDjur
New User
 
Posts: 2
Joined: Tue Jan 20, 2009 10:56 pm
Location: Germany

Postby LudDjur » Wed Jan 21, 2009 12:04 am

hello, its me again ;)

after 2 hours of debugging i got it run ... have to check if the right data arrives

the NXJ Console Viewer doesnt work properly so i have to find any workaround
LudDjur
New User
 
Posts: 2
Joined: Tue Jan 20, 2009 10:56 pm
Location: Germany

Postby gloomyandy » Wed Jan 21, 2009 12:21 am

I've never seen any problem with the console viewer, so what is happening for you...

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4119
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Next

Return to NXJ Software

Who is online

Users browsing this forum: Google [Bot] and 2 guests

more stuff