You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过蓝牙连接RaspberryPi与Android并传输WiFi配置文件的技术咨询

树莓派蓝牙传输WiFi配置解决方案(适配你的三个约束)

一、树莓派端:一次性SSH脚本完成全配置

因为最终仅能通过SSH执行一次脚本,且后续无网络,脚本需包含所有依赖安装、蓝牙配置、接收服务部署:

  • 安装蓝牙依赖(初始联网时完成,脚本执行时自动处理):
    sudo apt update && sudo apt install -y bluez bluez-tools python3-bluez
    
  • 持久化蓝牙可发现/可配对:
    修改蓝牙配置文件,确保树莓派始终处于可被安卓发现的状态:
    sudo sed -i 's/#DiscoverableTimeout = 0/DiscoverableTimeout = 0/' /etc/bluetooth/main.conf
    sudo sed -i 's/#PairableTimeout = 0/PairableTimeout = 0/' /etc/bluetooth/main.conf
    sudo systemctl restart bluetooth
    
  • 部署WiFi配置接收服务:
    脚本内嵌Python监听逻辑,接收安卓发来的WiFi配置并写入系统文件:
    1. 先写入接收脚本到树莓派:
    cat << 'EOF' > /home/pi/wifi_config_receiver.py
    import bluetooth
    import subprocess
    import json
    
    server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
    server_sock.bind(("", bluetooth.PORT_ANY))
    server_sock.listen(1)
    
    port = server_sock.getsockname()[1]
    uuid = "00001101-0000-1000-8000-00805F9B34FB"
    
    bluetooth.advertise_service(server_sock, "WiFiConfigServer", service_id=uuid)
    
    print(f"Waiting for Android connection on RFCOMM port {port}")
    try:
        client_sock, client_info = server_sock.accept()
        print(f"Connected to {client_info}")
    
        data = client_sock.recv(1024).decode('utf-8')
        if not data:
            raise ValueError("Empty config data received")
    
        config = json.loads(data)
        ssid = config.get('ssid')
        password = config.get('password')
        if not ssid or not password:
            raise ValueError("Invalid WiFi config")
    
        # 写入WiFi配置文件
        config_entry = f'\nnetwork={{\n    ssid="{ssid}"\n    psk="{password}"\n}}'
        with open('/etc/wpa_supplicant/wpa_supplicant.conf', 'a') as f:
            f.write(config_entry)
    
        # 重启网络服务生效
        subprocess.run(["sudo", "systemctl", "restart", "wpa_supplicant"], check=True)
        print("WiFi config applied successfully")
    except Exception as e:
        print(f"Error: {str(e)}")
    finally:
        if 'client_sock' in locals():
            client_sock.close()
        server_sock.close()
        print("Socket closed")
    EOF
    
    1. 设置开机自启,确保树莓派重启后自动监听:
    sudo cat << EOF > /etc/systemd/system/wifi-config-bt.service
    [Unit]
    Description=Bluetooth WiFi Config Receiver
    After=bluetooth.service
    
    [Service]
    ExecStart=/usr/bin/python3 /home/pi/wifi_config_receiver.py
    User=pi
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    EOF
    sudo systemctl daemon-reload
    sudo systemctl enable wifi-config-bt.service
    
  • 将以上所有命令整合成一个脚本,通过SSH一次性执行,执行后树莓派无需网络即可运行蓝牙监听服务。

二、安卓端:应用实现蓝牙发起连接与配置传输

安卓应用需完成蓝牙扫描、配对、RFCOMM连接、配置发送四个核心步骤:

  • 权限配置(AndroidManifest.xml):
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    
  • 核心逻辑(Kotlin示例):
    1. 扫描树莓派设备:
    private fun scanBluetoothDevices() {
        val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        if (!bluetoothAdapter.isEnabled) {
            // 提示用户开启蓝牙
            return
        }
        val scanner = bluetoothAdapter.bluetoothLeScanner
        scanner.startScan(object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult?) {
                result?.device?.let { device ->
                    if (device.name == "raspberrypi") { // 过滤树莓派设备
                        scanner.stopScan(this)
                        connectToDevice(device)
                    }
                }
            }
        })
    }
    
    1. 连接并发送配置:
    private fun connectToDevice(device: BluetoothDevice, ssid: String, password: String) {
        val uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
        val socket = device.createRfcommSocketToServiceRecord(uuid)
        try {
            socket.connect()
            val outputStream = socket.outputStream
            val configJson = """{"ssid":"$ssid","password":"$password"}"""
            outputStream.write(configJson.toByteArray(Charsets.UTF_8))
            outputStream.flush()
            // 提示用户发送成功
        } catch (e: IOException) {
            // 处理连接/发送失败
        } finally {
            socket.close()
        }
    }
    
  • 注意事项:处理蓝牙配对请求(安卓端会弹出配对提示,用户确认后即可连接),添加网络权限适配不同安卓版本。

三、验证流程

  1. 树莓派执行一次性SSH脚本,完成所有配置后重启
  2. 安卓应用开启蓝牙,扫描并配对树莓派
  3. 输入WiFi SSID和密码,发送配置
  4. 树莓派自动写入配置并重启网络,完成联网

内容的提问来源于stack exchange,提问作者Nihon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:51:20