如何使用android蓝牙接收串行数据

Posted

技术标签:

【中文标题】如何使用android蓝牙接收串行数据【英文标题】:How to receive serial data using android bluetooth 【发布时间】:2012-11-07 04:11:18 【问题描述】:

我是安卓新手。我正在设计一个通过蓝牙从硬件设备接收串行数据的 android 应用程序。我正在研究 Htc hope S。我使用示例蓝牙聊天代码来接收数据。但是收到的数据不正确。它错过了一些价值。谁能提供任何其他示例代码来通过蓝牙接收大量数据并将其保存在文件中。

【问题讨论】:

【参考方案1】:

试试这个代码:

活动:

package Android.Arduino.Bluetooth;
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.view.View;
import android.widget.TextView;
import android.widget.EditText;  
import android.widget.Button;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends Activity

TextView myLabel;
EditText myTextbox;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;

@Override
public void onCreate(Bundle savedInstanceState)

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button openButton = (Button)findViewById(R.id.open);
    Button sendButton = (Button)findViewById(R.id.send);
    Button closeButton = (Button)findViewById(R.id.close);
    myLabel = (TextView)findViewById(R.id.label);
    myTextbox = (EditText)findViewById(R.id.entry);

    //Open Button
    openButton.setOnClickListener(new View.OnClickListener()
    
        public void onClick(View v)
        
            try 
            
                findBT();
                openBT();
            
            catch (IOException ex)  
        
    );

    //Send Button
    sendButton.setOnClickListener(new View.OnClickListener()
    
        public void onClick(View v)
        
            try 
            
                sendData();
            
            catch (IOException ex)  
        
    );

    //Close button
    closeButton.setOnClickListener(new View.OnClickListener()
    
        public void onClick(View v)
        
            try 
            
                closeBT();
            
            catch (IOException ex)  
        
    );


void findBT()

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(mBluetoothAdapter == null)
    
        myLabel.setText("No bluetooth adapter available");
    

    if(!mBluetoothAdapter.isEnabled())
    
        Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBluetooth, 0);
    

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    if(pairedDevices.size() > 0)
    
        for(BluetoothDevice device : pairedDevices)
        
            if(device.getName().equals("MattsBlueTooth")) 
            
                mmDevice = device;
                break;
            
        
    
    myLabel.setText("Bluetooth Device Found");


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.setText("Bluetooth Opened");


void beginListenForData()

    final Handler handler = new Handler(); 
    final byte delimiter = 10; //This is the ASCII code for a newline character

    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.setText(data);
                                    
                                );
                            
                            else
                            
                                readBuffer[readBufferPosition++] = b;
                            
                        
                    
                 
                catch (IOException ex) 
                
                    stopWorker = true;
                
           
        
    );

    workerThread.start();


void sendData() throws IOException

    String msg = myTextbox.getText().toString();
    msg += "\n";
    mmOutputStream.write(msg.getBytes());
    myLabel.setText("Data Sent");


void closeBT() throws IOException

    stopWorker = true;
    mmOutputStream.close();
    mmInputStream.close();
    mmSocket.close();
    myLabel.setText("Bluetooth Closed");


这里是布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:ignore="TextFields,HardcodedText" >

<TextView
    android:id="@+id/label"
    android:layout_
    android:layout_
    android:text="Type here:" />

<EditText
    android:id="@+id/entry"
    android:layout_
    android:layout_
    android:layout_below="@id/label"
    android:background="@android:drawable/editbox_background" />

<Button
    android:id="@+id/open"
    android:layout_
    android:layout_
    android:layout_alignParentRight="true"
    android:layout_below="@id/entry"
    android:layout_marginLeft="10dip"
    android:text="Open" />

<Button
    android:id="@+id/send"
    android:layout_
    android:layout_
    android:layout_alignTop="@id/open"
    android:layout_toLeftOf="@id/open"
    android:text="Send" />

<Button
    android:id="@+id/close"
    android:layout_
    android:layout_
    android:layout_alignTop="@id/send"
    android:layout_toLeftOf="@id/send"
    android:text="Close" />

</RelativeLayout>

这里是清单: 添加到应用程序

// permission must be enabled complete
<manifest ....>

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <application>


    </application>
</manifest>

【讨论】:

我在行 mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid); 上得到一个 NullPointerException有什么帮助吗? Tomas 我认为您的设备 UUID 可能不正确?您使用的是什么值? 我也得到了 NullPointerException 。你找到任何解决方案了吗? @Tomáš'GunsBlazing'Frček 我无法解决这个问题。低于错误。 getBluetoothService() 调用时没有 BluetoothManagerCallback W/System.err:java.io.IOException:读取失败,套接字可能关闭或超时,读取 ret:-1 W/System.err:在 android.bluetooth.BluetoothSocket.readAll(BluetoothSocket. java:684) 用您的设备名称替换 MattsBlueTooth【参考方案2】:

我尝试了将连续数据(浮点值转换为字符串)从我的 PC (MATLAB) 传输到我的手机。但是,我的应用程序仍然误读了分隔符 '\n' 并且仍然数据出现乱码。因此,我将字符 'N' 作为分隔符而不是 '\n' (它可以是任何不作为数据的一部分出现的字符)并且我已经实现了更好的传输速度 - 我只给出了 0.1 秒的延迟在传输连续样本之间——接收器的数据完整性超过 99%,即在我传输的 2000 个样本(浮点值)中,只有 10 个在我的应用程序中没有正确解码。

简而言之,我的回答是:选择除 '\r' 或 '\n' 以外的分隔符,因为与我使用的其他字符相比,这些分隔符会给实时数据传输带来更多问题。如果我们更多地工作,也许我们可以进一步提高传输率。希望我的回答对大家有所帮助!

【讨论】:

【参考方案3】:

空连接的问题与 findBT() 函数有关。您必须将设备名称从“MattsBlueTooth”更改为您的设备名称,并确认您的服务/设备的 UUID。在 Android 上使用类似 BLEScanner 应用程序来确认两者。

【讨论】:

如何确认任何设备/服务的 UUID?【参考方案4】:

看看令人难以置信的 Bluetooth Serial 类,它具有 onResume() 能力,对我帮助很大。 我希望这会有所帮助;)

【讨论】:

以上是关于如何使用android蓝牙接收串行数据的主要内容,如果未能解决你的问题,请参考以下文章

如何让蓝牙 RFCOMM 始终如一地工作?

Android 10 中的蓝牙串行有啥变化吗?

如何让手机APP接收蓝牙模块发送的数据并显示出来

通过过滤和添加分隔符将串行数据从蓝牙存储到数组

如何强制串行端口写入方法在发送数据之前等待线路清除?

Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据,分包解包(附源码)