📄 bluetooth.java
字号:
if( ! CONCEPT_SDK_BUILD )
{ // Does not work correctly in Concept SDK,
// but should be done in real phone to deregister service
notifier.close();
}
}
catch(Exception e)
{
ErrorMessage.append("Error trying to close notifier");
ErrorMessage.append(e.getMessage());
}
notifier = null;
}
}
}
/** Sets the local name that is used by the server/device (not the friendly name).
* This can freely be chosen, it could also be the friendly name of the device.
* @param ln Name to be used.
*/
public void setName( String ln )
{
// Store service name
localName = ln;
}
/** Sets the UUID for the service.
* A UUID is made of:
* x = random, b = BD address of one of my Bluetooth devices (because BD addresses are also unique)
* xxxx xxxx xxxx 1xxx 8xxx bbbbbbbbbbbb
* Eg. for my 3650 the BD address is 006057028C19. So I could invent a
* UUID equal to "00000000000010008000006057028C19".
* @param UUID UUID that shall be used.
*/
/***
public void setServiceUUID( String UUID )
{
// store UUID
serviceUUID = UUID;
// Because this is normally one of the first functions called,
// this notification is placed here
}
***/
/** Starts the server and register the service.
* Waits until someone connects to this service.
* @return A list containing 1 element which is the connection that has been
* created from a remote device to this device. In case there has been a connection error
* a list containing 1 element which is null is returned.
* @throws BluetoothStateException Is thrown when a request is made to the Bluetooth system that the system cannot support in its present state.
* @throws InterruptedException Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread.
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
*/
public BluetoothConnection[] waitOnConnection()
throws BluetoothStateException, IOException, InterruptedException
{
acceptAndOpenThread t;
String ServiceName;
//System.out.println("BTHere11");
// Save Discoverability Mode
saveDiscoverability();
//System.out.println("BTHere12");
// Go in Limited Inquiry scan mode
localDevice.setDiscoverable( DiscoveryAgent.LIAC );
//System.out.println("BTHere13");
// Call connector.open to create Notifier object
notifier = (StreamConnectionNotifier) Connector.open( "btspp://localhost:" + serviceUUID + ";name=" + localName + ";authorize=false;authenticate=false;encrypt=false" );
//System.out.println("BTHere14 ");
// Show text box with possibility to cancel the server session.
// setTitle( "Waiting" );
// setString( "Waiting for someone to connect..." );
// setTimeout( FOREVER );
// addCommand( new Command( "Cancel", Command.CANCEL, 1 ) );
// setCommandListener( this );
// display.setCurrent( this );
// Spawn new thread which does acceptandopen
t = new acceptAndOpenThread();
//System.out.println("BTHere15");
// wait on thread (until someone connects)
synchronized( block_s )
{
//System.out.println("BTHere16");
// Start acceptAndOpen
t.start();
//System.out.println("BTHere17");
// wait
block_s.wait();
//System.out.println("BTHere18");
}
//System.out.println("BTHere19");
// Clear Notifier (is already closed)
notifier = null;
// restore discoverability mode
restoreDiscoverability();
//System.out.println("BTHere20");
// return the connection
return btConnections;
}
/** Does an Inquiry followed by a service search.
* The user has (depending on parameter) the possibility to select one or more devices.
* The devices are connected and a list of connections is returned.
* @param st Defines the search type. Depending on the search type the user might have to
* select one or more found devices. Allowed values are: <br>
* {@link #SEARCH_CONNECT_FIRST_FOUND SEARCH_CONNECT_FIRST_FOUND},<br>
* {@link #SEARCH_CONNECT_ALL_FOUND SEARCH_CONNECT_ALL_FOUND},<br>
* {@link #SEARCH_ALL_DEVICES_SELECT_ONE SEARCH_ALL_DEVICES_SELECT_ONE}, and<br>
* {@link #SEARCH_ALL_DEVICES_SELECT_SEVERAL SEARCH_ALL_DEVICES_SELECT_SEVERAL}.
* @return Returns a list of connected devices.
* @throws BluetoothStateException Is thrown when a request is made to the Bluetooth system that the system cannot support in its present state.
* @throws InterruptedException Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread.
* @throws IOException Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
*/
public BluetoothConnection[] searchService( int st )
throws BluetoothStateException, InterruptedException, IOException
{
StreamConnection con;
DataElement de;
String rname;
// Reset search transaction id
serviceSearchTransId = -1;
// store search type
searchType = st;
if( searchType == SEARCH_ALL_DEVICES_SELECT_SEVERAL )
{ // if user should select several devices
if( maxDevices == 1 )
{ // but only point-to-point possible
// So switch back to "SELECT_ONE"
searchType = SEARCH_ALL_DEVICES_SELECT_ONE;
}
}
// Initialize
foundServiceRecords = new Vector();
urlStrings = new Vector();
// obtain discovery object which will be used for inquiry
discoveryAgent = localDevice.getDiscoveryAgent();
// Create Discovery Listener (Inquiry Listener) Object
listener = new Listener();
// Show progress bar for Inquiry
// progressBar = new InqProgressBar( "Search Devices...", 105 );
// Init warning string
warning = "";
// startInquiry is asynchronous. Here we have to wait until it "notify"s us.
synchronized( block_c )
{ // start the inquiry on LIAC only
discoveryAgent.startInquiry( DiscoveryAgent.LIAC, listener );
// wait
block_c.wait();
}
// Release List object
deviceList = null;
// Stop progress bar
// if( progressBar != null )
// {
// progressBar.stop();
// }
// Check if service or devices not found and alert to user
if( ! warning.equals( "" ) )
{ // Do 2 secs alert
// Alert al = new Alert( null, warning, null, AlertType.INFO );
// Show 2 seconds
// al.setTimeout( 2000 );
// display.setCurrent( al );
// wait
/**
synchronized( al )
{
try
{
al.wait( 2000 );
}
catch(InterruptedException e )
{
// Shouldn't happen in MIDP
}
}
**/
}
// Create list
btConnections = new BluetoothConnection[urlStrings.size()];
// Check if devices have been found
if( urlStrings.size() > 0 )
{ // connect only if devices have been found
// Start connection progress bar
// progressBar = new PageProgressBar( "Connecting...", urlStrings.size() );
// Connect all devices
for( int i=0; i<urlStrings.size(); i++ )
{ // Retrieve remote name
de = ((ServiceRecord)foundServiceRecords.elementAt(i)).getAttributeValue( SERVICE_NAME_BASE_LANGUAGE );
rname = (String) de.getValue();
// Update progress bar
// ((PageProgressBar)progressBar).nextDevice();
btConnections[i] = new BluetoothConnection( (String) urlStrings.elementAt(i), localName, rname );
// Send name to remote device
btConnections[i].writeString( localName );
}
// Stop (connecting) progress bar
// progressBar.stop();
}
// Delete progressBar
// progressBar = null;
// reset listener
listener = null;
return btConnections;
}
/**
* SaveDiscoverability
* Saves the current discoverability mode.
*/
private void saveDiscoverability()
{
try
{
// Store discoverability mode
previousDiscoverabilityMode =
LocalDevice.getLocalDevice().getDiscoverable();
}
catch(Exception e)
{
// We will just ignore, and not try to save it.
}
}
/**
* RestoreDiscoverability
* Restores the discoverability mode.
*/
private void restoreDiscoverability()
{
try
{ // Restore discoverability mode
if( previousDiscoverabilityMode != -1 )
{
localDevice.setDiscoverable( previousDiscoverabilityMode );
}
}
catch( Exception e )
{
// We will just ignore; there is not much we can do.
}
}
/** acceptAndOpenThread.
* This is needed as thread to allow cancellation from user interface.
* Thread just does an acceptAndOpen and waits until Exception is thrown
* eg. UI called Cancel or client connects.
* If a client connects a thread is started for that connection.
*/
private class acceptAndOpenThread
extends Thread
{
/**
* run method
* Start acceeptAndOpen and wait on Exception or connection.
*/
public void run()
{
//System.out.println("BTHere in ACCandOpen - run1");
StreamConnection con;
// Prepare data
btConnections = new BluetoothConnection[1];
// Register service
try
{
//System.out.println("BTHere in ACCandOpen - run2");
// Wait on client
con = (StreamConnection) notifier.acceptAndOpen();
//System.out.println("BTHere in ACCandOpen - run2-2");
btConnections[0] = new BluetoothConnection(con, localName, "Host");
//System.out.println("BTHere in ACCandOpen - run2-3");
// Read host name
String remoteName = btConnections[0].readString();
//System.out.println("BTHere in ACCandOpen - run2-4");
btConnections[0].setRemoteName( remoteName );
//System.out.println("BTHere in ACCandOpen - run3");
}
catch(Exception e)
{
// Accept and open terminated abnormally (maybe cancel)
btConnections[0] = null;
//System.out.println("BTHere in ACCandOpen - run4");
}
// Remove notifier
closeNotifier();
// wakeup
synchronized( block_s )
{
block_s.notifyAll();
}
//System.out.println("BTHere in ACCandOpen - run5");
}
}
// Inner class: Listener
// Listens on events like deviceDiscovered or servicesDiscovered.
private class Listener
implements DiscoveryListener
{
private Vector cached_devices;
ServiceRecord currServRec;
/** Constructor
*/
public Listener()
{
// Initialize
cached_devices = new Vector();
}
/**
* Called when a device is found during an inquiry. An inquiry
* searches for devices that are discoverable. The same device may
* be returned multiple times.
*
* @see DiscoveryAgent#startInquiry
*
* @param btDevice the device that was found during the inquiry
*
* @param cod the service classes, major device class, and minor
* device class of the remote device
*
*/
public void deviceDiscovered( RemoteDevice btDevice, DeviceClass cod )
{
// Filter CoD: Ie. only store devices in case the device is
// a phone. That also prevents from the link level security problem:
// Phone's do not use link level security.
// (Because LIAC has been used for inquiry it is anyway very unlikely
// that we run into the link level security problem.)
if( ! CONCEPT_SDK_BUILD )
{ // Concept SDK returns wrong values for CoD
if( cod.getMajorDeviceClass() != MAJOR_DEVICE_CLASS_PHONE )
{ // return in case it's not a phone
return;
}
}
// It's another phone, so store it in the list
if( ! cached_devices.contains( btDevice ) )
{ // But only if it is not already in the list (same device might be reported more than once)
cached_devices.addElement( btDevice );
}
}
/**
* Called when an inquiry is completed. The <code>discType</code> will be
* <code>INQUIRY_COMPLETED</code> if the inquiry ended normally or
* <code>INQUIRY_TERMINATED</code> if the inquiry was canceled by a call to
* <code>DiscoveryAgent.cancelInquiry()</code>. The <code>discType</code>
* will be <code>INQUIRY_ERROR</code> if an error occurred while
* processing the inquiry causing the inquiry to end abnormally.
*
* @see #INQUIRY_COMPLETED
* @see #INQUIRY_TERMINATED
* @see #INQUIRY_ERROR
*
* @param discType the type of request that was completed; either
* <code>INQUIRY_COMPLETED</code>, <code>INQUIRY_TERMINATED</code>, or
* <code>INQUIRY_ERROR</code>
*/
public void inquiryCompleted( int discType )
{
if( discType == INQUIRY_COMPLETED )
{ // Check if devices have been found
if( cached_devices.size() == 0 )
{ // No device found
warning = "No devices found!";
}
else
{ // Stop Inquiry progress bar
// progressBar.stop();
// Start service search progress bar
// progressBar = new PageProgressBar( "Search Service...", cached_devices.size() );
// start service search
nextDeviceServiceSearch();
return;
}
}
// In case inquiry was terminated or no device has been found
// then return to main function
synchronized( block_c )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -