【问题标题】:Bluetooth Android SPP, send commands in series to device?蓝牙Android SPP,将命令串行发送到设备?
【发布时间】:2012-04-23 02:19:11
【问题描述】:

----------编辑---------- -----
一点点进步,虽然不是解决方案。如果我在要发送的命令之间插入以下代码,至少允许命令有时间在远程端处理(但这仍然不是正确的方法,正确的方法是等待在发送另一个命令之前用于响应“>”)...

android.os.SystemClock.sleep(150);

在系统时钟休眠期间,侦听器线程被阻塞,因此来自调制解调器的输入在发送代码序列之前不会附加到文本视图,这不太理想。不过,再次睡眠不是正确的方法,我需要找到更好的方法,所以在“>”结果从另一端的设备返回之前,我不会发送新命令。当我完成这段代码后,我将需要一种方法来处理输入,所以如果我考虑一下,睡眠真的没有进展。插入睡眠示例:

    sendData("enable");
    android.os.SystemClock.sleep(150);
    sendData("password");        
    android.os.SystemClock.sleep(150); 
    sendData("conf t");        
    android.os.SystemClock.sleep(150);     
    sendData("interface eth0");        
    android.os.SystemClock.sleep(150);    
    //etc...etc...etc... 

----------下面的原帖------ --------

我正在使用来自 Matt Bell 博客的这段优美的代码,位于此处: http://bellcode.wordpress.com/2012/01/02/android-and-arduino-bluetooth-communication/

来源位于此处: http://project-greengiant.googlecode.com/svn/trunk/Blog/Android%20Arduino%20Bluetooth

在不把代码切得太糟糕的情况下,我正在尝试以一种优雅的方式将命令串行发送到连接的调制解调器,每次都等到收到完整的响应后再发送下一个命令。 (我知道这不是 Android 的做事方式,我可以使用其他语言快速处理)。

