赞
踩
- private BluetoothAdapter btAdapt;
- private List<BluetoothDevice> listDevices = new ArrayList<BluetoothDevice>();
- private List<TieBean> listDeviceName = new ArrayList<TieBean>();
- private boolean bIsConnected;
- private BluetoothDevice myBluetooth;
- private public BluetoothGatt mBluetoothGatt;
- private TextView tv_seacher_ble;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
- setContentView(R.layout.activity_main);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//锁屏
- tv_seacher_ble = (LinearLayout) findViewById(R.id.tv_seacher_ble);//linear Layout
-
- BluetoothAdapter btAdapt = BluetoothAdapter.getDefaultAdapter();// 初始化本机蓝牙功能
-
- IntentFilter intent = new IntentFilter();
- intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver来取得搜索结果
- intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
- intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- mActivity.registerReceiver(searchDevicesBroadcast, intent);
-
- tv_seacher_ble.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- btAdapt.startDiscovery();
- }
- });
- }
-
-
- //搜索到的蓝牙设备在这里
- private BroadcastReceiver searchDevicesBroadcast = new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- if (TextUtils.isEmpty(device.getName())) {
- return;
- }
- ToastUtil.showToast(mActivity, "蓝牙设备 " + device.getName());
- String str = device.getName() + "|" + device.getAddress();
- if (listDeviceName.indexOf(str) == -1) {// 防止重复添加
- listDevices.add(device); // 获取设备名称和mac地址
- listDeviceName.add(new TieBean(str));
- }
- }
- };
-
-
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //断开设备
- if (msg.what == 1) {
- mBluetoothGatt.disconnect();
- //连接设备
- } else if (msg.what == 2) {
- ToastUtil.showToast(mActivity, "开始搜索蓝牙设备");
- if (btAdapt.getState() == BluetoothAdapter.STATE_OFF) {// 如果蓝牙还没开启
- ToastUtil.showToast(mActivity, "请先打开蓝牙");
- return;
- }
- if (btAdapt.isDiscovering())
- btAdapt.cancelDiscovery();
- listDevices.clear();
- listDeviceName.clear();
-
- btAdapt.startDiscovery();
- //定时器操作
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- //ToastUtil.showToast(mActivity,"搜索蓝牙完毕");
- btAdapt.cancelDiscovery();
- closeProgressDialog();
- //其中BuildBean,TieAdapter是在app的build.gradle中dependencies {compile 'com.dou361.dialogui:jjdxm-dialogui:1.0.3'};
- TieAdapter adapter = new TieAdapter(mContext, listDeviceName, true);
- BuildBean buildBean = DialogUIUtils.showMdBottomSheet(mActivity, true, "", listDeviceName, 0, new DialogUIItemListener() {
- @Override
- public void onItemClick(CharSequence text, int position) {
- myBluetooth = listDevices.get(position);
- //根据蓝牙地址获取远程蓝牙设备
- final BluetoothDevice device = btAdapt.getRemoteDevice(myBluetooth.getAddress());
- if (device == null) {
- return;
- }
- mBluetoothGatt = device.connectGatt(mActivity, false, mGattCallback);
-
- }
- });
- buildBean.mAdapter = adapter;
- buildBean.show();
- }
- }, 8000); //延时8s执行
- } else if (msg.what == 3) {
- tv_seacher_ble.setText("断开蓝牙");
- } else if (msg.what == 4) {
- tv_seacher_ble.setText("连接蓝牙");
- mBluetoothGatt.close();
- }
- super.handleMessage(msg);
- }
- };
两个项目中的蓝牙适配器的获取,去发现,动态注册广播、广播接收蓝牙搜索结果、蓝牙连接都一样,至于手机是否支持ble4.0,蓝牙是否开启的逻辑,连接上对数据的处理、断开mBluetoothGatt.disconnect(),关闭mBluetoothGatt.close() 的逻辑网上有很多,我这里就不在详说;
- package com.hand.hand16.activity;
- import android.app.Activity;
- import android.bluetooth.BluetoothAdapter;
- import android.bluetooth.BluetoothDevice;
- import android.bluetooth.BluetoothGatt;
- import android.bluetooth.BluetoothGattCallback;
- import android.bluetooth.BluetoothGattCharacteristic;
- import android.bluetooth.BluetoothGattService;
- import android.bluetooth.BluetoothManager;
- import android.bluetooth.BluetoothProfile;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.os.Vibrator;
- import android.support.v7.app.AlertDialog;
- import android.support.v7.app.AppCompatActivity;
- import android.view.Gravity;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.Window;
- import android.view.WindowManager;
- import android.widget.Button;
- import android.widget.TextView;
- import com.dou361.dialogui.DialogUIUtils;
- import com.dou361.dialogui.adapter.TieAdapter;
- import com.dou361.dialogui.bean.BuildBean;
- import com.dou361.dialogui.bean.TieBean;
- import com.dou361.dialogui.listener.DialogUIItemListener;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
-
- public class MainActivity extends AppCompatActivity implements View.OnClickListener {
- private TextView tv_seacher_ble;
- public boolean bIsConnected;
- private TieAdapter tieAdapter;
- private Vibrator vibrator;
- private BluetoothDevice mBluetoothDevice;
- private BluetoothAdapter btAdapt;
- List<BluetoothDevice> listDevices = new ArrayList<BluetoothDevice>();
- List<TieBean> listDeviceName = new ArrayList<TieBean>();
-
- private BluetoothDevice myBluetooth;
- public BluetoothGatt mBluetoothGatt;//中央使用和处理数据
- public BluetoothGattCharacteristic mNotifyCharacteristic;
- private boolean mScanning;
- //蓝牙服务
- private String strDevice = "";
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == 1) {
- //断开设备
- mBluetoothGatt.disconnect();
- } else if (msg.what == 2) {
- //连接设备
- if (btAdapt == null || !btAdapt.isEnabled() || btAdapt.getState() == BluetoothAdapter.STATE_OFF) {// 如果蓝牙还没开启
- Toast.makeText(MainActivity.this,"请先打开蓝牙",Toast.LENGTH_SHORT).show();
- Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
- startActivityForResult(enableBtIntent, 0);
- return;
- }
-
- if (mScanning) {
- btAdapt.stopLeScan(getmLeScanCallback);
- }
- listDevices.clear();
- listDeviceName.clear();
- mScanning = true;
- btAdapt.startLeScan(getmLeScanCallback); //开始搜索
- //定时器操作
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- mScanning = false;
- btAdapt.stopLeScan(getmLeScanCallback);
- //其中BuildBean,TieAdapter是在build.gradle中dependencies {compile 'com.dou361.dialogui:jjdxm-dialogui:1.0.3'};
- tieAdapter = new TieAdapter(mContext, listDeviceName, true);
- BuildBean buildBean = DialogUIUtils.showMdBottomSheet(mActivity, true, "", listDeviceName, 0, new DialogUIItemListener() {
- @Override
- public void onItemClick(CharSequence text, int position) {
- mBluetoothDevice = btAdapt.getRemoteDevice(listDevices.get(position).getAddress());
- if (mBluetoothDevice == null) {
- return;
- }
- mBluetoothGatt = mBluetoothDevice.connectGatt(mActivity, false, mGattCallback);
- }
- });
- if (listDevices.size() > 0) {
- buildBean.mAdapter = tieAdapter;
- buildBean.show();
- } else {
- Toast.makeText(MainActivity.this,"未搜索到蓝牙设备",Toast.LENGTH_SHORT).show();
- }
- }
- }, 2000); //延时2s执行
- } else if (msg.what == 3) {
- tv_seacher_ble.setText("断开蓝牙");
- bIsConnected = true;
- Toast.makeText(MainActivity.this,"蓝牙连接成功",Toast.LENGTH_SHORT).show();
- } else if (msg.what == 4) {
- tv_seacher_ble.setText("连接蓝牙");
- bIsConnected = false;
- mBluetoothGatt.close();
- mBluetoothGatt = null;
- }
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏
- setContentView(R.layout.activity_main);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//锁屏
- tv_seacher_ble = (TextView) findViewById(R.id.tv_main_id);
- final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
- btAdapt = bluetoothManager.getAdapter();
- // btAdapt = BluetoothAdapter.getDefaultAdapter();// 初始化本机蓝牙功能,除了搜索方法欢了,获取蓝牙适配器的方法也换了
- //添加了震动
- vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
- tv_seacher_ble.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final AlertDialog.Builder myDialog = new AlertDialog.Builder(MainActivity.this);
- //nomalDialog.setIcon(R.drawable.icon_dialog);
- myDialog.setTitle("提示");
- myDialog.setMessage("是否断开蓝牙设备?");
- myDialog.setPositiveButton("是", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
- Message message = new Message();
- message.what = 1;
- handler.sendMessage(message);
- }
- });
- myDialog.setNegativeButton("否", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int i) {
-
- }
- });
- myDialog.show();
-
- } else {
- vibrator.vibrate(200);//震动指定时间
- //蓝牙搜索
- Message message = new Message();
- message.what = 2;
- handler.sendMessage(message);
- }
- }
- });
-
-
- BluetoothAdapter.LeScanCallback getmLeScanCallback = new BluetoothAdapter.LeScanCallback() {
- @Override
- public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- boolean isSame = true;
- if (bluetoothDevice != null && bluetoothDevice.getName() != null) {
- LogUtil.e("蓝牙设备==" + bluetoothDevice.getName() + "|" + bluetoothDevice.getAddress());
- strDevice = bluetoothDevice.getName() + "|" + bluetoothDevice.getAddress();
- //去重
- for (BluetoothDevice bd : listDevices) {
- if (bd.getAddress().equalsIgnoreCase(bluetoothDevice.getAddress())) {
- isSame = false;
- }
- }
- if (isSame) {
- listDevices.add(bluetoothDevice);
- listDeviceName.add(new TieBean(strDevice));
- // tieAdapter.notifyDataSetChanged();
- }
-
- }
- }
- });
- }
- };
- private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
- @Override
- public void onConnectionStateChange(BluetoothGatt gatt, final int status, final int newState) {
- LogUtil.e("StateChange,status=" + status + ",newState==" + newState + ",Services=" + mBluetoothGatt.discoverServices());
- if (status == BluetoothGatt.GATT_SUCCESS) {
- if (newState == BluetoothProfile.STATE_CONNECTED) {//2
- LogUtil.e("去连接GATT server");
- } else if (newState == BluetoothProfile.STATE_CONNECTING) {
- LogUtil.e("连接中");
- } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
- LogUtil.e("已断开断开蓝牙Disconnected");
- Message message = new Message();
- message.what = 4;
- handler.sendMessage(message);
- } else if (newState == BluetoothProfile.STATE_DISCONNECTING) {
- LogUtil.e("断开中");
- }
- } else if (status == 133) {
- //防止出现133,搜索到列表连接不上
- LogUtil.e("出现133");
- Message message = new Message();
- message.what = 5;
- handler.sendMessage(message);
- } else if (status == 8) {
- //自动断开
- LogUtil.e("自动断开了");
- Message message = new Message();
- message.what = 6;
- handler.sendMessage(message);
- } else if (status == 40) {
- //距离太远
- Message message = new Message();
- message.what = 7;
- handler.sendMessage(message);
- }else {
- //其他连接不到设备的情况
- }Message message = new Message();
- message.what = 8;
- handler.sendMessage(message);
- }
-
- @Override
- public void onServicesDiscovered(BluetoothGatt gatt, int status) {
- LogUtil.e("ServicesDiscovered状态status==" + status + ",Services==" + gatt.getServices());
- if (status == BluetoothGatt.GATT_SUCCESS) {
- Message message = new Message();
- message.what = 3;
- handler.sendMessage(message);
- //激活要开启的服务
- displayGattServices(gatt.getServices());
- LogUtil.e("Discovered获取GATT_SUCCESS");
- } else {
- LogUtil.e("onServicesDiscovered received: " + status);
- bIsConnected = false;
- }
- }
-
- @Override
- public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
- }
-
- @Override
- public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- }
-
- @Override
- public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
- }
- };
-
- //打开服务
- private void displayGattServices(List<BluetoothGattService> gattServices) {
- if (gattServices == null)
- return;
- String uuid = null;
- for (BluetoothGattService gattService : gattServices) {
- uuid = gattService.getUuid().toString();
- List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
-
- for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
- uuid = gattCharacteristic.getUuid().toString();
- if (uuid.equals(SPP_UUID)) {
- final BluetoothGattCharacteristic characteristic = gattCharacteristic;
- final int charaProp = characteristic.getProperties();
//这里根据charaProp 去做读、写、通知,真正的连接成功是在这里做判断的
- // Message message = new Message();
- //message.what = 3;
- // handler.sendMessage(message)
- }
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mScanning) {
btAdapt.stopLeScan(getmLeScanCallback);
}
if (NotNull.isNotNull(mBluetoothGatt)) {
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
}
android.os.Process.killProcess(android.os.Process.myPid());
}
}
- BluetoothLeScanner scanner = btAdapt.getBluetoothLeScanner();
- scanner.startScan(scanCallback);
喜出过望,难道是用的方法过时了,所以需要定位权限,上代码:
- ScanCallback scanCallback = new ScanCallback() {
- @Override
- public void onScanResult(int callbackType, ScanResult result) {
- super.onScanResult(callbackType, result);
- final BluetoothDevice bluetoothDevice = result.getDevice();
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- boolean isSame = true;
- if (bluetoothDevice != null && bluetoothDevice.getName() != null) {
- LogUtil.e("蓝牙设备==" + bluetoothDevice.getName() + bluetoothDevice.getAddress());
- strDevice =bluetoothDevice.getName() + "|" + bluetoothDevice.getAddress();
- for (BluetoothDevice bd : listDevices) {
- if (bd.getAddress().equalsIgnoreCase(bluetoothDevice.getAddress())) {
- isSame = false;
- }
- }
- if (isSame) {
- listDevices.add(bluetoothDevice);
- listDeviceName.add(new TieBean(strDevice));
- if (bleDeviceAdapter != null) {
- bleDeviceAdapter.notifyDataSetChanged();
- }
- }
-
-
- }
- }
- });
- }
-
- @Override
- public void onBatchScanResults(final List<ScanResult> results) {
- super.onBatchScanResults(results);
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- LogUtil.d("扫描onBatchScanResults==" + results.size());
- }
- });
-
- }
-
- @Override
- public void onScanFailed(int errorCode) {
- super.onScanFailed(errorCode);
- LogUtil.e("扫描失败onScanFailed, errorCode==" + errorCode);
- }
- };
停止扫描的方法是:
scanner.stopScan(scanCallback);
然而,虽然使用了新方法,速度也是一样快,但是还是需要定位权限,魅族6和华为畅享7还得打开GPS,看来这个也不是正解,当然项目中的扫描外围蓝牙设备的方法也都换成了scanner.startScan(scanCallback);
- defaultConfig {
- applicationId "com.demo.ble"
- minSdkVersion 18
- targetSdkVersion 25
- versionCode 1
- versionName "1.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- }
中的 targetSdkVersion 25改成 targetSdkVersion 22,就不需要定位权限也可以搜索道蓝牙设备了,看到网上很少有人这样说的,搜了那么多资料,就一篇这样说的,带着半信半疑将targetSdkVersion改成 22, 编译,也没报任何错,运行,还真是又出奇迹,测试了手上的所有手机,都不需要定位,不要GPS就可以搜索到蓝牙设备。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。