gpt4 book ai didi

Android BluetoothSocket 连接后立即断开连接

转载 作者:行者123 更新时间:2023-11-29 00:41:37 25 4
gpt4 key购买 nike

我是 Android 的新手。现在我正在尝试使用蓝牙 API 制作一个两人 Pong 游戏。我或多或少尝试过复制 Android 网站上的 BluetoothChat 教程,但在切换到 ConnectedThread 后,我仍然收到套接字立即断开连接的错误。谁知道这是为什么?

我将三种类型的线程中的每一种都作为菜单屏幕上的私有(private)类。 ConnectThread 分为读和写,放在游戏画面内部。

public abstract class FindScreen extends EngineView {

private GUIFactory guiFact;

private TextButton backButton;
private ScrollingList buttonList;

public ConnectThread connectThread;
private BluetoothAdapter adapter;

public FindScreen(Context c, AndroidView aView) {
super(c, aView, 1);
adapter = BluetoothAdapter.getDefaultAdapter();

guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X,
EngineConstants.CENTER_Y), 8, 8, EngineConstants.VIRTUAL_W,
EngineConstants.VIRTUAL_H, EngineConstants.VIRTUAL_W / 32);

GUITask backTask = new GUITask() {
public void execute() {
goBack();
}
};
backButton = guiFact.newGradientTextButton(1, 6, 7, 7, backTask, "Back");
this.add(backButton, 0);

buttonList = guiFact.newScrollingList(1,1,7,6);
this.add(buttonList, 0);
}

@Override
public boolean onTouchEvent(MotionEvent e) {
backButton.executeIfContained(e.getX(), e.getY());
buttonList.executeIfContained(e.getX(), e.getY());
return true;
}

public void onIn() {
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(receiver, filter);

// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
context.registerReceiver(receiver, filter);
buttonList.clearButtons();
if(!adapter.startDiscovery()) { // if discovery doesn't start successfully, leave the screen
goBack();
}
}

public void onOut() {
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
context.unregisterReceiver(receiver);
if (connectThread != null) {
connectThread.cancel();
}
}

/**
* Return to the previous screen, the menu screen
*/
public abstract void goBack();

/**
* Do something after we've connected
* @param socket
*/

public abstract void connected(BluetoothSocket socket);

/**
* Broadcast receiver;
* Listens for discovered devices
* When discovery is finished, changes the list of discovered devices
* When discoverability is changed, changes text
*/

private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();

if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
buttonList.addButton(device.getName(), new ConnectTask(device.getAddress()));
// }
// doDiscovery();
}
}
};

private class ConnectTask extends GUITask {

private String address;

public ConnectTask(String addr) {
address = addr;
}

@Override
public void execute() {
BluetoothDevice device = adapter.getRemoteDevice(address);
if (connectThread != null) {
connectThread.cancel();
}
connectThread = new ConnectThread(device);
connectThread.start();
}

}

private class ConnectThread extends Thread {
private final BluetoothSocket socket;
private final BluetoothDevice device;

public ConnectThread(BluetoothDevice dev) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
device = dev;

// 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(EngineConstants.MY_UUID);
} catch (IOException e) { }
socket = tmp;
}

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

if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}

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

// Do work to manage the connection (in a separate thread)
connected(socket);
}

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

public abstract class HostScreen extends EngineView {

private GUIFactory guiFact;
private TextButton backButton;
private TextLabel waitText;

private BluetoothAdapter adapter;

public AcceptThread acceptThread;

private static final int DISCOVERY_LENGTH = 300;

public HostScreen(Context c, AndroidView aView) {
super(c, aView, 1);
adapter = BluetoothAdapter.getDefaultAdapter();

guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X,
EngineConstants.CENTER_Y), 8, 8, EngineConstants.VIRTUAL_W,
EngineConstants.VIRTUAL_H, EngineConstants.VIRTUAL_W / 32);

GUITask backTask = new GUITask() {
public void execute() {
goBack();
}
};
backButton = guiFact.newGradientTextButton(1, 6, 7, 7, backTask, "Back");
this.add(backButton, 0);

waitText = guiFact.newLabel(2, 3, 6, 4, Color.WHITE, "...");
this.add(waitText, 0);
}

public void onIn() {
if (adapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERY_LENGTH);
((Activity) context).startActivityForResult(discoverableIntent, EngineConstants.REQUEST_DISCOVERABLE);
}
if (!adapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivity(enableIntent);
}
}

public void onOut() {
if (acceptThread != null) {
acceptThread.cancel();
}
}

