如何运行client.py与server.py建立蓝牙连接,实现Kivy安卓端与PC端数据传输?
Hey there! Let's work through your two main problems—getting the Windows test to stop crashing, and setting up the Android client to talk to your PC server.
1. Fixing the Windows Terminal Crash & Code Errors
The immediate crash you're seeing is probably because either:
- The script runs and exits immediately (so the terminal closes before you can see output), or
- There's an uncaught error in your code that causes it to crash silently.
Quick Fix for the Terminal Crash
Instead of double-clicking the .py files to run them:
- Open a Command Prompt or PowerShell window.
- Navigate to the folder where your scripts are saved (use
cd path/to/your/scripts). - Run the server first with
python server.py, then in another terminal window runpython client.py. This way you'll see any error messages or output instead of the window closing instantly.
Critical Code Fixes
Looking at your code, there are a couple of bugs that are definitely causing issues:
Server.py Issues
- Wrong socket for sending data: You're trying to send data through
server_sock, but that's the listening socket. You need to useclient_sock(the socket created when a client connects) to send data to the client. - Can't send dictionaries directly: Socket functions only send bytes, not Python objects like dictionaries. You need to serialize the dictionary to a string (using JSON works great) then encode it to bytes.
Here's the corrected server code:
from bluetooth import * import json server_sock = BluetoothSocket(RFCOMM) port = 1030 server_sock.bind(("", port)) # Use empty string to bind to all available adapters server_sock.listen(1) print("Waiting for connection...") client_sock, address = server_sock.accept() print("Accepted connection from ", address) # Load the user data listOfUsers = {} try: with open("database.txt", "r") as f: for line in f: email, password, firstName, lastName = line.strip().split(",") listOfUsers[email] = (password, firstName, lastName) except Exception as e: print(f"Error loading file: {e}") client_sock.close() server_sock.close() exit() # Serialize and send the dictionary try: data = json.dumps(listOfUsers).encode('utf-8') client_sock.send(data) print("Data sent successfully") except Exception as e: print(f"Error sending data: {e}") # Clean up client_sock.close() server_sock.close()
Client.py Issues
- Need to deserialize the received data: The client gets bytes, so you need to decode them to a string then convert back to a dictionary with JSON.
Corrected client code:
from bluetooth import * import json server_addr = "xx:xx:xx:xx:xx:xx" # Replace with your PC's Bluetooth MAC port = 1030 try: sock = BluetoothSocket(RFCOMM) sock.connect((server_addr, port)) print("Connected to server") response = sock.recv(1024) if response: response_str = response.decode('utf-8') received_users = json.loads(response_str) print("Received user data:") print(received_users) else: print("No data received") except Exception as e: print(f"Connection error: {e}") finally: sock.close()
2. Getting Your Android Kivy App to Connect to the PC Server
The standard bluetooth library (PyBluez) you're using doesn't work well on Android—Android uses its own Bluetooth API, so you'll need to adjust your approach:
Step 1: Use Android-Compatible Bluetooth Libraries
Instead of PyBluez, use one of these:
- Plyer: A Kivy-compatible library that wraps native Android features. It has a Bluetooth module that works with Android's API.
- Pyjnius: Lets you call Java code directly from Python, so you can use Android's
BluetoothAdapterandBluetoothSocketclasses directly.
Step 2: Add Required Permissions
When packaging your app with Buildozer (the standard tool for Kivy Android apps), add these permissions to your buildozer.spec file:
android.permissions = BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_FINE_LOCATION
Android requires location permissions for Bluetooth device discovery on newer versions.
Step 3: Use UUIDs for Service Discovery
Android's Bluetooth uses UUIDs to identify services, instead of just port numbers. Update your PC server to use a UUID so the Android client can find it:
Modified server code snippet (adding UUID support):
from bluetooth import * import json # Define a unique UUID for your service UUID = "00001101-0000-1000-8000-00805F9B34FB" # Standard RFCOMM UUID server_sock = BluetoothSocket(RFCOMM) server_sock.bind(("", PORT_ANY)) server_sock.listen(1) port = server_sock.getsockname()[1] advertise_service(server_sock, "KivyFileServer", service_id=UUID) print(f"Waiting for connection on RFCOMM port {port}") client_sock, address = server_sock.accept() # ... rest of the server code remains similar ...
Then on the Android side (using Plyer), you can scan for devices with that UUID and connect to the server.
Step 4: Pair Devices First
Make sure your Android phone is paired with your PC via Bluetooth before trying to run the app. The app won't be able to connect to an unpaired device without additional pairing code.
Testing Tips
- First test the corrected server and client on your PC—run the server, then the client, and confirm you see the user dictionary printed in the client terminal.
- Once that works, start adapting the client code to use Plyer/Pyjnius for Android.
- When packaging with Buildozer, use
buildozer android debug deploy runto install and run the app directly on your connected Android device, so you can see log messages withbuildozer android logcat.
内容的提问来源于stack exchange,提问作者AlwaysLearning

