带有 Galaxy S3 的 Android 蓝牙 SPP

Posted

技术标签:

【中文标题】带有 Galaxy S3 的 Android 蓝牙 SPP【英文标题】:Android Bluetooth SPP with Galaxy S3 【发布时间】:2012-08-29 17:54:39 【问题描述】:

我正在尝试在运行 android 4.0.3 的三星 Galaxy S3 和 RN 42 蓝牙芯片之间建立蓝牙连接,here 是型号:

我使用了很多不同的代码来设置蓝牙串行通信,并且它们都在我之前使用的 HTC Wildfire 上运行良好。但现在我使用的是 Galaxy s3 手机,无法建立连接。这是我正在使用的代码,我找到了here:

我把权限放在了 android manifest 中。

首先,我的蓝牙接口:

public class BtInterface 

private BluetoothDevice device = null;
private BluetoothSocket socket = null;
private InputStream receiveStream = null;
private OutputStream sendStream = null;

private ReceiverThread receiverThread;

Handler handler;

public BtInterface(Handler hstatus, Handler h) 
    Set<BluetoothDevice> setpairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
    BluetoothDevice[] pairedDevices = (BluetoothDevice[]) setpairedDevices.toArray(new BluetoothDevice[setpairedDevices.size()]);

    for(int i=0;i<pairedDevices.length;i++) 
        if(pairedDevices[i].getName().contains("MyBluetoothChip")) 
            device = pairedDevices[i];
            try 
                socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                receiveStream = socket.getInputStream();
                sendStream = socket.getOutputStream();
             catch (IOException e) 
                e.printStackTrace();
            
            break;
        
    

    handler = hstatus;

    receiverThread = new ReceiverThread(h);


public void sendData(String data) 
    sendData(data, false);


public void sendData(String data, boolean deleteScheduledData) 
    try 
        sendStream.write(data.getBytes());
        sendStream.flush();
     catch (IOException e) 
        e.printStackTrace();
    


public void connect() 
    new Thread() 
        @Override public void run() 
            try 
                socket.connect();

                Message msg = handler.obtainMessage();
                msg.arg1 = 1;
                handler.sendMessage(msg);

                receiverThread.start();

             catch (IOException e) 
                Log.v("N", "Connection Failed : "+e.getMessage());
                e.printStackTrace();
            
        
    .start();


public void close() 
    try 
        socket.close();
     catch (IOException e) 
        e.printStackTrace();
    


public BluetoothDevice getDevice() 
    return device;


private class ReceiverThread extends Thread 
    Handler handler;

    ReceiverThread(Handler h) 
        handler = h;
    

    @Override public void run() 
        while(true) 
            try 
                if(receiveStream.available() > 0) 

                    byte buffer[] = new byte[100];
                    int k = receiveStream.read(buffer, 0, 100);

                    if(k > 0) 
                        byte rawdata[] = new byte[k];
                        for(int i=0;i<k;i++)
                            rawdata[i] = buffer[i];

                        String data = new String(rawdata);

                        Message msg = handler.obtainMessage();
                        Bundle b = new Bundle();
                        b.putString("receivedData", data);
                        msg.setData(b);
                        handler.sendMessage(msg);
                    
                
             catch (IOException e) 
                e.printStackTrace();
            
        
    


然后,我的主要活动,只需一个按钮即可连接和聊天:

public class MonApp extends Activity implements OnClickListener 

private TextView logview;
private EditText sendtext;
private Button connect, send;

private BtInterface bt = null;

private long lastTime = 0;

final Handler handler = new Handler() 
    public void handleMessage(Message msg) 
        String data = msg.getData().getString("receivedData");

        long t = System.currentTimeMillis();
        if(t-lastTime > 100) // Pour Èviter que les messages soit coupÈs
            logview.append("\n");
            lastTime = System.currentTimeMillis();
        
        logview.append(data);
    
;

final Handler handlerStatus = new Handler() 
    public void handleMessage(Message msg) 
        int co = msg.arg1;
        if(co == 1) 
            logview.append("Connected\n");
         else if(co == 2) 
            logview.append("Disconnected\n");
        
    
;

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

    bt = new BtInterface(handlerStatus, handler);

    logview = (TextView)findViewById(R.id.logview);
    sendtext = (EditText)findViewById(R.id.sendtxt);

    connect = (Button)findViewById(R.id.connect);
    connect.setOnClickListener(this);

    send = (Button)findViewById(R.id.send);
    send.setOnClickListener(this);


@Override
public void onClick(View v) 
    if(v == connect) 
        bt.connect();
     else if(v == send) 
        bt.sendData(sendtext.getText().toString());
    


当我尝试连接到芯片时,这是我从 logcat 得到的:

09-05 11:37:05.515: I/BluetoothPolicyService(2097): getBluetoothDataTransferAllowed 
09-05 11:37:05.520: D/BluetoothPolicyService(2097): MDM: isProfileEnabled = true
09-05 11:37:05.520: D/BluetoothUtils(6868): isSocketAllowedBySecurityPolicy start : device null
09-05 11:37:05.525: V/BluetoothService.cpp(2097): createDeviceNative
09-05 11:37:05.525: V/BluetoothService.cpp(2097): createDeviceNative
09-05 11:37:05.525: V/BluetoothEventLoop.cpp(2097): onCreateDeviceResult
09-05 11:37:05.525: V/BluetoothEventLoop.cpp(2097): onCreateDeviceResult
09-05 11:37:05.525: E/BluetoothEventLoop.cpp(2097): onCreateDeviceResult: D-Bus error: org.bluez.Error.AlreadyExists (Already Exists)
09-05 11:37:05.525: V/BluetoothService.cpp(2097): discoverServicesNative
09-05 11:37:05.525: V/BluetoothService.cpp(2097): ... Object Path = /org/bluez/3094/hci0/dev_00_06_66_43_A1_E6
09-05 11:37:05.525: V/BluetoothService.cpp(2097): ... Pattern = , strlen = 0
09-05 11:37:10.660: V/BluetoothEventLoop.cpp(2097): onDiscoverServicesResult
09-05 11:37:10.660: V/BluetoothEventLoop.cpp(2097): ... Device Path = /org/bluez/3094/hci0/dev_00_06_66_43_A1_E6
09-05 11:37:10.660: E/BluetoothEventLoop.cpp(2097): onDiscoverServicesResult: D-Bus error: org.bluez.Error.ConnectionAttemptFailed (Host is down)
09-05 11:37:10.670: V/N(6868): Connection Failed : Service discovery failed
09-05 11:37:10.670: W/System.err(6868): java.io.IOException: Service discovery failed
09-05 11:37:10.675: W/System.err(6868):     at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:462)
09-05 11:37:10.675: W/System.err(6868):     at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:240)
09-05 11:37:10.675: W/System.err(6868):     at com.example.bluetooth.BtInterface$1.run(BtInterface.java:68)

我不明白为什么此代码不适用于 Galaxy s3。我试图在谷歌上搜索有关蓝牙兼容性问题,但到目前为止我没有找到任何东西。

谢谢!

纪尧姆

【问题讨论】:

【参考方案1】:

新的 Android ICS 存在大量蓝牙不兼容问题。显然他们弄乱了蓝牙代码以“提高安全性”。

我发现并报告了一个bug(这使得我的整个嵌入式板在一周内无法与任何 Android ICS 设备连接)是,在与已配对的设备建立连接时,Android ICS 需要重新验证- 带或不带 PIN 取决于您是否使用 Bluetooth SSP(我使用它 - 这意味着对我来说,在 Android ICS 上连接 2 个绑定设备仍然可能无需用户交互 - 但需要更长的时间)。

Please vote this bug on Google Bugtracker - maybe someone will fix it...

也许这也是你的问题?你能具体说明你的代码在哪一行中断吗? 用 try/catch 等包围你所有的蓝牙系统代码。

无论如何,新的蓝牙行为非常非常糟糕,我听说很多人因此无法连接到他们的旧耳机。

【讨论】:

感谢您的回答,我也看到他们在使用 ICS 时遇到了很多麻烦……我终于找到了一种让它工作的方法,我现在使用这段代码来设置连接,使用不安全的 Rfcomm : device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddress);方法 m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] int.class ); socket = (BluetoothSocket)m.invoke(device, Integer.valueOf(1)); 原来是那个bug!不要忘记在这种情况下连接是不安全的! (我看到你也在使用反射......可能是为了兼容性)。如果您有时间,请也投票/纠正,也许也可以在 Google Android Bugtracker 上投票?! 我发现了同样的问题,所以我尝试使用不安全的连接,但它没有用 :(..!! 有人在 GALAXY TAB 2.7.0 上发现了同样的问题吗??跨度> 【参考方案2】:

您的代码似乎正确,但正如 Radu 所说,新的蓝牙行为并不那么好。 我自己确实遇到了一些麻烦(使用 Android 4.1+),最后使用 BlueTerm 作为我的应用程序的基础,因为它是开源的并且正在工作(至少对于连接部分)。 你可以在这里找到它的来源:http://pymasde.es/blueterm/

希望对你有帮助! D

【讨论】:

以上是关于带有 Galaxy S3 的 Android 蓝牙 SPP的主要内容,如果未能解决你的问题,请参考以下文章

Galaxy S3 Android 4.3 上 BLE 的连接间隔

三星 Galaxy S3、S4、S5 的 Android 相机/图片方向问题

三星 Galaxy S3 Android 浏览器上的 Web 套接字?

三星 Galaxy S3 上的原生窗口渲染问题

Galaxy s3打破了响应式布局

相机意图不适用于三星 Galaxy S3