public void discoverableAccepted() {
if (acceptThread != null) {
acceptThread.cancel();
}
acceptThread = new AcceptThread();
acceptThread.start();
}

public void discoverableDeclined() {
goBack();
}

/**
* Do something after we've connected
* @param socket
*/

public abstract void connected(BluetoothSocket socket);

@Override
public boolean onTouchEvent(MotionEvent e) {
backButton.executeIfContained(e.getX(), e.getY());
return true;
}

/**
* Return to the previous screen, the menu screen
*/
public abstract void goBack();

private class AcceptThread extends Thread {
private final BluetoothServerSocket serverSocket;

public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = adapter.listenUsingRfcommWithServiceRecord(EngineConstants.NAME, EngineConstants.MY_UUID);
} catch (IOException e) { }
serverSocket = tmp;
}

public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
connected(socket);
try {
serverSocket.close();
} catch (IOException e) {
android.util.Log.d("Accept thread", "Could not close serverSocket");
}
break;
}
}
}

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


public class GameScreen extends EngineView {

public ConnectedThread connectedThread;
public ConnectedWriteThread writeThread;
private PacketHandler handler;

private final static int N_LAYERS = 4;
// layer 0 = walls
// layer 1 = puck
// layer 2 = paddles
// layer 3 = GUI

public Paddle enemyPaddle, playerPaddle;
public Puck puck;

private GUIFactory guiFact;
private TextLabel playerLabel, enemyLabel;
public int playerScore = 0, enemyScore = 0;

private boolean isHeld;
private float startX, startTouchX, moveToX;
private final static float MIN_X = Paddle.RADIUS, MAX_X = EngineConstants.VIRTUAL_W - MIN_X;

public float myPaddlePrevPosX;
public boolean enemyScoreChanged = false;

private final static long PACKET_RATE = 200;
private long packetTime = 0;

public GameScreen(Context c, final AndroidView aView) {
super(c, aView, N_LAYERS);

enemyPaddle = new Paddle(new Vector2d(EngineConstants.CENTER_X, EngineConstants.VIRTUAL_H/8f), 255, 255, 100, 100);
playerPaddle = new Paddle(new Vector2d(EngineConstants.CENTER_X, EngineConstants.VIRTUAL_H*7f/8f), 255, 100, 255, 100);

puck = new Puck();

this.add(enemyPaddle, 2);
this.add(playerPaddle, 2);
this.add(puck, 1);

guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X, EngineConstants.CENTER_Y), 8, 10, EngineConstants.VIRTUAL_W, EngineConstants.VIRTUAL_H, 0);
playerLabel = guiFact.newLabel(2, 4, 3, 5, Color.rgb(100, 150, 100), "0");
enemyLabel = guiFact.newLabel(7, 3, 8, 4, Color.rgb(150, 100, 100), "0");

this.add(playerLabel, 3);
this.add(enemyLabel, 3);

this.constraints.add(new BoxConstraint(puck, false, false, 0 + Puck.RADIUS));
this.constraints.add(new BoxConstraint(puck, false, true, EngineConstants.VIRTUAL_W - Puck.RADIUS));

myPaddlePrevPosX = playerPaddle.pos.x;
}

public void onOut() {
if (connectedThread != null) {
connectedThread.cancel();
}
if (writeThread != null) {
writeThread.cancel();
}
}

public void update(long interval) {
super.update(interval);
EngineFunctions.collide(playerPaddle, puck);
EngineFunctions.collide(enemyPaddle, puck);
if (puck.pos.y < 0) {
score(true);
} else if (puck.pos.y > EngineConstants.VIRTUAL_H) {
score(false);
}

packetTime += interval;
if (packetTime > PACKET_RATE) {
// android.util.Log.d("fillQueue", "called");
packetTime = 0;
writeThread.fillQueue();
}
}

private void score(boolean isPlayer) {
if (isPlayer) {
playerScore++;
playerLabel.setText(String.valueOf(playerScore));
} else {
enemyScore++;
enemyLabel.setText(String.valueOf(enemyScore));
enemyScoreChanged = true;
}
puck.pos.x = EngineConstants.CENTER_X;
puck.pos.y = EngineConstants.CENTER_Y;
puck.prevPos.x = EngineConstants.CENTER_X;
puck.prevPos.y = EngineConstants.CENTER_Y;
}