这是我目前正在使用的内容(你会看到我还没有走多远,事实上,这段代码运行得非常好,直到我需要等待第一个命令完成才能发送更多命令命令)。我尽可能多地省略了与这个问题无关的代码。提前致谢。

    package Android.Arduino.Bluetooth;        

    import java.io.IOException;        
    import java.io.InputStream;        
    import java.io.OutputStream;        
    import java.util.Set;        
    import java.util.UUID;        
    import android.app.Activity;        
    import android.bluetooth.BluetoothAdapter;        
    import android.bluetooth.BluetoothDevice;        
    import android.bluetooth.BluetoothSocket;        
    import android.content.Intent;        
    import android.os.Bundle;        
    import android.os.Handler;        
    import android.widget.TextView;        


    public class BluetoothTest extends Activity        
    {        
        TextView myLabel;        
        BluetoothAdapter mBluetoothAdapter;        
        BluetoothSocket mmSocket;        
        BluetoothDevice mmDevice;        
        OutputStream mmOutputStream;        
        InputStream mmInputStream;        
        int counter;        
        Thread workerThread;        
        byte[] readBuffer;        
        int readBufferPosition;        
        volatile boolean stopWorker;        

        @Override        
        public void onCreate(Bundle savedInstanceState)        
        {        
            super.onCreate(savedInstanceState);        
            setContentView(R.layout.main);        

            myLabel = (TextView)findViewById(R.id.label);        

                        try         
                        {        
                            findBT();        
                            openBT();        
                            sendData("enable");        
                          //insert some code to wait for response before sending (or handle that in the above line, or otherwise)
                            sendData("password");        
                          //insert some code to wait for response before sending (or handle that in the above line, or otherwise)        
                            sendData("conf t");        
                          //insert some code to wait for response before sending (or handle that in the above line, or otherwise)        
                            sendData("interface eth0");        
                          //insert some code to wait for response before sending (or handle that in the above line, or otherwise)        
                          //etc...etc...etc...        
                        }        
                        catch (IOException ex) { }                            

        }        

        }        

        void openBT() throws IOException        
        {        
            UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID        
            mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);                
            mmSocket.connect();        
            mmOutputStream = mmSocket.getOutputStream();        
            mmInputStream = mmSocket.getInputStream();        
            beginListenForData();        
            myLabel.append("Bluetooth Opened" + "\n");        
        }        

        void beginListenForData()        
        {        
            final Handler handler = new Handler();         
            final byte delimiter = 62; //This is the ASCII code for a > character indicating all data received        

            stopWorker = false;        
            readBufferPosition = 0;        
            readBuffer = new byte[1024];              

            workerThread = new Thread(new Runnable()        
            {        
                public void run()        
                {                        

                while(!Thread.currentThread().isInterrupted() && !stopWorker)        
                   {        
                        try         
                        {        
                            int bytesAvailable = mmInputStream.available();                                
                            if(bytesAvailable > 0)        
                            {        
                                byte[] packetBytes = new byte[bytesAvailable];        
                                mmInputStream.read(packetBytes);        
                                for(int i=0;i<bytesAvailable;i++)        
                                {        
                                    byte b = packetBytes[i];        
                                    if(b == delimiter)        
                                    {        
                                        byte[] encodedBytes = new byte[readBufferPosition];        
                                        System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);        
                                        final String data = new String(encodedBytes, "US-ASCII");        
                                        readBufferPosition = 0;        

                                        handler.post(new Runnable()        
                                        {        
                                            public void run()        
                                            {                                                    
                                                myLabel.append(data);                                         
                                            }        
                                        });        
                                    }        
                                    else        
                                    {        
                                        readBuffer[readBufferPosition++] = b;        
                                    }        
                                }        
                            }        
                        }        
                        catch (IOException ex)         
                        {        
                            stopWorker = true;        
                        }        
                   }        

                }        
            });        

            workerThread.start();        
        }        

        void sendData(String msg0) throws IOException        
        {        
            msg0 += "\r";        
            mmOutputStream.write(msg0.getBytes());        
            myLabel.append("Data Sent" + "\n");        
        }        

    }        

【问题讨论】:

  • 好的,通过在命令之间暂停,我取得了一点进展,所以至少命令有一些时间在远程端执行。但是,这仍然不是正确的方法,因为在收到“完成处理”字符“>”之前,我不应该发送命令或解释/处理来自远程设备的输入。
  • 好的。我破解了这个方法并让它工作。这可能不正确,但我会在有机会时发布代码。它有效,但我需要添加更多错误处理!
  • 如果您能写下您提出的一些进展或最终解决方案,我将不胜感激。在此先感谢.. 干杯
  • @user1324818:我也参与了和你一样的项目。它在我的应用程序中处理 PAN1325 和 MSP430 微控制器。我真的不知道如何获取数据并处理它们。如果您能帮助开始,我将不胜感激..
  • 请在 BlueDroid 中为一个 bug 加注星标,以便我们吸引更多关注,并在此尽快修复它code.google.com/p/android/issues/…

标签: android bluetooth serial-port spp


【解决方案1】:

我知道这是一个很老的问题。但是,由于我正在开发一个类似的应用程序,所以我以不同的方式解决了它,它可能会有所帮助。

您可以通过标志实现发送/响应逻辑,而不是发送之间的延迟。所以一开始连接是initial。您发送enable 并将您的标志设置为enableRequested。然后你让你的听众等待响应。一旦你让它继续发送password,将标志设置为passwordSent并再次释放线程。

所以我建议不要在 onCreate 中这样做,而是触发一个线程从 onCreate 连接。这应该很好用。

【讨论】:

    猜你喜欢
    • 2016-12-15
    • 2013-03-10
    • 2014-12-02
    • 1970-01-01
    • 2012-07-02
    • 2017-12-14
    • 2018-07-17
    • 2012-04-22
    • 2012-02-29
    相关资源
    最近更新 更多