我是靠谱客的博主 顺心百褶裙,最近开发中收集的这篇文章主要介绍android系统蓝牙自动配对连接,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

蓝牙配对主要在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系统蓝牙自动配对连接所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部