Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android蓝牙:生成随机UUID后无法连接到侦听套接字_Android_Sockets_Bluetooth_Device_Serversocket - Fatal编程技术网

Android蓝牙:生成随机UUID后无法连接到侦听套接字

Android蓝牙:生成随机UUID后无法连接到侦听套接字,android,sockets,bluetooth,device,serversocket,Android,Sockets,Bluetooth,Device,Serversocket,我的程序有两个不同的实例不打算连接到BluetoothServerSocket 其中一个实例在使用scan\u mode\u CONNECTABLE\u DISCOVERABLE启动扫描模式之前,以及在使用相同生成的UUID创建用于侦听的BluetoothServerSocket之前,仅随机生成了1个UUID。另一个intance在Bluetooth设备尝试连接刚刚生成的UUID之前生成一个随机UUID 每个实例都无法完成蓝牙连接。在整个程序中,我放了很多日志,只是想看看为什么它无法连接 下面是

我的程序有两个不同的实例不打算连接到
BluetoothServerSocket

其中一个实例在使用
scan\u mode\u CONNECTABLE\u DISCOVERABLE
启动扫描模式之前,以及在使用相同生成的UUID创建用于侦听的
BluetoothServerSocket
之前,仅随机生成了1个UUID。另一个intance在Bluetooth设备尝试连接刚刚生成的UUID之前生成一个随机UUID

每个实例都无法完成蓝牙连接。在整个程序中,我放了很多日志,只是想看看为什么它无法连接

下面是第一个实例的代码。(在应用程序启动时生成1个随机UUID。)如果有人想下载我的Eclipse项目只是为了看一看,比如第二个实例,那么在下面的代码中取消注释C风格的注释就会显示出来

我希望结果是在两台设备之间成功连接。成功的连接使用生成的UUID将设备连接到侦听套接字。观察结果表明这不太可能。

据我所知,获取UUID的唯一方法是从
UUID.randomUUID()
获取它。如果还有其他方法,请在下面发表评论,我会检查一下。但现在,这不是我想要的答案

提前谢谢

package o.p;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

/**
 * The purpose of this app is to create a server-only Bluetooth connection that
 * only accepts incoming Bluetooth connections. It is used only for testing
 * one device that needs Bluetooth tweaking in order to consistently work
 * correctly on the other device. In short, 2 devices are required.
 * */

public class Main extends Activity implements View.OnClickListener {
    //Button
    private Button acceptButton;
    private Button scanButton;

    //Bluetooth stuffs.
    private BluetoothAdapter btAdapter;
    private BluetoothServerSocket serverSocket;
    private BluetoothSocket socket;
    private BluetoothDevice targetDevice;
    private final UUID uuid = UUID.randomUUID();

    /*private UUID randomUUID;*/

    //Accepting thread.
    private class Accept implements Runnable {
        private BluetoothServerSocket socket;
        private BluetoothSocket result = null;

        public Accept(BluetoothServerSocket s) {
            socket = s;
            result = null;
        }

        @Override
        public void run() {
            try {
                Log.d("DEBUG", "Accepting.");
                result = socket.accept();
                Log.d("DEBUG", "Closing server socket.");
                socket.close();
            }
            catch (IOException e) {
                Log.d("DEBUG - onClick(), case Accept", "Unable to accept incoming connection.");
            }
        }

        public BluetoothSocket getSocket() {
            while (result == null);
            return result;
        }
    }

    //Connecting thread.
    private class Connecting implements Runnable {
        private BluetoothDevice device;

        public Connecting(BluetoothDevice d) {
            device = d;
        }

        @Override
        public void run() {
            try {


                   /*Log.d("DEBUG", "Generating a new random UUID.");
                randomUUID = UUID.randomUUID();*/
                Log.d("DEBUG", "Obtaining a socket.");
                BluetoothSocket s = device.createRfcommSocketToServiceRecord(uuid);
                Log.d("DEBUG", "Cancelling discovery, if it's still discovering.");
                if (btAdapter.isDiscovering())
                    btAdapter.cancelDiscovery();
                Log.d("DEBUG", "Connecting to listening socket with UUID: " + uuid.toString());
                s.connect();

            }
            catch (IOException e) {
                Log.d("DEBUG - Connecting.run()", "Unable to connect to the listening socket.");
            }
        }
    }

