我需要将数据从Android手机传输到CSR8670开发板,但我是蓝牙,Android以及CSR芯片编程的初学者 利用我对蓝牙的基本知识,我使用此代码将手机连接到CSR板,它似乎可以顺利地完成配对步骤。这是MainActivity文件:
package com.example.bluetoothbasic1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;
import com.example.bluetoothbasic1.R;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
Button btnCheckBluetooth;
BluetoothAdapter myBluetoothAdapter;
BluetoothServerSocket serverSocketForCSRComm;
BluetoothSocket btSocketForCSRComm;
private Set <BluetoothDevice>mypairedDevices;
private Set <String> myArrayAdapter;
// Register the BroadcastReceiver
IntentFilter filter;
boolean connectedToCSR = false;
int i;
InputStream btInputStream;
OutputStream btOutputStream;
private static final UUID MY_UUID = UUID.fromString("0000FFFF-0000-1000-8000-00805F9B34FB");
// private static final UUID MY_UUID = UUID.fromString("00001F00-0000-1000-8000-00805F9B34FB");
// private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final UUID RANDOM_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCheckBluetooth = (Button)findViewById(R.id.btnCheckBluetooth_id);
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onStop()
{
unregisterReceiver(mReceiver);
super.onStop();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
Log.d("MYLOG", "INSIDE BROADCAST onReceive" );
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// When discovery finds a device,
// Get the BluetoothDevice object from the Intent
Log.d("MYLOG", "FOUND DEVICE" );
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d("MYLOG", "CALLED intent.getParcelableExtra()" );
// myArrayAdapter.add(device.getName() + "\n" + device.getAddress());
device.createBond();
// try {
// Method method = device.getClass().getMethod("createBond", (Class[]) null);
// method.invoke(device, (Object[]) null);
// } catch (Exception e) {
// e.printStackTrace();
// }
do{
}while(device.getBondState()!=BluetoothDevice.BOND_BONDED);
Toast.makeText(context, "Pairing complete", Toast.LENGTH_SHORT).show();
Log.d("MYLOG", "Bonding complete" );
// connectedToCSR = true;
myBluetoothAdapter.cancelDiscovery();
Log.d("MYLOG", "CALLED myBluetoothAdapter.cancelDiscovery();" );
try {
// serverSocketForCSRComm = myBluetoothAdapter.listenUsingRfcommWithServiceRecord("Hello world", MY_UUID); // NOT USED
// serverSocketForCSRComm = myBluetoothAdapter.listenUsingRfcommWithServiceRecord("random_text", RANDOM_UUID); // NOT USED
// Log.d("MYLOG", "CALLEDmyBluetoothAdapter.listenUsingRfcommWithServiceRecord()" );
btSocketForCSRComm = device.createRfcommSocketToServiceRecord(MY_UUID);
// btSocketForCSRComm = device.createRfcommSocketToServiceRecord(RANDOM_UUID);
Log.d("MYLOG", "CALLED createRfcommSocketToServiceRecord(MY_UUID)" );
// btSocketForCSRComm = serverSocketForCSRComm.accept(); // NOT USED
// Log.d("MYLOG", "CALLED serverSocketForCSRComm.accept()" ); // NOT USED
btSocketForCSRComm.connect(); // this is a blocking call so when this function returns
Log.d("MYLOG", "CALLED btSocketForCSRComm.connect()" );
// Log.d("MYLOG", "btSocketForCSRComm CONNECTION VERIFIED" );
//
btInputStream = btSocketForCSRComm.getInputStream();
btOutputStream = btSocketForCSRComm.getOutputStream();
for(i=0; i<1000; i++ ){
btOutputStream.write(65);
// btOutputStream.wait(4);
}
Log.d("MYLOG", "CALLED btOutputStream.write(65)" );
btSocketForCSRComm.close();
Log.d("MYLOG", "CALLED btSocketForCSRComm.close()" );
// serverSocketForCSRComm.close(); // NOT USED
// Log.d("MYLOG", "CALLED serverSocketForCSRComm.accept()" ); // NOT USED
} catch (IOException e) {
// TODO Auto-generated catch block
// Log.e("MYLOG", "accept() failed", e);
Toast.makeText(context, "REACHED EXCEPTION REACHED EXCEPTION REACHED EXCEPTION", Toast.LENGTH_LONG).show();
Log.d("MYLOG", "REACHEDEXCEPTIONREACHEDEXCEPTIONREACHEDEXCEPTION" );
e.printStackTrace();
}
}
}
};
public void btnCheckBluetooth_onCLick(View view){
Log.d("MYLOG", "ENTERD HERE" );
// ----- STEP 1: Detect presence of Bluetooth Adapter
// BluetoothAdapter myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if ( myBluetoothAdapter == null ) {
Toast.makeText( this, "Device does not support Bluetooth", Toast.LENGTH_LONG ).show();
}
else{
Toast.makeText( this, "Device supports Bluetooth", Toast.LENGTH_SHORT ).show();
}
// ----- STEP 2: Enable bluetooth
if ( !myBluetoothAdapter.isEnabled() ) {
Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE );
// startActivityForResult( enableBtIntent, REQUEST_ENABLE_BT );
startActivityForResult( enableBtIntent, 0 );
}
do{
}while(myBluetoothAdapter.getState()!=BluetoothAdapter.STATE_ON);
Log.d("MYLOG", "EXITED WHILE LOOP" );
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
// ----- STEP 3: Search
// After setting up the Bluetooth adapter, the next step is to find the Bluetooth-enabled
// devices (CSR8670) by searching the matched Bluetooth modules.
// Before finding a device, it needs to query
// the list of the matched devices to make sure whether the demanded device is known to the
// server. The following code is used to pair devices and fetch the device name.
// This block searches in the paired devices list
mypairedDevices = myBluetoothAdapter.getBondedDevices();
if(mypairedDevices.size() > 0){ // If there are paired devices
// Loop through paired devices
for(BluetoothDevice device : mypairedDevices){
// myArrayAdapter.add (device.getName()+"\n"+ device.getAddress());
Log.d("MYLOG", device.getName()+"\n"+ device.getAddress() );
}
}
else{
Log.d("MYLOG", "No paired devices" );
}
// ----- STEP 4:
// Start discovery
Log.d("MYLOG", "Calling StartDiscovery");
myBluetoothAdapter.startDiscovery();
Log.d("MYLOG", "StartDiscovery called");
// do{
//
// }while(connectedToCSR != true);
// Log.d("MYLOG", "Exited do{}while(connectedToCSR != true); infinite loop");
}
} // public class MainActivity extends ActionBarActivity { CLOSED
界面有一个按钮,按下后,将会:
名为mReceiver的BroadcastReceiver将查找被发现的设备。为简单起见,只有一个设备可以被发现(CSR板),并且在发现时总是不配对。
在onReceive()函数中,代码
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
将CSR委员会纳入device
。 device.createBond();将手机与CSR板配对。配对完成后,使用
btSocketForCSRComm = device.createRfcommSocketToServiceRecord(MY_UUID);
使用
建立与此套接字的连接btSocketForCSRComm.connect();
获取输入和输出流后,我以这种方式发送大量字节:
for(i=0; i<1000; i++ ){
btOutputStream.write(65);
// btOutputStream.wait(4);
}
如果我这样做,CSR板会检测到一定数量的字节,并且在CSR板的IDE屏幕上显示检测到的字节,只是检测到大量字节但是没有显示(我认为这与CSR板可以检测到的速度与手机发送字节流的速度有关,其中许多只是迷路了。如果我不发送一个大的连续字节流而只发送一个字节,它似乎就会丢失。
后来我试着看看我是否可以从android获取Bluechat示例程序以检测CSR板。该程序在设备发现阶段工作正常,但有些原因我仍然无法找到Bluechat示例程序的哪一部分进行配对(see my question here)。在Bluechat示例程序中似乎没有出现device.createBond()函数(SDK IDE在点之后没有显示它,这是我还没有理解的另一种奇怪现象),但我设法完成了削减使用Method类。主要的变化是在connect thread类的ConnectThread构造函数中:
public ConnectThread(BluetoothDevice device) {
Log.d("MYLOG", "ConnectThread(BluetoothDevice device) CONSTRUCTOR");
mmDevice = device;
BluetoothSocket tmp = null;
try {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
do{
}while(device.getBondState()!=BluetoothDevice.BOND_BONDED);
Log.d("MYLOG", "Bonding complete" );
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.d("MYLOG", "createRfcommSocketToServiceRecord(MY_UUID) GONE WRONG");
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
除了自定义UUID和logcat条目之外,Bluechat代码的其余部分基本上不受影响。如果我现在运行此程序,从电话发送的所有消息似乎都被CSR板正确检测和显示,并且没有数据丢失。
我的代码与Bluechat示例程序之间究竟有什么区别,发送数据在我的程序中丢失了,而在Bluechat示例中却没有?据我了解,它无法降低蓝牙RFCOMM的波特率,因此Bluechat程序无法以较低的速度发送数据。此外,Bluechat如何与另一部手机配对?当使用两部Android手机时,Bluechat样本开箱即用,没有任何修改,但我无法理解它是如何进行实际配对的。
我很乐意提供任何额外信息。