通过蓝牙将字符串从作为客户端的 PC 发送到作为服务器的移动设备 [英] Sending a string via Bluetooth from a PC as client to a mobile as server
问题描述
我需要通过蓝牙将字符串从 PC 传输到 Android 移动设备的帮助.Android 移动设备应充当服务器并在设备屏幕上显示字符串消息.作为客户端的 PC 应将字符串发送到移动设备.
I need help by transferring a string from a PC to an Android mobile device via Bluetooth. The Android mobile device should act as a server and displays the string message on the screen of the device. The PC which is the client should send the string to the mobile device.
我希望服务器对提取的字符串做出反应(通过蓝牙传输).这意味着在一方面服务器总是必须监听新字符串的到达,但另一方面仍然必须能够对这些消息做出反应(例如从一个菜单导航到另一个菜单).
I want the server react on the extracted string (transferred via Bluetooth). That means that on one side the server always has to listen for new strings to arrive, but on the other side still has to be able to react on these messages (e.g. navigate from one menu to another).
我尝试使用 BlueCove (2.1.1) 作为 BluetoothStack(为此我将 BlueCove 中的 jar 作为库添加到两个项目中)结合我发现的服务器-客户端通信示例 这里.
I tried it by using BlueCove (2.1.1) as BluetoothStack (for which I add the jar from BlueCove as a library to both projects) in combination with an example for a server-client communication that I found here.
由于 user_CC 使用服务器的 RFComm
连接,从服务器更新了代码:
Updated code from server thanks to user_CC using a RFComm
connection for the server:
public class RFCommServer extends Thread{
//based on java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
// The local server socket
private BluetoothServerSocket mmServerSocket;
// based on android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;
private Activity activity;
public RFCommServer(Activity activity) {
this.activity = activity;
}
public void run() {
BluetoothSocket socket = null;
mAdapter = BluetoothAdapter.getDefaultAdapter();
// Listen to the server socket if we're not connected
while (true) {
try {
// Create a new listening server socket
Log.d(this.getName(), ".....Initializing RFCOMM SERVER....");
// MY_UUID is the UUID you want to use for communication
mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService", MY_UUID);
//mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try using In Secure connection...
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (Exception e) {
}
try {
Log.d(this.getName(), "Closing Server Socket.....");
mmServerSocket.close();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
DataInputStream mmInStream = new DataInputStream(tmpIn);
DataOutputStream mmOutStream = new DataOutputStream(tmpOut);
// here you can use the Input Stream to take the string from the client whoever is connecting
//similarly use the output stream to send the data to the client
RelativeLayout layout = (RelativeLayout) activity.findViewById(R.id.relativeLayout_Layout);
TextView text = (TextView) layout.findViewById(R.id.textView_Text);
text.setText(mmInStream.toString());
} catch (Exception e) {
//catch your exception here
}
}
}
来自这里的SPP客户端代码:
/**
* A simple SPP client that connects with an SPP server
*/
public class SampleSPPClient implements DiscoveryListener{
//object used for waiting
private static Object lock=new Object();
//vector containing the devices discovered
private static Vector vecDevices=new Vector();
private static String connectionURL=null;
public static void main(String[] args) throws IOException {
SampleSPPClient client=new SampleSPPClient();
//display local device address and name
LocalDevice localDevice = LocalDevice.getLocalDevice();
System.out.println("Address: "+localDevice.getBluetoothAddress());
System.out.println("Name: "+localDevice.getFriendlyName());
//find devices
DiscoveryAgent agent = localDevice.getDiscoveryAgent();
System.out.println("Starting device inquiry...");
agent.startInquiry(DiscoveryAgent.GIAC, client);
try {
synchronized(lock){
lock.wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Device Inquiry Completed. ");
//print all devices in vecDevices
int deviceCount=vecDevices.size();
if(deviceCount <= 0){
System.out.println("No Devices Found .");
System.exit(0);
}
else{
//print bluetooth device addresses and names in the format [ No. address (name) ]
System.out.println("Bluetooth Devices: ");
for (int i = 0; i <deviceCount; i++) {
RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(i);
System.out.println((i+1)+". "+remoteDevice.getBluetoothAddress()+" ("+remoteDevice.getFriendlyName(true)+")");
}
}
System.out.print("Choose Device index: ");
BufferedReader bReader=new BufferedReader(new InputStreamReader(System.in));
String chosenIndex=bReader.readLine();
int index=Integer.parseInt(chosenIndex.trim());
//check for spp service
RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(index-1);
UUID[] uuidSet = new UUID[1];
uuidSet[0]=new UUID("446118f08b1e11e29e960800200c9a66", false);
System.out.println("
Searching for service...");
agent.searchServices(null,uuidSet,remoteDevice,client);
try {
synchronized(lock){
lock.wait();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
if(connectionURL==null){
System.out.println("Device does not support Simple SPP Service.");
System.exit(0);
}
//connect to the server and send a line of text
StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL);
//send string
OutputStream outStream=streamConnection.openOutputStream();
PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
pWriter.write("Test String from SPP Client
");
pWriter.flush();
//read response
InputStream inStream=streamConnection.openInputStream();
BufferedReader bReader2=new BufferedReader(new InputStreamReader(inStream));
String lineRead=bReader2.readLine();
System.out.println(lineRead);
}//main
//methods of DiscoveryListener
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
//add the device to the vector
if(!vecDevices.contains(btDevice)){
vecDevices.addElement(btDevice);
}
}
//implement this method since services are not being discovered
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
if(servRecord!=null && servRecord.length>0){
connectionURL=servRecord[0].getConnectionURL(0,false);
}
synchronized(lock){
lock.notify();
}
}
//implement this method since services are not being discovered
public void serviceSearchCompleted(int transID, int respCode) {
synchronized(lock){
lock.notify();
}
}
public void inquiryCompleted(int discType) {
synchronized(lock){
lock.notify();
}
}//end method
}
为了测试,我使用带有最新 Android API 的 Galaxy Nexus (GT-I9250).
For testing I use a Galaxy Nexus (GT-I9250) with the latest Android API.
多亏了 user_CC,客户端和服务器现在都可以正常运行.但遗憾的是客户端无法连接到服务器(请参见下面的屏幕截图).这是因为 connectionURL
从未设置(因此它默认跳转到这里 if(connectionURL==null)
.
Thanks to user_CC, the client and server now runs without an exception. But sadly the client is not able to connect to the server (see the screenshot below). It is because the connectionURL
is never set (thus it jumps in here if(connectionURL==null)
by default.
如何更改客户端代码,以便我可以将其与服务器连接?我需要在以下行中有一个正确的 connectionURL
:
How can I change the client code, so that I actually can connect it with the server? I need a proper connectionURL
in the following line:
StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL)
到目前为止,我只发现我需要以某种方式获取 ServiceRecord
,遗憾的是这也没有在 此处.
So far I only found out that I somehow need to get the ServiceRecord
, sadly this is also not described in the example code from here.
推荐答案
您将需要使用 RFComm APIS 来进行通信工作用于客户端连接.我还发表了一些评论供您理解.
You will need to use the RFComm APIS to make the communication work I have managed to define a class which is a Thread and will be acting as a server and listening for client connections. I have also placed some comments for you to understand.
private class AcceptThread extends Thread {
// The local server socket
private BluetoothServerSocket mmServerSocket;
public AcceptThread() {
}
public void run() {
BluetoothSocket socket = null;
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
// Listen to the server socket if we're not connected
while (true) {
try {
// Create a new listening server socket
Log.d(TAG, ".....Initializing RFCOMM SERVER....");
// MY_UUID is the UUID you want to use for communication
mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
//mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); you can also try using In Secure connection...
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (Exception e) {
}
try {
Log.d(TAG, "Closing Server Socket.....";
mmServerSocket.close();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
mmInStream = new DataInputStream(tmpIn);
mmOutStream = new DataOutputStream(tmpOut);
// here you can use the Input Stream to take the string from the client whoever is connecting
//similarly use the output stream to send the data to the client
} catch (Exception e) {
//catch your exception here
}
}
}
}
希望能帮到你
对于您的另一个问题:
在客户端 (PC) UUID 类上声明 javax.bluetooth.UUID 应来自 javax.bluetooth.UUID
Declaring javax.bluetooth.UUID on Client side (PC) UUID class should be from javax.bluetooth.UUID
uuidSet2[0] = new UUID("446118f08b1e11e29e960800200c9a66", false);
在服务器端 (Android) 声明 java.util.UUID
Declaring java.util.UUID at Server Side (Android)
UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
这篇关于通过蓝牙将字符串从作为客户端的 PC 发送到作为服务器的移动设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!