概述
蓝牙配对主要在settings应用下面的com.android.settings.bluetooth目录下,主要是有广播侦听BluetoothPairingRequest.java,配对对话框BluetoothPairingDialog.java,BluetoothPairingDialogFragment.java,
配对控制类BluetoothPairingController.java.实现的最终经过分析修改如下:
1.蓝牙配对请求广播
package com.android.settings.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.PowerManager;
import android.os.UserHandle;
import android.util.Log;
public final class BluetoothPairingRequest extends BroadcastReceiver {
private static final String TAG = "BluetoothPairingRequest";
private static final boolean DEBUG = true;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// SPRD:bug#785347 action may be null
if (!BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
return;
}
// convert broadcast intent into activity intent (same action string)
Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(context, intent);
PowerManager powerManager =
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceAddress = device != null ? device.getAddress() : null;
String deviceName = device != null ? device.getName() : null;
boolean shouldShowDialog = LocalBluetoothPreferences.shouldShowDialogInForeground(
context, deviceAddress, deviceName);
if (DEBUG) {
Log.d(TAG,"powerManager.isInteractive() == "+powerManager.isInteractive());
Log.d(TAG,"shouldShowDialog == "+shouldShowDialog);
}
//remove shouldShowDialog
//update by lsj start
/*if (powerManager.isInteractive()) {
// Since the screen is on and the BT-related activity is in the foreground,
// just open the dialog
context.startActivityAsUser(pairingIntent, UserHandle.CURRENT);
} else {
// Put up a notification that leads to the dialog
intent.setClass(context, BluetoothPairingService.class);
context.startServiceAsUser(intent, UserHandle.CURRENT);
}*/
if (powerManager.isInteractive()) {
// Since the screen is on and the BT-related activity is in the foreground,
// just open the dialog
BluetoothPairingSure sureControl=new BluetoothPairingSure(pairingIntent,context);
sureControl.sureParing();
} else {
// Put up a notification that leads to the dialog
BluetoothPairingSure sureControlNotify=new BluetoothPairingSure(intent,context);
sureControlNotify.sureParing();
}
//update by lsj end
}
}
2.自定义BluetoothPairingSure .java替换BluetoothPairingController.java
package com.android.settings.bluetooth;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.text.Editable;
import android.util.Log;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.android.settings.R;
import com.android.settings.bluetooth.BluetoothPairingDialogFragment.BluetoothPairingDialogListener;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import java.util.Locale;
public class BluetoothPairingSure {
private static final String TAG = "BtPairingSure";
// Different types of dialogs we can map to
public static final int INVALID_DIALOG_TYPE = -1;
public static final int USER_ENTRY_DIALOG = 0;
public static final int CONFIRMATION_DIALOG = 1;
public static final int DISPLAY_PASSKEY_DIALOG = 2;
private static final int BLUETOOTH_PIN_MAX_LENGTH = 16;
private static final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6;
// Bluetooth dependencies for the connection we are trying to establish
private LocalBluetoothManager mBluetoothManager;
private BluetoothDevice mDevice;
private int mType;
private String mUserInput;
private String mPasskeyFormatted;
private int mPasskey;
private String mDeviceName;
private LocalBluetoothProfile mPbapClientProfile;
private boolean mPbapAllowed=true;
/**
* Creates an instance of a BluetoothPairingSure.
*
* @param intent - must contain {@link BluetoothDevice#EXTRA_PAIRING_VARIANT}, {@link
* BluetoothDevice#EXTRA_PAIRING_KEY}, and {@link BluetoothDevice#EXTRA_DEVICE}. Missing extra
* will lead to undefined behavior.
*/
public BluetoothPairingSure(Intent intent, Context context) {
mBluetoothManager = Utils.getLocalBtManager(context);
mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG,"BluetoothPairingSure");
String message = "";
if (mBluetoothManager == null) {
throw new IllegalStateException("Could not obtain LocalBluetoothManager");
} else if (mDevice == null) {
throw new IllegalStateException("Could not find BluetoothDevice");
}
mType = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
mPasskey = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
mDeviceName = mBluetoothManager.getCachedDeviceManager().getName(mDevice);
mPbapClientProfile = mBluetoothManager.getProfileManager().getPbapClientProfile();
mPasskeyFormatted = formatKey(mPasskey);
notifyDialogDisplayed();
}
public void sureParing(){
if (getDialogType() == USER_ENTRY_DIALOG) {
if (mPbapAllowed) {
mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
} else {
mDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_REJECTED);
}
onPair(mUserInput);
} else {
onPair(null);
}
}
/**
* A method for querying which bluetooth pairing dialog fragment variant this device requires.
*
* @return - The dialog view variant needed for this device.
*/
public int getDialogType() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN:
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
return USER_ENTRY_DIALOG;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
return CONFIRMATION_DIALOG;
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
return DISPLAY_PASSKEY_DIALOG;
default:
return INVALID_DIALOG_TYPE;
}
}
/**
* @return - A string containing the name provided by the device.
*/
public String getDeviceName() {
return mDeviceName;
}
/**
* A method for querying if the bluetooth device has a profile already set up on this device.
*
* @return - A boolean indicating if the device has previous knowledge of a profile for this
* device.
*/
public boolean isProfileReady() {
return mPbapClientProfile != null && mPbapClientProfile.isProfileReady();
}
/**
* A method for querying if the bluetooth device has access to contacts on the device.
*
* @return - A boolean indicating if the bluetooth device has permission to access the device
* contacts
*/
public boolean getContactSharingState() {
switch (mDevice.getPhonebookAccessPermission()) {
case BluetoothDevice.ACCESS_ALLOWED:
return true;
case BluetoothDevice.ACCESS_REJECTED:
return false;
default:
if (mDevice.getBluetoothClass() != null && mDevice.getBluetoothClass().getDeviceClass()
== BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE) {
return true;
}
return false;
}
}
/**
* A method for querying if the provided editable is a valid passkey/pin format for this device.
*
* @param s - The passkey/pin
* @return - A boolean indicating if the passkey/pin is of the correct format.
*/
public boolean isPasskeyValid(Editable s) {
boolean requires16Digits = mType == BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS;
return s.length() >= 16 && requires16Digits || s.length() > 0 && !requires16Digits;
}
/**
* A method for querying what message should be shown to the user as additional text in the
* dialog for this device. Returns -1 to indicate a device type that does not use this message.
*
* @return - The message ID to show the user.
*/
public int getDeviceVariantMessageId() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
case BluetoothDevice.PAIRING_VARIANT_PIN:
return R.string.bluetooth_enter_pin_other_device;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
return R.string.bluetooth_enter_passkey_other_device;
default:
return INVALID_DIALOG_TYPE;
}
}
/**
* A method for querying what message hint should be shown to the user as additional text in the
* dialog for this device. Returns -1 to indicate a device type that does not use this message.
*
* @return - The message ID to show the user.
*/
public int getDeviceVariantMessageHintId() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
return R.string.bluetooth_pin_values_hint_16_digits;
case BluetoothDevice.PAIRING_VARIANT_PIN:
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
return R.string.bluetooth_pin_values_hint;
default:
return INVALID_DIALOG_TYPE;
}
}
/**
* A method for querying the maximum passkey/pin length for this device.
*
* @return - An int indicating the maximum length
*/
public int getDeviceMaxPasskeyLength() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
case BluetoothDevice.PAIRING_VARIANT_PIN:
return BLUETOOTH_PIN_MAX_LENGTH;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
return BLUETOOTH_PASSKEY_MAX_LENGTH;
default:
return 0;
}
}
/**
* A method for querying if the device uses an alphanumeric passkey.
*
* @return - a boolean indicating if the passkey can be alphanumeric.
*/
public boolean pairingCodeIsAlphanumeric() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
return false;
default:
return true;
}
}
/**
* A method used by the dialogfragment to notify the controller that the dialog has been
* displayed for bluetooth device types that just care about it being displayed.
*/
protected void notifyDialogDisplayed() {
// send an OK to the framework, indicating that the dialog has been displayed.
if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
mDevice.setPairingConfirmation(true);
} else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
byte[] pinBytes = BluetoothDevice.convertPinToBytes(mPasskeyFormatted);
mDevice.setPin(pinBytes);
}
Log.i(TAG,"notifyDialogDisplayed");
}
/**
* A method for querying if this bluetooth device type has a key it would like displayed
* to the user.
*
* @return - A boolean indicating if a key exists which should be displayed to the user.
*/
public boolean isDisplayPairingKeyVariant() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
return true;
default:
return false;
}
}
/**
* A method for querying if this bluetooth device type has other content it would like displayed
* to the user.
*
* @return - A boolean indicating if content exists which should be displayed to the user.
*/
public boolean hasPairingContent() {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
return true;
default:
return false;
}
}
/**
* A method for obtaining any additional content this bluetooth device has for displaying to the
* user.
*
* @return - A string containing the additional content, null if none exists.
* @see {@link BluetoothPairingSure#hasPairingContent()}
*/
public String getPairingContent() {
if (hasPairingContent()) {
return mPasskeyFormatted;
} else {
return null;
}
}
/**
* A method that exists to allow the fragment to update the controller with input the user has
* provided in the fragment.
*
* @param input - A string containing the user input.
*/
protected void updateUserInput(String input) {
mUserInput = input;
}
/**
* Returns the provided passkey in a format that this device expects. Only works for numeric
* passkeys/pins.
*
* @param passkey - An integer containing the passkey to format.
* @return - A string containing the formatted passkey/pin
*/
private String formatKey(int passkey) {
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
return String.format(Locale.US, "%06d", passkey);
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
return String.format("%04d", passkey);
default:
return null;
}
}
/**
* handles the necessary communication with the bluetooth device to establish a successful
* pairing
*
* @param passkey - The passkey we will attempt to pair to the device with.
*/
private void onPair(String passkey) {
Log.d(TAG, "Pairing dialog accepted");
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN:
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
byte[] pinBytes = BluetoothDevice.convertPinToBytes(passkey);
if (pinBytes == null) {
return;
}
mDevice.setPin(pinBytes);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
int pass = Integer.parseInt(passkey);
mDevice.setPasskey(pass);
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
mDevice.setPairingConfirmation(true);
break;
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
// Do nothing.
break;
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
mDevice.setRemoteOutOfBandData();
break;
default:
Log.e(TAG, "Incorrect pairing type received");
}
}
/**
* A method for properly ending communication with the bluetooth device. Will be called by the
* {@link BluetoothPairingDialogFragment} when it is dismissed.
*/
public void onCancel() {
Log.d(TAG, "Pairing dialog canceled");
mDevice.cancelPairingUserInput();
}
/**
* A method for checking if this device is equal to another device.
*
* @param device - The other device being compared to this device.
* @return - A boolean indicating if the devices were equal.
*/
public boolean deviceEquals(BluetoothDevice device) {
return mDevice == device;
}
}
最后
以上就是顺心百褶裙为你收集整理的android系统蓝牙自动配对连接的全部内容,希望文章能够帮你解决android系统蓝牙自动配对连接所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复