Android扫描蓝牙问题,你是不是位置权限和GPS都打开了还是扫不出东西 您所在的位置:网站首页 oppo手机定位偏差一千米了吗 Android扫描蓝牙问题,你是不是位置权限和GPS都打开了还是扫不出东西

Android扫描蓝牙问题,你是不是位置权限和GPS都打开了还是扫不出东西

2023-12-08 09:22| 来源: 网络整理| 查看: 265

目录 看看你的问题是否一样心历路程解决办法

看看你的问题是否一样

首先你检查一下,你手机是不是把GPS打开了(Android10后搜索蓝牙要打开GPS),再看一下你的app在系统设置里面的位置权限是不是已经打开。如果都打开,但按照别人的demo、博客执行的搜索蓝牙的代码,发现什么都搜不到,不过另外一台手机同样的app同样的代码,woc咋那台手机就能搜出蓝牙,这台手机就不行。 那接下来这样试一下,搜不出蓝牙的那台手机,你自己去系统设置,手动把位置权限关了,然后又手动把权限打开,再试一下看是不是就能把蓝牙搜出来了,如果是…… 恭喜你,你的问题可能和我一样。

心历路程

遇到这种问题是真坑爹,耗了我半天,无意中才发现了猫腻。下面是我遇到这问题到解决的整过程,如果大家不想看心历路程,可以直接跳到解决办法就行了。 首先自己写了个关于蓝牙功能的demo,在手机A上使用,可以搜到蓝牙没问题。那我就把demo蓝牙相关的代码移到公司要开发的项目中,一跑就糟糕,咋同样的代码公司的项目就扫不出蓝牙。 作为一个专业的程序员,肯定拿其他手机试试,拿了手机B试一下公司的项目,咦,可以搜到蓝牙啊。 于是第一反应肯定以为是机型问题,然后各种百度、谷歌,改啊改,调啊调,我就纳闷了。如果是机型的问题,为啥我一开始写的小demo在手机A上又能搜出东西。然后就无意中想到,发现到……

我的demo就一个小demo而已,我没有为它写一套动态申请权限的代码,因为公司项目已经有动态申请权限的代码,我的demo只管蓝牙行不行。所以我用demo的时候,都是先自己去系统把位置权限打开。又想到刚才公司项目装到手机B的时候,还没打开app之前,我好像就自己去系统给了它权限。这样一想,我就试一下把手机A对应app的那个位置权限关了,然后有打开,纳尼,突然就搜到蓝牙了。 然后经过多次跑代码验证,终于发现问题所在了。

首先看过官方文档的大家,都知道,我们是要申请以下这两个权限才能搜索蓝牙

Manifest.permission.ACCESS_COARSE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION

但这两个权限的打开,对于你手机上的表现,都是系统设置里面的位置权限打开了。打个比方,就像我的项目,以前它已经申请过Manifest.permission.ACCESS_COARSE_LOCATION的权限,那还要加一个权限,那我就加咯。

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { PermissionManager.instance().with(this).request(new OnPermissionCallback() { @Override public void onRequestAllow(String permissionName) { } @Override public void onRequestRefuse(String permissionName) { finish(); } @Override public void onRequestNoAsk(String permissionName) { finish(); } }, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); }

直接拿以前类似的代码搬过来,然后最后那里加个逗号和Manifest.permission.ACCESS_FINE_LOCATION,那就申请多个权限啦,就是这样写坑了自己半天。

这段话才是关键。 前面的其实看不看都没所谓,关键的就是下面这段结果,经我验证:

假如你自己去系统设置把位置权限打开,系统就会赋予你,这两个权限ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION但假如你是用代码动态申请了ACCESS_COARSE_LOCATION权限,然后发现系统设置那里位置权限的确打开了,就以为自己应用也有了ACCESS_FINE_LOCATION权限,那你就大错特错了。

由于我在项目中判断权限那里,只判断ACCESS_COARSE_LOCATION是否已经有,而项目以前动态申请过这个权限,所以上面的if判断代码就不会走进去,去申请ACCESS_FINE_LOCATION了。 一开始我觉得这样写没什么问题,因为判断ACCESS_COARSE_LOCATION就知道那个位置权限有没有打开啦,现在才知道原来差别这么大。然后我就改成下面这样:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { PermissionManager.instance().with(this).request(new OnPermissionCallback() { @Override public void onRequestAllow(String permissionName) { Log.e("test", "aaaaa"); } @Override public void onRequestRefuse(String permissionName) { finish(); } @Override public void onRequestNoAsk(String permissionName) { finish(); } }, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); }

改成上面这样,打印日志就能发现一个有趣的现象。以前每当你动态去申请一个权限的时候,手机系统会弹一个窗问要不要给app权限的嘛。 假如你手机已经动态申请过ACCESS_COARSE_LOCATION权限,然后再跑上面的代码,它判断了你没有ACCESS_FINE_LOCATION权限,所以就进入申请权限的逻辑,但这次系统就没弹窗,而是直接帮你允许了ACCESS_FINE_LOCATION这个权限,代码会直接跑进onRequestAllow方法里。

解决办法

同时检查是否有下面两个权限,并两个权限都去申请

Manifest.permission.ACCESS_COARSE_LOCATION Manifest.permission.ACCESS_FINE_LOCATION if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { PermissionManager.instance().with(this).request(new OnPermissionCallback() { @Override public void onRequestAllow(String permissionName) { Log.e("test", "aaaaa"); } @Override public void onRequestRefuse(String permissionName) { finish(); } @Override public void onRequestNoAsk(String permissionName) { finish(); } }, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有