Apologies for the lengthy post, but I wanted this to be at least semi-
useful, and there is not a lot of info out there. I see that the OP is
from awhile ago, but that this thread has been resurrected.

I am currently using my Droid (firmware push: 2.0.1) to communicate to
an ArduinoBT (Bluetooth) board via SPP (the ArduinoBT's default) using
the well-known SPP UUID (0x1101 host side, and the UUID-extended
version of 0x1101 on the client (Android) side; see the code below for
the actual UUID).  The ArduinoBT board uses a BlueGiga WT11 module and
iWrap firmware/API. We currently have it interfaced to a hobby robot.

*** Following pertains to Android 2.0 and up; there is no public
Bluetooth API before 2.0 ***

Given that the ArduinoBT comes out of the box set up for SPP, I
configured our Android client application to do the same. I've
commented the code, but you need to know something about Bluetooth to
get the most out of it. I highly recommend Bluetooth Essentials for
Programmers, available for free. On the Android side: the Android SDK
doc, and the Bluetooth Chat Sample are excellent references.

Before you run the client, you need to pair your robot controller with
your Android device. It doesn't have to be connected, just paired. You
can do the discovery/pairing from your handset's standard networking
settings. You will need a PIN; Android requires authentication even if
your robot controller doesn't (most controllers let you set this as an
option).  You will also need to enable Bluetooth.

This is a brain-dead simple client, no threading, no receiving; all it
does is send commands to our robot (modified a bit, since the OP only
cares about the SPP communication material), and should be very easy
to modify for various purposes.  All that needs to be changed on this
side is the MAC address.  Enter the robot controller's MAC address in
place of the "XX:XX..." string below.

package com.example.thinbtclient;

import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class ThinBTClient extends Activity {

    private static final String TAG = "THINBTCLIENT";
    private static final boolean D = true;
    private BluetoothAdapter mBluetoothAdapter = null;
    private BluetoothSocket btSocket = null;
    private OutputStream outStream = null;
    //Well known SPP UUID (will *probably* map to RFCOMM channel 1
(default) if not in use);
    //see comments in onResume().
    private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private static String address = "XX:XX:XX:XX:XX:XX"; //<==
hardcode your robot (server) MAC address here...

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        if(D)
                   Log.e(TAG, "+++ ON CREATE +++");

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter == null) {
            Toast.makeText(this, "Bluetooth is not available.",
Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        if (!mBluetoothAdapter.isEnabled()) {
                   Toast.makeText(this, "Please enable your BT and re-run
this program.", Toast.LENGTH_LONG).show();
                   finish();
                   return;
        }

        if(D)
                   Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER ++
+");
    }

    @Override
    public void onStart() {
        super.onStart();
        if(D) Log.e(TAG, "++ ON START ++");
    }

    @Override
    public void onResume() {
        super.onResume();

        if(D) {
                   Log.e(TAG, "+ ON RESUME +");
            Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");
        }

        //When this returns, it will 'know' about the server, via it's
MAC address.
        BluetoothDevice device =
mBluetoothAdapter.getRemoteDevice(address);

        //We need two things before we can successfully connect
(authentication issues
        //aside): a MAC address, which we already have, and an RFCOMM
channel.
        //Because RFCOMM channels (aka ports) are limited in number,
Android doesn't allow
        //you to use them directly; instead you request a RFCOMM
mapping based on a service
        //ID. In our case, we will use the well-known SPP Service ID.
This ID is in UUID
        //(GUID to you Microsofties) format. Given the UUID, Android
will handle the
        //mapping for you. Generally, this will return RFCOMM 1, but
not always; it
        //depends what other BlueTooth services are in use on your
Android device.
        try {
                   btSocket =
device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Log.e(TAG, "ON RESUME: Socket creation failed.", e);
        }

        //Discovery may be going on, e.g., if you're running a 'scan
for devices' search
        //from your handset's Bluetooth settings, so we call
cancelDiscovery(). It doesn't
        //hurt to call it, but it might hurt not to... discovery is a
heavyweight process;
        //you don't want it in progress when a connection attempt is
made.
        mBluetoothAdapter.cancelDiscovery();

        //Blocking connect, for a simple client nothing else can
happen until a successful
        //connection is made, so we don't care if it blocks.
        try {
                   btSocket.connect();
            Log.e(TAG, "ON RESUME: BT connection established, data
transfer link open.");
        } catch (IOException e) {
            try {
                btSocket.close();
            } catch (IOException e2) {
                Log.e(TAG, "ON RESUME: Unable to close socket during
connection failure", e2);
            }
        }

        //Create a data stream so we can talk to server.
        if(D)
                   Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");

        try {
            outStream = btSocket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
        }

        String message = "Hello message from client to server.";
        byte[] msgBuffer = message.getBytes();
        try {
            outStream.write(msgBuffer);
        } catch (IOException e) {
            Log.e(TAG, "ON RESUME: Exception during write.", e);
        }
    }

    @Override
    public void onPause() {
        super.onPause();

        if(D)
                   Log.e(TAG, "- ON PAUSE -");

        if (outStream != null) {
            try {
                       outStream.flush();
           } catch (IOException e) {
               Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
           }
        }

        try {
            btSocket.close();
        } catch (IOException e2) {
            Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if(D) Log.e(TAG, "-- ON STOP --");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(D) Log.e(TAG, "--- ON DESTROY ---");
    }
}

You will also need to add the following to the project manifest:

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />

PM me if you'd like the Eclipse project.

Host controller (robot server) setup notes (since the OP didn't
specify the controller, these are general notes that will apply to any
controller):

***Changing wireless communication settings is a GREAT way to brick
your controller; you won't damage it, but you won't be able to
communicate with it until you re-flash it, or otherwise reset it to
factory defaults.  It is recommended that you have the means to do so
within arm's reach.***

In no particular order:
- Set a recognizable PIN: 12345, 1234, or 0000 is usually set by
default; make sure you know what it is.  You can't pair an Android
device without it.
- Set communication settings, and verify they're correct for your
hardware (e.g., the ArduinoBT uses 115200, 8n1).
- Set up your host robot controller as a server (beware that some
manuals, notably BlueGiga's iWrap, refer to this as 'slave' mode since
the controller only listens and can't react until a 'master' connects;
I find this confusing and will stick to standard client/server
verbiage):
    - Set pagemode to 'visible to inquiry, connectable to'. You want
your host to listen, accept a connection when requested to, then go
back to listening when the client connection is closed down. This will
ensure that you can connect, leave and reconnect without having to
reboot your host controller. 'visible to inquiry' means that the
Android device can see the controller during discovery.
    - Set role switching to 'host does not request role switching when
answering'. Bluetooth allows client/server switches on the fly; we
disable it for this application.
- Set the service your host is broadcasting to SPP.  The service UUID
for this is 0x1101, but most boards have a user friendly command for
the well-known services they support, so you should not have to
explicitly set the UUID. For example, on the ArduinoBT board the
command is 'SET PROFILE SPP ON' (actually the default, but you get the
idea).
- You *probably* want to disable local echo host side; it makes
debugging/event tracking  harder, but you don't have to worry about
handling echoed data.

There will be others specific to various boards, but this should be a
start.  Most important are the MAC address, PIN, and service (SPP/
UUID) setup, the rest are most likely defaults. Sometimes, like with
the ArduinoBT, SPP is the default and you don't even need to set that
up.

If anyone needs to test the above code under WinXP, I have a server
emulator (Winsock2, Microsoft Bluetooth stack only, Visual Studio 2005
or higher) in unmanaged C/C++. PM me if you want the Visual Studio
project. You can also look at 32Feet.net for a managed solution, or
check out BlueCove for a Java solution that runs on multiple platforms
and on multiple Bluetooth stacks (Microsoft, WIDCOMM, BlueSoleil).

Hope this helps!
-XCaf


On Feb 11, 1:25 am, mikshel <miks...@hotmail.com> wrote:
> Based on my experience so far (and the information provided on Android
> site), SPP (Serial Port Profile) is not supported by existing Android
> SDK (as of Feb 2010).
>
> On a funny note, one of our developers managed to get a signal out and
> receive a reply using Bluetooth SPP on Android Dev Phone running SDK
> 1.6.  I do not have any additional information at this time as that
> developer was switched to another project.
>
> Hope this answers the question (and know that it will not help at
> all),
> M.

-- 
You received this message because you are subscribed to the Google
Groups "Android Beginners" group.

NEW! Try asking and tagging your question on Stack Overflow at
http://stackoverflow.com/questions/tagged/android

To unsubscribe from this group, send email to
android-beginners+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en

Reply via email to