蓝牙文件传输防止重入的方法
文章目录
蓝牙opp文件传输底层其实是支持同时传输多个文件的,但考虑到蓝牙速度较慢,UI也不好展示,故在系统层屏蔽了重入,当有文件传输时,新的连接请求会被拒绝。
public void ObexServerSockets::run() { try { while (!mStopped) { BluetoothSocket connSocket; BluetoothDevice device;
try {
... ...
/\* Signal to the service that we have received an incoming connection.
\*/
// 触发service的onConnect()
boolean isValid = ObexServerSockets.this.onConnect(device, connSocket);
if (!isValid) {
/\* Close connection if we already have a connection with another device
\* by responding to the OBEX connect request.
\*/
// service拒绝连接则创建ObexRejectServer响应回复
Log.i(mTag, "RemoteDevice is invalid - creating ObexRejectServer.");
BluetoothObexTransport obexTrans =
new BluetoothObexTransport(connSocket);
// Create and detach a selfdestructing ServerSession to respond to any
// incoming OBEX signals.
new ServerSession(obexTrans,
new ObexRejectServer(ResponseCodes.OBEX\_HTTP\_UNAVAILABLE,
connSocket), null);
// now wait for a new connect
} else {
// now wait for a new connect
}
} catch (IOException ex) {
if (mStopped) {
// Expected exception because of shutdown.
} else {
Log.w(mTag, "Accept exception for " + mServerSocket, ex);
ObexServerSockets.this.onAcceptFailed();
}
mStopped = true;
}
} // End while()
} finally { if (D) { Log.d(mTag, “AcceptThread ended for: " + mServerSocket); } } }
public boolean BluetoothOppService::onConnect(BluetoothDevice device, BluetoothSocket socket) {
if (D) { Log.d(TAG, " onConnect BluetoothSocket :” + socket + " \n :device :” + device); } // 有传输后拒绝新的连接请求 if (!mAcceptNewConnections) { Log.d(TAG, " onConnect BluetoothSocket :” + socket + " rejected”); return false; } BluetoothObexTransport transport = new BluetoothObexTransport(socket); Message msg = mHandler.obtainMessage(MSG_INCOMING_BTOPP_CONNECTION); msg.obj = transport; msg.sendToTarget(); mAcceptNewConnections = false; return true; }
public class ObexRejectServer extends ServerRequestHandler implements Callback {
private static final String TAG = "ObexRejectServer";
private static final boolean V = true;
private final int mResult;
private final HandlerThread mHandlerThread;
private final Handler mMessageHandler;
private static final int MSG\_ID\_TIMEOUT = 0x01;
private static final int TIMEOUT\_VALUE = 5 \* 1000; // ms
private final BluetoothSocket mSocket;
/\*\*
\* @param result the ResponseCodes.OBEX\_HTTP\_ code to respond to an incoming connect request.
\*/
// 5秒内onConnect响应错误码,之后自毁 public ObexRejectServer(int result, BluetoothSocket socket) { super(); mResult = result; mSocket = socket; mHandlerThread = new HandlerThread(“TestTimeoutHandler”, android.os.Process.THREAD_PRIORITY_BACKGROUND); mHandlerThread.start(); Looper timeoutLooper = mHandlerThread.getLooper(); mMessageHandler = new Handler(timeoutLooper, this); // Initiate self destruction. mMessageHandler.sendEmptyMessageDelayed(MSG_ID_TIMEOUT, TIMEOUT_VALUE); }
// OBEX operation handlers
@Override
public int onConnect(HeaderSet request, HeaderSet reply) {
if (V) {
Log.i(TAG, "onConnect() returning error");
}
return mResult;
}
public void shutdown() {
mMessageHandler.removeCallbacksAndMessages(null);
mHandlerThread.quit();
try {
// This will cause an exception in the ServerSession, causing it to shut down
mSocket.close();
} catch (IOException e) {
Log.w(TAG, "Unable to close socket - ignoring", e);
}
}
@Override
public boolean handleMessage(Message msg) {
if (V) {
Log.i(TAG, "Handling message ID: " + msg.what);
}
switch (msg.what) {
case MSG\_ID\_TIMEOUT:
shutdown();
break;
default:
// Message not handled
return false;
}
return true; // Message handled
}
}
文章作者 carter2005
上次更新 2019-05-28