android注册蓝牙广播无响应,Android framework 蓝牙开机连接慢与开机广播

问题:

项目需要使用蓝牙外接设备,但每次重启开机到launcher显示后,蓝牙设备均需要等待20秒以上才能操作,体验非常差。

分析:

蓝牙的回连是由framework层实现。BluetoothManagerService相关代码如下,可以看到,自动打开蓝牙的流程是接收开机广播实现的。

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

......省略

} else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {

synchronized(mReceiver) {

if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {

//Enable

if (DBG) Log.d(TAG, "Auto-enabling Bluetooth.");

sendEnableMsg(mQuietEnableExternal);

}

}

......省略

}

}

};

BluetoothManagerService(Context context) {

......省略

IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);

filter.addAction(Intent.ACTION_USER_SWITCHED);

registerForAirplaneMode(filter);

mContext.registerReceiver(mReceiver, filter);

loadStoredNameAndAddress();

if (isBluetoothPersistedStateOn()) {

mEnableExternal = true;

}

......省略

}

继续分析开机流程,可以发现,BluetoothManagerService在08:00:23才接收到开机广播,那么是开机广播发的迟了,还是接收慢了?

20190702161248901.png

可以看到,开机广播在08:00:07已经发出,也确实有其他APK接收到了,那么原因就是开机广播接收慢了。

20190702161551248.png

那为什么有的APK又能接收到呢?原因有可能是广播接收顺序不同导致:

1、如果是有序广播,那么是按Receiver的优先级来发送的;

2、如果是无序广播(普通广播),那么如果广播是动态注册的,接收时是并行发送,静态注册则也是串行发送,顺序是根据APK启动的顺序来的。

很明显我们这个不可能是第二种情况了,那么也就是说开机广播是一个有序广播,我们的优先级太低了,是这样吗?

查看开机广播发送代码,可以看到其是使用broadcastIntentLocked发送,倒数第五个参数表示是否为有序广播,所以确实开机广播是有序广播,那么问题原因就已经很明确了。

final void finishBooting() {

......省略

for (int i=0; i

UserStartedState uss = mStartedUsers.valueAt(i);

if (uss.mState == UserStartedState.STATE_BOOTING) {

uss.mState = UserStartedState.STATE_RUNNING;

final int userId = mStartedUsers.keyAt(i);

Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);

intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);

intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);

broadcastIntentLocked(null, null, intent, null,

new IIntentReceiver.Stub() {

@Override

public void performReceive(Intent intent, int resultCode,

String data, Bundle extras, boolean ordered,

boolean sticky, int sendingUser) {

synchronized (ActivityManagerService.this) {

requestPssAllProcsLocked(SystemClock.uptimeMillis(),

true, false);

}

}

},

0, null, null,

android.Manifest.permission.RECEIVE_BOOT_COMPLETED,

AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,

userId);

Slog.e(TAG, "RECEIVE_BOOT_COMPLETE");

}

}

}

}

}

解决方法:

原因已明确,那么只需要提高BluetoothManagerService对开机广播的优先级即可,如下:

setPriority 可设置优先级为-1000~1000,越高则优先级越高,但实际上是可以设置到Integer.MAX_VALUE,目前暂不需要这么改,设置为1000,即IntentFilter.SYSTEM_HIGH_PRIORITY即可。

IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);

filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY/*Integer.MAX_VALUE*/);//提高优先级

filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);

filter.addAction(Intent.ACTION_USER_SWITCHED);

registerForAirplaneMode(filter);

mContext.registerReceiver(mReceiver, filter);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值