【实例简介】
android蓝牙串口的官方资料,从GOOGLE网站上打印下来的,格式还行。本人觉得是开发蓝牙最佳的参考资料。
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topicswirclcss/bluct
Before your application can communicate over Bluetooth, you need to verify
that bluetooth is supported on the device, and if so, ensure that it is enabled
Bluetooth permission
If Bluetooth is not supported, then you should gracefully disable any Bluetooth
request
features. If Bluetooth is supported, but disabled, then you can request that the
An application on your phone
user enable bluetooth without leaving your application. This setup is
is requesting permission to
accomplished in two steps, using the bluctoothAdapter
turn on Bluetooth, Do you
want to do this?
1. Get the BluetoothAdapter
Yes
The bluetoothAdapter is required for any and all bluetooth activity. To get
the BluetoothAdapter, call the static get aDapter method. this
returns a Blue loothAdipler that represents the device's own bluetooth
The enabling Bluetooth
adapter(the Bluetooth radio). There's one bluetooth adapter for the entire
balog
system, and your application can interact with it using this object. If
get DefaultAdapter( returns null, then the device does not support Bluetooth and your story ends here. For
example:
BluetoothAdapter mBluetoothAdapter= BluetoothAdapter get DefaultAdapter(
if (mBluetoothAdapter = null
Device does not support Bluetooth
2. Enable bluetooth
Next, you need to ensure that Bluetooth is enabled. Call isLinabled( to check whether Bluetooth is currently
enable. If this method returns false, then bluetooth is disabled. To request that bluetooth be enabled, call
startActivityForResult( with the ACTION REQUEST ENABLE action Intent. This will issue a request to enable
Bluetooth through the system settings (without stopping your application For example
f(!mBluetoothAdapter isEnabled()i
Intent enablebtIntent new Intent(BluetoothAdapter ACTION REQUEST ENABLE)
startActivitylorResult(enableBtIntent, REQUEST ENABLE BT)
a dialog will appear requesting user permission to enable bluetooth, as shown in Figure 1. If the user responds
Yes, the system will begin to enable Bluetooth and focus will return to your application once the process
completes(or fails)
The REQUEST_ENABLE BT constant passed to startActivityForResulto is a locally defined integer(which must be
greater than 0), that the system passes back to you in your onActivityResult( implementation as the
requestCode parameter.
If enabling Bluetooth succeeds, your activity receives the RESUl T__ OK result code in the onActivityResulto
callback. If Bluetooth was not enabled due to an error (or the user responded"No")then the result code is
RESULT CA、 CELED
Optionally, your application can also listen for the ACTION STATE CHANGED broadcast Intent, which the system will
broadcast whenever the bluetooth state has changed. This broadcast contains the extra fields EXTRA STATE and
EXTRA PREVIOUS STATE, containing the new and old Bluetooth states, respectively. Possible values for these extra fields
are STATE TURNING ON, STATE ON, STATE TURVING OFE, and STATE OFF. Listening for this broadcast can be useful to
detect changes made to the bluetooth state while your app is running
Enabling discoverability will automatically enable bluetooth If you plan to consistently enable device
discoverability before performing Bluetooth activity, you can skip step 2 above. Read about enabling
discoverability below
2012-5-15
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topicswirclcss/bluct
Using the BluetoothAdapter, you can find remote Bluetooth devices either through device discovery or by querying the
list of paired(bonded)devices
Device discovery is a scanning procedure that searches the local area for bluetooth enabled devices and then
requesting some information about each one(this is sometimes referred to as"discovering ""inquiring"or"scanning")
However, a Bluetooth device within the local area will respond to a discovery request only if it is currently enabled to be
discoverable. If a device is discoverable, it will respond to the discovery request by sharing some information, such as
the device name, class, and its unique MAC address. Using this information, the device performing discovery can then
choose to initiate a connection to the discovered device
Once a connection is made with a remote device for the first time, a pairing request is automatically presented to the
user. When a device is paired, the basic information about that device(such as the device name, class, and mAc
address)is saved and can be read using the Bluetooth APls. Using the known MAc address for a remote device,a
connection can be initiated with it at any time without performing discovery(assuming the device is within range)
Remember there is a difference between being paired and being connected. To be paired means that two devices are
aware of each other's existence, have a shared link-key that can be used for authentication and are capable of
establishing an encrypted connection with each other. To be connected means that the devices currently share an
RFCOMM channel and are able to transmit data with each other. The current Android Bluetooth API's require devices
to be paired before an RFCOMM connection can be established. (Pairing is automatically performed when you initiate
an encrypted connection with the Bluetooth APIs)
The following sections describe how to find devices that have been paired, or discover new devices using device
discovery
Android-powered devices are not discoverable by default. a user can make the device discoverable for a
limited time through the system settings, or an application can request that the user enable discoverability without
leaving the application How to enable discoverability is discussed below
Before performing device discovery, its worth querying the set of paired devices to see if the desired device is already
known. To do so, call ge LBondedDevices (. This will return a Set of Blue loo thDev ices representing paired devices. For
example, you can query all paired devices and then show the name of each device to the user, using an Array Adapter
Set pairedDevices=mBluetoothAdapter. getBondedDevices(:
// If therc arc paired devices
if ( paircddcviccs sizc()>0)f
// Loop through paired devices
for (BluetoothDevice dcvicc: paircdDoviccs)
Add the namc and address to an array adaptor to show in a Listric
mArrayAdaptcr. add(dcvicc gctNamc()+\n"+ dcvicc gctAddrcss()
All that' s needed from the bluetoothDevice object in order to initiate a connection is the MAc address. In this example
it's saved as a part of an Array Adapter that's show n to the user. The Mac address can later be extracted in order to
initiate the connection. You can learn more about creating a connection in the section about Connecting Devices
To start discovering devices, simply call startDiscovery O. The process is asynchronous and the method will
immediately return with a boolean indicating whether discovery has successfully started. The discovery process usually
involves an inquiry scan of about 12 seconds, followed by a page scan of each found device to retrieve its bluetooth
name
Your application must register a broadcastReceiver for the ActioN_ FOUND Intent in order to receive information about
2012-5-15
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topicswirclcss/bluct
each device discovered. For each device, the system will broadcast the ACTION FOUND Intent. This Intent carries the
extra fields EXTRA DEVICE and EXTRA CLASS, containing a BluetoothDevice and a bluetoothclas s, respectively. For
example, here's how you can register to handle the broadcast w hen devices are discovered
Create a BroadcastReceiver for ACTION FOUND
private final BroadcastReceiver mReceiver new BroadcastReceiver(
public void on Receive( Context context, Intent intent)
String action intent getAction()
When discovery finds a device
if(BluetoothDevice ACTION FOUND, equals(action))
Get the bluetoothDevice ob iect from the intent
BluetoothDevice device intent getParcelableExtra(bluetoothDevice EXTRA DEVICE
Add the name and address to an array adapter to show in a Listview
mArray Adapter. add (device getName()+n"+ device. getAddress()
l Register the BroadcastReceiver
IntentFilter filter= new IntentFilter(BluetoothDevice ACTION FOUND)
register Receiver(mReceiver, filter);// Doit forget to unregister during onDestroy
All that's needed from the bluctoothDevicc object in order to initiate a connection is the MAc address. In this example.
it's saved as a part of an Array Adapter that's shown to the user. The MAC address can later be extracted in order to
initiate the connection. You can learn more about creating a connection in the section about Connecting Devices
Performing device discovery is a heavy procedure for the bluetooth adapter and will consume a lot of
its resources. Once you have found a device to connect, be certain that you always stop discovery with
cancelDiscoveryo before attempting a connection Also, if you already hold a connection with a device, then
performing discovery can significantly reduce the bandwidth available for the connection, so you should not
perform discovery while connected
If you would like to make the local device discoverable to other devices, call startActivityForRcsult(Intent, int)
with the ACTTON REQUEST DISCOVERABLE action Intent. This will issue a request to enable discoverable mode through the
system settings(without stopping your application). By default, the device will become discoverable for 120 seconds
You can define a different duration by adding the EXTRA DISCOVERABLE DURATION Intent extra. the maximum duration an
app can set is 3600 seconds, and a value of 0 means the device is always discoverable. Any value below 0 or above
3600 is automatically set to 120 secs). For example, this snippet sets the duration to 300
Intent discoverableIntent new
Intent (BluetoothAdapter ACTION REQUEST DISCOVERABLE)
discoverableIntent. put Extra(bluetoothAdapter EXTRA DISCOVERABLE DURATION, 300
startActivity(discoverableIntent
A dialog will be displayed, requesting user permission to make the device
discoverable, as shown in Figure 2. If the user responds Yes, then the
device will become discoverable for the specified amount of time. Your activity
Bluetooth permission
request
will then receive a call to the inactivity resulto) callback with the result
code equal to the duration that the device is discoverable. if the user
An application on your phone
responded"No"or if an error occurred, the result code will be
is requesting permission to
turn on Bluetooth and to
RESULT CANCELED
make your phone
discoverable by other devices
If Bluetooth has not been enabled on the device, then enabling
for 300 seconds. Do you want
device dis coverability will automatically enable bluetooth
to do this?
Yes
The device will silently remain in discoverable mode for the allotted time. If you
would like to be notified w hen the discoverable mode has changed, you can
register a BroadcastReceiver for the ACTTON SCAN MODE_ CHANGED Intent. This
will contain the extra fields eXtra SCAn mode and EXtRA Previous SCan mODE
The enabling
discoverability dialog
which tell you the new and old scan mode, respectively. Possible values for
2012-5-15
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topicswirclcss/bluct
each are scan MODE CONNECTABLE DISCOVERABLE, SCAn MODE CONNECTABLE, or scan MODE NoNe, which indicate that the
device is either in discoverable mode, not in discoverable mode but still able to receive connections or not in
discoverable mode and unable to receive connections, respectively
You do not need to enable device discoverability if you will be initiating the connection to a remote device. Enabling
discoverability is only necessary when you want your application to host a server socket that will accept incoming
connections because the remote devices must be able to discover the device before it can initiate the connection
In order to create a connection between your application on two devices, you must implement both the server-side and
client-side mechanisms, because one device must open a server socket and the other one must initiate the connection
(using the server device's mac address to initiate a connection The server and client are considered connected to
each other when they each have a connected BluetoothSocket on the same RFCOMM channel. At this point, each
device can obtain input and output streams and data transfer can begin, which is discussed in the section about
Managing a Connection. This section describes how to initiate the connection between two devices
The server device and the client device each obtain the required bluetoothsocket in different ways. The server will
receive it when an incoming connection is accepted. The client will receive it when it opens an RFCOMM channel to the
server
One implementation technique is to automatically prepare each device as a
server, so that each one has a server socket open and listening for
connections then either device can initiate a connection with the other and
i Bluetooth pairing request
become the client. Alternatively, one device can explicitly host" the connection
and open a server socket on demand and the other device can simply initiate
To pair with"android phone",
the connection
confirm that it is showing the
passkey: 980653
If the two devices have not been previously paired, then the Android
Pair
Don t pair
framework will automatically show a pairing request notification or dialog
to the user during the connection procedure, as shown in Figure 3. So
when attempting to connect devices, your application does not need to be
The Bluetooth pairing
concerned about whether or not the devices are paired. Your RFCOMm
dialog
connection attempt will block until the user has successfully paired, or will
fail if the user rejects pairing, or if pairing fails or times out
When you want to connect two devices, one must act as a server by holding an open BluetoothServer Socket. Th
purpose of the server socket is to listen for incoming connection requests and when one is accepted provide a
connected BluetoothSocket. When the BluetoothSocket is acquired from the blue toothServer Socket, the
BluetoothServer Socket can(and should)be discarded, unless you want to accept more connections
Here's the basic procedure to set up a server socket and
accept a connection
A Universally Unique Identifier(UUID)is a
Get a bluetoothServer Socket by calling the
standardized 128-bit format for a string id used to
istcnUsingRfcommWithScrviccRccord(String, UUID)
uniquely identify information the point of a UUID is
that it's big enough that you can select any random
The string is an identifiable name of your service, which
and it won t clash. In this case, it's used to uniquely
the system will automatically write to a new Service
identify your application, s Bluetooth service. To get a
Discovery Protocol(SDP)database entry on the device
UUid to use with your application, you can use one of
( the name is arbitrary and can simply be your
the many random uuid generators on the web, then
application name ). The UUId is also included in the SDP
initialize a UUid with froSting (string
entry and will be the basis for the connection
agreement with the client device. That is, when the
client attempts to connect with this device, it will carry a UUid that uniquely identifies the service with which it
wants to connect. These UUIDs must match in order for the connection to be accepted(in the next step)
2. Start listening for connection requests by calling accept ()
2012-5-15
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topicswirclcss/bluct
This is a blocking call. It will return when either a connection has been accepted or an exception has occurred. A
connection is accepted only when a remote device has sent a connection request with a UUID matching the one
registered with this listening server socket. When successful, accept() will return a connected BluetoothSocket
3. Unless you want to accept additional connections, call close
This releases the server socket and all its resources, but does close the connected bluetooth Socket that 's
been returned by accept o. Unlike TCP/IP, RFCOMM only allows one connected client per channel at a time, so in
most cases it makes sense to call close o on the bluetoothServerSocket immediately after accepting a
connected socket
The accept( call should not be executed in the main activity Ul thread because it is a blocking call and will prevent any
other interaction with the application. It usually makes sense to do all work with a BluetoothServerSocket or
BluetoothSocket in a new thread managed by your application. to abort a blocked call such as accept(, call close ()
on the BluetoothServerSocket (or BluetoothSocket) from another thread and the blocked call will immediately return
Note that all methods on a bluetoothserver socket or bluetooth socket are thread-safe
Here's a simplified thread for the server component that accepts incoming connections
private class accept thread extends thread
private final bluetoothserverSocket mmServer Socket
public acceptthreado i
A Use a temporary object that is later assigned to mmServerSocket
l because mm.ServerSocket is final
Bluetooth Serversocket tm
try
// MY UUID is the app's Uuid string, also uscd by thc client codc
t
BluctoothAdaptcr. listcnUsingRfcommWithScrviccRccord(NAME, MY UUID)
catch(IOException c)1)
mmScrvcrSockct- tmp;
public void run O
BluetoothSocket socket null
Keep listening until exception occurs or a socket is returned
hile (true) I
try
socket= mm ServerSocket accept O
catch (IOException e)i
break
d If a connection was accepted
if (socket ! null)
d Do work to manage the connection (in a separate thread)
Manage Connec ledSocke l(sockel)
break
/kk will cancel the listening socket, and cause the thread to finish i
public void cancel
ry
mmServerSocket. close()
catch (IOException e)()
In this example, only one incoming connection is desired, so as soon as a connection is accepted and the
BluetoothSocket is acquired, the application sends the acquired bluetoothSocket to a separate thread closes the
2012-5-15
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidctopics/wirclcss/bluct
BluctoothScrvcr Socket and breaks the loop.
Note that when accept( returns the BluetoothSocket, the socket is already connected, so you should call
connect((as you do from the client-side)
manage ConncctcdSockct()is a fictional method in the application that will initiate the thread for transferring data, which
is discussed in the section about Managing a Connection
You should usually close your BluetoothServer Socket as soon as you are done listening for incoming connections. In
this example, close( is called as soon as the blue loo thSockel is acquired. You may also want to provide a public
method in your thread that can close the private Blue toothSocket in the event that you need to stop listening on th
server socket
In order to initiate a connection with a remote device(a device holding an open server socket), you must first obtain a
BluetoothDevice object that represents the remote device (Getting a BluetoothDevice is covered in the above section
about Find ing Devices. You must then use the bluetoothDevice to acquire a blue toothSocket and initiate the
connection
Here's the basic procedure:
1. Using the BluctoothDovicc, get a bluctoothSockct by calling crcatcRfcommSockctToScrviccRccord (UUID)
This initializes a Blue toothSocket that will connect to the BluetoothDevice. The UUId passed here must match the
UUID used by the server device when it opened its blue toothServer Socket (with
listenUsingRfcommWithServiceRecord(String, UUID)). Using the same UUID is simply a matter of hard-coding
the UUID string into your application and then referencing it from both the server and client code
2. Initiate the connection by calling connect. O
Upon this call, the system will perform an SDP lookup on the remote device in order to match the UUID. If the
lookup is successful and the remote device accepts the connection, it will share the rfcomm channel to use
during the connection and connect o will return. This method is a blocking call. If, for any reason, the connection
fails or the connect O method times out(after about 12 seconds), then it will throw an exception
Because connectO is a blocking call, this connection procedure should always be performed in a thread separate
from the main activity thread
Note: You should always ensure that the device is not performing device discovery when you call connect(. If
discovery is in progress, then the connection attempt will be significantly slowed and is more likely to fail
Here is a basic example of a thread that initiates a bluetooth connection
private class Connect Thread extends Thread I
private final bluetoothSocket mmSocket:
private final bluetoothDevice mmDevice:
public ConnectThread (BluetoothDevice device)[
A Use a temporary object that is later assigned to mmSocket,
because mm socket is final
BluetoothSocket tmp= null
mmdevice device
// Gct a BluctoothSockot to connect with thc givon BluctoothDcvicc
try
// My UUID is the app's uvid string, also uscd by thc sarver codc
tmp- dcvicc crcatcRfcomm SockctTo ScrviccRccord (MY UUID)
catch (IOException c)I)
mSocket tmp
2012-5-1511:10
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topicswirclcss/bluct
public void runo
/7 Cancel discovery because it will slow down the connection
uBlue loothAdapler cancelDiscovery o
try
// Connect the device through the socket. This will block
y until it succeeds or throws an exception
mmSocket connect O
I catch (IOException connectException) t
unable to connect, close the socket and get out
try
mmSocket closed
catch (IOException closelxception)i j
return
/ Do work to manage the connection (in a separate thread)
sOcket(mmsock
*k WilI cancel an in-progress connection, and close the socket x/
public void cancel( i
try
mmSockct. close
catch (IOException c)i)
Notice that cancelDiscovery() is called before the connection is made. You should always do this before connecting
and it is safe to call w ithout actually checking whether it is running or not (but if you do want to check, call
diScovering()
manage ConncctcdSockct() is a fictional method in the application that will initiate the thread for transferring data, which
is discussed in the section about Managing a Connection
When you're done with your BluetoothSocket, always call close( to clean up doing so will immediately close the
connected socket and clean up all internal resources
When you have successfully connected two(or more)devices, each one will have a connected Bluetoothsocket. This
is w here the fun begins because you can share data between devices. Using the Blue Socket, the general
procedure to transfer arbitrary data is simple
1. Get the InputStream and Output Stream that handle transmissions through the socket, via getInput Stream()and
getOutputStream(, respectively
2. Read and write data to the streams with read (byte l) and write (byte ld)
That' s it
There are, of course, implementation details to consider First and foremost, you should use a dedicated thread for all
stream reading and writing This is important because both read (byte [] and write(byte[l) methods are blocking
calls. read(byle[] will block until there is something to read from the stream write(by lell) does not usually block,
but can block for flow control if the remote device is not calling rcad(byte) quickly enough and the intermediate
buffers are full. So, your main loop in the thread should be dedicated to reading from the Inputstream. A separate
public method in the thread can be used to initiate writes to the Outputstream
Here s an example of how this might look
2012-5-1511:10
Bluctooth Android Dcvclopcrs
http://dcvclopcr.androidcom/guidc/topics/wirclcss/bluct
private class ConnectedThread extends Thread
private final bluetoothsocket mmSocket
private final Inputstream mmInStream:
private final outputstream mmOutstream
public ConnectedThread (BluetoothSocket socket
SOcket
ocke
Inputstream tmpIn= null
Outputstream tmpOut = null
d Get the input and output streams, using temp objects because
7 member streams are final
try
In= socket. getInputStreamo
tmpOut= socket getOutputStream(
t catch (IOException c)1)
mmInStrcam- tmpin
mmOutstrcam- tmpOut
public void runo
byte[ buffer new byte[1024];// buffer store for the stream
int bytes; / bytes returned from reado
l Keep listening to the Input Stream until an exception occurs
while (true)i
try
// Read from the Input stream
by les-mmInStreal read(buffer)
Send he obtained byles lo the lI
hAndler obtainMessage(MESSAGE READ, by tes, -1, buffer
endToTargetO
i catch (IOException e
break
k cal this from the main activity to send data to the remote device ft
public void write(byte[] bytes)(
try
catch (IOException e)f)
/* Ca I this from the main activity to shutdown the connection *
public void cancel i
try
mmSocket. close
catch (IOException e)i j
The constructor acquires the necessary streams and once executed, the thread will wait for data to come through the
Input Stream. When read(byte_]) returns with bytes from the stream the data is sent to the main activity using a
member Handler from the parent class. Then it goes back and waits for more bytes from the stream
Sending outgoing data is as simple as calling the thread s write( method from the main activity and passing in the
bytes to be sent. This method then simply calls write(bytell) to send the data to the remote device.
The thread s cancel() method is important so that the connection can be terminated at any time by closing the
luetoothSocket. This should always be called when you're done using the Bluetooth connection.
10 of
2012-5-15
【实例截图】
【核心代码】