0 快速索引表
- 权限汇总
https://developer.android.google.cn/reference/android/Manifest.permission
/frameworks/base/core/res/AndroidManifest.xml
android.permission.BLUETOOTH
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH_CONNECT
android.permission.BLUETOOTH_ADVERTISE
android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH_PRIVILEGED
android.permission.BLUETOOTH_MAP
android.permission.BLUETOOTH_STACK
android.permission.LOCAL_MAC_ADDRESS
- 接口汇总
https://developer.android.google.cn/reference/android/bluetooth/BluetoothManager
https://developer.android.google.cn/reference/android/bluetooth/BluetoothAdapter
https://developer.android.google.cn/reference/android/bluetooth/BluetoothSocket
/packages/modules/Bluetooth/framework/java/android/bluetooth/
/frameworks/base/core/java/android/bluetooth/
android.bluetooth.BluetoothManager.getAdapter
android.bluetooth.BluetoothAdapter.getDefaultAdapter
android.bluetooth.BluetoothAdapter.disable
android.bluetooth.BluetoothAdapter.enableandroid.bluetooth.BluetoothAdapter.getAddress
android.bluetooth.BluetoothAdapter.isEnabled
android.bluetooth.BluetoothSocket.connect
android.bluetooth.BluetoothSocket.close
- adb shell svc ~
打开蓝牙
- adb shell svc bluetooth enable
关闭蓝牙
- adb shell svc bluetooth disable
- adb shell service call ~
打开蓝牙
- adb shell service call bluetooth_manager 6
关闭蓝牙
- adb shell service call bluetooth_manager 8 i32 1
- adb shell settings
查询状态
- adb shell settings get global bluetooth_on 0关1开
修改状态
- adb shell settings put global bluetooth_on 0/1
- adb shell dumpsys ~
adb shell dumpsys bluetooth_manager
- AppOps汇总
adb shell dumpsys appops --op 77
adb shell dumpsys appops --op 111
adb shell dumpsys appops --op 114
1 需求
- 打开蓝牙的ADB命令
- adb shell svc bluetooth enable
- 关闭蓝牙的ADB命令
- adb shell svc bluetooth disable
- AppOps
- adb shell dumpsys appops --op 77
- adb shell dumpsys appops --op 111
- adb shell dumpsys appops --op 114
2 权限
android.permission.BLUETOOTH
- Added in API level 1
- Protection level: normal
2207 <!-- Allows applications to connect to paired bluetooth devices.
2208 <p>Protection level: normal
2209 -->
2210 <permission android:name="android.permission.BLUETOOTH"
2211 android:description="@string/permdesc_bluetooth"
2212 android:label="@string/permlab_bluetooth"
2213 android:protectionLevel="normal" />
android.permission.BLUETOOTH_SCAN
- Added in API level 31
- Protection level: dangerous
2215 <!-- Required to be able to discover and pair nearby Bluetooth devices.
2216 <p>Protection level: dangerous -->
2217 <permission android:name="android.permission.BLUETOOTH_SCAN"
2218 android:permissionGroup="android.permission-group.UNDEFINED"
2219 android:description="@string/permdesc_bluetooth_scan"
2220 android:label="@string/permlab_bluetooth_scan"
2221 android:protectionLevel="dangerous" />
android.permission.BLUETOOTH_CONNECT
- Added in API level 31
- Protection level: dangerous
2223 <!-- Required to be able to connect to paired Bluetooth devices.
2224 <p>Protection level: dangerous -->
2225 <permission android:name="android.permission.BLUETOOTH_CONNECT"
2226 android:permissionGroup="android.permission-group.UNDEFINED"
2227 android:description="@string/permdesc_bluetooth_connect"
2228 android:label="@string/permlab_bluetooth_connect"
2229 android:protectionLevel="dangerous" />
android.permission.BLUETOOTH_ADVERTISE
- Added in API level 31
- Protection level: dangerous
2231 <!-- Required to be able to advertise to nearby Bluetooth devices.
2232 <p>Protection level: dangerous -->
2233 <permission android:name="android.permission.BLUETOOTH_ADVERTISE"
2234 android:permissionGroup="android.permission-group.UNDEFINED"
2235 android:description="@string/permdesc_bluetooth_advertise"
2236 android:label="@string/permlab_bluetooth_advertise"
2237 android:protectionLevel="dangerous" />
android.permission.BLUETOOTH_ADMIN
- Added in API level 1
- Protection level: normal
2262 <!-- Allows applications to discover and pair bluetooth devices.
2263 <p>Protection level: normal
2264 -->
2265 <permission android:name="android.permission.BLUETOOTH_ADMIN"
2266 android:description="@string/permdesc_bluetoothAdmin"
2267 android:label="@string/permlab_bluetoothAdmin"
2268 android:protectionLevel="normal" />
android.permission.BLUETOOTH_PRIVILEGED
- Added in API level 19
- Not for use by third-party applications
2270 <!-- Allows applications to pair bluetooth devices without user interaction, and to
2271 allow or disallow phonebook access or message access.
2272 <p>Not for use by third-party applications. -->
2273 <permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
2274 android:protectionLevel="signature|privileged" />
android.permission.BLUETOOTH_MAP
2276 <!-- @SystemApi Control access to email providers exclusively for Bluetooth
2277 @hide
2278 -->
2279 <permission android:name="android.permission.BLUETOOTH_MAP"
2280 android:protectionLevel="signature|role" />
android.permission.BLUETOOTH_STACK
2282 <!-- Allows bluetooth stack to access files
2283 @hide This should only be used by Bluetooth apk.
2284 -->
2285 <permission android:name="android.permission.BLUETOOTH_STACK"
2286 android:protectionLevel="signature|role" />
android.permission.LOCAL_MAC_ADDRESS
5844 <!-- @SystemApi Allows applications to read the local WiFi and Bluetooth MAC address.
5845 @hide -->
5846 <permission android:name="android.permission.LOCAL_MAC_ADDRESS"
5847 android:protectionLevel="signature|privileged" />
5848 <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"/>
3 接口
android.bluetooth.BluetoothManager.getAdapter
- Added in API level 18
77 /**
78 * Get the BLUETOOTH Adapter for this device.
79 *
80 * @return the BLUETOOTH Adapter
81 */
82 @RequiresNoPermission
83 public BluetoothAdapter getAdapter() {
84 return mAdapter;
85 }
android.bluetooth.BluetoothAdapter.getDefaultAdapter
- Added in API level 5
- Deprecated in API level 31
947 /**
948 * Get a handle to the default local Bluetooth adapter.
949 * <p>
950 * Currently Android only supports one Bluetooth adapter, but the API could
951 * be extended to support more. This will always return the default adapter.
952 * </p>
953 *
954 * @return the default local adapter, or null if Bluetooth is not supported
955 * on this hardware platform
956 * @deprecated this method will continue to work, but developers are
957 * strongly encouraged to migrate to using
958 * {@link BluetoothManager#getAdapter()}, since that approach
959 * enables support for {@link Context#createAttributionContext}.
960 */
961 @Deprecated
962 @RequiresNoPermission
963 public static synchronized BluetoothAdapter getDefaultAdapter() {
964 if (sAdapter == null) {
965 sAdapter = createAdapter(AttributionSource.myAttributionSource());
966 }
967 return sAdapter;
968 }
android.bluetooth.BluetoothAdapter.disable
- Added in API level 5
- Deprecated in API level 33
- 权限
1451 /**
1452 * Turn off the local Bluetooth adapter—do not use without explicit
1453 * user action to turn off Bluetooth.
1454 * <p>This gracefully shuts down all Bluetooth connections, stops Bluetooth
1455 * system services, and powers down the underlying Bluetooth hardware.
1456 * <p class="caution"><strong>Bluetooth should never be disabled without
1457 * direct user consent</strong>. The {@link #disable()} method is
1458 * provided only for applications that include a user interface for changing
1459 * system settings, such as a "power manager" app.</p>
1460 * <p>This is an asynchronous call: it will return immediately, and
1461 * clients should listen for {@link #ACTION_STATE_CHANGED}
1462 * to be notified of subsequent adapter state changes. If this call returns
1463 * true, then the adapter state will immediately transition from {@link
1464 * #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time
1465 * later transition to either {@link #STATE_OFF} or {@link
1466 * #STATE_ON}. If this call returns false then there was an
1467 * immediate problem that will prevent the adapter from being turned off -
1468 * such as the adapter already being turned off.
1469 *
1470 * @return true to indicate adapter shutdown has begun, or false on immediate error
1471 *
1472 * @deprecated Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, applications
1473 * are not allowed to enable/disable Bluetooth.
1474 * <b>Compatibility Note:</b> For applications targeting
1475 * {@link android.os.Build.VERSION_CODES#TIRAMISU} or above, this API will always fail and return
1476 * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#S}
1477 * or below), they can continue to use this API.
1478 * <p>
1479 * Deprecation Exemptions:
1480 * <ul>
1481 * <li>Device Owner (DO), Profile Owner (PO) and system apps.
1482 * </ul>
1483 */
1484 @Deprecated
1485 @RequiresLegacyBluetoothAdminPermission
1486 @RequiresBluetoothConnectPermission
1487 @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
1488 public boolean disable() {
1489 try {
1490 return mManagerService.disable(mAttributionSource, true);
1491 } catch (RemoteException e) {
1492 Log.e(TAG, "", e);
1493 }
1494 return false;
1495 }
android.bluetooth.BluetoothAdapter.enable
- Added in API level 5
- Deprecated in API level 33
- 权限
- android.permission.BLUETOOTH_ADMIN
- android.permission.BLUETOOTH_CONNECT
1396 /**
1397 * Turn on the local Bluetooth adapter—do not use without explicit
1398 * user action to turn on Bluetooth.
1399 * <p>This powers on the underlying Bluetooth hardware, and starts all
1400 * Bluetooth system services.
1401 * <p class="caution"><strong>Bluetooth should never be enabled without
1402 * direct user consent</strong>. If you want to turn on Bluetooth in order
1403 * to create a wireless connection, you should use the {@link
1404 * #ACTION_REQUEST_ENABLE} Intent, which will raise a dialog that requests
1405 * user permission to turn on Bluetooth. The {@link #enable()} method is
1406 * provided only for applications that include a user interface for changing
1407 * system settings, such as a "power manager" app.</p>
1408 * <p>This is an asynchronous call: it will return immediately, and
1409 * clients should listen for {@link #ACTION_STATE_CHANGED}
1410 * to be notified of subsequent adapter state changes. If this call returns
1411 * true, then the adapter state will immediately transition from {@link
1412 * #STATE_OFF} to {@link #STATE_TURNING_ON}, and some time
1413 * later transition to either {@link #STATE_OFF} or {@link
1414 * #STATE_ON}. If this call returns false then there was an
1415 * immediate problem that will prevent the adapter from being turned on -
1416 * such as Airplane mode, or the adapter is already turned on.
1417 *
1418 * @return true to indicate adapter startup has begun, or false on immediate error
1419 *
1420 * @deprecated Starting with {@link android.os.Build.VERSION_CODES#TIRAMISU}, applications
1421 * are not allowed to enable/disable Bluetooth.
1422 * <b>Compatibility Note:</b> For applications targeting
1423 * {@link android.os.Build.VERSION_CODES#TIRAMISU} or above, this API will always fail and return
1424 * {@code false}. If apps are targeting an older SDK ({@link android.os.Build.VERSION_CODES#S}
1425 * or below), they can continue to use this API.
1426 * <p>
1427 * Deprecation Exemptions:
1428 * <ul>
1429 * <li>Device Owner (DO), Profile Owner (PO) and system apps.
1430 * </ul>
1431 */
1432 @Deprecated
1433 @RequiresLegacyBluetoothAdminPermission
1434 @RequiresBluetoothConnectPermission
1435 @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
1436 public boolean enable() {
1437 if (isEnabled()) {
1438 if (DBG) {
1439 Log.d(TAG, "enable(): BT already enabled!");
1440 }
1441 return true;
1442 }
1443 try {
1444 return mManagerService.enable(mAttributionSource);
1445 } catch (RemoteException e) {
1446 Log.e(TAG, "", e);
1447 }
1448 return false;
1449 }
android.bluetooth.BluetoothAdapter.getAddress
- Added in API level 5
1521 /**
1522 * Returns the hardware address of the local Bluetooth adapter.
1523 * <p>For example, "00:11:22:AA:BB:CC".
1524 *
1525 * @return Bluetooth hardware address as string
1526 *
1527 * Requires {@code android.Manifest.permission#LOCAL_MAC_ADDRESS} and
1528 * {@link android.Manifest.permission#BLUETOOTH_CONNECT}.
1529 */
1530 @RequiresLegacyBluetoothPermission
1531 @RequiresBluetoothConnectPermission
1532 public String getAddress() {
1533 try {
1534 return mManagerService.getAddress(mAttributionSource);
1535 } catch (RemoteException e) {
1536 Log.e(TAG, "", e);
1537 }
1538 return null;
1539 }
android.bluetooth.BluetoothAdapter.isEnabled
- Added in API level 5
1133 /**
1134 * Return true if Bluetooth is currently enabled and ready for use.
1135 * <p>Equivalent to:
1136 * <code>getBluetoothState() == STATE_ON</code>
1137 *
1138 * @return true if the local adapter is turned on
1139 */
1140 @RequiresLegacyBluetoothPermission
1141 @RequiresNoPermission
1142 public boolean isEnabled() {
1143 return getState() == BluetoothAdapter.STATE_ON;
1144 }
参考资料:
https://developer.android.google.cn/reference/android/bluetooth/BluetoothAdapter
/packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothAdapter.java
/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java
android.bluetooth.BluetoothSocket.connect
- Added in API level 5
402 /**
403 * Attempt to connect to a remote device.
404 * <p>This method will block until a connection is made or the connection
405 * fails. If this method returns without an exception then this socket
406 * is now connected.
407 * <p>Creating new connections to
408 * remote Bluetooth devices should not be attempted while device discovery
409 * is in progress. Device discovery is a heavyweight procedure on the
410 * Bluetooth adapter and will significantly slow a device connection.
411 * Use {@link BluetoothAdapter#cancelDiscovery()} to cancel an ongoing
412 * discovery. Discovery is not managed by the Activity,
413 * but is run as a system service, so an application should always call
414 * {@link BluetoothAdapter#cancelDiscovery()} even if it
415 * did not directly request a discovery, just to be sure.
416 * <p>{@link #close} can be used to abort this call from another thread.
417 *
418 * @throws IOException on error, for example connection failure
419 */
420 @RequiresBluetoothConnectPermission
421 @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
422 public void connect() throws IOException {
423 if (mDevice == null) throw new IOException("Connect is called on null device");
424
425 try {
426 if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
427 IBluetooth bluetoothProxy =
428 BluetoothAdapter.getDefaultAdapter().getBluetoothService();
429 if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
430 IBluetoothSocketManager socketManager = bluetoothProxy.getSocketManager();
431 if (socketManager == null) throw new IOException("bt get socket manager failed");
432 mPfd = socketManager.connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags());
433 synchronized (this) {
434 if (DBG) Log.d(TAG, "connect(), SocketState: " + mSocketState + ", mPfd: " + mPfd);
435 if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
436 if (mPfd == null) throw new IOException("bt socket connect failed");
437 FileDescriptor fd = mPfd.getFileDescriptor();
438 mSocket = new LocalSocket(fd);
439 mSocketIS = mSocket.getInputStream();
440 mSocketOS = mSocket.getOutputStream();
441 }
442 int channel = readInt(mSocketIS);
443 if (channel <= 0) {
444 throw new IOException("bt socket connect failed");
445 }
446 mPort = channel;
447 waitSocketSignal(mSocketIS);
448 synchronized (this) {
449 if (mSocketState == SocketState.CLOSED) {
450 throw new IOException("bt socket closed");
451 }
452 mSocketState = SocketState.CONNECTED;
453 }
454 } catch (RemoteException e) {
455 Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
456 throw new IOException("unable to send RPC: " + e.getMessage());
457 }
458 }
android.bluetooth.BluetoothSocket.close
- Added in API level 5
636 @Override
637 public void close() throws IOException {
638 Log.d(TAG, "close() this: " + this + ", channel: " + mPort + ", mSocketIS: " + mSocketIS
639 + ", mSocketOS: " + mSocketOS + ", mSocket: " + mSocket + ", mSocketState: "
640 + mSocketState);
641 if (mSocketState == SocketState.CLOSED) {
642 return;
643 } else {
644 synchronized (this) {
645 if (mSocketState == SocketState.CLOSED) {
646 return;
647 }
648 mSocketState = SocketState.CLOSED;
649 if (mSocket != null) {
650 if (DBG) Log.d(TAG, "Closing mSocket: " + mSocket);
651 mSocket.shutdownInput();
652 mSocket.shutdownOutput();
653 mSocket.close();
654 mSocket = null;
655 }
656 if (mPfd != null) {
657 mPfd.close();
658 mPfd = null;
659 }
660 }
661 }
662 }
参考资料
https://developer.android.google.cn/reference/android/bluetooth/BluetoothSocket
/packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothSocket.java
/frameworks/base/core/java/android/bluetooth/BluetoothSocket.java
4 示例
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dsl.bluetoothdemo">
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BluetoothDemo">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/btnBtstate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="获取蓝牙状态" />
<TextView
android:id="@+id/tvBtState"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnTurnOn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开蓝牙 方法:enable"
android:textAllCaps="false" />
<Button
android:id="@+id/btnTurnOnUseIntent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="打开蓝牙 方法:intent"
android:textAllCaps="false" />
<Button
android:id="@+id/btnTurnOff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关闭蓝牙"
android:textAllCaps="false" />
<Button
android:id="@+id/btnGetAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="获取蓝牙MAC地址" />
<TextView
android:id="@+id/tvBtAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Main.java
package com.dsl.bluetoothdemo;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
/**
* 第一步,判断设备是否支持蓝牙;
* 第二步,判断设备蓝牙是否开启;
* 第三步,操作蓝牙;
*/
public class MainActivity extends AppCompatActivity {
BluetoothManager bluetoothManager;
BluetoothAdapter bluetoothAdapter;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnBtState = findViewById(R.id.btnBtstate);
TextView tvBtState = findViewById(R.id.tvBtState);
Button btnTurnOn = findViewById(R.id.btnTurnOn);
Button btnTurnOnUseIntent = findViewById(R.id.btnTurnOnUseIntent);
Button btnTurnOff = findViewById(R.id.btnTurnOff);
Button btnGetAddress = findViewById(R.id.btnGetAddress);
TextView tvBtAddress = findViewById(R.id.tvBtAddress);
/**
* 获取蓝牙适配器实例,有两种方式,推荐方式二
* 方式一:getSystemService
* 方式二:getDefaultAdapter
*/
// bluetoothManager = (BluetoothManager) getSystemService(BluetoothManager.class);
bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
// bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
btnBtState.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean state = bluetoothAdapter.isEnabled();
tvBtState.setText(state + "");
}
});
btnTurnOn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bluetoothAdapter.enable();
}
});
btnTurnOnUseIntent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
});
btnTurnOff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
bluetoothAdapter.disable();
}
});
btnGetAddress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String mac = bluetoothAdapter.getAddress();
tvBtAddress.setText(mac);
}
});
}
}
5 adb svc命令
adb shell svc bluetooth enable
adb shell svc bluetooth disable
6 adb appops命令
adb shell dumpsys appops --op 77
- APP_OP_BLUETOOTH_SCAN = 77
- Manifest.permission.BLUETOOTH_SCAN
adb shell dumpsys appops --op 111
- APP_OP_BLUETOOTH_CONNECT = 111
- Manifest.permission.BLUETOOTH_CONNECT
adb shell dumpsys appops --op 114
- APP_OP_BLUETOOTH_ADVERTISE = 114
- Manifest.permission.BLUETOOTH_ADVERTISE
参考资料:
Bluetooth permissions | Android Developers
AppOpsManager.java - OpenGrok cross reference for /frameworks/base/core/java/android/app/AppOpsManager.javaenums.proto - OpenGrok cross reference for /frameworks/proto_logging/stats/enums/app/enums.proto
7 参考资料(权限)
Manifest.permission | Android Developers
/frameworks/base/core/res/AndroidManifest.xml
参考资料(接口)
https://developer.android.google.cn/reference/android/bluetooth/BluetoothManager
https://developer.android.google.cn/reference/android/bluetooth/BluetoothAdapter
https://developer.android.google.cn/reference/android/bluetooth/BluetoothSocket
/packages/modules/Bluetooth/framework/java/android/bluetooth/
/frameworks/base/core/java/android/bluetooth/
参考资料(指南)