• 打开蓝牙设置,报错信息java.lang.SecurityException: Permission Denial: starting Intent { act=android.settings.BLUETOOTH_SETTINGS flg=0x10000000 cmp=com.android.settings/.Settings$...

    判断蓝牙是否开启

    public static boolean isBluetoothEnable() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        return bluetoothAdapter.isEnabled();
    }

    AndroidManifest文件中添加权限:

    <uses-permission android:name="android.permission.BLUETOOTH" />

    打开蓝牙设置

    private int openSetting(String setting){
        Intent intent = new Intent();
        intent.setAction(Settings.ACTION_BLUETOOTH_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try{
            startActivity(intent);
        } catch(ActivityNotFoundException ex){
            ex.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    此时发现并不能打开蓝牙设置界面,报错如下:

    java.lang.SecurityException: Permission Denial: starting Intent { act=android.settings.BLUETOOTH_SETTINGS flg=0x10000000 cmp=com.android.settings/.Settings$BluetoothSettingsActivity } from ProcessRecord{4444b4b0 31323:org.zywx.wbpalmstar.widgetone.uexdevice/u0a1149} (pid=31323, uid=11149) requires android.permission.BLUETOOTH_ADMIN
           at android.os.Parcel.readException(Parcel.java:1472)
           at android.os.Parcel.readException(Parcel.java:1426)
           at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2317)
           at android.app.Instrumentation.execStartActivity(Instrumentation.java:1437)
           at android.app.Activity.startActivityForResult(Activity.java:3479)
           at android.app.Activity.startActivityForResult(Activity.java:3440)

    由log可知,权限被拒绝,但是没说是缺少什么权限,Google之后发现是缺少如下权限:

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    将其添加进AndroidManifest文件中即可。

    展开全文
  • Android 蓝牙开启关闭

    2020-04-21 11:28:45
    Android 蓝牙开启关闭 允许蓝牙权限 在AndroidManifest.xml中加入: //所有手机需要的权限,蓝牙功能才能正常使用 <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-...

    Android 蓝牙开启关闭

    1. 允许蓝牙权限

    在AndroidManifest.xml中加入:

    //所有手机需要的权限,蓝牙功能才能正常使用

    <uses-permission android:name="android.permission.BLUETOOTH" />

     

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

     

    //部分手机需要将下面两个权限添加进去,蓝牙功能才能正常使用

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

     

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

     

     

    1. 获取本地蓝牙适配器

    蓝牙适配器是我们操作蓝牙的主要对象,获取蓝牙适配器的方法有俩种:

     

    1)直接获取

    BluetoothAdapter bluetothAdapter=BluetoothAdapter.getDefaultAdapter;

     

    2)调用系统来获取

    BluetoothAdapter  bluetoothAdapter=(BluetoothAdapter)getSystemService(Context.BLUETOOTH_SERVICE);

     

    1. 打开蓝牙
    1. 第一种方式会需要用户授权:

    系统API(BluetoothAdapter.ACTION_REQUEST_ENABLE)去打开蓝牙,该方式会弹出一个对话框样式的Activity供用户选择是否开蓝牙;

     

    注意:如果蓝牙已经开启,不会弹出该Activity界面

     

    1. 直接调用函数enable()去打开蓝牙设备;
    2. 开启蓝牙搜,需要设置蓝牙为可发现状态,让其他设备能够搜索到,最多只能设置300秒;

       putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

     

    1. 关闭蓝牙

    直接调用API函数disable()即可:

       功能:关闭蓝牙

       返回值:改函数会立即返回

                True:表示关闭操作成功

                Flash:表示蓝牙关闭操作失败(当前蓝牙已经关闭或者有其他一些异常状态)

     

    展开全文
  • 摘要:Android打开和关闭 Bluetooth 的代码虽然并不困难,但是我们还是需要注意一些细节和异常情况,这样我们才能更好的优化我们的与 Bluetooth 相关的应用。 Runtime Environment OS:

    转载:http://www.ifeegoo.com/android-turn-on-and-turn-off-bluetooth.html

    摘要:Android 中打开和关闭 Bluetooth 的代码虽然并不困难,但是我们还是需要注意一些细节和异常情况,这样我们才能更好的优化我们的与 Bluetooth 相关的应用。

    Runtime Environment
    OS: Windows 8.1
    IDE: ADT Bundle v22.6.2
    Device:
    Nexus 5 / Android 4.4.4
    MI 2SC / MIUI-4.7.11 (Android 4.1.1 JRO03L)
    Android 中打开和关闭 Bluetooth 的代码虽然并不困难,但是我们还是需要注意一些细节和异常情况,这样我们才能更好的优化我们的与 Bluetooth 相关的应用。

    在研究打开和关闭 Bluetooth 之前,我们应该了解 Android 版本和 Bluetooth 版本之间的关系,请参考本博客文章《Android 版本与 Bluetooth 版本之间的关系》

    Android 在 Android 2.0 Eclair / API Level 5 中就已经有开放的操作 Bluetooth 的 API 了,在此版本已经有以下公开类:

    1 /**
    2 * 本地 Bluetooth 适配器,执行基本的 Bluetooth 任务,例如:初始设备扫描、查询已经绑定
    3 * (或已经配对)的设备、通过已知的 MAC 地址来实例化 BluetoothDevice 对象、创建
    4 * BluetoothServerSocket 来监听其它设备的连接请求等。
    5 */
    6 BluetoothAdapter.java
    7  
    8 /**
    9  * 描述设备的一般特性和能力。例如,它会指定一般设备类型,例如:手机、电脑、耳机等,还
    10  * 有是否支持音频或电话等服务。但是不能可靠的描述诸如设备支持哪些 Profile 或者 Service。
    11  */
    12 BluetoothClass.java
    13  
    14 /**
    15  * 表示一个远程的 Bluetooth 设备。它能让你与各个设备创建连接或者查询信息。
    16  * 例如:名字、地址、类和绑定状态等。
    17  */
    18 BluetoothDevice.java
    19  
    20 /**
    21  * Bluetooth socket 和 TCP socket 有些类似。最普通的 Bluetooth socket 类型是 RFCOMM,
    22  * 这是 Android API 支持的类型。RFCOMM 是一个方向性的连接。通过 Bluetooth 传输流。
    23  * 同样也称作 SPP (Serial Port Profile)。
    24  */
    25 BluetoothServerSocket.java
    26 BluetoothSocket.java
    Android 中打开 Bluetooth:有以下三种方法:
    1.强制打开
    2.调用系统弹出框提示用户打开
    3.跳转到系统设置中让用户自己打开

    1.强制打开 Bluetooth 的代码:

    1 BluetoothAdapter.getDefaultAdapter() 需要注册权限:
    2 <uses-permission android:name="android.permission.BLUETOOTH" />
    3  
    4 BluetoothAdapter.enable() 需要注册权限:
    5 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    1 /**
    2  * Bluetooth 管理类
    3  *
    4  * @author ifeegoo www.ifeegoo.com
    5  *
    6  */
    7 public class BluetoothManager
    8 {
    9  
    10     /**
    11      * 当前 Android 设备是否支持 Bluetooth
    12      *
    13      * @return true:支持 Bluetooth false:不支持 Bluetooth
    14      */
    15     public static boolean isBluetoothSupported()
    16     {
    17         return BluetoothAdapter.getDefaultAdapter() != null ? true : false;
    18     }
    19  
    20     /**
    21      * 当前 Android 设备的 bluetooth 是否已经开启
    22      *
    23      * @return true:Bluetooth 已经开启 false:Bluetooth 未开启
    24      */
    25     public static boolean isBluetoothEnabled()
    26     {
    27         BluetoothAdapter bluetoothAdapter = BluetoothAdapter
    28                 .getDefaultAdapter();
    29  
    30         if (bluetoothAdapter != null)
    31         {
    32             return bluetoothAdapter.isEnabled();
    33         }
    34  
    35         return false;
    36     }
    37  
    38     /**
    39      * 强制开启当前 Android 设备的 Bluetooth
    40      *
    41      * @return true:强制打开 Bluetooth 成功 false:强制打开 Bluetooth 失败
    42      */
    43     public static boolean turnOnBluetooth()
    44     {
    45         BluetoothAdapter bluetoothAdapter = BluetoothAdapter
    46                 .getDefaultAdapter();
    47  
    48         if (bluetoothAdapter != null)
    49         {
    50             return bluetoothAdapter.enable();
    51         }
    52  
    53         return false;
    54     }
    55 }
    以上强制打开 Bluetooth 是调用了 BluetoothAdapter.enable() 方法。首先需要获取 BluetoothAdapter 对象,如果这个对象为 null 的话,说明当前设备不支持 Bluetooth 功能。还有以下几点需要注意:
    1° 在 Nexus 5 Android 4.4.4 原生系统中,在没有任何其它管理 Bluetooth 权限的应用情况下,调用强制打开 Bluetooth 的方法,没有任何提示就直接打开 Bluetooth 了。
    2° 在小米手机 MI 2SC / MIUI-4.7.11 (Android 4.1.1 JRO03L) 上系统自带的 “安全中心” – “应用权限管理” – “开启蓝牙” 中,有三种设置:
    允许:调用强制打开 Bluetooth 代码,没有任何提示,Bluetooth 被成功打开。
    提示:会弹出提示框,提示安全警告 “ ***应用尝试开启蓝牙”,可以选择“拒绝”或“允许”,还有记住此次选择(备注:如果不记住的话,下次还会弹出同样的提示框,除非你自己去修改了应用开启蓝牙的权限)。
    拒绝:调用强制打开 Bluetooth 代码,没有任何提示,Bluetooth 强制打开失败。
    备注:各种手机自带的权限管理功能或者第三方权限管理应用略有不同。
    3° 对于 BluetoothAdapter.enable() 这个方法,API 中有以下说明 (备注:初始 API 中,如 Android 2.0 Eclair / API Level 5 中并没有这段提示)
    Bluetooth should never be enabled without direct user consent. If you want to turn on Bluetooth in order to create a wireless connection, you should use the ACTION_REQUEST_ENABLE Intent, which will raise a dialog that requests user permission to turn on Bluetooth. The enable() method is provided only for applications that include a user interface for changing system settings, such as a “power manager” app.
    没有直接的用户的允许绝不要开启 Bluetooth。如果你想要打开 Bluetooth 创建一个无线连接,你应当使用 ACTION_REQUEST_ENABLE Intent,这样会弹出一个提示框提示用户是否开启 Bluetooth,enable() 方法仅提供给有 UI 、更改系统设置的应用来使用,例如“电源管理”应用。

    从以上官方 API 提示可以看出:不建议你调用此方法来打开 Bluetooth,至少是在没有任何用户提醒的前提下!

    mi-2sc-security-center-authorization-management-application-permission-management-turn-on-bluetooth-selection

    mi-2sc-one-application-try-to-turn-on-bluetooth

    2.调用系统弹出框提示用户打开:

    1 this.startActivityForResult(requestBluetoothOn, REQUEST_CODE_BLUETOOTH_ON) 需要注册权限:
    2 <uses-permission android:name="android.permission.BLUETOOTH" />
    1 public class MainActivity extends Activity
    2 {
    3     /**
    4      * 自定义的打开 Bluetooth 的请求码,与 onActivityResult 中返回的 requestCode 匹配。
    5      */
    6     private static final int REQUEST_CODE_BLUETOOTH_ON = 1313;
    7  
    8     /**
    9      * Bluetooth 设备可见时间,单位:秒。
    10      */
    11     private static final int BLUETOOTH_DISCOVERABLE_DURATION = 250;
    12  
    13     @Override
    14     protected void onCreate(Bundle savedInstanceState)
    15     {
    16         super.onCreate(savedInstanceState);
    17         this.setContentView(R.layout.activity_main);
    18  
    19         if ((BluetoothManager.isBluetoothSupported())
    20                 && (!BluetoothManager.isBluetoothEnabled()))
    21         {
    22             this.turnOnBluetooth();
    23         }
    24     }
    25  
    26     /**
    27      * 弹出系统弹框提示用户打开 Bluetooth
    28      */
    29     private void turnOnBluetooth()
    30     {
    31         // 请求打开 Bluetooth
    32         Intent requestBluetoothOn = new Intent(
    33                 BluetoothAdapter.ACTION_REQUEST_ENABLE);
    34  
    35         // 设置 Bluetooth 设备可以被其它 Bluetooth 设备扫描到
    36         requestBluetoothOn
    37                 .setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    38  
    39         // 设置 Bluetooth 设备可见时间
    40         requestBluetoothOn.putExtra(
    41                 BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
    42                 BLUETOOTH_DISCOVERABLE_DURATION);
    43  
    44         // 请求开启 Bluetooth
    45         this.startActivityForResult(requestBluetoothOn,
    46                 REQUEST_CODE_BLUETOOTH_ON);
    47     }
    48  
    49     @Override
    50     protected void onActivityResult(int requestCode, int resultCode, Intent data)
    51     {
    52         // requestCode 与请求开启 Bluetooth 传入的 requestCode 相对应
    53         if (requestCode == REQUEST_CODE_BLUETOOTH_ON)
    54         {
    55             switch (resultCode)
    56             {
    57             // 点击确认按钮
    58                 case Activity.RESULT_OK:
    59                 {
    60                     // TODO 用户选择开启 Bluetooth,Bluetooth 会被开启
    61                 }
    62                 break;
    63  
    64                 // 点击取消按钮或点击返回键
    65                 case Activity.RESULT_CANCELED:
    66                 {
    67                     // TODO 用户拒绝打开 Bluetooth, Bluetooth 不会被开启
    68                 }
    69                 break;
    70                 default:
    71                 break;
    72             }
    73         }
    74     }
    75 }
    对于以上弹出系统弹框提示用户打开 Bluetooth 的代码,有以下几点需要注意:
    1° 这种调用系统的弹出框提示用户打开 Bluetooth 的方式,一般不会受到系统或者第三方权限管理应用的阻止。只有当你不提示用户的情况下,可以理解为“偷偷摸摸”的打开 Bluetooth ,这个是被认为侵犯用户的知情权,系统或者第三方权限管理应用可能加以阻止:直接禁止不提示用户的情况下打开 Bluetooth,或者提示用户,又或者是让用户自己选择哪些应用可以强制开启 Bluetooth。而在 Nexus 5 / Android 4.4.4 原生系统强制打开 Bluetooth 是没有任何提示,并且可以成功打开。
    2° 弹出系统的提示框提醒用户打开 Bluetooth 的主要代码:

    this.startActivityForResult(requestBluetoothOn,REQUEST_CODE_BLUETOOTH_ON);

    注意:这个方法是需要 Activity 的对象来调用的!并且需要在 Activity 中重写 onActivityResult 方法来获取用户操作弹出提示框的结果!
    3° 这种弹出的系统弹框,根据系统的不同,UI 会有所不同,下图左边是 Nexus 5 Android 4.4.4 系统手机显示效果,右边是小米手机 MI 2SC / MIUI-4.7.11 (Android 4.1.1 JRO03L) 系统显示的效果:
    nexus-5-android-4.4.4-and-mi-2sc-miui-4.7.11-android-4.1.1-jro03l-request-to-turn-on-bluetooth4° 如果你只设置了 Bluetooth 设备的可见时间,而不去调用 setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE) 方法的话,Bluetooth 依然是不可见的。你设置的 Bluetooth 的可见时间是不生效的,当前 Android 系统的 Bluetooth 不可见!
    5° 设置 Bluetooth 设备的可见时间的时候,在 Android 4.4.2 官方 API 中的说明如下:
    The current default is 120 seconds, and requests over 300 seconds will be capped. These values could change.
    当前默认值是 120s ,300s 是上限。这些值可能会变。
    目前测试出来的有以下结论:
    — 可设置的可见时间为 [1,3600] s ,也就是最小1秒钟,最大1个小时。
    — 设置的可见时间为 0 时,表示打开 Bluetooth 之后一直可见,设置小于0或者大于3600 时,系统会默认为 120s。
    6° 如果你设备的 Bluetooth 已经打开,而且你不设置设备的可见时间的话,调用以上开启 Bluetooth 的方法,是不会有任何提示的。当然,如果 Bluetooth 已经开启,也可以通过这个方法来修改 Bluetooth 的可见性。

    3.跳转到系统设置中让用户自己打开:

    1 // 跳转到系统 Bluetooth 设置
    2 this.startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
    考虑到涉及用户隐私和用户体验,推荐以下方式开启 Bluetooth :
    1° 采用强制开启 Bluetooth 的方式打开 Bluetooth ,但是调用强制开启 Bluetooth 代码之前,我们自己在应用中提示用户,我们的应用需要开启 Bluetooth ,让用户自己选择是否开启 Bluetooth 。自己在应用中提示用户我们需要开启 Bluetooth 相对于弹出系统的提示框提示用户当前应用需要开启 Bluetooth 的优势在于我们可以控制提示的内容和提示的方式以及 UI。
    2° 假若用户选择了开启 Bluetooth,但是强制开启 Bluetooth 失败,比如系统自带的权限管理禁止你的应用开启 Bluetooth ,我们不去提示用户说当前系统禁止了应用开启 Bluetooth,让用户自己去解除禁止。这样显然用户体验很差。这种情况下,我们再去调用弹出系统提示框提醒用户打开 Bluetooth 即可。这种方式一般系统或者第三方应用不会禁止。
    3° 如果弹出系统提示框提醒用户打开 Bluetooth 有问题的话,最后采用提示用户自己去系统 Bluetooth 设置中打开 Bluetooth,跳转到系统的 Bluetooth 设置界面。
    Android 中关闭 Bluetooth:有以下俩种方法:
    1.强制关闭
    2.跳转到系统设置中让用户自己关闭

    1.强制关闭:

    1 BluetoothAdapter.getDefaultAdapter() 需要注册权限:
    2 <uses-permission android:name="android.permission.BLUETOOTH" />
    3  
    4 BluetoothAdapter.disable() 需要注册权限:
    5 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    1 /**
    2  * Bluetooth 管理类
    3  *
    4  * @author ifeegoo www.ifeegoo.com
    5  *
    6  */
    7 public class BluetoothManager
    8 {
    9     /**
    10      * 当前 Android 设备是否支持 Bluetooth
    11      *
    12      * @return true:支持 Bluetooth false:不支持 Bluetooth
    13      */
    14     public static boolean isBluetoothSupported()
    15     {
    16         return BluetoothAdapter.getDefaultAdapter() != null ? true : false;
    17     }
    18  
    19