{"id":21335409,"url":"https://github.com/alexliusheng/easybluetoothframe","last_synced_at":"2025-08-13T01:10:58.299Z","repository":{"id":43342224,"uuid":"187773982","full_name":"AlexLiuSheng/EasyBluetoothFrame","owner":"AlexLiuSheng","description":"经典（传统）蓝牙快速开发框架，A fast develop frame of classic bluetooth","archived":false,"fork":false,"pushed_at":"2022-03-07T07:03:10.000Z","size":5370,"stargazers_count":104,"open_issues_count":7,"forks_count":19,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-12T12:44:05.293Z","etag":null,"topics":["ble","bluetooth","bluetoothframe","classic","classic-bluetooth","classicbluetooth"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexLiuSheng.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-21T06:20:57.000Z","updated_at":"2025-04-20T03:15:27.000Z","dependencies_parsed_at":"2022-09-19T13:51:28.858Z","dependency_job_id":null,"html_url":"https://github.com/AlexLiuSheng/EasyBluetoothFrame","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/AlexLiuSheng/EasyBluetoothFrame","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLiuSheng%2FEasyBluetoothFrame","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLiuSheng%2FEasyBluetoothFrame/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLiuSheng%2FEasyBluetoothFrame/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLiuSheng%2FEasyBluetoothFrame/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexLiuSheng","download_url":"https://codeload.github.com/AlexLiuSheng/EasyBluetoothFrame/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexLiuSheng%2FEasyBluetoothFrame/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270161538,"owners_count":24537664,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ble","bluetooth","bluetoothframe","classic","classic-bluetooth","classicbluetooth"],"created_at":"2024-11-21T23:45:13.181Z","updated_at":"2025-08-13T01:10:58.236Z","avatar_url":"https://github.com/AlexLiuSheng.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=center\u003e\n\u003cimg src='https://github.com/AlexLiuSheng/EasyBluetoothFrame/blob/master/ui/logo.png' width=20%/\u003e\n \u003c/p\u003e\n \u003cp align=center\u003e\n\n\u003ca href=\"https://jitpack.io/#AlexLiuSheng/EasyBluetoothFrame\"\u003e\n    \u003cimg src=\"https://jitpack.io/v/AlexLiuSheng/EasyBluetoothFrame.svg\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://android-arsenal.com/api?level=14\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://developer.android.com/index.html\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/platform-android-brightgreen.svg\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/AlexLiuSheng/EasyBluetoothFrame/blob/master/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/license-Apache%202.0-blue.svg\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n \n \n## EasyBluetoothFrame\n这是一个适用于经典蓝牙通讯的快速开发框架。\n\n\n \n \n \n### 框架适用范围\n   本框架只适用于支持蓝牙3.0协议的设备进行数据连接传输，也就是通常说的经典蓝牙，通常手机与手机之间的连接都属于经典蓝牙模式范畴，而一般连接外设耳机等设备，大多\n   属于BLE蓝牙（低功耗蓝牙），这两种蓝牙除了名字有相同之外，通信方式、原理、协议完全不一样。\n  \n### 导入\n\u003e **version=**[![](https://jitpack.io/v/AlexLiuSheng/EasyBluetoothFrame.svg)](https://jitpack.io/#AlexLiuSheng/EasyBluetoothFrame)\n```\nallprojects {\n    repositories {\n        maven { url \"https://jitpack.io\" }\n    }\n}\ndependencies {\n      implementation 'com.github.AlexLiuSheng:EasyBluetoothFrame:version'\n}\n\n```\n### 蓝牙连接流程\n---\n 经典蓝牙采用C/S模式，所以同一个设备，只能作为Client端或者Server端的其中一个，\n - 如果设备充当Server端，那么监听流程如下：\n    - 蓝牙权限获取\n    - 设置设备可被发现\n    - 设置监听UUID\n    - 注册为Server\n    - 等待配对、连接、传输数据\n    \n - 如果设备充当Client，本框架蓝牙的连接流程一般为：\n    - 蓝牙权限获取\n    - 扫描设备\n    - 配对、绑定设备\n    - 建立连接\n    - 传输数据\n   \n\n### 蓝牙权限获取\n 可以使用库`BluetoothPermissionHandler`来辅助获取蓝牙权限或者开发者自己动态获取权限，`BluetoothPermissionHandler`用法如下：\n  ```\n private val permissionCallBack=BluetoothPermissionHandler(this,this)\n    override fun onCreate(savedInstanceState: Bundle?) {\n       permissionCallBack.start();\n    }\n    override fun permissionFailed() {\n    }\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        permissionCallBack.onActivityResult(requestCode, resultCode, data)\n    }\n  override  fun onRequestPermissionsResult(requestCode: Int, permissions: Array\u003cString\u003e, grantResults: IntArray) {\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults)\n        permissionCallBack.onRequestPermissionsResult(requestCode, permissions, grantResults)\n    }\n    override fun onBlueToothEnabled() {\n\n\n    }\n```\n\n### 初始化以及相关方法\n---\n   -  初始化操作可以放到任何地方\n     `BleManager.getInstance().init(application)`\n   -  使用前台service传输数据\n      `BleManager.getInstance().setForegroundService(true)`\n   - 如果使用ForegroundService模式，可自定义通知栏\n    `BleManager.getInstance().setNotification(notification)`\n   - 获取所有配对过的设备\n     `BleManager.getInstance().getPairedDevices()`\n   \n## 连接\n不管是服务端还是客户端都需要获取蓝牙权限，并且进行初始化BleManager。如果使用`BluetoothPermissionHandler`，应该在`onBlueToothEnabled`回调中做\n扫描连接等操作。\n\n### 设置为Server端\n---\n#### 设置UUID\n默认使用`00001101-0000-1000-8000-00805F9B34FB`，当然可以自定义\n```\nBleManager.getInstance().setConnectionUUID()\n```\n#### 设置设备可被扫描发现\n传入参数为可被发现的时间，单位秒\n```\n  BleManager.getInstance().enableDiscoverable(300)\n```\n#### 注册为Server\n注册为Server端之后，当有设备连接成功后，会回调`connectSuccess`方法，我们可以保存回调回来的\n`Connect`为全局，方便读写操作\n```\n  BleManager.getInstance().registerServerConnection(object: ConnectResultlistner {\n                override fun connectSuccess(connect: Connect?) {\n                    this@MainActivity.connect=connect\n                    read()\n                }\n\n                override fun connectFailed(e: Exception?) {\n\n                }\n\n            })\n  ```\n### 设置为Client端\n---\n#### 扫描设备\n\n配置扫描时间，然后扫描，在扫描回调中，通常操作是将回调的蓝牙设备添加到列表并显示，需要注意的是，回调的蓝牙设备可能会**重复**，因此需要手动去重\n```\n//配置扫描时间\n val config=ScanConfig(5000)\n BleManager.getInstance().scan(config,object :ScanResultListener{\n                override fun onDeviceFound(device: BluetoothDevice?) {\n                  \n                }\n\n                override fun onFinish() {\n                }\n\n                override fun onError() {\n                }\n            })\n```\n   \n#### 设置UUID\n默认使用`00001101-0000-1000-8000-00805F9B34FB`，当然可以自定义\n```\nBleManager.getInstance().setConnectionUUID()\n```\n\n#### 配对(如果已经配对，跳过此步)\n如果没有配对，需要先进行设备配对，如果已经配对，那么可以直接进行连接操作\n判断是否已经配对，可以用`BleManager.getInstance().getPairedDevices()`返回的集合进行判断\n配对代码如下：\n```\n    BleManager.getInstance().pin(data[p1],object:PinResultListener{\n                    override fun paired(device: BluetoothDevice?) {\n                        connect(context,data[p1])\n                    }\n\n                    override fun startPair(device: BluetoothDevice?) {\n                        super.startPair(device)\n                    }\n\n                    override fun pairing(device: BluetoothDevice?) {\n                        super.pairing(device)\n                    }\n\n                    override fun pairFailed(device: BluetoothDevice?) {\n                        super.pairFailed(device)\n                    }\n                })\n```\n\n#### 连接Server\n当有设备连接成功后，会回调`connectSuccess`方法，我们可以保存回调回来的\n`Connect`为全局，方便读写操作\n```\nBleManager.getInstance().connect(d, object : ConnectResultlistner {\n        override fun connectSuccess(connect: Connect?) {\n        }\n\n        override fun connectFailed(e: Exception?) {\n        }\n    })\n```\n\n\n### 传输数据\n#### **NewFeature自定义一个完整数据包包头、包尾**\n```\n   connect?.setReadPacketVerifyListener(object : PacketDefineListener {\n            override fun getPacketStart(): ByteArray {\n                return start\n\n            }\n\n            override fun getPacketEnd(): ByteArray {\n                return end\n\n            }\n        })\n```\n#### 读\n```\n  connect?.read(object: TransferProgressListener {\n            override fun transferSuccess(bytes: ByteArray?) {\n                bytes?.let { it1 -\u003e\n                    tvReceive.text=String(it1)\n                }\n                CLog.e(\"read string\")\n            }\n            override fun transferFailed(msg:String) {\n                t(msg)\n            }\n            override fun transfering(progress: Int) {\n                CLog.e(\"read progress:$progress\")\n            }\n        })\n```\n#### 写\n```\n connect?.write(text.toByteArray(), object : TransferProgressListener {\n            override fun transferSuccess(bytes: ByteArray?) {\n\n            }\n\n            override fun transferFailed(msg:String) {\n                t(msg)\n            }\n\n            override fun transfering(progress: Int) {\n                CLog.e(\"write progress:$progress\")\n            }\n        })\n```\n### 断开连接\n```\n BleManager.getInstance().destory()\n```\n## API Function\n所有功能接口\n```\n    void init(Context context);\n    void setConnectionUUID(String uuid);\n\n    boolean isSupported();\n\n    void setResultListener(ScanResultListener resultListener);\n\n    Set\u003cBluetoothDevice\u003e getPairedDevices();\n\n    void scan(ScanConfig scanConfig, ScanResultListener scanResultListener);\n\n    void stopSearch();\n\n    void connect(BluetoothDevice device, ConnectResultlistner connectResultlistner);\n    void destory();\n    void pin(BluetoothDevice device, PinResultListener resultListener);\n    void cancelPin(BluetoothDevice device, ResultListener resultListener);\n    void setServerConnectResultListener(ConnectResultlistner connectResultListener);\n    void registerServerConnection(ConnectResultlistner connectResultListener);\n\n    void setForegroundService(boolean foregroundService);\n    void setNotification(Notification notification);\n    void enableDiscoverable(long time);\n```\n## demo\n\u003cimg src='https://github.com/AlexLiuSheng/EasyBluetoothFrame/blob/master/ui/gif.gif' width=20%/\u003e\n\n## TODO\n  - [ ] 传输数据进度完善\n## Last\n- 详细适用请看demo，第一版可能还有些不完善,持续完善中\n- 欢迎PR或Issues\n- 如果使用过程中觉得还不错，请不要吝啬你的star,哈哈。\n## License\n---\nApache 2.0\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexliusheng%2Feasybluetoothframe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexliusheng%2Feasybluetoothframe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexliusheng%2Feasybluetoothframe/lists"}