注:"fd_501_car".equals(android.os.Build.CUSTOM_FEATURE):这个是我自己添加的一个变量,可用宏控实现
packages/apps/Settings/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
这个类用是设置里面扫描到的蓝牙设备列表,可以在 public void onDeviceAdded(CachedBluetoothDevice cachedDevice)方法中过滤,使指定的蓝牙添加到列表中,可通过mac地址和蓝牙名,建议使用mac地址,蓝牙名称可变化,不具有唯一性,如:
public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
Xlog.d(TAG, "onDeviceAdded, Device name is " + cachedDevice.getName());
//zhy cachedDevice.getAddress() || cachedDevice.getName()
if (mDevicePreferenceMap.get(cachedDevice) != null) {
Xlog.d(TAG, "Device name " + cachedDevice.getName() + " already have preference");
return;
}
//add by zhy start
if("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE)){
if(!("11:22:33:44:55:66".equals(cachedDevice.getDevice().getAddress()) || "11:22:33:44:55:77".equals(cachedDevice.getDevice().getAddress())))
return;
}
//add by zhy end
packages/apps/Settings/src/com/android/settings/bluetooth/Utils.java
在static void showError(Context context, String name, int messageResId)方法中添加retrun退出,如:
static void showError(Context context, String name, int messageResId) {
String message = context.getString(messageResId, name);
LocalBluetoothManager manager = LocalBluetoothManager.getInstance(context);
if(manager == null) {
return;
}
//add by zhy start
if ("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE)) {
return;
}
//add by zhy end
防止配对失败弹出对话框,对于没有显示屏开发是很有必要的,下面会讲下取消配对弹出对话框的实现方法
packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEventManager.java
这个类是对BluetoothDevice.ACTION_FOUND广播监听的
private class DeviceFoundHandler implements Handler {
public void onReceive(Context context, Intent intent,
BluetoothDevice device) {
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
BluetoothClass btClass = intent.getParcelableExtra(BluetoothDevice.EXTRA_CLASS);
String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
Xlog.d(TAG, "Device " + name + " ,Class: " + (btClass != null ? btClass.getMajorDeviceClass() : null));
// TODO Pick up UUID. They should be available for 2.1 devices.
// Skip for now, there's a bluez problem and we are not getting uuids even for 2.1.
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
if (cachedDevice == null) {
cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, device);
Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
+ cachedDevice);
}
// callback to UI to create Preference for new device
/// M: no matter the found device is in the device list,
/// call onDeviceAdded(), if the device preference has been
/// added to the screen, it will not add again
dispatchDeviceAdded(cachedDevice);
cachedDevice.setRssi(rssi);
cachedDevice.setBtClass(btClass);
cachedDevice.setName(name);
cachedDevice.setVisible(true);
//add by zhy start
if("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE)){
if("11:22:33:44:55:66".equals(device.getAddress()) || "11:22:33:44:55:77".equals(device.getAddress())){
bluetoothAutoConnect(cachedDevice,context);//扫描到指定mac地址自动发起连接
}
}
//add by zhy end
}
}
//add by zhy start
public void bluetoothAutoConnect(CachedBluetoothDevice cachedDevice,Context context) {
int bondState = cachedDevice.getBondState();
Xlog.d(TAG, "zhy address " + cachedDevice.getDevice().getAddress());
if (bondState == BluetoothDevice.BOND_BONDED) {
cachedDevice.connect(true);
} else if (bondState == BluetoothDevice.BOND_NONE) {
pair(cachedDevice,context);
}
}
private void pair(CachedBluetoothDevice cachedDevice,Context context) {
if (!cachedDevice.startPairing()) {
Utils.showError(context, cachedDevice.getName(),
R.string.bluetooth_pairing_error_message);
}
}
//add by zhy end
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
这个用于只有指定的设备mac才能进行配对成功,其他的不能配对成功
private class StableState extends State {
........
removeBond(dev, true);
break;
case BONDING_STATE_CHANGE:
int newState = msg.arg1;
/* if incoming pairing, transition to pending state */
//modify bluetooth mac addres dev.getAddress() 请求配对
if (newState == BluetoothDevice.BOND_BONDING)
{
if("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE)){
if("11:22:33:44:55:66".equals(dev.getAddress()) || "11:22:33:44:55:77".equals(dev.getAddress())){
sendIntent(dev, newState, 0);//BluetoothDevice.ACTION_BOND_STATE_CHANGED发送蓝牙绑定状态改变的广播
transitionTo(mPendingCommandState);
}
}
else{
sendIntent(dev, newState, 0);
transitionTo(mPendingCommandState);
}
}
packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
private int getConnectionSummary(){
......
if (profileConnected) {
if (a2dpNotConnected && headsetNotConnected) {
return R.string.bluetooth_connected_no_headset_no_a2dp;
} else if (a2dpNotConnected) {
return R.string.bluetooth_connected_no_a2dp;
} else if (headsetNotConnected) {
return R.string.bluetooth_connected_no_headset;
} else {
//add by zhy start
android.provider.Settings.System.putInt(getContext().getContentResolver(), "blue_connected", 1);
//add by zhy end
return R.string.bluetooth_connected;
}
}
switch (cachedDevice.getBondState()) {
case BluetoothDevice.BOND_BONDING:
return R.string.bluetooth_pairing;
case BluetoothDevice.BOND_BONDED:
case BluetoothDevice.BOND_NONE:
default:
//add by zhy start
android.provider.Settings.System.putInt(getContext().getContentResolver(), "blue_connected", 0);
//add by zhy end
return 0;
}
用于写系统数据库,功能是用于判断蓝牙设备是否已连接状态,如不是已连接状态,则一直扫描
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
用于开机后启动扫描功能,通过log分析,发现这里比较适合
//add by zhy start
public BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
public void startDiscovery(Context context){
int blue_connect = android.provider.Settings.System.getInt(context.getContentResolver(), "blue_connected", 0);;
if (adapter.getState() == BluetoothAdapter.STATE_OFF) {// 如果蓝牙还没开启
adapter.enable();
}
Object[] lstDevice = adapter.getBondedDevices().toArray();
for (int i = 0; i < lstDevice.length; i++) {
BluetoothDevice device = (BluetoothDevice) lstDevice;
Log.d("zhy","zhy----"+device.getName());
}
Log.d("zhy","zhy----blue_connect="+blue_connect);
if(blue_connect == 1){
Log.d("zhy","zhy----stop");
if (adapter.isDiscovering())
adapter.cancelDiscovery();
}else{
Log.d("zhy","zhy----start");
adapter.startDiscovery();
}
}
//add by zhy end
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_TIME_TICK.equals(action)
|| Intent.ACTION_TIME_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)
|| Intent.ACTION_LOCALE_CHANGED.equals(action)) {
if (Intent.ACTION_LOCALE_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
// need to get a fresh date format
mDateFormat = null;
}
updateClock();
//add by zhy start
if ("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE)) {
startDiscovery(context);
}
//add by zhy end
}
}
};
packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
用于取消配对对话框功能
//add zhy start
String temp = null;
private void onPair(String value,int type,BluetoothDevice device) {
switch (type) {
case BluetoothDevice.PAIRING_VARIANT_PIN:
byte[] pinBytes = BluetoothDevice.convertPinToBytes(value);
if (pinBytes == null) {
return;
}
device.setPin(pinBytes);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
int passkey = Integer.parseInt(value);
device.setPasskey(passkey);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
device.setPairingConfirmation(true);
break;
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
// Do nothing.
break;
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
device.setRemoteOutOfBandData();
break;
default:
}
}
//add zhy end
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
// convert broadcast intent into activity intent (same action string)
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
BluetoothDevice.ERROR);
Intent pairingIntent = new Intent();
pairingIntent.setClass(context, BluetoothPairingDialog.class);
pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, type);
if (type == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION ||
type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY ||
type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
int pairingKey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY,
BluetoothDevice.ERROR);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pairingKey);
//add zhy start
temp = pairingKey+"";
if ("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE) && type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
byte[] pinBytes = BluetoothDevice.convertPinToBytes(String.format(java.util.Locale.US,"%04d", temp));
device.setPin(pinBytes);
}
//add zhy end
}
pairingIntent.setAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PowerManager powerManager =
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
String deviceAddress = device != null ? device.getAddress() : null;
//zhy
// Since its only a notification, send an OK to the framework,
// indicating that the dialog has been displayed.
if ("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE) && type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
device.setPairingConfirmation(true);
}
if ("fd_501_car".equals(android.os.Build.CUSTOM_FEATURE) || powerManager.isScreenOn() &&
LocalBluetoothPreferences.shouldShowDialogInForeground(context, deviceAddress)) {
// Since the screen is on and the BT-related activity is in the foreground,
// just open the dialog
//zhy
if (!"fd_501_car".equals(android.os.Build.CUSTOM_FEATURE)) {
context.startActivity(pairingIntent);//这个是对话框dialogactivity
} else {
onPair(temp,type,device);
}
}
这个是发送接收配对的广播
以上就是这几天修改问题总结的经验,里面还有很多是可以优化的,做的不是很好,请大家谅解