BluetoothAdapter.java关闭蓝牙的两个接口,设置如何记忆开关

该代码片段展示了如何通过编程方式关闭设备上的蓝牙功能。这里有两种方法,disable()disable(boolean persist),它们都涉及到蓝牙的关闭操作,但有一些关键的不同点:

  1. disable() 方法

    • 这是一个公开的方法,意味着它可以在任何遵循了适当权限设置的应用中使用。
    • 关闭蓝牙前需要得到用户的明确同意,因为这会影响到用户当前可能依赖蓝牙进行的各种连接和服务。
    • 调用该方法后会立即返回结果,但实际的蓝牙关闭过程是异步完成的。这意味着你需要监听 ACTION_STATE_CHANGED 广播来跟踪蓝牙状态的变化。
    • 如果方法调用成功(返回 true),蓝牙状态将从 STATE_ON 变为 STATE_TURNING_OFF,最终变为 STATE_OFF 或者回到 STATE_ON(如果关闭过程中出现了问题)。
  2. disable(boolean persist) 方法

    • 这个方法有一个额外的参数 persist,用来指示是否保存这个设置。这个方法被标记为隐藏(@hide),通常不建议外部应用直接使用。
    • 与 disable() 类似,也需要适当的权限才能调用。
    • 当 persist 设置为 false 时,关闭蓝牙的操作不会被记住,也就是说,如果设备重启,蓝牙的状态不会保持关闭状态。

这两个方法都需要特定的权限来执行,如 BLUETOOTH_CONNECT 权限,并且需要处理可能发生的 RemoteException 异常。在实现涉及蓝牙控制的功能时,开发者应确保获得了用户的明确同意,并适当地处理各种可能的错误情况。

最后都会调到frameworks\base\services\core\java\com\android\server\BluetoothManagerService.java

可以看到第一个不带参的disable调用时直接给true,第二个带参可选择是否记忆开关

false:不记忆

true:记忆

    public boolean disable(AttributionSource attributionSource, boolean persist)
            throws RemoteException {
        final String packageName = attributionSource.getPackageName();
        if (!checkBluetoothPermissions(attributionSource, "disable", true)) {
            if (DBG) {
                Slog.d(TAG, "disable(): not disabling - bluetooth disallowed");
            }
            return false;
        }

        final int callingUid = Binder.getCallingUid();
        final boolean callerSystem = UserHandle.getAppId(callingUid) == Process.SYSTEM_UID;
        if (!callerSystem && isEnabled() && mWirelessConsentRequired
                && startConsentUiIfNeeded(packageName,
                callingUid, BluetoothAdapter.ACTION_REQUEST_DISABLE)) {
            return false;
        }

        if (DBG) {
            Slog.d(TAG, "disable(): mBluetooth = " + mBluetooth + " mBinding = " + mBinding);
        }

        synchronized (mReceiver) {
            if (!isBluetoothPersistedStateOnAirplane()) {
                if (persist) {
                    persistBluetoothSetting(BLUETOOTH_OFF);
                }
                mEnableExternal = false;
            }
            sendDisableMsg(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST,
                    packageName);
        }
        return true;
    }

进入同步块(针对 mReceiver 对象),进行以下检查和操作:

如果蓝牙不在飞行模式下持久化状态,则根据 persist 参数决定是否保存蓝牙关闭设置。

    /**
     *  Save the Bluetooth on/off state
     */
    private void persistBluetoothSetting(int value) {
        if (DBG) {
            Slog.d(TAG, "Persisting Bluetooth Setting: " + value);
        }
        // waive WRITE_SECURE_SETTINGS permission check
        final long callingIdentity = Binder.clearCallingIdentity();
        Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.BLUETOOTH_ON, value);
        Binder.restoreCallingIdentity(callingIdentity);
    }

这段代码定义了一个名为 persistBluetoothSetting 的私有方法,用于保存蓝牙的开关状态。该方法接收一个整型参数 value,表示要保存的蓝牙状态(例如:开启或关闭)。以下是这个方法的主要逻辑和操作步骤:

  1. 调试信息输出

    • 在调试模式下(当 DBG 墫量为真时),通过 Slog.d 方法记录一条日志,显示正在保存的蓝牙设置值。
  2. 权限处理

    • 使用 Binder.clearCallingIdentity 方法暂时清除调用者的身份标识,这样可以在不检查 WRITE_SECURE_SETTINGS 权限的情况下执行接下来的操作。这一步主要是为了能够在系统级别修改设置而不受限于应用的权限。
  3. 保存蓝牙状态

    • 通过 Settings.Global.putInt 方法将蓝牙的状态值写入系统的全局设置中。这里使用了 mContext.getContentResolver() 获取内容解析器,并将其与 Settings.Global.BLUETOOTH_ON 键一起使用来更新蓝牙的状态值。
  4. 恢复调用者身份

    • 最后,通过 Binder.restoreCallingIdentity 方法恢复原来的调用者身份标识,确保后续的操作能够正确识别调用者及其权限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值