android蓝牙开发,注册一个android 广播接收器者报空指针异常的错误。

爱生活,爱Android
Android应用程序注册广播接收器(registerReceiver)的过程分析
前面我们介绍了Android系统的广播机制,从本质来说,它是一种消息订阅/发布机制,因此,使用这种消息驱动模型的第一步便是订阅消息;而对Android应用程序来说,订阅消息其实就是注册广播接收器,本文将探讨Android应用程序是如何注册广播接收器以及把广播接收器注册到哪里去的。《Android系统源代码情景分析》一书正在进击的程序员网()中连载,点击进入!
在Android的广播机制中,ActivityManagerService扮演着广播中心的角色,负责系统中所有广播的注册和发布操作,因此,Android应用程序注册广播接收器的过程就把是广播接收器注册到ActivityManagerService的过程。Android应用程序是通过调用ContextWrapper类的registerReceiver函数来把广播接收器BroadcastReceiver注册到ActivityManagerService中去的,而ContextWrapper类本身又借助ContextImpl类来注册广播接收器。
在Android应用程序框架中,Activity和Service类都继承了ContextWrapper类,因此,我们可以在Activity或者Service的子类中调用registerReceiver函数来注册广播接收器。Activity、Service、ContextWrapper和ContextImpl这四个类的关系可以参考前面一文中描述的Activity类图。
这篇文章还是继续以实例来进行情景分析,所用到的例子便是上一篇文章里面介绍的应用程序了,所以希望读者在继续阅读本文之前,先看看这篇文章;又由于Android应用程序是把广播接器注册到ActivityManagerService中去的,因此,这里又会涉入到Binder进程间通信机制,所以希望读者对Android系统的Binder进程间通信机制有所了解,具体请参考一文。
开始进入主题了,在一文所介绍的例子中,注册广播接收器的操作是MainActivity发起的,我们先来看看注册过程的序列图:
在分析这个序列图之前,我们先来看一下MainActivity是如何调用registerReceiver函数来注册广播接收器的:public class MainActivity extends Activity implements OnClickListener {
public void onResume() {
super.onResume();
IntentFilter counterActionFilter = new IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);
registerReceiver(counterActionReceiver, counterActionFilter);
MainActivity在onResume函数里,通过其父类ContextWrapper的registerReceiver函数注册了一个BroadcastReceiver实例counterActionReceiver,并且通过IntentFilter实例counterActionFilter告诉ActivityManagerService,它要订阅的广播是CounterService.BROADCAST_COUNTER_ACTION类型的,这样,ActivityManagerService在收到CounterService.BROADCAST_COUNTER_ACTION类型的广播时,就会分发给counterActionReceiver实例的onReceive函数。
接下来,就开始分析注册过程中的每一个步骤了。
Step 1. ContextWrapper.registerReceiver
这个函数实现在frameworks/base/core/java/android/content/ContextWrapper.java文件中:public class ContextWrapper extends Context {
Context mB
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
这里的成员变量mBase是一个ContextImpl实例,想知道为什么,可以回过头去看看这篇文章&~&。
Step 2. ContextImpl.registerReceiver
这个函数实现在frameworks/base/core/java/android/app/ContextImpl.java文件中:class ContextImpl extends Context {
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, filter, broadcastPermission,
scheduler, getOuterContext());
private Intent registerReceiverInternal(BroadcastReceiver receiver,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd =
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
return ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(),
rd, filter, broadcastPermission);
} catch (RemoteException e) {
通过两个函数的中转,最终就进入到ContextImpl.registerReceiverInternal这个函数来了。这里的成员变量mPackageInfo是一个LoadedApk实例,它是用来负责处理广播的接收的,在后面一篇文章讲到广播的发送时(sendBroadcast),会详细描述。参数broadcastPermission和scheduler都为null,而参数context是上面的函数通过调用函数getOuterContext得到的,这里它就是指向MainActivity了,因为MainActivity是继承于Context类的,因此,这里用Context类型来引用。
由于条件mPackageInfo != null和context != null都成立,而且条件scheduler == null也成立,于是就调用mMainThread.getHandler来获得一个Handler了,这个Hanlder是后面用来分发ActivityManagerService发送过的广播用的。这里的成员变量mMainThread是一个ActivityThread实例,在前面这篇文章也描述过了。我们先来看看ActivityThread.getHandler函数的实现,然后再回过头来继续分析ContextImpl.registerReceiverInternal函数。
Step 3. ActivityThread.getHandler
这个函数实现在frameworks/base/core/java/android/app/ActivityThread.java文件中:public final class ActivityThread {
final H mH = new H();
private final class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
final Handler getHandler() {
return mH;
有了这个Handler之后,就可以分发消息给应用程序处理了。
再回到上一步的ContextImpl.registerReceiverInternal函数中,它通过mPackageInfo.getReceiverDispatcher函数获得一个IIntentReceiver接口对象rd,这是一个Binder对象,接下来会把它传给ActivityManagerService,ActivityManagerService在收到相应的广播时,就是通过这个Binder对象来通知MainActivity来接收的。
我们也是先来看一下mPackageInfo.getReceiverDispatcher函数的实现,然后再回过头来继续分析ContextImpl.registerReceiverInternal函数。
Step 4. LoadedApk.getReceiverDispatcher
这个函数实现在frameworks/base/core/java/android/app/LoadedApk.java文件中:final class LoadedApk {
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd =
HashMap&BroadcastReceiver, LoadedApk.ReceiverDispatcher& map =
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) {
if (map == null) {
map = new HashMap&BroadcastReceiver, LoadedApk.ReceiverDispatcher&();
mReceivers.put(context, map);
map.put(r, rd);
rd.validate(context, handler);
return rd.getIIntentReceiver();
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference&LoadedApk.ReceiverDispatcher& mD
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference&LoadedApk.ReceiverDispatcher&(rd);
final IIntentReceiver.Stub mIIntentR
final Handler mActivityT
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
mIIntentReceiver = new InnerReceiver(this, !registered);
mActivityThread = activityT
IIntentReceiver getIIntentReceiver() {
return mIIntentR
在LoadedApk.getReceiverDispatcher函数中,首先看一下参数r是不是已经有相应的ReceiverDispatcher存在了,如果有,就直接返回了,否则就新建一个ReceiverDispatcher,并且以r为Key值保在一个HashMap中,而这个HashMap以Context,这里即为MainActivity为Key值保存在LoadedApk的成员变量mReceivers中,这样,只要给定一个Activity和BroadcastReceiver,就可以查看LoadedApk里面是否已经存在相应的广播接收发布器ReceiverDispatcher了。
在新建广播接收发布器ReceiverDispatcher时,会在构造函数里面创建一个InnerReceiver实例,这是一个Binder对象,实现了IIntentReceiver接口,可以通过ReceiverDispatcher.getIIntentReceiver函数来获得,获得后就会把它传给ActivityManagerService,以便接收广播。在ReceiverDispatcher类的构造函数中,还会把传进来的Handle类型的参数activityThread保存下来,以便后面在分发广播的时候使用。
现在,再回到ContextImpl.registerReceiverInternal函数,在获得了IIntentReceiver类型的Binder对象后,就开始要把它注册到ActivityManagerService中去了。
Step 5. ActivityManagerProxy.registerReceiver
这个函数实现在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:class ActivityManagerProxy implements IActivityManager
public Intent registerReceiver(IApplicationThread caller,
IIntentReceiver receiver,
IntentFilter filter, String perm) throws RemoteException
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
filter.writeToParcel(data, 0);
data.writeString(perm);
mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
reply.readException();
Intent intent =
int haveIntent = reply.readInt();
if (haveIntent != 0) {
intent = Intent.CREATOR.createFromParcel(reply);
reply.recycle();
data.recycle();
这个函数通过Binder驱动程序就进入到ActivityManagerService中的registerReceiver函数中去了。
Step 6. ActivityManagerService.registerReceiver
这个函数实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
public Intent registerReceiver(IApplicationThread caller,
IIntentReceiver receiver, IntentFilter filter, String permission) {
synchronized(this) {
ProcessRecord callerApp =
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
if (callerApp == null) {
List allSticky =
// Look for any matching sticky broadcasts...
Iterator actions = filter.actionsIterator();
if (actions != null) {
while (actions.hasNext()) {
String action = (String)actions.next();
allSticky = getStickiesLocked(action, filter, allSticky);
// The first sticky in the list is returned directly back to
// the client.
Intent sticky = allSticky != null ? (Intent)allSticky.get(0) :
if (receiver == null) {
ReceiverList rl
= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp,
Binder.getCallingPid(),
Binder.getCallingUid(), receiver);
if (rl.app != null) {
rl.app.receivers.add(rl);
mRegisteredReceivers.put(receiver.asBinder(), rl);
BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
rl.add(bf);
mReceiverResolver.addFilter(bf);
// Enqueue broadcasts for all existing stickies that match
// this filter.
if (allSticky != null) {
函数首先是获得调用registerReceiver函数的应用程序进程记录块:
ProcessRecord callerApp =
if (caller != null) {
callerApp = getRecordForAppLocked(caller);
if (callerApp == null) {
这里得到的便是上一篇文章里面介绍的应用程序Broadcast的进程记录块了,MainActivity就是在里面启动起来的。
List allSticky =
// Look for any matching sticky broadcasts...
Iterator actions = filter.actionsIterator();
if (actions != null) {
while (actions.hasNext()) {
String action = (String)actions.next();
allSticky = getStickiesLocked(action, filter, allSticky);
// The first sticky in the list is returned directly back to
// the client.
Intent sticky = allSticky != null ? (Intent)allSticky.get(0) :
这里传进来的filter只有一个action,就是前面描述的CounterService.BROADCAST_COUNTER_ACTION了,这里先通过getStickiesLocked函数查找一下有没有对应的sticky intent列表存在。什么是Sticky Intent呢?我们在最后一次调用sendStickyBroadcast函数来发送某个Action类型的广播时,系统会把代表这个广播的Intent保存下来,这样,后来调用registerReceiver来注册相同Action类型的广播接收器,就会得到这个最后发出的广播。这就是为什么叫做Sticky Intent了,这个最后发出的广播虽然被处理完了,但是仍然被粘住在ActivityManagerService中,以便下一个注册相应Action类型的广播接收器还能继承处理。
这里,假设我们不使用sendStickyBroadcast来发送CounterService.BROADCAST_COUNTER_ACTION类型的广播,于是,这里得到的allSticky和sticky都为null了。
继续往下看,这里传进来的receiver不为null,于是,继续往下执行:
ReceiverList rl
= (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp,
Binder.getCallingPid(),
Binder.getCallingUid(), receiver);
if (rl.app != null) {
rl.app.receivers.add(rl);
mRegisteredReceivers.put(receiver.asBinder(), rl);
这里其实就是把广播接收器receiver保存一个ReceiverList列表中,这个列表的宿主进程是rl.app,这里就是MainActivity所在的进程了,在ActivityManagerService中,用一个进程记录块来表示这个应用程序进程,它里面有一个列表receivers,专门用来保存这个进程注册的广播接收器。接着,又把这个ReceiverList列表以receiver为Key值保存在ActivityManagerService的成员变量mRegisteredReceivers中,这些都是为了方便在收到广播时,快速找到对应的广播接收器的。
再往下看:
BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
rl.add(bf);
mReceiverResolver.addFilter(bf);
上面只是把广播接收器receiver保存起来了,但是还没有把它和filter关联起来,这里就创建一个BroadcastFilter来把广播接收器列表rl和filter关联起来,然后保存在ActivityManagerService中的成员变量mReceiverResolver中去。
这样,广播接收器注册的过程就介绍完了,比较简单,但是工作又比较琐碎,主要就是将广播接收器receiver及其要接收的广播类型filter保存在ActivityManagerService中,以便以后能够接收到相应的广播并进行处理,在下一篇文章,我们将详细分析这个过程,敬请关注。老罗的新浪微博:,欢迎关注!
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Android中广播接收者的注册与释放
Android中常常利用广播机制来在各个组件之间传递消息,例如在Activity和Service之间。
在Activity中注册广播接收者,接收来自Service的广播:
public class LoginReceiver extends BroadcastReceiver {
private boolean loginResult = false;
public void onReceive(Context context, Intent intent) {
unregisterReceiver(this);
loginResult = intent.getBooleanExtra("login_result", false);
if (loginResult) {
Intent loginIntent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(loginIntent);
Log.d("IntoMainActivity", "进入主Activity");
LoginActivity.this.finish();
Log.d("FinishLoginActivity", "结束登陆Activity");
其中的onReceive()方法是继承BroadcastReceiver时必须实现的方法,当接收到指定的广播时,调用该方法。
将自定义的广播接收者注册到Activity中并接收来自其他组件的广播:
loginRec = new LoginReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.whu.mobileoa.login_result");
registerReceiver(loginRec, filter);
在Service组件中定义并发送广播:
Intent loginReltInt = new Intent();
if (loginResult == 0) {
loginReltInt.putExtra("login_result", false);
loginReltInt.putExtra("login_result", true);
loginReltInt.setAction("com.whu.mobileoa.login_result");
sendBroadcast(loginReltInt);
我在这里要进行的操作是,当接收到广播并进行判断后,需要跳转到其他的Activity,并关闭当前的Activity。如果在关闭当前Activity之前没有释放注册到它那里的广播接收者,会报广播接收者泄露的错误:
Activity……
has leaked IntentReceiver……
that was originally registered here. Are you missing a call to unregisterReceiver()?
出现这个错误的原因在当前Activity被销毁前,没有释放注册的广播接收者。
因此在接收并处理完广播消息后(即回调了onReceive()时),需要释放之前注册的广播接收者:
unregisterReceiver(this);
依此类推,在其他组件中注册广播接收者,也需要在组件销毁前释放广播接收者。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Android 动态注册广播接收器
&从本质来说, 的广播机制是一种消息订阅/发布机制,因此,使用这种消息驱动模型的第一步便是订阅消息;而对 Android 应用程序来说,订阅消息其实就是注册广播接收器。
&&& 注册的方法有两种,一种是静态注册,一种是动态注册。在 Android 的广播机制中,动态注册的优先级是要高于静态注册优先级的,因此在必要的情况下,我们是需要动态注册广播接收器的。
&&& 先回顾一下静态注册。所谓注册,就是在 Manifest.xml 中去注册广播接收器。
&receiver android:name=&& &&
&&&&&&&&&& &intent-filter android:priority=&& &&
&&&&&&&&&&&&&& &action android:name=&android.provider.Telephony.SMS_RECEIVED& &&
&&&&&&&&&&&&&& &/action&&
&&&&&&&&&& &/intent-filter&&
&&&&&& &/receiver&&
&&& 然后再创建一个继承 BroadcastReceiver 得类即可。在这里要特意强调一下的是,intent-filter 标签中的 priority 是设置广播接收器的优先级,网上很多资料都表示,优先级的设置数值为,1000最大,但事实上,当 priority 值为integer 的最大值才时,才是优先级最高的,即& ;当然,&最高&只是限于静态注册。
&&& 了解更多关于静态注册信息,可参考《【Android】短信应用&&短信信息实时获取》&一文,其短信信息的获取就是运用了广播接收器的静态注册。
&&& 下面回到正题,如何动态注册广播接收器。
&&& 首先,我们来写一个内部类,继承 BroadcastReceiver。
private BroadcastReceiver myReceiver = new BroadcastReceiver() {&
&&&&&&& @Override&
&&&&&&& public void onReceive(Context context, Intent intent) {&
&&&&&&&&&&& Toast.makeText(context, &myReceiver receive&, Toast.LENGTH_SHORT)&
&&&&&&&&&&&&&&&&&&& .show();&
&&&&&&& }&
&&& onReveice 中我们写一个 Toast,稍后用来检测广播接收器是否成功注册。
&&& 下面来看看如何去注册广播接收器。
private static final String ACTION = &cn.etzmico.broadcastreceiverregister.SENDBROADCAST&;&
IntentFilter filter = new IntentFilter();&
&&&&&&&&&&&&&&& filter.addAction(ACTION);&
&&&&&&&&&&&&&&& filter.setPriority(Integer.MAX_VALUE);&
&&&&&&&&&&&&&&& registerReceiver(myReceiver, filter);&
&&& 我们在注册的时候也来设置下优先级,正如上面文章提到的,用 Integer& 的最大值来获得广播机制中的最高优先级。
&&& 广播注册完毕,下面就是来做测试,来检验广播接收器是否注册个成功。
sendBroadcast(new Intent(ACTION));&
&&& 动态注册广播接收器还有一个特点,就是当用来注册的 Activity 关掉后,广播也就失效了。同时反映了静态注册的一个优势,就是无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器就是打开着的。
&&& 不过,我们可以通过将广播接收器在 Service 中动态注册,并设置开机自启动,这样一来,就不会担心像Activity一样的关闭问题了。但又如果要用&自启动管家&等带有管理开机自启动程序功能的软件讲相关自启动程序关闭时,广播接收器也就无法成功注册了。要想解决这个问题,就要看,是否能防止程序的自启动被关闭。另外,现市场上有没有程序能通过管理广播接收器来关闭静态注册的广播接收器,我还在调研,目前没有发现,如果有知道的,欢迎留言说明~谢谢!
&&& 后续的文章我会写一篇关于通过动态注册广播接收器方法来实现有最高优先级的短信拦截功能的文章。文章中会提到如何开机自启动 Service 和 用 Service 动态注册广播接收器,敬请关注!谢谢~
PS:之前附加的资源有一个小BUG,给大家带来了不便,不好意思!!!下面的链接是新上传的&&没BUG的&&I promise!&
摘自& Etzmico&订阅你的位置: >
> 【已解决】Android中连接蓝牙设备时遇到createRfcommSocketToServiceRecord的UUID问题和BluetoothSocket的connect失败
【问题】折腾:期间,参考:参考“Connecting as a client”中的:tmp = device.createRfcommSocketToServiceRecord(MY_UUID);遇到UUID不懂的问题。然后随便去弄了个UUID:e214d9ae-c3ba-4e25-abb5-bc3结果运行到:
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// U close the socket and get out
mmSocket.close();
} catch (IOException closeException) { }
}中的:mmSocket.connect(); 时就抛异常了。即:遇到createRfcommSocketToServiceRecord的UUID不懂,以及BluetoothSocket的connect失败。 【解决过程】1.参考:去试试:Method m = device.getClass().getMethod(&createRfcommSocket&, new Class[] {int.class});
mBTSocket = (BluetoothSocket) m.invoke(device, 1);结果看着就不太对啊。。就不继续试了。2.参考:去试试:0-100-0-F9B34FB结果直接挂掉。3.再去试试:0-100-0-F9B34FB也会挂掉。4.后来再去搜:android bluetooth connect fail然后去参考:和:去试试,用代码: // Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
BluetoothDevice deviceExtra = intent.getParcelableExtra(&android.bluetooth.device.extra.DEVICE&);
Parcelable[] uuidExtra = intent.getParcelableArrayExtra(&android.bluetooth.device.extra.UUID&);
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice btDev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] btDevUuid = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);调试得到的btDevUuid都是null的。5.换用:
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice btDev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Parcelable[] btDevUuid = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
UUID btDevUuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID);还是不行。6.参考:中提到的:中提示的:Hint: If you are connecting to a Bluetooth serial board then try using the well-known SPP UUID 0-805F9B34FB. However if you are connecting to an Android peer then please generate your own unique UUID.所以再去试试这个UUID:0-805F9B34FB最终是可以了:对应的相关代码为: private String mactekHartModemN
private UUID mactekHartModemU
//void afterFoundBtHartModem(BluetoothDevice btDev, Parcelable[] btDevUuid){
void afterFoundBtHartModem(BluetoothDevice btDev, UUID btDevUuid){
if(null != btDevUuid){
//mactekHartModemName = btDev.getName(); //&MACTekViator75FE&
//mactekHartModemUuid = UUID.fromString(mactekHartModemName);
String uuidV
//http://www.guidgenerator.com/online-guid-generator.aspx
//uuidValue = &e214d9ae-c3ba-4e25-abb5-bc3&;
//https://groups.google.com/forum/#!topic/android-developers/vyTEJOXELos
//uuidValue = &0-100-0-F9B34FB&;
//uuidValue = &0-100-0-F9B34FB&;
uuidValue = &0-805F9B34FB&;
mactekHartModemUuid = UUID.fromString(uuidValue);
ConnectThread connectBtThread = new ConnectThread(btDev);
connectBtThread.start();
private class ConnectThread extends Thread {
private final BluetoothSocket mmS
private final BluetoothDevice mmD
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp =
mmDevice =
// Get a BluetoothSocket to connect with the given BluetoothDevice
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(mactekHartModemUuid);//0-805F9B34FB
} catch (IOException e) { }
mmSocket =
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// U close the socket and get out
mmSocket.close();
} catch (IOException closeException) { }
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
mmSocket.close();
} catch (IOException e) { }
}&#160;【总结】此处,必须使用Android的SSP(协议栈默认)的UUID:<font color="#ff01-00-FB才能正常和外部的,也是SSP串口的蓝牙设备去连接。转载请注明: & 与本文相关的文章
11 queries in 0.234 seconds, using 10.39MB memory

我要回帖

更多关于 android 广播接收器 的文章

 

随机推荐