首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android应用蓝牙收发数据失败: Socket意外关闭

Android应用蓝牙收发数据失败: Socket意外关闭
EN

Stack Overflow用户
提问于 2016-03-25 02:23:05
回答 1查看 255关注 0票数 0

我的蓝牙代码无法正确接收我发送的数据。上面说插座是关着的。

ADB错误:

代码语言:javascript
复制
03-24 11:09:01.189 6826-7480/com.team980.thunderscout W/System.err: java.io.IOException: bt socket closed, read return: -1
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:     at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:442)
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:     at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)

                                                                [ 03-24 11:09:01.190 25999:26018 I/         ]
                                                                [JSR82][JBT] JBT bt_handle_session_disconnect_ind parms.ps_type:01
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:     at java.io.InputStreamReader.read(InputStreamReader.java:231)
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:     at java.io.InputStreamReader.read(InputStreamReader.java:181)
03-24 11:09:01.190 6826-7480/com.team980.thunderscout W/System.err:     at com.team980.thunderscout.thread.ServerReadThread.run(ServerReadThread.java:48)

ServerReadThread.java:

代码语言:javascript
复制
package com.team980.thunderscout.thread;

import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class ServerReadThread extends Thread {
private final BluetoothSocket mmSocket;

private Context context;

public ServerReadThread(BluetoothSocket socket, Context context) {
    mmSocket = socket;

    this.context = context;
}

public void run() {

    InputStream is;

    try {
        is = mmSocket.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
        return;
    }

    InputStreamReader isr;

    try {
        isr = new InputStreamReader(is, "UTF-8");
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }

    StringBuilder sb = new StringBuilder();

    try {

        int data = isr.read(); //TODO somehow the socket closes here, returning -1! This is bad!

        while (data != -1) {
            char theChar = (char) data;
            sb.append(theChar);
            data = isr.read();
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

    String message = sb.toString();

    try {
        isr.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    postToastMessage("Found message: " + message); //TODO print result

    // Send the obtained bytes to the UI activity - TODO put it in a DB
    /*Intent broadcastIntent = new Intent();
    broadcastIntent.setAction("ThunderScout_RefreshData");
    context.sendBroadcast(broadcastIntent);*/
}

/* Call this from the main activity to shutdown the connection */
public void cancel() {
    try {
        mmSocket.close();
    } catch (IOException e) {
    }
}

public void postToastMessage(final String message) {
    Handler handler = new Handler(Looper.getMainLooper());

    handler.post(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
        }
    });
}
}

ServerAcceptThread:

代码语言:javascript
复制
package com.team980.thunderscout.thread;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import com.team980.thunderscout.bluetooth.BluetoothInfo;

import java.io.IOException;
import java.util.UUID;

public class ServerAcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;

private BluetoothAdapter mBluetoothAdapter;

private Context context;

public ServerAcceptThread(Context context) {
    // Use a temporary object that is later assigned to mmServerSocket,
    // because mmServerSocket is final
    BluetoothServerSocket tmp = null;

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    try {
        // MY_UUID is the app's UUID string, also used by the client code
        tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(BluetoothInfo.SERVICE_NAME, UUID.fromString(BluetoothInfo.UUID));
    } catch (IOException e) {
    }
    mmServerSocket = tmp;

    this.context = context;
}

public void run() {
    // Keep listening until exception occurs
    while (true) {
        BluetoothSocket socket;
        try {
            postToastMessage("Listening for incoming connections");
            socket = mmServerSocket.accept(); //TODO find cause of error
        } catch (IOException e) {
            e.printStackTrace();
            break;
        }
        // If a connection was accepted
        if (socket != null) {
            // Do work to manage the connection (in a separate thread)

            postToastMessage("Connected to " + socket.getRemoteDevice().getName());

            ServerReadThread readThread = new ServerReadThread(socket, context);
            readThread.start();
        }
    }
}

/**
 * Will cancel the listening socket, and cause the thread to finish
 */
public void cancel() {
    try {
        mmServerSocket.close();
    } catch (IOException e) {

    }
}

public void postToastMessage(final String message) {
    Handler handler = new Handler(Looper.getMainLooper());

    handler.post(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
        }
    });
}
}

ClientConnectionThread:

代码语言:javascript
复制
package com.team980.thunderscout.thread;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import com.team980.thunderscout.bluetooth.BluetoothInfo;
import com.team980.thunderscout.data.ScoutData;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.UUID;

public class ClientConnectionThread extends Thread {
private final BluetoothSocket mmSocket;

private BluetoothAdapter mBluetoothAdapter;

private ScoutData scoutData;

private Context context;


public ClientConnectionThread(BluetoothDevice device, ScoutData data, Context context) {
    // Use a temporary object that is later assigned to mmSocket,
    // because mmSocket is final
    BluetoothSocket tmp = null;

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    // Get a BluetoothSocket to connect with the given BluetoothDevice
    try {
        // MY_UUID is the app's UUID string, also used by the server code
        tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(BluetoothInfo.UUID));
    } catch (IOException e) { }
    mmSocket = tmp;

    scoutData = data;

    this.context = context;
}

public void run() {
    // Cancel discovery because it will slow down the connection
    mBluetoothAdapter.cancelDiscovery();

    try {
        // Connect the device through the socket. This will block
        // until it succeeds or throws an exception
        mmSocket.connect();
    } catch (IOException connectException) {
        // Unable to connect; close the socket and get out
        try {
            mmSocket.close();
        } catch (IOException closeException) {
            closeException.printStackTrace();
        }
        return;
    }

    postToastMessage("Successfully connected to server device");

    try {
        OutputStream os = mmSocket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");

        postToastMessage("Writing data: " + scoutData.getTeamNumber());

        osw.write(scoutData.getTeamNumber());

        postToastMessage("Send complete!");

        osw.close();
       //mmSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
    try {
        mmSocket.close();
    } catch (IOException e) { }
}

public void postToastMessage(final String message) {
    Handler handler = new Handler(Looper.getMainLooper());

    handler.post(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
        }
    });
}
}

我已经为此工作了几个小时,但没有结果。ServerAcceptThread不断地在后台运行,并等待另一台设备上的ClientConnectThread与其联系。然后,ServerAcceptThread产生一个ServerReadThread来读取ClientConnectThread发送的数据,但它每次都无法读取数据。

ServerAcceptThread由服务管理,ClientConnectThreads通过“发送”按钮在用户交互时产生。

如果你需要更多的信息,我很乐意提供。

EN

回答 1

Stack Overflow用户

发布于 2016-03-25 05:48:34

这是一个愚蠢的错误消息,就像这个领域的其他消息一样。它应该说的是对等体已经关闭了连接。插座仍处于打开状态。在关闭的套接字上调用read(),或者当read()在另一个线程中执行时将其关闭,这将(应该)导致异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36207382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档