我正在开发用于控制机器人汽车的应用程序,该程序基于BluetoothChat,BluetoothChatService和DeviceListActivity。
在我的第一个活动中,它用于连接蓝牙,然后如果连接成功则跳转到下一个活动。代码如下所示:
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket mBluetoothSocket = null;
...
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
}
@Override
public void onStart(){
super.onStart();
if(mService == null)
setupControl();
}
@Override
public synchronized void onResume(){
super.onResume();
if(mService != null){
if(mService.getState() == Service.STATE_NONE){
mService.start();
}
}
}
@Override
public synchronized void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
if (mService != null) mService.stop();
}
private void sendMessage(String message) {
if (mService.getState() != Service.STATE_CONNECTED) {
Toast.makeText(this, "not connect", Toast.LENGTH_SHORT).show();
return;
}
if (message.length() > 0) {
byte[] send = message.getBytes();
mService.write(send);
}
}
private final Handler mHandler = new Handler() {
...
};
public void onClick(View v){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
switch(v.getId()){
case R.id.tgbn_bt:
...
break;
case R.id.bt_connect:
if(mBluetoothDevice == null && tgbn_bt.isChecked()==true){
bt_connect.setText("Connect");
Intent intent = new Intent(this,DeviceListActivity.class);
startActivityForResult(intent,REQUEST_CONNECT_DEVICE);
}
...
}
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
if (resultCode == Activity.RESULT_OK) {
String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(address);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
try{
mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e1){
//TODO Auto-genterated catch block
e1.printStackTrace();
}
mService.connect(mBluetoothDevice);
}
break;
}
}
}
服务程序基于BluetoothChatService,我只是对其进行了一些修改
public class Service extends Application{
// Debugging
private static final String TAG = "Service";
private static final boolean D = true;
// Name for the SDP record when creating server socket
private static final String NAME = "ProjectActivity";
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
/**
* Constructor. Prepares a new BluetoothChat session.
* @param context The UI Activity Context
* @param handler A Handler to send messages back to the UI Activity
*/
public Service(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
/**
* Set the current state of the chat connection
* @param state An integer defining the current connection state
*/
private synchronized void setState(int state) {
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(ProjectActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state. */
public synchronized int getState() {
return mState;
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume() */
public synchronized void start() {
setState(STATE_LISTEN);
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* @param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
* @param socket The BluetoothSocket on which the connection was made
* @param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
// Cancel the thread that completed the connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Cancel the accept thread because we only want to connect to one device
if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(ProjectActivity.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(ProjectActivity.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
setState(STATE_NONE);
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* @param out The bytes to write
* @see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(ProjectActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(ProjectActivity.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_NONE);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(ProjectActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(ProjectActivity.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) {
Log.e(TAG, "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
setName("AcceptThread");
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (Service.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D) Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (D) Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
// Start the service over to restart listening mode
Service.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (Service.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(ProjectActivity.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
//connectionLost();
break;
}
}
}
/**
* Write to the connected OutStream.
* @param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(ProjectActivity.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}}
然后,我想将蓝牙连接传递给其他活动,例如控制面板活动:
public class ControlMethodActivity extends Activity {
static final String[] m=new String[] {"Arrow_Multi-Touch","Arrow_8 Buttons","Test2"};
//private TextView view;
private String holder;
private Spinner spinner;
private Button bt_Ok;
private ArrayAdapter<String> adapter;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.control_method);
bt_Ok = (Button) findViewById(R.id.bt_OK);
bt_Ok.setOnClickListener(new OnClickListener(){
public void onClick(View v){
if(holder=="Arrow_Multi-Touch"){
Intent i = new Intent(ControlMethodActivity.this,ArrowActivity.class);
startActivity(i);
}
else if(holder=="Arrow_8 Buttons"){
Intent i = new Intent(ControlMethodActivity.this,Arrow8Activity.class);
startActivity(i);
}
}
});
spinner = (Spinner) findViewById(R.id.method_spinner);
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,m);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3){
arg0.setVisibility(View.VISIBLE);
holder = arg0.getSelectedItem().toString();
}
public void onNothingSelected(AdapterView<?> arg0){
}
});
}}
我该怎么办? 谢谢你的好建议和教学....