简体   繁体   English

无法在android中的两个蓝牙设备之间发送文本数据?

[英]Unable to send text data between two bluetooth devices in android?

I have downloaded the android sample of Bluetooth chat app to send text between two android devices using Bluetooth. 我已经下载了蓝牙聊天应用程序的android示例,使用蓝牙在两个Android设备之间发送文本。

I have installed and run this app in two android devices. 我在两个Android设备上安装并运行了这个应用程序。

I faced many problems in that code 我在那段代码中遇到了很多问题

  1. Service discovery failed exception - Fixed 服务发现失败异常 - 已修复
  2. java.io.IOException: Software caused connection abort - Fixed java.io.IOException:软件导致连接中止 - 已修复
  3. java.io.IOException: Connection reset by Peer - Struck on this java.io.IOException:由Peer重置连接 - 对此进行攻击

1. Cleared the Service discovery failed exception: 1.清除服务发现失败异常:

For service discovery failed exception, In Bluetooth Chat Service, I have checked sdk version and for the sdk version which is greater than Ginger Bread, 对于服务发现失败的异常,在蓝牙聊天服务中,我检查了sdk版本和sdk版本大于Ginger Bread,

I have used Method class to invoke RfCOMM socket connection and my first exception is solved in this approach. 我已经使用Method类来调用RfCOMM套接字连接,并且我的第一个异常在这种方法中得到了解决。

Exception Code 例外代码

 tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

Fixed Exception code 修复了异常代码

