java - 无法与远程设备进行蓝牙连接。安卓6.0

标签 java android bluetooth android-6.0-marshmallow

我无法连接到远程蓝牙设备。我可以在 ListView 中看到配对和建立的设备,但是当我单击 ListView 中的项目(我的电脑或 Nexus 5 的名称)时,什么也没有发生。不出现蓝牙配对请求窗口。

Manifest.xml

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>

</application>

activity_main.xml

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">

<LinearLayout
    android:layout_gravity="center_horizontal"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/button_enable_BT"
        android:layout_marginRight="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/enableBT"/>

    <Button
        android:id="@+id/button_start_discovery"
        android:layout_marginRight="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/start_discovery_button"/>

    <Button
        android:id="@+id/button_stop_discovery"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/stop_discovery_button"/>

</LinearLayout>

<TextView
    android:id="@+id/status"
    android:hint="@string/status"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="10dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="10dp"
    android:text="@string/paired_devices"/>

<ListView
    android:id="@+id/paired_list"
    android:layout_marginTop="10dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
<LinearLayout

MainActivity.java

public class MainActivity extends Activity {
private final static int REQUEST_ENABLE_BT = 1;
private final static int REQUEST_COARSE_LOCATION_PERMISSIONS = 2;
UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothAdapter mBluetoothAdapter;
ListView pairedList;
ListView newList;
Button mStart;
Button mStop;
Button mEnableBT;
TextView status;
ArrayAdapter<String> mArrayAdapter;
ArrayList<BluetoothDevice> devices;
IntentFilter filter;
String[] names;
ConnectThread mConnectThread;
ConnectedThread mConnectedThread;

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

    init();

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    if (pairedDevices.size() > 0) {
        for (BluetoothDevice device : pairedDevices) {
            devices.add(device);
            mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
        }
    }
    pairedList.setAdapter(mArrayAdapter);

    mStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            doDiscovery();
        }
    });
    mStop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mBluetoothAdapter.cancelDiscovery();
        }
    });
    mEnableBT.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }
    });
    AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if(mBluetoothAdapter.isDiscovering()){
                mBluetoothAdapter.cancelDiscovery();
            }
            BluetoothDevice selectedDevice = devices.get(position);
            mConnectThread = new ConnectThread(selectedDevice);
            mConnectThread.start();

        }
    };
    pairedList.setOnItemClickListener(itemClickListener);

    filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mReceiver, filter);
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
    registerReceiver(mReceiver, filter);
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    registerReceiver(mReceiver, filter);
    filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(mReceiver, filter);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mBluetoothAdapter.cancelDiscovery();
    unregisterReceiver(mReceiver);
}

public void init(){
    names = new String[10];
    devices = new ArrayList<>();
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    status = (TextView)findViewById(R.id.status);
    mStart = (Button)findViewById(R.id.button_start_discovery);
    mStop = (Button)findViewById(R.id.button_stop_discovery);
    mEnableBT = (Button)findViewById(R.id.button_enable_BT);
    pairedList = (ListView)findViewById(R.id.paired_list);
    mArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
            if(BluetoothAdapter.STATE_ON == state){
                Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
                if (pairedDevices.size() > 0) {
                    for (BluetoothDevice device : pairedDevices) {
                        mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                        devices.add(device);
                    }
                }
            }
            if(BluetoothAdapter.STATE_OFF == state){
                mArrayAdapter.clear();
                devices.clear();
            }
        }
        if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
            status.setText("Discovery started");
        }
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            status.setText("Device found");
            if(device.getBondState() != BluetoothDevice.BOND_BONDED) {
                if(mArrayAdapter.getPosition(device.getName()+"\n"+device.getAddress()) < 0){
                    mArrayAdapter.add(device.getName()+"\n"+device.getAddress());
                    devices.add(device);
                    status.setText("!!!");
                }
            }
        }
        if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
            status.setText("Discovery stopped");
        }
    }
};
public void doDiscovery(){
    int hasPermission = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);
    if (hasPermission == PackageManager.PERMISSION_GRANTED) {
        if(mBluetoothAdapter.isDiscovering()){
            mBluetoothAdapter.cancelDiscovery();
        }
        mBluetoothAdapter.startDiscovery();
    }
    requestPermissions(new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},
            REQUEST_COARSE_LOCATION_PERMISSIONS);
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_COARSE_LOCATION_PERMISSIONS: {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if(mBluetoothAdapter.isDiscovering()){
                    mBluetoothAdapter.cancelDiscovery();
                }
                mBluetoothAdapter.startDiscovery();
            } else {
                Toast.makeText(this,
                        getResources().getString(R.string.permission_failure),
                        Toast.LENGTH_LONG).show();
                mBluetoothAdapter.cancelDiscovery();
            }
            return;
        }
    }
}
public synchronized void connected(BluetoothSocket socket) {

    // Cancel the thread that completed the connection
    if (mConnectThread != null) {
        mConnectThread.cancel();
        mConnectThread = null;
    }

    // Cancel any thread currently running a connection
    if (mConnectedThread != null) {
        mConnectedThread.cancel();
        mConnectedThread = null;
    }

    // Start the thread to manage the connection and perform transmissions
    mConnectedThread = new ConnectedThread(socket);
    mConnectedThread.start();
}
private class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;

    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
        BluetoothSocket tmp = null;
        mmDevice = device;

        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }

    public void run() {
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();

        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }

        // Do work to manage the connection (in a separate thread)
        connected(mmSocket);
    }
    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            mmSocket.close();
        } 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;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI activity

            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }

    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}

}

最佳答案

对于 6.0 (API 23) 及以上版本,现在您需要在运行时请求权限,仅在 list 上声明它们是不够的。因此,您需要执行以下操作:https://stackoverflow.com/a/33052902/2328012

希望对你有帮助!

关于java - 无法与远程设备进行蓝牙连接。安卓6.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36661680/

相关文章:

java - Maven 没有找到本地依赖

android - 如何跟踪 Android 中应用程序的使用时间?

android - 如何在运行时更新 Android BLE Advertiser 服务数据?

android - 在 Android 中从蓝牙音频设备录制音频

bluetooth - 哪些范围的蓝牙 UUID 可用于供应商定义的配置文件?

java - 使用 Jackson 在没有堆栈跟踪的情况下序列化/反序列化异常

java - 在 spring 批处理器中执行查询

java - 如何用 Java 制作多组件 Swing 类

java - Android 上点击定时器

android - 如何从 android 中的 SocialAuth Api 获取 linkedIn 公共(public)个人资料 url?