手把手教你Android手机与BLE终端通信--搜索
2016-06-17 11:43
567 查看
由于代码量大,这次只写搜索,以后接着写连接和发送数据。
1,界面上只有一个按钮和一个listview
2,MainActivity首先初始化蓝牙并打开service,service用于后台和界面的沟通。
3,点击MainActivity搜索按钮开启异步任务,调用搜索方法
异步任务中只有一句,开始搜索
4,初始化,搜索等蓝牙操作都在controller类中。搜索代码中设置5秒后停止搜索,搜索成功回调中发消息给service,
service发广播给MainActivity更新listview.
不要忘了注册service和广播receiver
不要忘了注册和注销这个receiver
我们的实体类,暂存设备
一定要注意:
1,这是蓝牙和串口连接,不是和另外一个手机的蓝牙连接。
2,由于安卓6.0以上的权限管理问题,需要以下三个权限(6.0以前只要后两个就可以):
完整代码链接:
http://pan.baidu.com/s/1mi71vWO
1,界面上只有一个按钮和一个listview
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffff" > <Button android:id="@+id/btn_search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="搜索" android:layout_marginTop="40dp" android:layout_marginLeft="40dp" android:background="@null" android:textColor="#ff2222ff" android:textSize="32sp"/> <ListView android:id="@+id/list_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_below="@id/btn_search" android:layout_marginLeft="40dp"> </ListView> </RelativeLayout>
2,MainActivity首先初始化蓝牙并打开service,service用于后台和界面的沟通。
//开始服务 intentService = new Intent(MainActivity.this,BLEService.class); startService(intentService); // 初始化蓝牙 BluetoothController.getInstance().initBLE();下面是initBle方法,初始化蓝牙,注释要看哦。
/** * 初始化蓝牙 * @return */ public boolean initBLE(){ //检查当前手机是否支持ble 蓝牙,如果不支持退出程序 //App.app可能会报错,清单文件中不要忘了配置application if (!App.app.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { return false; } // 初始化 Bluetooth adapter, 通过蓝牙管理器得到一个参考蓝牙适配器(API必须在以上android4.3或以上版本) final BluetoothManager bluetoothManager = (BluetoothManager) App.app.getSystemService(Context.BLUETOOTH_SERVICE); bleAdapter = bluetoothManager.getAdapter(); // 检查设备上是否支持蓝牙 if (bleAdapter == null) return false; else return true; }
3,点击MainActivity搜索按钮开启异步任务,调用搜索方法
search = (Button) findViewById(R.id.btn_search); search.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if(!BluetoothController.getInstance().initBLE()){//手机不支持蓝牙 Toast.makeText(MainActivity.this, "您的手机不支持蓝牙", Toast.LENGTH_SHORT).show(); return;//手机不支持蓝牙就啥也不用干了,关电脑睡觉去吧 } if (!BluetoothController.getInstance().isBleOpen()) {// 如果蓝牙还没有打开 Toast.makeText(MainActivity.this, "请打开蓝牙", Toast.LENGTH_SHORT).show(); return; } new GetDataTask().execute();// 搜索任务 } });
异步任务中只有一句,开始搜索
private class GetDataTask extends AsyncTask<Void, Void, String[]> { @Override protected String[] doInBackground(Void... params) { if(BluetoothController.getInstance().isBleOpen()){ BluetoothController.getInstance().startScanBLE(); };// 开始扫描 return null; } @Override protected void onPostExecute(String[] result) { super.onPostExecute(result); } }
4,初始化,搜索等蓝牙操作都在controller类中。搜索代码中设置5秒后停止搜索,搜索成功回调中发消息给service,
service发广播给MainActivity更新listview.
不要忘了注册service和广播receiver
/** * 开始扫描蓝牙 */ public void startScanBLE(){ bleAdapter.startLeScan(bleScanCallback); if(serviceHandler!=null) serviceHandler.sendEmptyMessageDelayed(ConstantUtils.WM_STOP_SCAN_BLE, 5000); }bleScanCallback是搜索成功后的回调,搜索成功后发消息给service,让它发广播更新界面
/** * 搜索蓝牙回调 */ BluetoothAdapter.LeScanCallback bleScanCallback =new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(BluetoothDevice device, int arg1, byte[] arg2) { // device就是搜索到的设备 String name=device.getName(); if(name==null) return; if(BluetoothController.this.serviceHandler!=null&&!name.isEmpty()){ Message msg=new Message(); msg.what=ConstantUtils.WM_UPDATE_BLE_LIST; msg.obj=device; BluetoothController.this.serviceHandler.sendMessage(msg); } } };其中的serviceHandler是在service中初始化的,所以它会发消息到service中。
Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case ConstantUtils.WM_STOP_SCAN_BLE://搜索5秒后停止搜索 bleCtrl.stopScanBLE(); break; case ConstantUtils.WM_UPDATE_BLE_LIST://回调发来的更新列表消息 //更新蓝牙列表广播 Intent intent=new Intent(ConstantUtils.ACTION_UPDATE_DEVICE_LIST); BluetoothDevice device=(BluetoothDevice)msg.obj; intent.putExtra("name",device.getName()); intent.putExtra("address", device.getAddress()); sendBroadcast(new Intent(intent)); break; } } };5, MainActivity收到更新列表的消息后更新列表,更新列表时一定要先判断Listview中是否已经有那个设备了,否则会搜的很多次那个设备,然后你的手机就卡了,说不定还要害你重启手机呢,至少得关了这个app了。
public class MsgReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equalsIgnoreCase( ConstantUtils.ACTION_UPDATE_DEVICE_LIST)) { String name = intent.getStringExtra("name"); String address = intent.getStringExtra("address"); boolean found=false;//记录该条记录是否已在list中, for(EntityDevice device:list){ if(device.getAddress().equals(address)){ found=true; break; } }// for if(!found){ EntityDevice temp = new EntityDevice(); temp.setName(name); temp.setAddress(address); list.add(temp); adapter.notifyDataSetChanged(); } } } }
不要忘了注册和注销这个receiver
我们的实体类,暂存设备
public class EntityDevice { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
一定要注意:
1,这是蓝牙和串口连接,不是和另外一个手机的蓝牙连接。
2,由于安卓6.0以上的权限管理问题,需要以下三个权限(6.0以前只要后两个就可以):
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
完整代码链接:
http://pan.baidu.com/s/1mi71vWO
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析