在两个设备之间交换数据时,在多个活动上实现蓝牙服务时,需要哪种服务?当我在活动之间切换时,连接丢失了。研究使我在本地服务和远程Messenger服务之间进行选择。
我的项目需要通过蓝牙在两个android设备之间交换传感器数据。我一直找不到能够实现此目的的项目,只能找到一个Messenger类型的功能。
如果有人完成了类似的项目,则将非常感谢您提出实施建议。
非常感谢。
到目前为止,这是我的主要活动和聊天服务代码:
public class MainActivity extends AppCompatActivity {
public MainActivity() {
}
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
public static final int REQUEST_ENABLE_BT = 3;
Button chatBtn, accelerometerBtn, proximityBtn;
CheckBox pairedCheckbox;
public BluetoothAdapter bluetoothAdapter;
public ChatService chatService;
public String connectedDeviceName = null;
// Constants that indicate the current connection state
private static final int STATE_NONE = 0; // we're doing nothing
private static final int STATE_LISTEN = 1; // now listening for incoming connections
private static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
private static final int STATE_CONNECTED = 3; // now connected to a remote device
public StringBuffer messageOutBuffer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chatBtn = (Button)findViewById(R.id.chat_btn);
accelerometerBtn = (Button)findViewById(R.id.accelerometer_btn);
accelerometerBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*if (pairedCheckbox.isChecked()==true){
openActivityAudio();
} else {
Activity activity = MainActivity.this;
Toast toast = Toast.makeText(activity,"Need to pair device", Toast.LENGTH_SHORT);
toast.show();
}*/
openActivityAccelerometer();
}
});
proximityBtn = (Button)findViewById(R.id.proximity_btn);
proximityBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*if (pairedCheckbox.isChecked()==true){
openActivityProximity();
} else {
Activity activity = MainActivity.this;
Toast toast = Toast.makeText(activity,"Need to pair device", Toast.LENGTH_SHORT);
toast.show();
}*/
openActivityProximity();
}
});
pairedCheckbox = (CheckBox)findViewById(R.id.paired_checkbox);
// Get local Bluetooth adapter
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (bluetoothAdapter == null){
Activity activity = MainActivity.this;
Toast.makeText(activity, "Bluetooth is not available", Toast.LENGTH_LONG).show();
activity.finish();
}
// enable bt adapter here
if (!bluetoothAdapter.isEnabled()){
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent = null;
switch (item.getItemId()) {
case R.id.secure_connect_scan:
serverIntent = new Intent(MainActivity.this, ConnectionActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
return true;
case R.id.insecure_connect_scan:
serverIntent = new Intent(MainActivity.this, ConnectionActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);
return true;
case R.id.discoverable:
ensureDiscoverable();
return true;
}
return false;
}
@Override
public void onStart() {
super.onStart();
if (chatService == null){
//Toast.makeText(this, "setting up chat", Toast.LENGTH_SHORT).show();
setupChat();
}
}
@Override
public void onStop() {
super.onStop();
if (chatService != null) {
chatService.stop();
}
}
@Override
public void onResume() {
super.onResume();
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (chatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (chatService.getState() == ChatService.STATE_NONE) {
// Start the Bluetooth chat services
chatService.start();
}
}
}
private void setupChat() {
// Initialize the ChatService to perform bluetooth connections
chatService = new ChatService(this, chatHandler);
// Initialize the buffer for outgoing messages
messageOutBuffer = new StringBuffer("");
}
protected final Handler chatHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
MainActivity activity = MainActivity.this;
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, connectedDeviceName));
pairedCheckbox.setChecked(true);
break;
case STATE_CONNECTING:
setStatus(R.string.title_connecting);
pairedCheckbox.setChecked(false);
break;
case STATE_LISTEN:
case STATE_NONE:
setStatus(R.string.title_not_connected);
pairedCheckbox.setChecked(false);
break;
}
break;
case Constants.MESSAGE_DEVICE_NAME:
// save the connected device's name
connectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);
if (null != activity) {
Toast.makeText(activity, "Connected to " + connectedDeviceName, Toast.LENGTH_SHORT).show();
}
break;
case Constants.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
Toast.makeText(MainActivity.this, readMessage, Toast.LENGTH_SHORT).show();
break;
case Constants.MESSAGE_TOAST:
if (null != activity) {
Toast.makeText(activity, msg.getData().getString(Constants.TOAST), Toast.LENGTH_SHORT).show();
}
break;
}
}
};
private void setStatus(int resId) {
MainActivity activity = MainActivity.this;
if (null == activity) {
return;
}
final ActionBar actionBar = this.getActionBar();
if (null == actionBar) {
return;
}
actionBar.setSubtitle(resId);
}
private void setStatus(CharSequence subTitle) {
MainActivity activity = MainActivity.this;
if (null == activity) {
return;
}
final ActionBar actionBar = activity.getActionBar();
if (null == actionBar) {
return;
}
actionBar.setSubtitle(subTitle);
}
private void ensureDiscoverable() {
if (bluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, true);
}
break;
case REQUEST_CONNECT_DEVICE_INSECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, false);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_CANCELED) {
// User did not enable Bluetooth or an error occurred
Toast.makeText(MainActivity.this, R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
MainActivity.this.finish();
}
}
}
private void connectDevice(Intent data, boolean secure) {
// Get the device MAC address
String address = data.getExtras().getString(ConnectionActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
// Connect device
chatService.connect(device, secure);
}
public void openActivityProximity(){
Intent intent = new Intent(this, ProximityActivity.class);
startActivity(intent);
}
public void openActivityAccelerometer(){
Intent intent = new Intent(this, AccelerometerActivity.class);
startActivity(intent);
}
}
聊天服务:
public class ChatService {
// Name for the SDP record when creating server socket
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
// Unique UUID for this application
private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final UUID MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
// Member fields
private final BluetoothAdapter adapter;
private final Handler chatHandler;
private AcceptThread secureAcceptThread;
private AcceptThread insecureAcceptThread;
private ConnectThread connectThread;
private ConnectedThread connectedThread;
private int state;
private int newState;
// 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
public ChatService(Context context, Handler handler){
adapter = BluetoothAdapter.getDefaultAdapter();
state = STATE_NONE;
newState = state;
chatHandler = handler;
}
private synchronized void updateUserInterfaceTitle() {
state = getState();
newState = state;
// Give the new state to the Handler so the UI Activity can update
chatHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, newState, -1).sendToTarget();
}
public synchronized int getState() {
return state;
}
public synchronized void start() {
// Cancel any thread attempting to make a connection
if (connectThread != null) {
connectThread.cancel();
connectThread = null;
}
// Cancel any thread currently running a connection
if (connectedThread != null) {
connectedThread.cancel();
connectedThread = null;
}
// Start the thread to listen on a BluetoothServerSocket
if (secureAcceptThread == null) {
secureAcceptThread = new AcceptThread(true);
secureAcceptThread.start();
}
if (insecureAcceptThread == null) {
insecureAcceptThread = new AcceptThread(false);
insecureAcceptThread.start();
}
}
public synchronized void connect(BluetoothDevice device, boolean secure) {
// Cancel any thread attempting to make a connection
if (state == STATE_CONNECTING) {
if (connectThread != null) {
connectThread.cancel();
connectThread = null;
}
}
// Cancel any thread currently running a connection
if (connectedThread != null) {
connectedThread.cancel();
connectedThread = null;
}
// Start the thread to connect with the given device
connectThread = new ConnectThread(device, secure);
connectThread.start();
// Update UI title
updateUserInterfaceTitle();
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device, final String socketType) {
// Cancel the thread that completed the connection
if (connectThread != null) {
connectThread.cancel();
connectThread = null;
}
// Cancel any thread currently running a connection
if (connectedThread != null) {
connectedThread.cancel();
connectedThread = null;
}
// Cancel the accept thread because we only want to connect to one device
if (secureAcceptThread != null) {
secureAcceptThread.cancel();
secureAcceptThread = null;
}
if (insecureAcceptThread != null) {
insecureAcceptThread.cancel();
insecureAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
connectedThread = new ConnectedThread(socket, socketType);
connectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = chatHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
chatHandler.sendMessage(msg);
// Update UI title
updateUserInterfaceTitle();
}
public synchronized void stop() {
if (connectThread != null) {
connectThread.cancel();
connectThread = null;
}
if (connectedThread != null) {
connectedThread.cancel();
connectedThread = null;
}
if (secureAcceptThread != null) {
secureAcceptThread.cancel();
secureAcceptThread = null;
}
if (insecureAcceptThread != null) {
insecureAcceptThread.cancel();
insecureAcceptThread = null;
}
state = STATE_NONE;
// Update UI title
updateUserInterfaceTitle();
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (state != STATE_CONNECTED) return;
r = connectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
// Send a failure message back to the Activity
Message msg = chatHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "Unable to connect device");
msg.setData(bundle);
chatHandler.sendMessage(msg);
state = STATE_NONE;
// Update UI title
updateUserInterfaceTitle();
// Start the service over to restart listening mode
ChatService.this.start();
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
// Send a failure message back to the Activity
Message msg = chatHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "Device connection was lost");
msg.setData(bundle);
chatHandler.sendMessage(msg);
state = STATE_NONE;
// Update UI title
updateUserInterfaceTitle();
// Start the service over to restart listening mode
ChatService.this.start();
}
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
private String mSocketType;
public AcceptThread(boolean secure) {
BluetoothServerSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
// Create a new listening server socket
try {
if (secure) {
tmp = adapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
tmp = adapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
}
mmServerSocket = tmp;
state = STATE_LISTEN;
}
public void run() {
setName("AcceptThread" + mSocketType);
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (state != 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) {
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (ChatService.this) {
switch (state) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice(),
mSocketType);
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
}
break;
}
}
}
}
}
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device, boolean secure) {
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
// initialise sockets
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
}
} catch (IOException e){
}
mmSocket = tmp;
state = STATE_CONNECTING;
}
public void run() {
setName("ConnectThread" + mSocketType);
// attempt connection
adapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException e) {
try {
mmSocket.close();
} catch (IOException e2) {
}
connectionFailed();
return;
}
synchronized (ChatService.this) {
connectThread = null;
}
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
mmSocket = socket;
// initialise input and output streams
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
state = STATE_CONNECTED;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (state == STATE_CONNECTED) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
chatHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
connectionLost();
break;
}
}
}
public void write(byte[] buffer) {
try {
// write to outstream
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
chatHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
}