我正在尝试使用这些来源制作文件传输蓝牙应用程序:
http://developer.android.com/guide/topics/connectivity/bluetooth.html
当我尝试以这种方式使用InputStream.read()
方法获取InputStream字节时:
public class ConnectedThread extends Thread {
...(some code here)
public void run(){
byte[] buffer = new byte[1024];
int bytes = -1;
//Keep listening to the InputStream while connected
while (true){
try {
bytes = this.mmInStream.read(buffer);
//* this part is not reached
if (bytes==-1){
Log.d("NoData:","-1");
}
}
catch(Exception e){
Log.d("inStream exception:",e.getMessage());
break;
}
}
}
...(some code here)
}
永远不会到达代码的下一部分(在这种情况下为"if"
部分),也不会出现Log.D
调试输出或我放在下面的任何其他内容。我刚从LogCat收到此消息:
BluetoothSocket read in: android.net.LocalStocketImpl$SocketInputStream@f7e
b08 len: 1024
要将数据从客户端传输到服务器,我这样做:
public class MainActivity extends Activity {
...(some code here)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
clientConnect();
//serverConnect();
}
...(some code here)
public void clientConnect(){
Set<BluetoothDevice> devices;
devices = bConfig.getPairedDevices();
if (devices == null){
return;
}
if (devices.size() > 0) {
BluetoothDevice device = devices.iterator().next();
ConnectThread connectTransmit = new ConnectThread(device,bConfig.getBluetoothAdapter(),BluetoothConfig.mUUID);
connectTransmit.start();
Toast.makeText(this, "connected", Toast.LENGTH_SHORT).show();
socket = connectTransmit.mmSocket;
ConnectedThread connectedThread = new ConnectedThread(socket);
//write file bytes to the connected thread, so the thread can receive its own input written bytes later
File file_to_transfer = new File(Environment.getExternalStorageDirectory() + "/txtTransfer.txt");
//get bytes from our File
int size = (int) file_to_transfer.length();
byte[] bytes = new byte[size];
try {
//14b are read succesfully, the whole text file
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file_to_transfer));
buf.read(bytes,0,bytes.length);
buf.close();
}catch (FileNotFoundException e){
Log.d("FileNotFoundException:",e.getMessage());
}catch (IOException e){
Log.d("IOException:",e.getMessage());
}
//send the data to the server
connectedThread.start();
connectedThread.write(bytes);
//connectedThread.cancel();
}
}
...(some code here)
}
AcceptThread
(实现的服务器部分)工作,因为当我运行客户端部分以连接然后传输数据时,在设备中进行调试时,服务器部件上的LogCat会激活并到达运行方法线程,我调用ConnectedThread
实现,但之后“显然”读取字节但它被卡在LogCat上没有错误。
请让我知道如何完成读取字节以转移到流程的下一部分。
谢谢
答案 0 :(得分:5)
你被阻止等待更多输入。
标记为... (some code here)
的部分应该在读取循环内,在流结束测试之后。注意如果read()
返回-1,它并不意味着没有数据&#39;,它意味着流的结束,你应该关闭套接字并打破读循环。否则,您应该继续处理您刚读过的数据。目前你只是读取并忽略所有输入,直到流结束,这是没有意义的。最多只能处理最后一个部分缓冲区,而且你不知道它有多长。
答案 1 :(得分:1)
在您的客户端代码中,您应该将connectedThread对象保持活动一段时间。可能是一旦if子句关闭并且它超出了范围(不太确定GC和所有情况会发生什么),写入就不会发生,并且您的连接没有关闭但也没有使用。
写入后在connectedThread内的mmOutStream上调用flush()也可能有所帮助。
与建议的@EJP一样,你应该把一些东西放在你的阅读循环中。
编辑:为了便于调试,您可以在写入客户端代码后立即添加this.wait(1000);
。
答案 2 :(得分:1)
在我看来你应该在阅读之前验证某些东西是否在缓冲区中。 从流中读取是阻止操作,因此应用程序将挂起,直到出现某些数据。 How can I check if an InputStream is empty without reading from it?
答案 3 :(得分:1)
尝试将run方法更改为:
public void run(){
byte[] buffer = new byte[1024];
int bytesRead = 0;
final int shortSleepTime = 1000;
final int longSleepTime = 5000;
int emptyReadCounter = 0;
int sleepCounter = 0;
int currentSleepTime = shortSleepTime;
//Keep listening to the InputStream while connected
while (bytesRead >= 0){
try {
// if available() returns 0, there is nothing to read yet
if (this.mmInStream.available() != 0){
bytesRead = this.mmInStream.read(buffer);
// Check if we need to reset the sleep counters
if (emptyReadCounter != 0){
emptyReadCounter = 0;
sleepCounter = 0;
currentSleepTime = shortSleepTime;
// We can also do anything else dependent on just waking up
// from a sleep cycle in this block
}
// Do something with my now full buffer
// Remember not to process more than
// 'bytesRead' bytes from my buffer because the
// rest could be filled with crap left over from
// the last iteration
} else {
// Three consecutive empty reads means sleep
if (emptyReadCounter++ >= 3){
if (currentSleepTime != longSleepTime && sleepCounter++ >= 3){
currentSleepTime = longSleepTime;
}
Thread.sleep(currentSleepTime);
}
}
}
catch(Exception e){
Log.d("inStream exception:",e.getMessage());
break;
}
}
}