read(byte类型数据[]) 丢数据 安卓蓝牙 byte类型数据[]中的数据比发过来的少 怎么解决

安卓蓝牙串口中InputStream数据接收不完整,已解决
先描述一下问题,烦了我一段时间。我是在单片机上使用HC05蓝牙模块和安卓手机进行通讯,从手机往单片机发送正常,从单片机往手机发数据总是不完整,一段字符被分成几段了,安卓的程序用的是谷歌官方的BluetoothChat例程。分析原因
分析了一下原因,谷歌官方的BluetoothChat读取线程的代码如上,是由于安卓程序使用InputStream读取时不能和串口一样设置一个结束符(串口的结束符一般是换行符'\r\n'),安卓中线程读取就很随机性了,你不知道它在什么时候就读完一刀下去,你的字符串就不完整了。解决方案
本来想找找InputStream中有没有结束符这个东西,找了半天也没找到,所以还是自己写一个吧。
就是使用InputStream.read()逐个读取字符,判读是不是结束符,如果没到结束符就一直读取写入。
注意if(ch!=-1)这个判断不能省,如果什么也没读到就是返回-1,这个时候不能让字符写进去。最后我的调试成功了,发的字符串再长也不会被一刀切开了。
inputStream 数据分段传输问题
Android 蓝牙开发(一)蓝牙通信
Android之Bluetooth—蓝牙操作
没有更多推荐了,java.io.InputStream.read(byte[] b, int off, int len)&方法从输入流读取转换为字节数组数据达到len个字节。如果参数len为0,则读取任何字节并返回0;否则有尝试读取至少一个字节。如果该流是在该文件的末尾,则返回的值为-1。
以下是java.io.InputStream.read(byte[] b, int off, int len) 方法的声明:
public int read(byte[] b, int off, int len)
b&-- 目标字节数组。
off&-- 在数组b在其中写入数据的起始位置的偏移。
len&-- 要读取的字节数。
该方法返回读入缓冲区的总字节数,或如果没有更多的数据,因为数据流的末尾已到达返回-1。
IOException&-- 如果发生I/ O错误。
NullPointerException&-- 如果b为&null.
IndexOutOfBoundsException&-- 如果off为负,len为负,或len大于b.length - off。
下面的例子显示java.io.InputStream.read(byte[] b, int off, int len)方法用法。
package com.yiibai;
import java.io.FileInputStream;
import java.io.InputStream;
public class InputStreamDemo {
public static void main(String[] args) throws Exception {
InputStream is = null;
byte[] buffer=new byte[5];
// new input stream created
is = new FileInputStream(&C://test.txt&);
System.out.println(&Characters printed:&);
// read stream data into buffer
is.read(buffer, 2, 3);
// for each byte in the buffer
for(byte b:buffer)
// convert byte to character
// if b is empty
c='-';
// if b is read
c=(char)b;
// prints character
System.out.print(c);
}catch(Exception e){
// if any I/O error occurs
e.printStackTrace();
// releases system resources associated with this stream
if(is!=null)
is.close();
假设我们有一个文本文件c:/ test.txt,它具有以下内容。该文件将被用作输入到我们的示例程序:
让我们来编译和运行上面的程序,这将产生以下结果:
Characters printed:
易百教程移动端:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"教程" 选择相关教程阅读或直接访问:http://m.yiibai.com 。
上一篇:下一篇:
加QQ群啦,易百教程官方技术学习群
注意:建议每个人选自己的技术方向加群,同一个QQ最多限加3个群。
Java技术群:
(人数:2000,等级:LV5,免费:否)
MySQL/SQL群:
(人数:2000,等级:LV5,免费:否)
大数据开发群:
(人数:2000,等级:LV5,免费:否)
Python技术群:
(人数:2000,等级:LV5,免费:否)
人工智能深度学习:
(人数:2000,等级:LV5,免费:否)
测试工程师(新群):
(人数:1000,等级:LV1,免费:是)
前端技术群(新群):
(人数:1000,等级:LV1,免费:是)
C/C++技术(新群):
(人数:1000,等级:LV1,免费:是)
Node.js技术(新群):
(人数:1000,等级:LV1,免费:是)
PostgreSQL数据库(新群):
(人数:1000,等级:LV1,免费:否)
Linux技术:
(人数:2000,等级:LV5,免费:否)
PHP开发者:
(人数:2000,等级:LV5,免费:是)
Oracle数据库:
(人数:2000,等级:LV5,免费:是)
C#/ASP.Net开发者:
(人数:2000,等级:LV5,免费:是)
数据分析师:
(人数:1000,等级:LV1,免费:是)R语言,Matlab语言等技术在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
package myapplication.com.
import android.app.S
import android.bluetooth.BluetoothA
import android.bluetooth.BluetoothD
import android.bluetooth.BluetoothServerS
import android.bluetooth.BluetoothS
import android.content.C
import android.content.I
import android.os.AsyncT
import android.os.H
import android.os.IB
import android.os.M
import android.support.v7.app.AppCompatA
import android.os.B
import android.util.L
import android.view.V
import android.widget.B
import android.widget.EditT
import android.widget.PopupM
import android.widget.PopupW
import android.widget.TextV
import android.widget.T
import java.io.ByteArrayOutputS
import java.io.IOE
import java.io.InputS
import java.io.OutputS
import java.net.S
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter BA;
BluetoothServerSocket mmServerS
private static String address = "20:16:09:26:81:80"; // &==应填写蓝牙串口模块的蓝牙地址。
private BluetoothSocket btSocket =
private OutputStream outStream =
public InputStream inStream =
EditText editT
TextView textV
Button button, button1;
private static final UUID MY_UUID = UUID.fromString("0-805F9B34FB");
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
* 连接蓝牙
public void connect() {
BA = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = BA.getRemoteDevice(address);
pairedDevices = BA.getBondedDevices();
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
ReceiveDatas(btSocket).start();
} catch (IOException e) {
BA.cancelDiscovery();
btSocket.connect();
String s="sm\n";
outStream = btSocket.getOutputStream();
outStream.write(s.getBytes());
//outStream.write(0x41);
inStream = btSocket.getInputStream();
Jieshou();
System.out.println("**" + inStream.toString());
System.out.println("**" + inStream.read());
int x = inStream.read();
//outStream.write(x+1);
// System.out.println("****--"+x);
} catch (IOException e) {
btSocket.close();
} catch (Exception e2) {
// Log .e(TAG,"ON RESUME: Unable to close socket during connection failure", e2);
public void initView() {
editText = (EditText) findViewById(R.id.edit);
textView = (TextView) findViewById(R.id.textView);
button = (Button) findViewById(R.id.button);
button1 = (Button) findViewById(R.id.button1);
BA = BluetoothAdapter.getDefaultAdapter();
* 连接蓝牙
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
System.out.println("***11");
* 发送信息 可以发送了
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String s = editText.getText().toString().trim();
outStream = btSocket.getOutputStream();
inStream=btSocket.getInputStream();
outStream.write(s.getBytes());
} catch (IOException e) {
e.printStackTrace();
public void as() {
new AsyncTask() {
protected String doInBackground(Object[] params) {
connect();
protected void onPreExecute() {
super.onPreExecute();
protected void onPostExecute(Object o) {
super.onPostExecute(o);
Toast.makeText(getApplicationContext(), "2", Toast.LENGTH_SHORT).show();
}.execute();
void Jieshou() {
new Thread(new Runnable() {
public void run() {
while(true){
ByteArrayOutputStream
byteArrayOutputStream=
byteArrayOutputStream = new ByteArrayOutputStream();
inStream=btSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
byte[] buffer = new byte[1024];// 缓冲数据流
int temp = 0;
while( (temp = inStream.read(buffer)) != -1) {
os.write(buffer, 0, temp);
byteArrayOutputStream.write(buffer, 0, temp);
System.out.println("*shuju*"+byteArrayOutputStream.toByteArray().toString());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}).start();
已经可以发送信息到蓝牙了,可是怎么接收数据啊?求助
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
自己找了个接受数据的线程……
private class ConnectedThread extends Thread {
private final BluetoothS
private final InputStream inputS
private final OutputStream outputS
public ConnectedThread(BluetoothSocket socket) {
this.socket =
InputStream input =
OutputStream output =
input = socket.getInputStream();
output = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
this.inputStream =
this.outputStream =
public void run() {
byte[] buff = new byte[1024];
while (true) {
bytes = inputStream.read(buff);
String str = new String(buff, "ISO-8859-1");
str = str.substring(0, bytes);
Log.e("recv", str);
Message message=handler.obtainMessage();
message.obj=
handler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
public void write(byte[] bytes) {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
public void cancel() {
socket.close();
} catch (IOException e) {
e.printStackTrace();
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
感觉你的写法有点奇怪……
mBluetoothGattCallback 是 BluetoothGattCallback的实现,用于回调连接状态和传输数据,具体你可以百度一下或看官方文档
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。STM8s中这个FLASH_ReadOptionByte的库函数怎么写出来的? - STM32/STM8技术论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
STM8s中这个FLASH_ReadOptionByte的库函数怎么写出来的?
23:57:29  
* 函数名:FLASH_ReadOptionByte
* 描述&&:读取的选项字
* 输入&&:无
* 输出&&:无
* 返回&&:选项字的值
* 调用&&:内部调用 设置Beep的选项字函数调用
*************************************************************************/
static uint16_t FLASH_ReadOptionByte(uint16_t Address)&&
& & uint8_t value_optbyte, value_optbyte_complement = 0;
& & uint16_t res_value = 0;
& & value_optbyte = *((NEAR uint8_t*)Address); /* Read option byte *
& & value_optbyte_complement = *(((NEAR uint8_t*)Address) + 1); /* Read option byte complement */
& && &&&if (value_optbyte == (uint8_t)(~value_optbyte_complement))
& && && && &res_value = (uint16_t)((uint16_t)value_optbyte && 8);
& && && && &res_value = res_value | (uint16_t)value_optbyte_
& && &&&else
& && && && &res_value = FLASH_OPTIONBYTE_ERROR ((uint16_t)0x5555)
& & return(res_value);
已退回1积分
工程师职场
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司11:39 提问
关于Android通过蓝牙接收的数据发生丢失的问题
背景:我现在在做手机端与单片机通过蓝牙进行数据传递。
问题:在我通过蓝牙接收单片机通过串口发来的数据的时候,出现了:
1:大量为0的无用数据;
2:缺失部分数据;
接收代码如下。
while(true){
num = inputStream.read(buffer_z);
for(i=0;i&i++){
buffer_z_new[n] = buffer_z[i];
String s =bytesToHexString(buffer_z_new);
smsg+=s.trim();
if(inputStream.available()==0)
} catch (IOException e) {
e.printStackTrace();
StringBuffer stringBuffer = new StringBuffer();
String a = smsg.replace("FB0000",",");
String[] b = a.split(",");
String c = b[1].replace("1000",",");
String[] d = c.split(",");
stringBuffer.append(d[1]);
String ends = stringBuffer.toString();
Message msg = new Message();
Bundle data = new Bundle();
data.putByteArray("bytes",ends.getBytes());
msg.what = MainActivity.ACCEPT_MESSAGE;
msg.setData(data);
handler.sendMessage(msg);
我该如何解决呢?
按赞数排序
你这个问题我也遇到过:
1.大量为0的无用数据应该是你的byte数组声明的长度太大了,这样没有数据的部分默认就是0,你可以这样声明的byte数组
byte [] b = new byte[inputStream.available()];
2.数据丢失问题有可能是蓝牙分段传输了,也可能是丢包了,分段问题你可以让单片机设备研发人员把给你发送的数据加上很好区别的头和尾,这样你就可以知道你收到的是否是一条完整的数据,如果不是就先把这个数组缓存起来,这样就可以解决了,丢包问题可能就是蓝牙设备连接不太稳定了。
我在字符串截取操作中将在数据一开始出现的大量为0的无用数据截取掉了,现在的遗留的问题是:数据的缺失。
一开始我发送handler的是obtainMessage,后来发现这个方法虽然效率快但是或会发现数据缺失问题,但是我改用sendMessage之后,数据缺失问题
依然没有改变。
我该怎么去处理呢?
数据流并不是连续的,在接收第一帧数据后,你使用break跳出了while(true)循环,后面的数据就没有了
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐

我要回帖

更多关于 byte类型数据 的文章

 

随机推荐