    //Thread executor
    private ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();

    //BroadcastReceiver for accepting Bluetooth
    private BroadcastReceiver receiver;

    @Override
    public void onCreate(Bundle b) {
        super.onCreate(b);
        setContentView(R.layout.main);
        init();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_accept:
                Log.d("DEBUG", "Pressing the Accept button.");
                Accept acceptThread = new Accept(serverSocket);
                Connecting connectThread = new Connecting(targetDevice);
                if (serverSocket != null) {
                    executor.execute(acceptThread);
                    executor.execute(connectThread);
                    socket = acceptThread.getSocket();
                }
                else {
                    Log.d("DEBUG", "Server socket isn't ready.");
                    Toast.makeText(this, "Server socket isn't ready.", Toast.LENGTH_LONG).show();
                }
                break;
            case R.id.button_scan:
                if (btAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                    Log.d("DEBUG", "Initiating discovery scan mode.");
                    Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                    discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
                    this.startActivity(discoverableIntent);
                    Toast.makeText(this, "Being discovered...", Toast.LENGTH_LONG).show();
                }
                if (btAdapter.isDiscovering()) {
                    Toast.makeText(this, "Re-scanning...", Toast.LENGTH_SHORT).show();
                    Log.d("DEBUG", "Re-scanning.");
                    btAdapter.cancelDiscovery();
                }
                Log.d("DEBUG", "Scanning.");
                Toast.makeText(this, "Scanning...", Toast.LENGTH_LONG).show();
                btAdapter.startDiscovery();
                break;
        }
    }

    private void init() {
        Log.d("DEBUG", "Initializing.");
        Log.d("DEBUG", "Button initializing.");
        acceptButton = (Button) findViewById(R.id.button_accept);
        acceptButton.setOnClickListener(this);
        scanButton = (Button) findViewById(R.id.button_scan);
        scanButton.setOnClickListener(this);
        Log.d("DEBUG", "Registering BroadcastReceiver.");
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    Log.d("DEBUG", "Device has been found.");
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    Log.d("DEBUG", "Obtained a device from Intent.");
                    if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                        Log.d("DEBUG", "Removing paired device.");
                        try {
                            Method m = device.getClass().getMethod("removeBond", (Class[]) null);
                            m.invoke(device, (Object[]) null);
                            Log.d("DEBUG", "Removed " + device);
                        }
                        catch (NoSuchMethodException e) {
                            Log.e("ERROR - DeviceReceiver.onReceive()", "", e);
                        }
                        catch (IllegalArgumentException e) {
                            Log.e("ERROR - DeviceReceiver.onReceive()", "", e);
                        }
                        catch (IllegalAccessException e) {
                            Log.e("ERROR - DeviceReceiver.onReceive()", "", e);
                        }
                        catch (InvocationTargetException e) {
                            Log.e("ERROR - DeviceReceiver.onReceive()", "", e);
                        }
                    }
                    else {
                        Log.d("DEBUG", "Obtaining remote device's address.");
                        btAdapter.getRemoteDevice(device.getAddress());
                        try {
                            serverSocket = btAdapter.listenUsingRfcommWithServiceRecord(device.getName(), uuid);
                            Log.d("DEBUG", "Listening to " + device.getName() + "...");
                        }
                        catch (IOException e) {
                            Log.d("DEBUG - onReceive()", "Unable to create a server socket after receiving a broadcast.", e);
                            serverSocket = null;
                            Log.d("DEBUG", "Server socket is set to null.");
                        }
                    }
                    targetDevice = device;
                }
                else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    Log.d("DEBUG", "Scanning finished.");
                }
            }
        };
        Log.d("DEBUG", "Creating Bluetooth Adapter.");
        btAdapter = BluetoothAdapter.getDefaultAdapter();
        try {
            Log.d("DEBUG", "Creating a server socket for listening using UUID: " + uuid.toString());
            serverSocket = btAdapter.listenUsingRfcommWithServiceRecord("server", uuid);
        }
        catch (IOException e) {
            Log.d("DEBUG - init()", "Error in creating a server socket from uuid.");
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        //TODO: Not done with the receivers.
        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(receiver, filter);
        filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(receiver, filter);
    }

    @Override
    public void onPause() {
        //TODO: Complete this one. Same for onResume().
        super.onPause();
        unregisterReceiver(receiver);
    }
}

