蓝牙文件接收的过程
来源:互联网 发布:c语言小项目 编辑:程序博客网 时间:2024/04/28 11:50
1. 蓝牙开启后,蓝牙状态即是 BluetoothAdapter.STATE_ON
2. BluetoothOppService 里 Receiver接收到BluetoothAdapter.STATE_ON后,启动startSocketListener()。
void BtoppServiceBroadcastReceiver::onReceive(const sp<Context>& context, const sp<Intent>& intent) {
GLOGENTRY();
sp<BluetoothOppService> mspbtoppser = mwpbtoppserice.promote();
CHECK_NULL_POINTER_RETURN(mspbtoppser);
sp<String> action = intent->getAction();
if (action->equals(BluetoothAdapter::ACTION_STATE_CHANGED())) {
switch (intent->getIntExtra(BluetoothAdapter::EXTRA_STATE(), BluetoothAdapter::ERROR)) {
case BluetoothAdapter::STATE_ON:
GLOGI("Receiver BLUETOOTH_STATE_CHANGED_ACTION, BLUETOOTH_STATE_ON");
mspbtoppser->startSocketListener();
break;
case BluetoothAdapter::STATE_TURNING_OFF:
GLOGI("Receiver DISABLED_ACTION");
mspbtoppser->mSocketListener->stop();
mspbtoppser->mListenStarted = false;
{
RecursiveMutex::Autolock _l(mspbtoppser->mBluetoothOppServiceMutex);
if (mspbtoppser->mUpdateThread == NULL) {
mspbtoppser->stopSelf();
}
}
break;
}
}
}
3. 在mSocketListener.start(mHandler) 里通过handler发送一个MSG_INCOMING_BTOPP_CONNECTION消息
void BluetoothOppService::startSocketListener() {
GLOGENTRY();
GLOGI("start RfcommListener");
mSocketListener->start(mHandler);
GLOGV("RfcommListener started");
}
bool BluetoothOppRfcommListener::start(const sp<Handler>& callback) {
GLOGENTRY();
if (mSocketAcceptThread == NULL) {
mCallback = callback;
mSocketAcceptThread = new BTORFCLThread(this);
mInterrupted = false;
if (!Constants::USE_TCP_SIMPLE_SERVER) {
mSocketAcceptThread->run("BtOppRfcommListener");
}
}
return true;
}
bool BTORFCLThread::threadLoop() {
GLOGENTRY();
sp<BluetoothOppRfcommListener> spbtorfcl = mwpbtorfcl.promote();
if (spbtorfcl == NULL) {
LOGE("spbtorfcl is NULL");
return false;
}
..............
}
GLOGV("TCP listen thread finished");
} else {
bool serverOK = true;
GLOGI("Create BtServerSocket");
/*
* it's possible that create will fail in some cases.
* retry for 10 times
*/
for (int32_t i = 0; i < BluetoothOppRfcommListener::CREATE_RETRY_TIME && !spbtorfcl->mInterrupted; i++) {
GLOGD("BTORFCLThread::threadLoop() i = %d", i);
spbtorfcl->mBtServerSocket = spbtorfcl->mAdapter->listenUsingInsecureRfcommOn(spbtorfcl->mBtOppRfcommChannel);
if (spbtorfcl->mBtServerSocket == NULL) {
LOGE("Error create RfcommServerSocket");
serverOK = false;
}
if (!serverOK) {
{
RecursiveMutex::Autolock _l(spbtorfcl->mBluetoothOppRfcommListenerMutex);
GLOGI("wait 3 seconds");
// TODO TODO TODO
// check
Thread::milliSleep(3000);
}
} else {
break;
}
}
if (!serverOK) {
LOGE("Error start listening after %d try", BluetoothOppRfcommListener::CREATE_RETRY_TIME);
spbtorfcl->mInterrupted = true;
}
if (!spbtorfcl->mInterrupted) {
GLOGI("Accept thread started on channel %d", spbtorfcl->mBtOppRfcommChannel);
}
sp<BluetoothSocket> clientSocket = NULL;
while (!spbtorfcl->mInterrupted) {
GLOGI("BTORFCLThread::threadLoop() while loop");
clientSocket = spbtorfcl->mBtServerSocket->accept();
if (clientSocket != NULL) {
sp<BluetoothDevice> btdevice = clientSocket->getRemoteDevice();
GLOGI("Accepted connectoin from %s", SP_TOSTRING_STR(btdevice));
sp<BluetoothOppRfcommTransport> transport = new BluetoothOppRfcommTransport(clientSocket);
sp<Message> msg = Message::obtain();
msg->setTarget(spbtorfcl->mCallback);
msg->what = BluetoothOppRfcommListener::MSG_INCOMING_BTOPP_CONNECTION;
msg->obj = transport;
msg->sendToTarget();
} else {
LOGE("Error accept connection");
return false;
}
}
GLOGI("BluetoothSocket listen thread finished");
}
return false;
}
4. 这个消息在BluetoothOppService的handler处理后创建一个 createServerSession(transport);
void BtoppServiceHandler::handleMessage(const sp<Message>& msg) {
GLOGENTRY();
GLOGI("BtoppServiceHandler::handleMessage, msg->what %d", msg->what);
sp<BluetoothOppService> mspbtoppser = mwpbtoppserice.promote();
CHECK_NULL_POINTER_RETURN(mspbtoppser);
switch (msg->what) {
..................................
}
case BluetoothOppRfcommListener::MSG_INCOMING_BTOPP_CONNECTION:
{
GLOGI("Get incoming connection");
sp<ObexTransport> transport = safe_cast<ObexTransport*>(msg->obj);
/*
* Strategy for incoming connections:
* 1. If there is no ongoing transfer, no on-hold connection, start it
* 2. If there is ongoing transfer, hold it for 20 seconds(1 seconds * 20 times)
* 3. If there is on-hold connection, reject directly
*/
if (mspbtoppser->mBatchs->size() == 0 && mspbtoppser->mPendingConnection == NULL) {
GLOGI("Start Obex Server");
mspbtoppser->createServerSession(transport);
} else {
if (mspbtoppser->mPendingConnection != NULL) {
GLOGW("OPP busy! Reject connection");
// try {
transport->close();
// } catch(IOException e) {
// LOGE("close tranport error");
// }
} else if (Constants::USE_TCP_DEBUG && !Constants::USE_TCP_SIMPLE_SERVER) {
GLOGI("Start Obex Server in TCP DEBUG mode");
mspbtoppser->createServerSession(transport);
} else {
GLOGI("OPP busy! Retry after 1 second");
mspbtoppser->mIncomingRetries = mspbtoppser->mIncomingRetries + 1;
mspbtoppser->mPendingConnection = transport;
sp<Message> msg1 = Message::obtain(mspbtoppser->mHandler);
msg1->what = BluetoothOppService::MSG_INCOMING_CONNECTION_RETRY;
mspbtoppser->mHandler->sendMessageDelayed(msg1, 1000);
}
}
break;
}
5. createServerSession 里 mServerSession.preStart(),进而new obexSesstion,接收文件
void BluetoothOppService::createServerSession(const sp<ObexTransport>& transport) {
GLOGENTRY();
mServerSession = new BluetoothOppObexServerSession(this, transport);
GLOGD("BluetoothOppService:: BluetoothOppObexServerSession count %d", getStrongCount());
mServerSession->preStart();
GLOGI("Get ServerSession %s for incoming connection %s", mServerSession->toString()->string(), transport->toString()->string());
}
void BluetoothOppObexServerSession::preStart() {
GLOGENTRY();
GLOGI("BluetoothOppObexServerSession preStart");
GLOGD("acquire full WakeLock");
if (!mWakeLock->isHeld()) {
GLOGD("acquire in");
mWakeLock->acquire();
}
GLOGI("Create ServerSession with transport %s", SP_TOSTRING_STR(mTransport));
sp<Authenticator> auth = NULL;
mSession = new ServerSession(mTransport, this, auth);
if (mSession == NULL) {
LOGE("Create server session error");
}
}
OPP接收文件进度的更新:
BluetoothOppService.java里调用mNotifier.updateNotification(),通过Handlder来实现没100ms来更新一次UI,更新UI是另起的一个线程
NotificationUpdateThread,在该线程里更新进度updateActiveNotification
- 蓝牙文件接收的过程
- Android 蓝牙开发【五】OPP接收文件
- android 通过蓝牙接收文件,从历史传输记录打开,无法自动选择合适的应用程序
- 关于Mac Pro蓝牙接收移动设备传送文件的问题
- Android6.0源码分析之蓝牙显示接收到的文件
- 关于蓝牙接收数据的解决方案
- 【MTK】通过蓝牙分享及接收apk应用文件
- Android 蓝牙开发(五)OPP接收文件
- Android 蓝牙开发(五)OPP接收文件
- 7.0 灭屏接收蓝牙到文件唤醒屏幕
- 蓝牙连接的建立过程
- 蓝牙查寻的具体过程
- 蓝牙A2DP的初始化过程
- 蓝牙连接的建立过程
- 网络包的接收过程
- 窗口过程接收的消息
- 数字电视机顶盒的接收过程
- 蓝牙后台接收数据
- 开源搜索引擎评估:lucene sphinx elasticsearch
- 联发科4G产品到位 先进制程和高通零距离
- [c++]宏备忘
- Android中获取应用程序(包)的大小-----PackageManager的使用(二) .
- PHPEclipse搭建PHP开发环境
- 蓝牙文件接收的过程
- vs2005 调试技巧
- 身份证归属地查询免费api接口代码
- 分布式搜索Elasticsearch 概述
- 程序的顶部行
- hdu1241 Oil Deposits
- @Override报错问题
- SSH分页
- 【ORA-02049】超时分布式事务处理等待锁 解决方法