蓝牙打开和搜索并显示在列表

开始第一天,着手这个项目的学习。

首先写一个简单的布局文件,包含三个按钮,一个listView列表显示搜索到的蓝牙

样式如图:

布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/turn_on"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="turn on"
        android:textAllCaps="false"/>
    <Button
        android:id="@+id/turn_off"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="turn off"
        android:textAllCaps="false"/>
    <Button
        android:id="@+id/search_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="search"
        android:textAllCaps="false"/>

    <ListView
        android:id="@+id/search_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></ListView>
    
</LinearLayout>

我将两个功能的代码暂写在MainActivity中,如下:

package com.example.hitmi.bluetoothtest;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
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.Toast;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static android.app.PendingIntent.getActivity;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
    private String TAG ="MainActivity";
    IntentFilter intentFilter;
    ListView listView;
    private List<String> bluetoothList = new ArrayList<String>();
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    ArrayAdapter<String> adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button turnOn = (Button)findViewById(R.id.turn_on);
        Button turnOff = (Button)findViewById(R.id.turn_off);
        Button search = (Button)findViewById(R.id.search_button);
        turnOn.setOnClickListener(this);
        turnOff.setOnClickListener(this);
        search.setOnClickListener(this);
        //安卓6以后使用蓝牙要用定位权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Android M Permission check
            if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
            }
        }
        //蓝牙广播注册
        registerBluetooth();
        //listView布局加载
        adapter =new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,bluetoothList);
        listView = (ListView) findViewById(R.id.search_result);
        listView.setAdapter(adapter);
        //listView点击函数
        listClick();

    }

    //listView点击的实现
    void listClick(){
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

            }
        });
    }
    //广播注册的实现
    void registerBluetooth(){
        // 设置广播信息过滤
        intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        //注册广播
        registerReceiver(bluetoothReceiver, intentFilter);
    }
    //安卓6回调(有bug)
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG,"回调request");
                    //TODO request success/
                }
                break;
        }
    }

    //button点击的实现
    @Override
    public void onClick(View view){
        switch (view.getId()){
            case R.id.turn_on:
            {
                if(mBluetoothAdapter==null){
                    Toast.makeText(this,"当前设备不支持蓝牙功能",Toast.LENGTH_SHORT).show();
                }
                if(!mBluetoothAdapter.isEnabled()){
                 /* Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                  startActivity(i);*/
                    mBluetoothAdapter.enable();
                }
                //开启被其它蓝牙设备发现的功能
                if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                    Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                    //设置为一直开启
                    i.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
                    startActivity(i);
                }
            }
                break;
            case R.id.turn_off:
                //
                break;
            case R.id.search_button:
                Log.d(TAG,"有点击search_button");
                if (bluetoothList==null||!bluetoothList.isEmpty())
                    bluetoothList.clear();
                //如果当前在搜索,就先取消搜索
                if (mBluetoothAdapter.isDiscovering()) {
                    mBluetoothAdapter.cancelDiscovery();
                }
                //开启搜索
                mBluetoothAdapter.startDiscovery();
                break;
                default:
                    break;
        }
    }
    //注册销毁
    @Override
    protected void onDestroy(){
        super.onDestroy();
        unregisterReceiver(bluetoothReceiver);
    }
    //蓝牙开始搜索的回调
    private BroadcastReceiver bluetoothReceiver = new BroadcastReceiver()  {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG,"有回调");
            if (action.equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                //已匹配的设备
                if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                    //此处的adapter是列表的adapter,不是BluetoothAdapter
                    bluetoothList.add(device.getName()+":"+device.getAddress()+"(已配对设备)");
                    adapter.notifyDataSetChanged();
                }else {
                    bluetoothList.add(device.getName()+":"+device.getAddress()+"(未配对设备)");
                    adapter.notifyDataSetChanged();
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                Toast.makeText(MainActivity.this,"开始搜索",Toast.LENGTH_SHORT).show();
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                Toast.makeText(MainActivity.this,"搜索完毕",Toast.LENGTH_SHORT).show();
            }
        }
    };

}

网上类似的代码很多,我重点讲两个问题

1.安卓6.0以后蓝牙使用权限要加上定位权限

在第一尝试写这个代码时,我copy的是网上有些年份的代码,没有加入定位权限,导致startDiscovery方法无法回调BroadcastReceiver,使得搜索功能一直无法实现。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      // Android M Permission check
     if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
     }
}

这段代码是判断手机是不是6.0以上,是则要开定位权限

而我使用的的权限有:

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

2.listView列表重复添加

在startDiscovery方法回调问题解决,listView能显示出蓝牙后我开开心心的蹦蹦跳跳的回家了。结果第二天一来一看,我去,重复添加了。这个时候我在搜索按钮的点击事件中判断listView是否为空,不为空则清空再搜索,代码如下:

                if (bluetoothList==null||!bluetoothList.isEmpty())
                    bluetoothList.clear();

第一个功能写出来,迈出第一步——2019.01.03

-----------------------------------------------分割线---------------------------------------------

猜你喜欢

转载自blog.csdn.net/Hitmi_/article/details/85684648
今日推荐