1

我正在开发一个包含蓝牙 SPP 连接的 Android 应用程序。从 Android 发送的关于在 PC 上从 RFCOMM 接收字符串的帖子对我很有帮助。

甚至我在 Eclipse 中的日志也多次显示“写了 6 个字节中的 6 个字节”,然后套接字就关闭了。但是,我想使用超级终端在我的 PC 中接收(无论我发送什么)。我怎么做?如何在代码中指定虚拟 COM 端口?

我正在使用三星 SGH-T759 在 USB 调试模式下进行测试。

这是我的代码:

public class BluetoothActivity extends Activity {

private int bluetooth = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bluetooth);
    TextView text = (TextView) findViewById(R.id.text);
    text.setText("Click on the button to access devices through Bluetooth");
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_bluetooth, menu);
    return true;
}

public void bluetoothActivate(View view) {
    int REQUEST_ENABLE_BT = 1;
    int RESULT_ENABLE_BT  = 0;
    //TextView text = (TextView) findViewById(R.id.text);
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    System.out.println("Button clicked...");
    if (mBluetoothAdapter == null) {
        //txtView.setText("This device does not support Bluetooth");
        CharSequence txt = "This device does not support Bluetooth";
        Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();

    }
    else {
        //CharSequence text = "Bluetooth is supported!!!";
        System.out.println("Bluetooth is supported!!!");
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            onActivityResult(REQUEST_ENABLE_BT, RESULT_ENABLE_BT, enableBtIntent);
        }
        else 
            bluetooth = 1;

        device_access(view);
    }
}

public void device_access(View view) {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    TextView text = (TextView) findViewById(R.id.text);
    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    Spinner btDevices = (Spinner) findViewById(R.id.btDevices);

    System.out.println("Bluetooth devices...");

    if (bluetooth == 1)
        // If there are paired devices
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            System.out.println("Bluetooth paired devices...");
            final ArrayAdapter<CharSequence> mArrayAdapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1);
            ArrayAdapter<CharSequence> deviceName = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1);
            mArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            deviceName.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            for (BluetoothDevice device : pairedDevices) {

                // Add the name and address to an array adapter to show in a ListView
                mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                deviceName.add(device.getName());
            }
            btDevices.setVisibility(1);
            btDevices.setAdapter(mArrayAdapter);
            //txtView.append("\nPaired Bluetooth Devices Found...");


            /*// Create a BroadcastReceiver for ACTION_FOUND
            final BroadcastReceiver mReceiver = new BroadcastReceiver() {
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    // When discovery finds a device
                    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                        // Get the BluetoothDevice object from the Intent
                        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        // Add the name and address to an array adapter to show in a ListView
                        mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    }
                }
            };
            // Register the BroadcastReceiver
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
             */         

            String[] dvc = btDevices.getSelectedItem().toString().split("\n");
            final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
            String mac = "90:00:4E:DC:41:9D"; //my laptop's mac adress
            //mac = dvc[1];
            text.append("\n Data sent to " + btDevices.getSelectedItem().toString());
            BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired


            // Get a BluetoothSocket to connect with the given BluetoothDevice
            BluetoothSocket socket = null;
            OutputStream out = null;
            InputStream inp = null;
            //try {
            //socket = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
            Method m;
            try {
                m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                socket = (BluetoothSocket) m.invoke(device, 1); 
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            //}catch (IOException e) {}

            try {     
                mBluetoothAdapter.cancelDiscovery();
                socket.connect(); 
                out = socket.getOutputStream();
                inp = socket.getInputStream();
                //now you can use out to send output via out.write
                String outputValue = "Hi...\n",inputValue;
                byte[] op = outputValue.getBytes(),buffer = null;
                int inpBytes;
                for (int i=0; i<1000000; i++) {
                    out.write(op);
                    out.flush();
                }   
                System.out.println("Data written!!");
                /*while (true) {
                    try {
                        // Read from the InputStream
                        inpBytes = inp.read(buffer);

                        inputValue = buffer.toString();
                        text.append(inpBytes+ " " + inputValue);

                    } catch (IOException e) {

                    }

                }*/ }catch (IOException e) {} finally {
                    try {
                        socket.close();
                        System.out.println("Socket closed...");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 
                }
        }

}

}

4

