开始第一天,着手这个项目的学习。
首先写一个简单的布局文件,包含三个按钮,一个listView列表显示搜索到的蓝牙
样式如图:
布局文件如下:
我将两个功能的代码暂写在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 bluetoothList = new ArrayList();
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
ArrayAdapter 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(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以上,是则要开定位权限
而我使用的的权限有:
2.listView列表重复添加
在startDiscovery方法回调问题解决,listView能显示出蓝牙后我开开心心的蹦蹦跳跳的回家了。结果第二天一来一看,我去,重复添加了。这个时候我在搜索按钮的点击事件中判断listView是否为空,不为空则清空再搜索,代码如下:
if (bluetoothList==null||!bluetoothList.isEmpty())
bluetoothList.clear();
第一个功能写出来,迈出第一步——2019.01.03
-----------------------------------------------分割线---------------------------------------------