@Override
public boolean onTouchEvent(MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
if (playerPaddle.touching(e.getX(), e.getY())) {
isHeld = true;
startX = playerPaddle.pos.x;
startTouchX = e.getX();
}
break;
case MotionEvent.ACTION_MOVE:
if (isHeld) {
myPaddlePrevPosX = playerPaddle.pos.x;
moveToX = startX + (e.getX() - startTouchX);
if (moveToX < MIN_X) {
moveToX = MIN_X;
} else if (moveToX > MAX_X) {
moveToX = MAX_X;
}
playerPaddle.pos.x = moveToX;
playerPaddle.prevPos.x = moveToX;
}
break;
case MotionEvent.ACTION_UP:
isHeld = false;
break;
}
return true;
}

public void startNewConnectedThread(BluetoothSocket soc, boolean isServer) {
if (connectedThread != null) {
connectedThread.cancel();
}
connectedThread = new ConnectedThread(soc, handler);
connectedThread.start();

if (writeThread != null) {
writeThread.cancel();
}
writeThread = new ConnectedWriteThread(soc, handler, isServer);
writeThread.start();
}

public void setHandler(PacketHandler h) {
handler = h;
}

public class ConnectedThread extends Thread {
private final BluetoothSocket socket;
private final InputStream inStream;

private final BufferedReader in;

private PacketHandler handler;

public ConnectedThread(BluetoothSocket soc, PacketHandler pHandler) {
socket = soc;
handler = pHandler;
InputStream tmpIn = null;

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

}

inStream = tmpIn;

in = new BufferedReader(new InputStreamReader(inStream));
}

public void run() {
/*
// Keep listening to the InputStream until an exception occurs
android.util.Log.d("connectedThread", "started");
String str;
try {
inStream.read();
inStream.read();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
android.util.Log.d("connectedThread", "normal read is fine");

while (true) {

try {
// Read from the InputStream
str = in.readLine();
byte type = Byte.valueOf(str);
android.util.Log.d("connectedThread", "read");
handler.handlePacket(in, type);
} catch (IOException e) {
break;
}
}*/

for (int i = 0; i < 20; i++) {
try {
String str = in.readLine();
android.util.Log.d("read", str + " ");
} catch (IOException e) {
// TODO Auto-generated catch block
android.util.Log.d("io exception", e.getMessage() + " " + e.getLocalizedMessage() + " " + e.getCause());
}

}
while (true) {

}

}

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


public class ConnectedWriteThread extends Thread {
public ConcurrentLinkedQueue<String> que;

private final BluetoothSocket socket;
private final OutputStream outStream;

private final BufferedWriter out;

private PacketHandler handler;

private boolean isServ;

public ConnectedWriteThread(BluetoothSocket soc, PacketHandler pHandler, boolean isServer) {
socket = soc;
handler = pHandler;
isServ = isServer;
OutputStream tmpOut = null;
que = new ConcurrentLinkedQueue<String>();

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

outStream = tmpOut;

out = new BufferedWriter(new OutputStreamWriter(outStream));
}

public void run() {
// Keep listening to the InputStream until an exception occurs
android.util.Log.d("connectedThread", "started");
/*
try {
if (isServ) {
out.write(String.valueOf(EngineConstants.PACKET_SYNC) + '\n');
out.write(String.valueOf(0) + '\n');
}
} catch (IOException e1) {
android.util.Log.d("connectedThread", "io exception " + e1.getMessage() + " " + e1.getLocalizedMessage() + " " + e1.getCause());
}
//android.util.Log.d("connectedThread", "sent initial packet");
while (true) {
if (!que.isEmpty()) {
try {
out.write(que.poll());
out.flush();
// android.util.Log.d("connectedThread", "sent packet");
} catch (IOException e) {
android.util.Log.d("write thread", "io exception " + e.getMessage());
}
}
}*/
try {
outStream.write(3);
out.write("343567\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {

}
}

public void fillQueue() {
// android.util.Log.d("fillQueue", "in method");
handler.queuePacket(que);
}

/* Call this from the main Activity to send data to the remote device */
public void write(String str) {
try {
out.write(str);
} catch (IOException e) { }
}

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

最佳答案

尝试使用反射:

try {
BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice("MAC of remote device");
Method m = mDevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mSocket = (BluetoothSocket) m.invoke(mDevice, Integer.valueOf(1));
mSocket.connect();
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
} catch (Exception e) {}

在你的话题中过了一段时间

mInStream = mSocket.getInputStream();
mOutStream = mSocket.getOutputStream();

mInStream 是 InputStream(),mOutStream 是 OutputStream()。

我在 HTC 设备上使用蓝牙连接时遇到了这个问题。

关于Android BluetoothSocket 连接后立即断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8981590/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com