- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 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/
是否可以在蓝牙设备连接到 iOS 或从 iOS 断开连接时收到通知,即使我的应用程序处于后台?在 Android 上,我使用 ACTION_ACL_CONNECTED 和 ACTION_ACL_DIS
我对使用 Delphi 使用 USB 设备感到不舒服,并且对编写设备驱动程序的细节几乎一无所知(尽管我在学习使用 GoASM 进行汇编时遇到过一些)。 该设备可以是 USB 调制解调器或 USB 打印
我正在使用 java/servlet 和前端 JSP 开发 Web 应用程序。 我的页面为用户显示一些信息。 是否有任何适当的方法来检查网络连接是否处于 Activity 状态(开/关)以及支持所有浏
这个问题在这里已经有了答案: C# -- TcpListener.Start() causing SocketException with message "Only one usage of ea
我想向我的应用程序添加功能,以允许在 Windows 操作系统上检测播放/捕获设备的到达和断开连接。就像在 Skype 中一样 - 当您拔下设备时 - 它会显示设备丢失的通知,例如要求您选择另一个。
如何断开 org. apache. http. client.HttpClient 对象? 我正在这样创建它,但它没有任何 disconnect() 或 getHttpConnectionManage
我们正在开发一个 .NET 应用程序,其中一个要求是监视系统是否连接到 Internet。 我们能够获得“以太网电缆断开连接”的 .NET 事件,但如果调制解调器被重置,则不会触发此事件。我不想一直通
我正在尝试与使用自签名证书的后端服务器建立 websocket 连接。在 Firefox 中,我为自签名证书添加了一个异常(exception)。 但是我的 websocket 连接 wss://连接
我正在使用由 Excel 生成的用户窗体来修改 PowerPoint 演示文稿(这是避免需要启用宏的电子表格的迂回方法)。该表单工作得很好,但每次我将焦点放在它上时,Excel 应用程序都会获得焦点(
您好,我成功地开始了视频通话,但是当我断开视频通话时,摄像头 LED 指示灯仍然亮着。我怎样才能完全断开通话? Video.createLocalVideoTrack().then(track =>
您好,我成功地开始了视频通话,但是当我断开视频通话时,摄像头 LED 指示灯仍然亮着。我怎样才能完全断开通话? Video.createLocalVideoTrack().then(track =>
我正在尝试断开客户端与服务器的连接,但服务器仍将其视为已连接。我找不到解决这个问题的方法,关机、断开连接和关闭都不起作用。 我与客户端断开连接并检查服务器的一些代码: 客户: private vo
我正在使用 magic record 来完成我所有的核心数据工作。 一切都很好,除了有时我在后台进行更新时我需要从上下文中分离或断开实体。 例如 ButtonList = [Buttons MR_fi
我正在尝试实现一个颜色选择器,它从屏幕上各处的像素中获取颜色。为此,我计划使用全局鼠标 Hook 来监听 WM_MOUSEMOVE,以便在鼠标四处移动时更新颜色,并监听鼠标点击以确认 (WM_LBUT
我有一个使用 C# 编写的 TLS 连接的客户端/服务器 TCP 场景。 客户端在安静并恢复后无法传递消息(不活动时间约为 25 分钟)。但如果我让客户聊天(每 30 秒),就没有问题。 客户端和服务
我编写的这段代码完美运行,但我担心每 2 秒执行一次 ping 操作会消耗太多资源,或者可能导致互联网连接出现一些问题。 new Thread(() => {
关闭带有附加 MediaPlayer 的 MediaController 的正确方法是什么? 您不能执行 mediaController.setMediaPlayer(null) - 立即调用 upd
从我的笔记本电脑上断开外接显示器后,我丢失了一些应用程序,因为断开连接的显示器仍设置为默认显示器。我的一些窗口试图在断开连接的显示器上显示。 我有一个解决方法,例如右键单击应用程序图标并选择移动,然后
是否可以将分片节点从分片集中取出并独立运行? 例如,每个分片都有一个特定的客户。 谢谢。 最佳答案 是的,这是可能的。 MongoDB“主”节点不知道分片。只有路由器(和配置服务器)知道。如果您使用正
我正在探索 Cassandra 及其复制系统。为此,我在本地创建了 3 个节点并测试了不同的场景。我想暂停节点之间的通信,用相同的键写入不同的值,然后观察它们将决定什么。 那么问题来了:如何限制节点在
我是一名优秀的程序员,十分优秀!