try {
if (Build.VERSION.SDK_INT < 9) { 
try {
     tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
       } catch (IOException e1) {
            e1.printStackTrace();
       }
       } else {
   Method m = null;
  try {
  m = device.getClass().getMethod("createRfcommSocket",
        new Class[] { int.class });
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
                }
                try {
                    tmp = (BluetoothSocket) m.invoke(device, 1);
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                }
            } catch (Exception e) {
                Log.e(TAG, "create() failed", e);
            }

2. Cleared java.io.IOException: Software caused connection abort 2.清除java.io.IOException:软件导致连接中止

I have made check whether the InputStream is available 我已经检查了InputStream是否可用

Exception Code 例外代码

bytes = mmInStream.read(buffer);

Fixed Exception code 修复了异常代码

 if (mmInStream.available() > 0) {
                            // Read from the InputStream
                            bytes = mmInStream.read(buffer);

Now my problem is when I try to send data between connected devices, it throws the following error message "Connection Reset By Peer" while writing to output stream 现在我的问题是当我尝试在连接的设备之间发送数据时,它会在写入输出流时抛出以下错误消息“Connection Reset By Peer”

Exception code: 例外代码:

public void write(byte[] buffer, int start, int end) {
mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
    if (mmOutStream !=null) {
        try {
             mmOutStream.write(buffer);
        } catch (IOException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
        }
    }
    else{
        Log.e("OutputStream Null","");
    }
}

== Update == ==更新==

Even though it shows that both devices are connected, the accept method returns fail 即使它显示两个设备都已连接,但accept方法返回失败

**06-19 10:30:23.625: D/BluetoothChatService(2630): connected
06-19 10:30:23.625: D/BluetoothChatService(2630): cancel Thread[AcceptThread,5,main]
06-19 10:30:23.625: V/BluetoothSocket.cpp(2630): abortNative
06-19 10:30:23.625: V/BluetoothSocket.cpp(2630): ...asocket_abort(50) complete
06-19 10:30:23.625: V/BluetoothSocket.cpp(2630): ...accept(50, RFCOMM) = -1 (errno 125)
06-19 10:30:23.632: E/BluetoothChatService(2630): accept() failed
06-19 10:30:23.632: E/BluetoothChatService(2630): java.io.IOException: Operation Canceled
06-19 10:30:23.632: E/BluetoothChatService(2630):   at android.bluetooth.BluetoothSocket.acceptNative(Native Method)

I had alot of problems with the chat example myself, so i tried another approach. 我自己的聊天示例有很多问题,所以我尝试了另一种方法。

First you have to make one device host and the other the client, this works with the example pretty well. 首先,您必须创建一个设备主机,而另一个设备客户端,这很好地适用于示例。 if you dont have this running, i can provide you with that code aswell. 如果你没有这个运行,我也可以为你提供该代码。

Using the classes above, you get the socket for the connection. 使用上面的类,您将获得连接的套接字。 Use that to pass it to this class and then you can send using the write method. 使用它将它传递给这个类,然后你可以使用write方法发送。 and the incoming messages are automatically parsed in the run-method (i added a message id and length to the front, thats why there is so much things going on in there) 并且在run-method中自动解析传入的消息(我在前面添加了一个消息id和长度,这就是为什么那里有很多事情发生)

private class ConnectedThread extends Thread {

/** the connection socket */
private final BluetoothSocket mmSocket;

/** input stream for incoming messages */
private final InputStream mmInStream;

/** output stream for outgoing messages */
private final OutputStream mmOutStream;

/**
 * save the socket and get the streams
 * 
 * @param socket
 */
public ConnectedThread(BluetoothSocket socket) {
    mmSocket = socket;
    InputStream tmpIn = null;
    OutputStream tmpOut = null;

    // Get the input and output streams, using temp objects because
    // member streams are final
    try {
        tmpIn = socket.getInputStream();
        tmpOut = socket.getOutputStream();
    } catch (IOException e) {
        e.printStackTrace();
    }

    mmInStream = tmpIn;
    mmOutStream = tmpOut;
}

/**
 * reads incoming data and splits it into single messages
 */
public void run() {
    /** buffer for a single byte message */
    byte[] buffer = new byte[1024];

    /** number of bytes returned from read() */
    int bytes;

    // Keep listening to the InputStream until an exception occurs
    while (true) {
        try {
            // read overhead from the InputStream
            bytes = mmInStream.read(buffer, 0, LEN_SIZE + LEN_TYPE);

            // if no bytes are read, wait for a new message
            if (bytes == 0)
                continue;

            // get the size bytes and convert them to int
            byte[] size_arr = new byte[LEN_SIZE];
            for (int i = 0; i < LEN_SIZE; i++)
                size_arr[i] = buffer[i];
            int size = convertByteArrayToInt(size_arr, LEN_SIZE);

            // the type is 1 byte after the size
            byte type = buffer[LEN_SIZE];

            // array for the output data
            byte[] output = new byte[size + LEN_TYPE];
            output[0] = type;

            // current position, read until cPos == size
            int cPos = 0;
            while (cPos < size) {
                // either read the buffer lenght or the remaining bytes
                int read_len = Math.min(buffer.length, size - cPos);
                bytes = mmInStream.read(buffer, 0, read_len);

                // write the bytes to the output
                for (int i = 0; i < bytes; i++)
                    output[cPos + i + LEN_TYPE] = buffer[i];

                // increase the current position
                cPos += bytes;
            }

            // add the message to the queue
            mMessageData.add(output);

            // tell the service about the new message
            mHandler.obtainMessage(BluetoothService.CONNECTION_RECV_MSG, mConnectionAddress).sendToTarget();

        } catch (IOException e) {
            // tell the service about the disconnect
            mHandler.obtainMessage(BluetoothService.CONNECTION_LOST, mConnectionAddress).sendToTarget();
            e.printStackTrace();
            break;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/**
 * writes a byte stream to the connection
 * 
 * @param bytes
 *            the byte stream
 */
public void write(byte[] bytes) {
    try {
        mmOutStream.write(bytes, 0, bytes.length);
        mmOutStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * close the socket
 */
public void cancel() {
    try {
        mmSocket.close();
    } catch (IOException e) {
    }
}

} }

This worked for me, i hope it also does for you. 这对我有用,我希望它也适合你。 If you have any question, feel free to ask :-) 如果您有任何疑问,请随时询问:-)

You could try this, although it probably shouldn't be a final fix. 你可以试试这个,虽然它可能不应该是最后的修复。 When I followed that example, I had this onResume() in my main activity, and I imagine you have something similar: 当我按照那个例子,我在我的主要活动中有这个onResume() ,我想你有类似的东西:

@Override
public synchronized void onResume() {
    super.onResume();
    if(D) Log.e(TAG, "+ ON RESUME +");
}

Try this: 尝试这个:

@Override
public synchronized void onResume() {
//    super.onResume();
    if(D) Log.e(TAG, "+ ON RESUME +");
}

This will stop the main activity from creating the AcceptThread more than once. 这将阻止主要活动多次创建AcceptThread。

I think your reading is wrong. 我觉得你的阅读错了。 I have the line 我有线

while (true) {
    try {
        // read overhead from the InputStream
        bytes = mmInStream.read(buffer, 0, LEN_SIZE + LEN_TYPE);

in my code and it is working perfectly, without .available() and so does @gtRfnkN. 在我的代码中它运行正常,没有.available(),@ gtRfnkN也是如此。 From my interpretation of the Java documentation, you cannot use .available() with InputStream. 根据我对Java文档的解释,您不能将.available()与InputStream一起使用。 See: http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available() particularly the part where it says "always returns zero for class InputStream". 请参阅: http//docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available(),特别是其中“始终为类InputStream返回零”的部分。

And just in case, here is an example of my write: 以防万一,这是我写的一个例子:

    public void write(byte[] buffer){
        try{
            //a delay of 20ms occurs after each flush...
            mmOutStream.write((byte)buffer[0]);
            mmOutStream.flush();
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM