android - 连接2个蓝牙设备

标签 android sockets bluetooth server client

我正在尝试制作一个使用蓝牙的应用程序。它非常简单,但我被困在连接设备上。

到目前为止,我制作了 2 个 ListView ,一个显示配对设备,另一个显示已找到的设备。我不明白套接字如何工作以及如何制作设备服务器或客户端。

谁能给我解释一下,或者至少告诉我如何处理我已经制作(复制)的代码。

我已经浏览了所有我能找到的教程,但我仍然不明白。蓝牙聊天示例非常困惑,我是 android 编程的初学者,并没有真正学习太多 java。

这是代码:

public class ConnectThread extends Thread{
        BluetoothDevice device;
        private BluetoothSocket socket;

        ConnectThread(){
            connect(device, MY_UUID);
        }
        public boolean connect(BluetoothDevice bTDevice, UUID mUUID) {
            BluetoothSocket temp = null;
            try {
                temp = bTDevice.createRfcommSocketToServiceRecord(mUUID);
            } catch (IOException e) {
                Log.d("CONNECTTHREAD","Could not create RFCOMM socket:" + e.toString());
                return false;
            }
            try {
                socket.connect();
            } catch(IOException e) {
                Log.d("CONNECTTHREAD","Could not connect: " + e.toString());
                try {
                    socket.close();
                } catch(IOException close) {
                    Log.d("CONNECTTHREAD", "Could not close connection:" + e.toString());
                    return false;
                }
            }
            return true;
        }

        public boolean cancel() {
            try {
                socket.close();
            } catch(IOException e) {
                Log.d("CONNECTTHREAD","Could not close connection:" + e.toString());
                return false;
            }
            return true;
        }
    }
private class AcceptThread extends Thread {


       private final BluetoothServerSocket mmServerSocket;


       public AcceptThread() {
           // Use a temporary object that is later assigned to mmServerSocket,
           // because mmServerSocket is final
           BluetoothServerSocket tmp = null;
           try {
               // MY_UUID is the app's UUID string, also used by the client code
               tmp = bluetooth.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
           } catch (IOException e) { }
           mmServerSocket = tmp;
       }

       public void run() {
           BluetoothSocket socket = null;
           // Keep listening until exception occurs or a socket is returned
           while (true) {
               try {
                   socket = mmServerSocket.accept();
               } catch (IOException e) {
                   break;
               }
               // If a connection was accepted
               if (socket != null) {
                   // Do work to manage the connection (in a separate thread)
                   try {
                       mmServerSocket.close();
                   } catch (IOException e) {
                       e.printStackTrace();
                   }
                   break;
               }
           }
       }

       /** Will cancel the listening socket, and cause the thread to finish */
       public void cancel() {
           try {
               mmServerSocket.close();
           } catch (IOException e) { }
       }}

这是 xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1"
        android:baselineAligned="false">
    <ListView
        android:layout_width="170dp"
        android:layout_height="fill_parent"
        android:layout_gravity="start"
        android:background="@drawable/lviewbg"
        android:id="@+id/paired_devies">
    </ListView>
        <ListView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="fill_horizontal"
            android:background="@drawable/lviewbg"
            android:id="@+id/new_devices">
        </ListView>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
    <Button
        android:id="@+id/discover"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight="1"
        android:background="#aa0000ff"
        android:text="@string/disc"
        style="?android:attr/buttonBarButtonStyle"
        />
    <Button
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight="1"
        android:background="#aa0000ff"
        android:text="@string/discoverable"
        android:onClick="makeDiscoverable"
        style="?android:attr/buttonBarButtonStyle"
        />
    </LinearLayout>
</LinearLayout>

如果您需要,这是其余代码:

package com.example.user.broj;

    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.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;

    import java.io.IOException;
    import java.util.Set;
    import java.util.UUID;

    public class BluetoothDevices extends AppCompatActivity{

        private static final String TAG = "DeviceListActivity";
        private static final boolean D = true;

        BluetoothDevice device;

        static int REQUEST_ENABLE_BT = 1;
        static int DISCOVERABLE_BT_REQUEST_CODE = 1;
        static int DISCOVERABLE_DURATION = 120;
        public static String EXTRA_DEVICE_ADDRESS = "device_address";
        private BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
        ArrayAdapter<String> mPairedDevicesArrayAdapter;
        private ArrayAdapter<String> mNewDevicesArrayAdapter;
    //This is used for connecting devices
        static final String NAME = "BluetoothGame";
        static final UUID MY_UUID = UUID.fromString("ae19c8fa-9b60-11e5-8994-feff819cdc9f");

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.start);
            Button scanButton = (Button) findViewById(R.id.discover);
            scanButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View view) {
                    doDiscovery();
                    view.setClickable(false);
                }
            });
    //enabling bluetooth
            if(!bluetooth.isEnabled()){
                Intent btIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(btIntent, REQUEST_ENABLE_BT);
            }
    //arrayadapters for paired and new devices list views
            mPairedDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.device_name);
            mNewDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.device_name);
    //listview for paired devices
            ListView deviceList = (ListView) findViewById(R.id.paired_devies);
            deviceList.setAdapter(mPairedDevicesArrayAdapter);
            deviceList.setOnItemClickListener(mDeviceClickListener);
    //listview for new devices
            ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
            newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
            newDevicesListView.setOnItemClickListener(mDeviceClickListener);

            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            this.registerReceiver(mReceiver, filter);

            filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            this.registerReceiver(mReceiver, filter);

            bluetooth = BluetoothAdapter.getDefaultAdapter();

            Set<BluetoothDevice> pairedDevices = bluetooth.getBondedDevices();

            if (pairedDevices.size() > 0) {
                //findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
                for (BluetoothDevice device : pairedDevices) {
                    mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                }
            } else {
                String noDevices = getResources().getText(R.string.none_paired).toString();
                mPairedDevicesArrayAdapter.add(noDevices);
            }
        }
    //button onClick for making the device discoverable
        public void makeDiscoverable(View view) {
            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERABLE_DURATION);
            startActivityForResult(discoverableIntent, DISCOVERABLE_BT_REQUEST_CODE);
        }

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == DISCOVERABLE_BT_REQUEST_CODE){
                if (resultCode == DISCOVERABLE_DURATION){
                    Toast.makeText(getApplicationContext(), "Your device is now discoverable by other devices for " +
                                    DISCOVERABLE_DURATION + " seconds",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(getApplicationContext(), "Fail to enable discoverability on your device.",
                            Toast.LENGTH_SHORT).show();
                }
            }
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            // Make sure we're not doing discovery anymore
            if (bluetooth != null) {
                bluetooth.cancelDiscovery();
            }
            // Unregister broadcast listeners
            this.unregisterReceiver(mReceiver);
        }

        private void doDiscovery() {
            if (D) Log.d(TAG, "doDiscovery()");
            // Indicate scanning in the title
            setProgressBarIndeterminateVisibility(true);
            setTitle(R.string.scanning);
            // Turn on sub-title for new devices
            // findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
            // If we're already discovering, stop it
            if (bluetooth.isDiscovering()) {
                bluetooth.cancelDiscovery();
            }
            // Request discover from BluetoothAdapter
            bluetooth.startDiscovery();
        }

        private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
                // Cancel discovery because it's costly and we're about to connect
                bluetooth.cancelDiscovery();
                // Get the device MAC address, which is the last 17 chars in the View
                String info = ((TextView) v).getText().toString();
                String address = info.substring(info.length() - 17);
                // Create the result Intent and include the MAC address
                Intent intent = new Intent();
                intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
                // Set result and finish this Activity
                setResult(Activity.RESULT_OK, intent);
                finish();
            }
        };

        private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Button scanButton = (Button) findViewById(R.id.discover);
                String action = intent.getAction();
                // When discovery finds a device
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    // Get the BluetoothDevice object from the Intent
                     device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    // If it's already paired, skip it, because it's been listed already
                    if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                        mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    }
                    // When discovery is finished, change the Activity title
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    setProgressBarIndeterminateVisibility(false);
                    setTitle(R.string.select_device);
                    scanButton.setClickable(true);
                    if (mNewDevicesArrayAdapter.getCount() == 0) {
                        String noDevices = getResources().getText(R.string.none_found).toString();
                        mNewDevicesArrayAdapter.add(noDevices);
                    }
                }
            }
        };
    }

最佳答案

通过蓝牙套接字连接的异步类

UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
InputStream is1;
OutputStream os1;
BluetoothAdapter bluetoothAdapter = null;
BluetoothSocket socket = null; 

class UserInterface extends Thread {
BluetoothDevice bdDevice;
public UserInterface() {
    bdDevice = your pair device;

}

@Override
public void run() {
    Looper.prepare();
    try {

        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(bdDevice.getAddress());

        if (socket != null && socket.isConnected()) {
            is1.close();
            os1.close();
            socket.close();

        }
        try {
            socket = device.createInsecureRfcommSocketToServiceRecord(SERIAL_UUID);
        } catch (Exception e) {
            Log.e("", "Error creating socket");
        }
        if (bluetoothAdapter.isDiscovering()) {
            bluetoothAdapter.cancelDiscovery();
        }


        try {
            socket.connect();
            Log.e("", "Connected Rfcomm");

        } catch (IOException e) {
            Log.e("", e.getMessage());
            try {
                Log.e("", "trying fallback...");

                socket = device.createInsecureRfcommSocketToServiceRecord(SERIAL_UUID);
                socket.connect();
                Log.e("", "Connected serial UDID");

            } catch (Exception e2) {
                Log.e("", "Couldn't establish Bluetooth connection!");
            }
        }


        if (socket.isConnected()) {
           // dismiss Progress Dialog
                os1 = socket.getOutputStream();
                is1 = socket.getInputStream();
                Log.i("TAG", "Socket Connected");
           //code after socket connect

        } else {
            // dismiss Progress Dialog
            showProgressDialogToast("Please restart bluetooth Device");
            closeSocket();
            Log.i("TAG", "Socket Disconnected");
        }

        Log.i("Log", "Removed" + bdDevice.getName());
    } catch (Exception e) {
        // TODO Auto-generated catch block
        Log.i("Log", "Under Catch of thread");
        e.printStackTrace();
        // dismiss Progress Dialog
    }
}
}

像这样使用线程类

UserInterface userInterface = new UserInterface();
userInterface.start();

关于android - 连接2个蓝牙设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34153833/

相关文章:

java - 什么是 TCP 窗口更新?

Android - 如何确定是否连接了外部扬声器

java - OpenCV 安卓工作室

android - 在 actionbar customview imagebutton 中刷新动画

.net - 本地主机和127.0.0.1不一样吗?

android - 安卓设备之间的蓝牙音频流

android - 如何定期扫描安卓上的蓝牙设备

java - 如何在 java 中使用 openCV 检查两个图像是否相似?

java - 无法使用 dagger2 android java 注入(inject) ViewModel

c# - 套接字断开连接行为