今天写好了项目准备交给测试人员去测试,但是问题来了,我平时运行的都是自己的手机,sdk版本是5.0(21)的,但是测试组给我的手机是安卓4.4的,结果搜都搜不到Ble设备,苦逼了好久,我拿了一个demo对比,发现demo可以搜索的到,然后我就对着代码看,看完了也没发现个所以然,最后我决定自己写个demo,很简单,只要实现搜索功能就可以了,结果并没什么卵用,依然搜不到,我是知道adapter只提供了两个搜索方法的,但是鉴于在每个公司的产品都不同,最好设定uuid去搜索。于是换了个方法,然后我去掉了uuid,结果Log就打印出来了,好吧,这都不是问题,反正在android 5.0版本是可以秒杀扫出的,于是做个版本判断吧。希望能帮到此时还在烦恼的你。

 

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

    绕回来了,今天在android6.0设备上搜索蓝牙,结果又是搜索不到,百度搜了一下,重要在stackoverflow上找到了答案。   

   虽然android快要发布7.0了,可是我们好像还没用上6.0,可是如果发布了7.0,我们离用上6.0还会久吗?

   先说一下,虽然下面这个方法已经在5.0给抛弃了,但是还是可以用,因为android在5.0以后可以让手机作为BLE设备端,

   估计整合了一下方法吧,所以下面的方法被废弃了。

boolean startLeScan(BluetoothAdapter.LeScanCallback callback) Starts a scan for Bluetooth LE devices.
boolean startLeScan(UUID[] serviceUuids, BluetoothAdapter.LeScanCallback callback) Starts a scan for Bluetooth LE devices, looking for devices that advertise given services.
  我试过新方法也是可以搜索的,就是参数设置比较麻烦,有兴趣的朋友自己去试试。下面说下我是怎么解决在6.0上搜索蓝牙

  因为在android6.0对安全权限做了很大的改变,同时搜索蓝牙是需要在AndroidManifest.xml上添加

  uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION

  如果在studio上设置目标版本是6.0的话,则需要请求上面这个权限,代码如下

 // 判断蓝牙是否开启     if(mBluetoothAdapter.isEnabled()){        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {            if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {                    final AlertDialog.Builder builder = new AlertDialog.Builder(this);                    builder.setTitle("This app needs location access");                    builder.setMessage("Please grant location access so this app can detect Bluetooth.");                    builder.setPositiveButton(android.R.string.ok, null);                    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {                        @Override                        public void onDismiss(DialogInterface dialog) {                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {                                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);                            }                        }                    });                    builder.show();                }            }        }  /***     *对授权做处理,0代表授权,-1拒绝授权     */    @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, "coarse location permission granted");                    finish();                } else {                    final AlertDialog.Builder builder = new AlertDialog.Builder(this);                    builder.setTitle("Functionality limited");                    builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                  builder.setPositiveButton(android.R.string.ok, null);                  builder.setOnDismissListener(new DialogInterface.OnDismissListener() {                        @Override                        public void onDismiss(DialogInterface dialog) {                        }                    });                    builder.show();                }                return;            }        }    }

以上工作只是打开权限而已,或许你会发现设置了上面代码要求了位置权限是可以搜索蓝牙,为什么呢,因为会在Location打开GPS,这时候试试关闭GPS,而这个权限请求是完成的,你会发现根本搜索不到蓝牙,为什么呢?能所有蓝牙的关键原因是打开了GPS,soga,那知道问题就好办了,我们只要打开GPS就行了,下面是判断GPS是否打开的代码:

 // Gps是否可用    public static final boolean isGpsEnable(final Context context) {        LocationManager locationManager                = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);        if (gps || network) {            return true;        }        return false;    }

以上可以用于在点击搜索对GPS判断,打开的话直接搜索,没有打开的话就........那就打开呗。

我们可以通过startactivityforresult(activity,requestcode)这个方法来跳转到setting的Location界面,

        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);        activity.startActivityForResult(intent,requestCode);
打开GPS,然后返回就可以收到Ble设备了!

其实我并没有用上面那么的权限代码,只要设置目标版本是6.0,设为5.0,同时打开GPS,同样可以实现Ble设备在6.0上的搜索功能!

至此,已经解决了搜索蓝牙这个问题

下面贴一下我写的代码

               if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {                    if(isGpsEnable(this)){                       // gps 已开,接下来请求定位权限,已授权则开始搜索,未授权则提示权限通知                       requestLocationPermission()                    }else {                         // 通过Intent 进入GPS设置界面,这里建议用startActivityForResult()进入GPS设置界面,                         // 并在onActivityResult()方法做处理,判断gps是否打开,未打开给出提醒,打开了进入定位权限流程                        liteble.enableLocation(this,PERMISSION_REQUEST_COARSE_LOCATION);                        Toast.makeText(this,R.string.openGps,Toast.LENGTH_LONG).show();                    }                    return;                }                showListView();

在点击按钮的时候,先判断android版本,如果是6.0就判断GPS有没有打开,打开了再判断权限是否已申请,申请了直接去搜索,没有打开就跳转到打开GPS界面,6.0版本一下就直接搜索了,是不是发现很简单?


------------------------------------------------------------------------------

更新于 2017/1/22

关于权限问题,不推荐大家使用我上面的方法,在这给大家推荐一个权限的库,

谷歌自己出品的 EasyPermission ,具体用法大家可以去github一下。

然后建议会RxJava的可以试一下 Rxpermission, 不过我是没有尝试,没有太多时间,很多人都再使用。

新出的手机基本都是6.0,有的还是7.0了,国内6.0慢慢的会全部普及,所以大家写程序的时候要适配好权限,基本权限库也是必备了。

------------------------------------------------------------------------------

更新于 2018/4/27

权限库还是建议使用RxPermission,相比EasyPermission 还是具有很大的优势的,不用写那么多接口注解,而且权限请求操作本就是观察者行为,天然符合Rx这种异步库,反正我推荐使用。

然后分享一下关于搜索很慢的问题
亲测手机蓝牙模块比较差的是ovb系列,不是我黑它,除了蓝牙模块还有WiFi模块也做的很烂,相比其它品牌手机,简直不止差一个档次,比较快的是华为,三星,小米魅族也还不错,所以对于有搜索时间限制的应用来说,需要给这三个品牌的手机开个后门,留有足够的时间


更多相关文章

  1. Unity 3D 读取android 本地相册打开相机
  2. 【定制Android系统】Android(安卓)O 应用静默升级安装、安装后静
  3. Android开发入门——Android(安卓)Studio 如何导入他人项目(·刚
  4. Android(安卓)Studio - 安卓开发工具 打开后报错集合、修复指南
  5. Android在界面中重复点击导致多次跳转或打开多个相同界面的问题
  6. Android之Android(安卓)6.0权限机制及开发流程详解
  7. Android6.0(Android(安卓)M) 悬浮窗被禁用,无权限开启悬浮窗的解决
  8. Android蓝牙开发全面总结
  9. Android蓝牙开发中电话音频(HSP,HFP)和媒体音频(A2DP,AVRCP)到底是个什

随机推荐

  1. Android 检测键盘显示或隐藏键盘的实现代
  2. Android(安卓)开发遇到的问题
  3. Android的文件监控系统不可靠
  4. android屏幕触摸事件机制
  5. Android Binder 面试知识小结
  6. Android 更新UI的两种方法——handler和r
  7. android的软盘影响背景问题
  8. 如何解决android studio 运行时中文乱码
  9. Android 各 API Level 权限变更和功能限
  10. android 入门1 核心包简介@