1 回答 1

0

我自己解决了。我必须使用 listenUsingRfcommWithServiceRecord(NAME,SERIAL_UUID) 在笔记本电脑上注册手机的 SPP 功能。然后,我的笔记本电脑分配了一个 COM 端口,用于与我的手机进行 SPP 通信。然后,我在AccessPort137(另一个类似于超级终端的应用程序,在某些方面比那个更好)中指定了这个端口,并正确建立了通信。我的工作代码如下:

package com.example.bluetoothtest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

import com.example.bluetoothtest.R;
import com.example.bluetoothtest.DynamicGraph;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class BluetoothActivity extends Activity {

    public final static String EXTRA_MESSAGE = "com.example.bluetoothtest.MESSAGE";
    public int bluetooth = 0, mState = 0;
    public boolean runThread = false;
    private TextView text;
    public static final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //UUID for serial connection
    public static final int STATE_DISCONNECTED = 0;
    public static final int STATE_CONNECTED = 1;
    public static final int MESSAGE_READ = 2;
    public static final int START_INTENT = 3;
    public static final int REQ_CODE_DYNAMIC = 4;

    public static BluetoothAdapter mBluetoothAdapter = null;
    public static BluetoothDevice device = null;

    BluetoothServerSocket mmServerSocket = null;
    BluetoothSocket socket = null,finalSocket = null;
    OutputStream out = null;
    //InputStream aStream = null;
    InputStreamReader aReader = null;
    BufferedReader mBufferedReader = null;

    ConnectedThread con = null;
    AcceptThread accept = null;
    ConnectThread connect = null;

    Intent intent;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth);

        if (con != null) {con.cancel(); con = null;}

        mState = STATE_DISCONNECTED;

        // Start the thread to listen on a BluetoothServerSocket
        if (accept!= null) {
            accept = null;
        }


        text = (TextView) findViewById(R.id.text);
        text.setText("Click on the button to access devices through Bluetooth");

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_bluetooth, menu);
        return true;
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        runThread = false;
    }

    public void bluetoothActivate(View view) {
        int REQUEST_ENABLE_BT = 1;
        int RESULT_ENABLE_BT  = 0;

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        System.out.println("Button clicked...");
        if (mBluetoothAdapter == null) {

            CharSequence txt = "This device does not support Bluetooth";
            Toast toast = Toast.makeText(getApplicationContext(), txt, Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();

        }
        else {

            System.out.println("Bluetooth is supported!!!");
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
                onActivityResult(REQUEST_ENABLE_BT, RESULT_ENABLE_BT, enableBtIntent);
            }
            else 
                bluetooth = 1;

            device_access(view);
        }
    }

    public void bluetoothDisconnect(View view) {

        runThread = false;  
        con.cancel();
        //connect.cancel();
        System.out.println("Connection disconnected");
        text.append("\n Connection disconnected");
    }

    public void device_access(View view) {

        System.out.println("Bluetooth devices...");

        if (bluetooth == 1)  {

            //String mac = "F0:08:F1:36:D3:5B"; //my other phone's mac adress
            String mac = "90:00:4E:DC:41:9D"; //my laptop's mac adress
            //String mac = "A0:4E:04:B8:1D:62";
            //mac = dvc[1];
            //text.append("\n Data sent to " + btDevices.getSelectedItem().toString());

            //device = mBluetoothAdapter.getRemoteDevice(mac); //get remote device by mac, we assume these two devices are already paired

            //text.append("device = " + device);
            text.append("\n Bluetooth started...");
            System.out.println("Bluetooth Started...");
            //ensureDiscoverable();

            String backup_file = "dynamic_bluetooth.csv";

            intent = new Intent(this, DynamicGraph.class);
            intent.putExtra(EXTRA_MESSAGE, backup_file);

            System.out.println("Dynamic intent about to start...");

            /*connect = new ConnectThread(device);
            connect.start();*/


                    CheckBox plotGraph = (CheckBox) findViewById(R.id.plotGraph);
            if (plotGraph.isChecked())
                startActivityForResult(intent,REQ_CODE_DYNAMIC);
            else {
                accept = new AcceptThread();
                accept.start();
            }


        }

    }


    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        public ConnectThread(BluetoothDevice device) {
            this.mmDevice = device;
            BluetoothSocket tmp1 = null;
            try {
                tmp1 = device.createRfcommSocketToServiceRecord(SERIAL_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mmSocket = tmp1;
        }

        @Override
        public void run() {
            setName("ConnectThread");
            mBluetoothAdapter.cancelDiscovery();
            try {
                mmSocket.connect();
                System.out.println("Connected with the device");
            } catch (IOException e) {
                try {
                    mmSocket.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }

                return;

            }
            /*synchronized (PrinterService.this) {
                mConnectThread = null;
            }*/
            //connected(mmSocket, mmDevice);
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e("PrinterService", "close() of connect socket failed", e);
            }
        }
    }


    private void ensureDiscoverable() {

        if (mBluetoothAdapter.getScanMode() !=
                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            startActivity(discoverableIntent);
        }
        System.out.println("Device set discoverable");

        text.append("\n Device set discoverable");
        return;
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {

            case MESSAGE_READ:
                /*byte[] readBuf = (byte[]) msg.obj;
                // construct a string from the valid bytes in the buffer
                String readMessage = new String(readBuf, 0, msg.arg1);*/
                //float readM = Float.parseFloat(readMessage);

                System.out.println("Into handler...");
                String readMessage = (String) msg.obj;
                text.append("\n" + readMessage);
                try{
                    float readM = Float.parseFloat(readMessage);
                    text.append(" " + readM);
                }catch (NumberFormatException e) {
                    text.append(" - Number Format Exception!!");
                    e.printStackTrace();
                }
                break;

            case START_INTENT:
                System.out.println("Dynamic intent about to start...");
                //startActivityForResult(intent,REQ_CODE_DYNAMIC);
                break;
            }

        }

    };

    private class AcceptThread extends Thread {

        public AcceptThread() {

            BluetoothServerSocket tmp = null;

            try {
                System.out.println("Listening...");
                tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("SPP", SERIAL_UUID);

            }catch (IOException e) {
                System.out.println("Listening Failed");


            }

            mmServerSocket = tmp;
            if (mmServerSocket != null)
                System.out.println("Server socket established: tmp = " + tmp);
            else
                System.out.println("Server socket NOT established: tmp = " + tmp);


        }

        public void run() {

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {     
                //socket = mmServerSocket.accept();

                System.out.println("AcceptThread Run");
                while (true) {
                    if ((mmServerSocket != null) && (mState != STATE_CONNECTED)) {  
                        try {
                            socket = mmServerSocket.accept();
                            device = socket.getRemoteDevice();
                        } catch (IOException e) {
                            System.out.println("Socket not received");
                            break;
                        }

                        if (socket!= null)  {

                            System.out.println("Device Address: " + device.getAddress());
                            runThread = true;
                            con = new ConnectedThread(socket);
                            con.start();
                            mState = STATE_CONNECTED;

                            break;
                        }
                    }
                    else {
                        System.out.println("Code incomplete. Repeat Listening");
                        break;
                    }


                }
            } 
            finally {
                /*try {
                                con.cancel();
                                mmServerSocket.close();
                                System.out.println("Socket closed...");
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                System.out.println("Server Socket close problem...");
                                e.printStackTrace();
                            } */
            }
        }

        public void cancel() {

            try {
                mmServerSocket.close();
                accept.start();
            } catch (IOException e) {

            }
        }
    }


    private class ConnectedThread extends Thread {

        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;


        public ConnectedThread(BluetoothSocket socket) {

            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {

            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void run() {

            byte[] buffer = new byte[1024],readBuffer = new byte[1024];
            int bytesAvailable,readBufferPosition;
            char[] readMsg = new char[8192];
            /*try {
                aStream = socket.getInputStream();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                System.out.println("InputStream problem...");
                e.printStackTrace();
            }*/

            /*aReader = new InputStreamReader( mmInStream );
            mBufferedReader = new BufferedReader( aReader );*/ 

            String aString = "---";

            System.out.println("Waiting for input...");

            /*try {
                Thread.sleep(10000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                System.out.println("Sleeping problem...");
                e1.printStackTrace();
            }*/


            while (runThread) {
                try {

                    /*aReader = new InputStreamReader( mmInStream );

                    mBufferedReader = new BufferedReader( aReader );
                    //aString = mBufferedReader.readLine();

                    mBufferedReader.read(readMsg);
                    aString = new String(readMsg);
                    readMsg = new char[8192];
                    System.out.println(aString);*/

                    aString = "---";
                    byte delimiter = 'N';     //New line
                    readBuffer = new byte[1024];
                    readBufferPosition = 0;
                    bytesAvailable = mmInStream.read(buffer);
                    boolean copied = false;

                    if (bytesAvailable > 0)
                        System.out.println(bytesAvailable + " bytes available");
                    else
                        System.out.println("Bytes not available");

                    for(int i=0;i<bytesAvailable;i++)
                    {
                        byte b = buffer[i];
                        System.out.println("Byte = "+ b);
                        if(b == delimiter)
                        {
                            byte[] encodedBytes = new byte[readBufferPosition];
                            System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                            aString = new String(encodedBytes, "US-ASCII");
                            readBufferPosition = 0;
                            copied= true;
                            break;

                        }
                        else
                        {
                            readBuffer[readBufferPosition++] = b;
                        }
                    }

                    /*aString = new String(buffer);
                    aString = aString.trim();*/
                    //float rx_data = Float.parseFloat(aString);

                    System.out.println("aString = " + aString);


                    /*mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, bytes, -1, buffer)
                    .sendToTarget();*/

                    //buffer = new byte[1024];

                    if (copied && (aString != "---"))
                        mHandler.obtainMessage(BluetoothActivity.MESSAGE_READ, aString)
                        .sendToTarget();



                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    System.out.println("mBufferedReader problem...");
                    e.printStackTrace();
                    break;
                }

            }


            //cancel();

            /*out = socket.getOutputStream();
            //now you can use out to send output via out.write
            String outputValue = "Hi...\n",inputValue;
            byte[] op = outputValue.getBytes(),buffer = null;
            int inpBytes;
            for (int i=0; i<1000000; i++) {
                out.write(op);
                out.flush();
            }   
            System.out.println("Data written!!");


            while (true) {
    try {
        // Read from the InputStream
        inpBytes = inp.read(buffer);

        inputValue = buffer.toString();
        text.append(inpBytes+ " " + inputValue);

    } catch (IOException e) {

    }

} */
        }

        public void cancel() {
            try {

                /*aReader.close();
                mBufferedReader.close();*/
                runThread = false;
                mState = STATE_DISCONNECTED;
                mmSocket.close();
                mmServerSocket.close();
                System.out.println("Socket closed in thread...");
                accept = new AcceptThread();
                accept.start();
            } catch (IOException e) {
                System.out.println("Socket close problem...");
            }
        }

    }



}

如果您想要双向通信,请取消注释并运行 ConnectThread。我只需要接收价值;所以,我已经注释掉了。但是,必须运行此线程才能为您的手机与您的笔记本电脑建立一个 COM 端口。这是因为,只有当这样的使用蓝牙 SPP 的应用程序在手机中运行并尝试与笔记本电脑配对(使用此 ConnectThread)时,笔记本电脑才会注册手机的 SPP 功能。要查看此内容并从笔记本电脑一侧启用 SPP,请执行以下操作:

  1. 右键单击任务栏中的蓝牙图标,然后单击“显示蓝牙设备”。

  2. 在打开的窗口中,找到您的手机(请记住,在运行此 SPP 应用程序之前,它必须已经与您的笔记本电脑配对),右键单击它并转到“属性”。

  3. 转到“服务”选项卡,您将找到一个新条目,该条目由您在 listenUsingRfcommWithServiceRecord() 方法中作为第一个参数提供的名称调用。对我来说,它是“SPP”。

  4. 检查该新服务以在您的笔记本电脑和手机之间启用 SPP。

  5. 现在,如果您检查“硬件”选项卡,将指定一个 COM 端口,您可以在超级终端或任何此类应用程序中使用它并开始通信。

另外,请记住,这在 Windows 8 中是不可能的!我在这里提到的一切都与 Windows 7 相关。我没有在 Windows XP 中这样做,尽管它几乎是相同的方法。

我希望我的解决方案有所帮助!而且,我欢迎这些方面的专家对我的(新手)代码发表评论——毕竟,我猜 StackOverflow 主要是为了这个目的。

于 2013-04-20T09:05:00.830 回答