最近在做蓝牙扫描功能,了解了蓝牙的一部分知识,虽然不够深入,但是感觉良好,没做的时候感觉非常难:
但是做完了以后感觉 其他并不难 希望看到此篇文章的你---加油
需要时这样:开启扫描蓝牙周围设备,拿到MAC地址已经广播包数据,下面我们来写一下代码
先来看一下效果
大概流程如下
1.添加权限
2.判断设备是否支持BLE4.0
3.判断蓝牙是否开启,如果未开启,则静默开启窗口
4.开启后,开始进行蓝牙扫描
5.通过BluetoothAdapter.LeScanCallback获取扫描结果
如果这些代码都写在V层那就有些过于臃肿了,所以我们来写一个工具类
建立BlueUtils.java
public class BlueUtils { //蓝牙适配器 private BluetoothAdapter mBluetoothAdapter; //搜索状态的标示 private boolean mScanning = true; //蓝牙适配器List private List<BluetoothDevice> mBlueList; //上下文 private Context context; //单例模式 private static BlueUtils blueUtils; //蓝牙的回调地址 private BluetoothAdapter.LeScanCallback mLesanCall; //扫描执行回调 private BlueUddtils.Callback callback; }
先把变量都写好 下面咱们开始写方法
先写一个单例模式
//单例模式 public static BlueUtils getBlueUtils(){ if(blueUtils == null){ blueUtils = new BlueUtils(); } return blueUtils; }
然后getInitialization方法中初始化一些蓝牙的相关类
/*** * 初始化蓝牙的一些信息 */ public void getInitialization(Context context){ this.context = context; //初始化蓝牙适配器 BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); //初始化蓝牙 mBluetoothAdapter = bluetoothManager.getAdapter(); //初始化List mBlueList = new ArrayList<>(); //实例化蓝牙回调 mLesanCall = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) { //返回三个对象 分类别是 蓝牙对象 蓝牙信号强度 以及蓝牙的广播包 if(!mBlueList.contains(bluetoothDevice)){ mBlueList.add(bluetoothDevice); } } }; }
接下来我们就要写开始扫描和关闭的方法了
/** * 开启蓝牙 */ public void startBlue(){ if(mScanning){ mScanning = false; //开始扫描并设置回调 mBluetoothAdapter.startLeScan(mLesanCall); } } /** * 停止蓝牙扫描 */ public void stopBlue(){ if(!mScanning){ //结束蓝牙扫描 mBluetoothAdapter.stopLeScan(mLesanCall); } }
设置接口回调
/** * 接口回调 */ public interface Callbacks{ void CallbackList(List<BluetoothDevice> mBlueLis); } /** * 设置接口回调 * @param callback 自身 */ public void setCallback(Callbacks callback) { this.callback = callback; }
大家需要注意的是,蓝牙扫描到设备就会回调onLeScan方法 所以我们需要在此方法中把搜索到的蓝牙对象加入到List中,然后利用接口回调把数据送出去
//实例化蓝牙回调 mLesanCall = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) { //返回三个对象 分类别是 蓝牙对象 蓝牙信号强度 以及蓝牙的广播包 if(!mBlueList.contains(bluetoothDevice)){//重复的则不添加 mBlueList.add(bluetoothDevice); //接口回调 callback.CallbackList(mBlueList); } } };
还有isSupportBlue方法是用来检测设备是否支持蓝牙的
/** * 判断是否支持蓝牙 * @return */ public boolean isSupportBlue(){ if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { return true; }else { return false; } }
/** * 返回蓝牙对象 * @return */ public BluetoothAdapter getmBluetoothAdapter() { return mBluetoothAdapter; }
下面我们开始调用吧 在调用之前,我们需要给程序加入蓝牙权限,(6.0以后需要动态申请)
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
先贴布局文件
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:layout_weight="1" android:id="@+id/scan" android:layout_width="0dp" android:layout_height="wrap_content" android:text="搜索" /> <Button android:layout_weight="1" android:id="@+id/end" android:layout_width="0dp" android:layout_height="wrap_content" android:text="关闭扫描" /> </LinearLayout> <ListView android:id="@+id/result" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>
大体布局如下
MainActivity.java
package com.example.myapplication; import android.bluetooth.BluetoothDevice; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import com.example.myapplication.adapter.BlueAdapter; import java.util.List; /** * Created by huitao on 2017/12/27. */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { //搜索BUTTON private Button scan,end; //搜索结果List private ListView resultList; //蓝牙工具类 private BlueUtils blueUtils; //蓝牙的Adapter private BlueAdapter blueAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); blueUtils = new BlueUtils(); //初始化工具类 blueUtils.getInitialization(this); //判断是否支持蓝牙 if (!blueUtils.isSupportBlue()) { Toast.makeText(this, "设备支持蓝牙4.0", Toast.LENGTH_SHORT).show(); blueUtils.getmBluetoothAdapter().enable(); }else { Toast.makeText(this, "设备不支持蓝牙4.0", Toast.LENGTH_SHORT).show(); //静默开启蓝牙 } inint(); } /** * 初始化数据 */ private void inint() { scan = findViewById(R.id.scan); end = findViewById(R.id.end); resultList = findViewById(R.id.result); scan.setOnClickListener(this); end.setOnClickListener(this); blueUtils.setCallback(new BlueUtils.Callbacks() { @Override public void CallbackList(List<BluetoothDevice> mBlueLis) { //我们在此处设置Adapter if(blueAdapter == null){ blueAdapter = new BlueAdapter(mBlueLis,MainActivity.this); resultList.setAdapter(blueAdapter); }else { blueAdapter.notifyDataSetChanged(); } } }); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.scan: blueUtils.startBlue(); Toast.makeText(this, "开启成功", Toast.LENGTH_SHORT).show(); break; case R.id.end: blueUtils.stopBlue(); Toast.makeText(this, "关闭成功", Toast.LENGTH_SHORT).show(); break; } } }
BlueAdapter.java
package com.example.myapplication.adapter; import android.annotation.SuppressLint; import android.bluetooth.BluetoothDevice; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import com.example.myapplication.R; import java.util.List; /** * 蓝牙填充 * Created by huitao on 2017/12/27. */ public class BlueAdapter extends BaseAdapter{ private List<BluetoothDevice> mBluelist; private LayoutInflater layoutInflater; public BlueAdapter(List<BluetoothDevice> list, Context context) { mBluelist = list; layoutInflater = LayoutInflater.from(context);//context :要使用当前的Adapter的界面对象 layoutInflater: 布局装载器对象 } @Override public int getCount() { return mBluelist.size(); } @Override public Object getItem(int i) { return mBluelist.get(i); } @Override public long getItemId(int i) { return i; } @SuppressLint("SetTextI18n") @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder viewHolder; if (view == null) { viewHolder = new ViewHolder(); view = layoutInflater.inflate(R.layout.list_item,null); viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name); viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address); view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); } BluetoothDevice blueDevice = mBluelist.get(i); final String deviceName = blueDevice.getName(); if (deviceName != null && deviceName.length() > 0) { viewHolder.deviceName.setText(blueDevice.getName()); } else { viewHolder.deviceName.setText("未知设备"); } viewHolder.deviceAddress.setText("MAC地址:"+blueDevice.getAddress()); return view; } class ViewHolder { TextView deviceName; TextView deviceAddress; } }
adapter的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/device_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="24dp"/> <TextView android:id="@+id/device_address" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="12dp"/> </LinearLayout>
最后说一下 BluetoothDevice获取信息的方法
getName 是获取设备名字
getAddress 是获取设备的MAC地址
getBluetoothClass().getDeviceClass 是获取设备的类型
到此就结束了 感谢大家
Demo下载地址:http://download.csdn.net/download/crackgmkey/10175546