要能够连接,UUID应该匹配。 在服务器端,您所做的是正确的,即生成一个ramdom UUID并监听它, 但是客户端需要使用服务器正在侦听的相同UUID进行连接。
获取它的方法是从客户端使用服务器BluetoothDevice对象上的fetchUUIDSWithDP()并使用获得的UUID连接到服务器。

要能够连接UUID,UUID应该匹配。 在服务器端,您所做的是正确的,即生成一个ramdom UUID并监听它, 但是客户端需要使用服务器正在侦听的相同UUID进行连接。
获取它的方法是从客户端使用服务器BluetoothDevice对象上的fetchUUIDSWithDP()并使用获得的UUID连接到服务器。

我也做了同样的事情。你可以把它作为参考。这是答案。我也做了同样的事。你可以把它作为参考。下面是示例。您知道在使用
fetchUUIDSWITHDP()
后过滤掉
parceluId
数组的方法吗,以便它与客户端的UUID匹配?使用
fetchuuidwithdp()
,我能够获得
parcelouids
,但它们实际上都不允许服务器接受连接。这就像客户端的UUID不在阵列中一样,并且同一个UUID与服务器的UUID不匹配。简而言之,UUID不能在编译时生成。无法使用
UUID.randomUUID()
生成UUID,除非它们用于其他特定用途。即使使用
BluetoothDevice.getUuids()
BluetoothDevice.fetchUuidsWithSDP()
也没有用,因为uuid也是在编译时生成的。(这包括使用反射方法和调用这两个函数以用于Android 4.0之前的版本,它们没有用处。)感谢您链接到讨论并提出适合您的解决方案,在编译时生成UUID基本上可以确保应用程序客户机和服务器使用相同的UUID,而这是连接的基本要求。只要您同时连接服务器和客户端,这是可以的,但是连接到一些现有的服务器应用程序呢?操作系统从SDP获取UUID的唯一方法,这就是蓝牙的工作原理,我自己也曾使用过FetchUUIDSWithDP(),但奇怪的是它返回的UUID没有用处。一些消息来源提到,一些设备,特别是HTC设备,没有100%的蓝牙兼容性。他们认为,这些设备的蓝牙集成尚未完成,而且当API级别达到更高的数字时(比如18到20),蓝牙集成很可能已经完成。即便如此,如果使用SDP获取的UUID失败,旧的API级别将很难利用蓝牙功能,这正是我现在所经历的。您知道在使用
fetchUUIDSWithDP()
后过滤掉
parceluid
数组的方法吗,以便它与客户端的UUID匹配?使用
fetchuuidwithdp()
,我能够获得
parcelouids
,但它们实际上都不允许服务器接受连接。这就像客户端的UUID不在阵列中一样,并且同一个UUID与服务器的UUID不匹配。简而言之,UUID不能在编译时生成。无法使用
UUID.randomUUID()
生成UUID,除非它们用于其他特定用途。即使使用
BluetoothDevice.getUuids()
BluetoothDevice.fetchUuidsWithSDP()
也没有用,因为uuid也是在编译时生成的。(这包括使用反射方法和调用这两个函数以用于Android 4.0之前的版本,它们没有用处。)感谢您链接到讨论并提出适合您的解决方案,在编译时生成UUID基本上可以确保应用程序客户机和服务器使用相同的UUID,而这是连接的基本要求。只要您同时连接服务器和客户端,这是可以的,但是连接到一些现有的服务器应用程序呢?操作系统从SDP获取UUID的唯一方法,这就是蓝牙的工作原理,我自己也曾使用过FetchUUIDSWithDP(),但奇怪的是它返回的UUID没有用处。一些消息来源提到,一些设备,特别是HTC设备,没有100%的蓝牙兼容性。他们表示,这些设备的蓝牙集成还不完善,而且很可能是我的