├── .github
├── dependabot.yml
├── setup
│ └── action.yml
└── workflows
│ └── validate.yml
├── .gitignore
├── .tool-versions
├── CHANGELOG.md
├── LICENSE
├── README.md
├── apps
├── example
│ ├── .bundle
│ │ └── config
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .watchmanconfig
│ ├── Gemfile
│ ├── Gemfile.lock
│ ├── README.md
│ ├── android
│ │ ├── app
│ │ │ ├── build.gradle
│ │ │ ├── debug.keystore
│ │ │ ├── proguard-rules.pro
│ │ │ └── src
│ │ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ │ └── main
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── exampleapp
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ └── MainApplication.kt
│ │ │ │ └── res
│ │ │ │ ├── drawable
│ │ │ │ └── rn_edit_text_material.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ └── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ ├── build.gradle
│ │ ├── gradle.properties
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ ├── app.json
│ ├── babel.config.js
│ ├── index.js
│ ├── ios
│ │ ├── .xcode.env
│ │ ├── ExampleApp.xcodeproj
│ │ │ ├── project.pbxproj
│ │ │ └── xcshareddata
│ │ │ │ └── xcschemes
│ │ │ │ └── ExampleApp.xcscheme
│ │ ├── ExampleApp.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ ├── ExampleApp
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Images.xcassets
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Info.plist
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── PrivacyInfo.xcprivacy
│ │ ├── Podfile
│ │ └── Podfile.lock
│ ├── metro.config.js
│ ├── package.json
│ ├── react-native.config.js
│ ├── src
│ │ ├── App.tsx
│ │ ├── HomeScreen.tsx
│ │ ├── Permissions.tsx
│ │ └── queryClient.ts
│ └── tsconfig.json
└── expo-example-app
│ ├── .babelrc.js
│ ├── android
│ ├── .gitignore
│ ├── app
│ │ ├── build.gradle
│ │ ├── debug.keystore
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── patwoz
│ │ │ │ └── expoexampleapp
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── MainApplication.kt
│ │ │ └── res
│ │ │ ├── drawable-hdpi
│ │ │ └── splashscreen_logo.png
│ │ │ ├── drawable-mdpi
│ │ │ └── splashscreen_logo.png
│ │ │ ├── drawable-xhdpi
│ │ │ └── splashscreen_logo.png
│ │ │ ├── drawable-xxhdpi
│ │ │ └── splashscreen_logo.png
│ │ │ ├── drawable-xxxhdpi
│ │ │ └── splashscreen_logo.png
│ │ │ ├── drawable
│ │ │ ├── ic_launcher_background.xml
│ │ │ └── rn_edit_text_material.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.webp
│ │ │ ├── ic_launcher_foreground.webp
│ │ │ └── ic_launcher_round.webp
│ │ │ ├── values-night
│ │ │ └── colors.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
│ ├── app.json
│ ├── assets
│ ├── adaptive-icon.png
│ ├── favicon.png
│ ├── icon.png
│ └── splash.png
│ ├── eas.json
│ ├── index.js
│ ├── ios
│ ├── .gitignore
│ ├── .xcode.env
│ ├── ExpoExampleApp.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── ExpoExampleApp.xcscheme
│ ├── ExpoExampleApp.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── ExpoExampleApp
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.mm
│ │ ├── ExpoExampleApp-Bridging-Header.h
│ │ ├── ExpoExampleApp.entitlements
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── App-Icon-1024x1024@1x.png
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── SplashScreenBackground.colorset
│ │ │ │ └── Contents.json
│ │ │ └── SplashScreenLogo.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ ├── image.png
│ │ │ │ ├── image@2x.png
│ │ │ │ └── image@3x.png
│ │ ├── Info.plist
│ │ ├── PrivacyInfo.xcprivacy
│ │ ├── SplashScreen.storyboard
│ │ ├── Supporting
│ │ │ └── Expo.plist
│ │ ├── main.m
│ │ └── noop-file.swift
│ ├── Podfile
│ ├── Podfile.lock
│ └── Podfile.properties.json
│ ├── metro.config.js
│ ├── package.json
│ ├── src
│ └── app
│ │ └── App.tsx
│ ├── tsconfig.app.json
│ └── tsconfig.json
├── babel.config.json
├── bun.lock
├── nx.json
├── package.json
├── packages
└── react-native-bluetooth-state-manager
│ ├── .gitignore
│ ├── .watchmanconfig
│ ├── BluetoothStateManager.podspec
│ ├── README.md
│ ├── android
│ ├── CMakeLists.txt
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── kls_database.db
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── cpp
│ │ └── cpp-adapter.cpp
│ │ └── java
│ │ └── com
│ │ └── margelo
│ │ └── nitro
│ │ └── bluetoothstatemanager
│ │ ├── BluetoothStateManager.kt
│ │ └── BluetoothStateManagerPackage.java
│ ├── babel.config.js
│ ├── ios
│ └── HybridBluetoothStateManager.swift
│ ├── nitro.json
│ ├── nitrogen
│ └── generated
│ │ ├── .gitattributes
│ │ ├── android
│ │ ├── BluetoothStateManager+autolinking.cmake
│ │ ├── BluetoothStateManager+autolinking.gradle
│ │ ├── BluetoothStateManagerOnLoad.cpp
│ │ ├── BluetoothStateManagerOnLoad.hpp
│ │ ├── c++
│ │ │ ├── JBluetoothState.hpp
│ │ │ ├── JFunc_void_BluetoothState.hpp
│ │ │ ├── JHybridBluetoothStateManagerSpec.cpp
│ │ │ └── JHybridBluetoothStateManagerSpec.hpp
│ │ └── kotlin
│ │ │ └── com
│ │ │ └── margelo
│ │ │ └── nitro
│ │ │ └── bluetoothstatemanager
│ │ │ ├── BluetoothState.kt
│ │ │ ├── BluetoothStateManagerOnLoad.kt
│ │ │ ├── Func_void_BluetoothState.kt
│ │ │ └── HybridBluetoothStateManagerSpec.kt
│ │ ├── ios
│ │ ├── BluetoothStateManager+autolinking.rb
│ │ ├── BluetoothStateManager-Swift-Cxx-Bridge.cpp
│ │ ├── BluetoothStateManager-Swift-Cxx-Bridge.hpp
│ │ ├── BluetoothStateManager-Swift-Cxx-Umbrella.hpp
│ │ ├── BluetoothStateManagerAutolinking.mm
│ │ ├── BluetoothStateManagerAutolinking.swift
│ │ ├── c++
│ │ │ ├── HybridBluetoothStateManagerSpecSwift.cpp
│ │ │ └── HybridBluetoothStateManagerSpecSwift.hpp
│ │ └── swift
│ │ │ ├── BluetoothState.swift
│ │ │ ├── Func_void.swift
│ │ │ ├── Func_void_BluetoothState.swift
│ │ │ ├── Func_void_std__exception_ptr.swift
│ │ │ ├── HybridBluetoothStateManagerSpec.swift
│ │ │ └── HybridBluetoothStateManagerSpec_cxx.swift
│ │ └── shared
│ │ └── c++
│ │ ├── BluetoothState.hpp
│ │ ├── HybridBluetoothStateManagerSpec.cpp
│ │ └── HybridBluetoothStateManagerSpec.hpp
│ ├── package.json
│ ├── react-native.config.js
│ ├── src
│ ├── BluetoothStateManager.ts
│ ├── index.ts
│ ├── specs
│ │ └── BluetoothStateManager.nitro.ts
│ └── useBluetoothState.ts
│ └── tsconfig.json
├── patches
└── nx@21.1.2.patch
├── tools
└── scripts
│ └── eas-build-post-install.mjs
├── tsconfig.base.json
└── tsconfig.json
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | updates:
4 | - package-ecosystem: "github-actions"
5 | directory: "/"
6 | schedule:
7 | interval: "daily"
8 | labels:
9 | - "dependencies"
10 |
11 | - package-ecosystem: "gradle"
12 | directories:
13 | - "/package/android/"
14 | - "/example/android/"
15 | schedule:
16 | interval: "daily"
17 | labels:
18 | - "nitro-core"
19 | - "nitrogen"
20 | - "dependencies"
21 | - "kotlin"
22 |
23 | - package-ecosystem: "npm"
24 | directories:
25 | - "/package/"
26 | - "/example/"
27 | schedule:
28 | interval: "daily"
29 | labels:
30 | - "nitro-core"
31 | - "dependencies"
32 | - "typescript"
33 | - "nitrogen"
34 |
35 | groups:
36 | react-native-cli:
37 | patterns:
38 | - "@react-native-community/cli*"
39 | babel:
40 | patterns:
41 | - "@babel/*"
42 | react-native:
43 | patterns:
44 | - "@react-native/*"
45 |
--------------------------------------------------------------------------------
/.github/setup/action.yml:
--------------------------------------------------------------------------------
1 | name: setup
2 |
3 | runs:
4 | using: "composite"
5 | steps:
6 | - uses: oven-sh/setup-bun@v2
7 | with:
8 | bun-version-file: ".tool-versions"
9 |
10 | - name: 📦 Install dependencies
11 | run: bun install
12 | shell: bash
13 |
--------------------------------------------------------------------------------
/.github/workflows/validate.yml:
--------------------------------------------------------------------------------
1 | name: validate
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | permissions:
12 | actions: read
13 | contents: read
14 |
15 | jobs:
16 | eslint:
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: actions/checkout@v4
21 | with:
22 | fetch-depth: 0
23 | - uses: ./.github/setup
24 | - uses: nrwl/nx-set-shas@v4
25 |
26 | - name: 🔎 Lint
27 | run: bunx nx affected -t lint
28 |
29 | types:
30 | runs-on: ubuntu-latest
31 |
32 | steps:
33 | - uses: actions/checkout@v4
34 | with:
35 | fetch-depth: 0
36 | - uses: ./.github/setup
37 | - uses: nrwl/nx-set-shas@v4
38 |
39 | - name: 🩺 Type Checking
40 | run: bunx nx affected -t typecheck
41 |
42 | formatting:
43 | runs-on: ubuntu-latest
44 |
45 | steps:
46 | - uses: actions/checkout@v4
47 | with:
48 | fetch-depth: 0
49 | - uses: ./.github/setup
50 | - uses: nrwl/nx-set-shas@v4
51 |
52 | - name: 💅 Formatting
53 | run: bunx nx affected -t check-format
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | **/.xcode.env.local
6 |
7 | # XDE
8 | .expo/
9 |
10 | # VSCode
11 | .vscode/
12 | jsconfig.json
13 |
14 | # Xcode
15 | #
16 | build/
17 | *.pbxuser
18 | !default.pbxuser
19 | *.mode1v3
20 | !default.mode1v3
21 | *.mode2v3
22 | !default.mode2v3
23 | *.perspectivev3
24 | !default.perspectivev3
25 | xcuserdata
26 | *.xccheckout
27 | *.moved-aside
28 | DerivedData
29 | *.hmap
30 | *.ipa
31 | *.xcuserstate
32 | project.xcworkspace
33 |
34 | # Android/IJ
35 | #
36 | .classpath
37 | .cxx
38 | .gradle
39 | .idea
40 | .project
41 | .settings
42 | local.properties
43 | android.iml
44 |
45 | # Cocoapods
46 | #
47 | example/ios/Pods
48 |
49 | # Ruby
50 | example/vendor/
51 |
52 | # node.js
53 | #
54 | node_modules/
55 | npm-debug.log
56 | yarn-debug.log
57 | yarn-error.log
58 |
59 | # Bun
60 | package-lock.json
61 | **/*.bun
62 |
63 | # BUCK
64 | buck-out/
65 | \.buckd/
66 | android/app/libs
67 | android/keystores/debug.keystore
68 |
69 | # Yarn
70 | .yarn/*
71 | !.yarn/patches
72 | !.yarn/plugins
73 | !.yarn/releases
74 | !.yarn/sdks
75 | !.yarn/versions
76 |
77 | # Expo
78 | .expo/
79 |
80 | # Turborepo
81 | .turbo/
82 |
83 | # generated by bob
84 | lib/
85 |
86 | # TypeScript
87 | tsconfig.tsbuildinfo
88 |
89 |
90 | .nx/cache
91 | .nx/workspace-data
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | bun 1.2.5
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## 2.0.2 (2025-05-29)
2 |
3 | ### 🩹 Fixes
4 |
5 | - **android:** fixes Java IndexOutOfBoundsException exception ([e8326ff](https://github.com/patlux/react-native-bluetooth-state-manager/commit/e8326ff))
6 | - **ios:** lazy init of ble manager to avoid prompting bluetooth permission on app start ([dfcb901](https://github.com/patlux/react-native-bluetooth-state-manager/commit/dfcb901))
7 |
8 | ### ❤️ Thank You
9 |
10 | - Patrick Wozniak @patlux
11 |
12 | ## 2.0.1 (2025-05-19)
13 |
14 | ### 🩹 Fixes
15 |
16 | - **docs:** wrong readme at npmjs.com ([00160c1](https://github.com/patlux/react-native-bluetooth-state-manager/commit/00160c1))
17 | - **example:** organize code files ([969a72d](https://github.com/patlux/react-native-bluetooth-state-manager/commit/969a72d))
18 |
19 | ### ❤️ Thank You
20 |
21 | - Patrick Wozniak @patlux
22 |
23 | # 2.0.0 (2025-05-19)
24 |
25 | ### Features
26 |
27 | - Complete rewrite using [nitro-modules](https://nitro.margelo.com/)
28 | - Native TypeScript support
29 | - New synchronous API: `getStateSync()` to retrieve Bluetooth state
30 |
31 | ### Breaking Changes
32 |
33 | - Requires `react-native-nitro-modules` to be installed
34 | - Removed `enable()` and `disable()` due to deprecation starting from Android SDK 33. If your app targets SDK < 33 and depends on these methods, remain on `v1.3.5`
35 | - Replacing programmatic Bluetooth control: use `askToEnable()` and `askToDisable()` to prompt the user instead
36 |
37 | ## 2.0.0-0 (2025-03-26)
38 |
39 | ### Features
40 |
41 | - Complete rewrite. Based on [nitro-modules](https://nitro.margelo.com/)
42 |
43 | ### ❤️ Thank You
44 |
45 | - Patrick Wozniak @patlux
46 |
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Patrick Wozniak
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/apps/example/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/apps/example/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native',
4 | rules: {
5 | 'react-native/no-inline-styles': 'off',
6 | semi: 'off',
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/apps/example/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | **/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 | *.keystore
35 | !debug.keystore
36 |
37 | # node.js
38 | #
39 | node_modules/
40 | npm-debug.log
41 | yarn-error.log
42 |
43 | # fastlane
44 | #
45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
46 | # screenshots whenever they are needed.
47 | # For more information about the recommended setup visit:
48 | # https://docs.fastlane.tools/best-practices/source-control/
49 |
50 | **/fastlane/report.xml
51 | **/fastlane/Preview.html
52 | **/fastlane/screenshots
53 | **/fastlane/test_output
54 |
55 | # Bundle artifact
56 | *.jsbundle
57 |
58 | # Ruby / CocoaPods
59 | **/Pods/
60 | /vendor/bundle/
61 |
62 | # Temporary files created by Metro to check the health of the file watcher
63 | .metro-health-check*
64 |
65 | # testing
66 | /coverage
67 |
68 | # Yarn
69 | .yarn/*
70 | !.yarn/patches
71 | !.yarn/plugins
72 | !.yarn/releases
73 | !.yarn/sdks
74 | !.yarn/versions
75 |
--------------------------------------------------------------------------------
/apps/example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/apps/example/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby ">= 2.6.10"
5 |
6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9 | gem 'xcodeproj', '< 1.26.0'
10 | gem 'concurrent-ruby', '< 1.3.4'
11 |
--------------------------------------------------------------------------------
/apps/example/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | CFPropertyList (3.0.7)
5 | base64
6 | nkf
7 | rexml
8 | activesupport (7.2.2.1)
9 | base64
10 | benchmark (>= 0.3)
11 | bigdecimal
12 | concurrent-ruby (~> 1.0, >= 1.3.1)
13 | connection_pool (>= 2.2.5)
14 | drb
15 | i18n (>= 1.6, < 2)
16 | logger (>= 1.4.2)
17 | minitest (>= 5.1)
18 | securerandom (>= 0.3)
19 | tzinfo (~> 2.0, >= 2.0.5)
20 | addressable (2.8.7)
21 | public_suffix (>= 2.0.2, < 7.0)
22 | algoliasearch (1.27.5)
23 | httpclient (~> 2.8, >= 2.8.3)
24 | json (>= 1.5.1)
25 | atomos (0.1.3)
26 | base64 (0.2.0)
27 | benchmark (0.4.0)
28 | bigdecimal (3.1.9)
29 | claide (1.1.0)
30 | cocoapods (1.15.2)
31 | addressable (~> 2.8)
32 | claide (>= 1.0.2, < 2.0)
33 | cocoapods-core (= 1.15.2)
34 | cocoapods-deintegrate (>= 1.0.3, < 2.0)
35 | cocoapods-downloader (>= 2.1, < 3.0)
36 | cocoapods-plugins (>= 1.0.0, < 2.0)
37 | cocoapods-search (>= 1.0.0, < 2.0)
38 | cocoapods-trunk (>= 1.6.0, < 2.0)
39 | cocoapods-try (>= 1.1.0, < 2.0)
40 | colored2 (~> 3.1)
41 | escape (~> 0.0.4)
42 | fourflusher (>= 2.3.0, < 3.0)
43 | gh_inspector (~> 1.0)
44 | molinillo (~> 0.8.0)
45 | nap (~> 1.0)
46 | ruby-macho (>= 2.3.0, < 3.0)
47 | xcodeproj (>= 1.23.0, < 2.0)
48 | cocoapods-core (1.15.2)
49 | activesupport (>= 5.0, < 8)
50 | addressable (~> 2.8)
51 | algoliasearch (~> 1.0)
52 | concurrent-ruby (~> 1.1)
53 | fuzzy_match (~> 2.0.4)
54 | nap (~> 1.0)
55 | netrc (~> 0.11)
56 | public_suffix (~> 4.0)
57 | typhoeus (~> 1.0)
58 | cocoapods-deintegrate (1.0.5)
59 | cocoapods-downloader (2.1)
60 | cocoapods-plugins (1.0.0)
61 | nap
62 | cocoapods-search (1.0.1)
63 | cocoapods-trunk (1.6.0)
64 | nap (>= 0.8, < 2.0)
65 | netrc (~> 0.11)
66 | cocoapods-try (1.2.0)
67 | colored2 (3.1.2)
68 | concurrent-ruby (1.3.3)
69 | connection_pool (2.5.0)
70 | drb (2.2.1)
71 | escape (0.0.4)
72 | ethon (0.16.0)
73 | ffi (>= 1.15.0)
74 | ffi (1.17.1)
75 | fourflusher (2.3.1)
76 | fuzzy_match (2.0.4)
77 | gh_inspector (1.1.3)
78 | httpclient (2.8.3)
79 | i18n (1.14.7)
80 | concurrent-ruby (~> 1.0)
81 | json (2.9.1)
82 | logger (1.6.5)
83 | minitest (5.25.4)
84 | molinillo (0.8.0)
85 | nanaimo (0.3.0)
86 | nap (1.1.0)
87 | netrc (0.11.0)
88 | nkf (0.2.0)
89 | public_suffix (4.0.7)
90 | rexml (3.4.0)
91 | ruby-macho (2.5.1)
92 | securerandom (0.4.1)
93 | typhoeus (1.4.1)
94 | ethon (>= 0.9.0)
95 | tzinfo (2.0.6)
96 | concurrent-ruby (~> 1.0)
97 | xcodeproj (1.25.1)
98 | CFPropertyList (>= 2.3.3, < 4.0)
99 | atomos (~> 0.1.3)
100 | claide (>= 1.0.2, < 2.0)
101 | colored2 (~> 3.1)
102 | nanaimo (~> 0.3.0)
103 | rexml (>= 3.3.6, < 4.0)
104 |
105 | PLATFORMS
106 | ruby
107 |
108 | DEPENDENCIES
109 | activesupport (>= 6.1.7.5, != 7.1.0)
110 | cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
111 | concurrent-ruby (< 1.3.4)
112 | xcodeproj (< 1.26.0)
113 |
114 | RUBY VERSION
115 | ruby 3.3.6p108
116 |
117 | BUNDLED WITH
118 | 2.5.22
119 |
--------------------------------------------------------------------------------
/apps/example/README.md:
--------------------------------------------------------------------------------
1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
2 |
3 | # Getting Started
4 |
5 | > **Note**: Make sure you have completed the [Set Up Your Environment](https://reactnative.dev/docs/set-up-your-environment) guide before proceeding.
6 |
7 | ## Step 1: Start Metro
8 |
9 | First, you will need to run **Metro**, the JavaScript build tool for React Native.
10 |
11 | To start the Metro dev server, run the following command from the root of your React Native project:
12 |
13 | ```sh
14 | # Using npm
15 | npm start
16 |
17 | # OR using Yarn
18 | yarn start
19 | ```
20 |
21 | ## Step 2: Build and run your app
22 |
23 | With Metro running, open a new terminal window/pane from the root of your React Native project, and use one of the following commands to build and run your Android or iOS app:
24 |
25 | ### Android
26 |
27 | ```sh
28 | # Using npm
29 | npm run android
30 |
31 | # OR using Yarn
32 | yarn android
33 | ```
34 |
35 | ### iOS
36 |
37 | For iOS, remember to install CocoaPods dependencies (this only needs to be run on first clone or after updating native deps).
38 |
39 | The first time you create a new project, run the Ruby bundler to install CocoaPods itself:
40 |
41 | ```sh
42 | bundle install
43 | ```
44 |
45 | Then, and every time you update your native dependencies, run:
46 |
47 | ```sh
48 | bundle exec pod install
49 | ```
50 |
51 | For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html).
52 |
53 | ```sh
54 | # Using npm
55 | npm run ios
56 |
57 | # OR using Yarn
58 | yarn ios
59 | ```
60 |
61 | If everything is set up correctly, you should see your new app running in the Android Emulator, iOS Simulator, or your connected device.
62 |
63 | This is one way to run your app — you can also build it directly from Android Studio or Xcode.
64 |
65 | ## Step 3: Modify your app
66 |
67 | Now that you have successfully run the app, let's make changes!
68 |
69 | Open `App.tsx` in your text editor of choice and make some changes. When you save, your app will automatically update and reflect these changes — this is powered by [Fast Refresh](https://reactnative.dev/docs/fast-refresh).
70 |
71 | When you want to forcefully reload, for example to reset the state of your app, you can perform a full reload:
72 |
73 | - **Android**: Press the R key twice or select **"Reload"** from the **Dev Menu**, accessed via Ctrl + M (Windows/Linux) or Cmd ⌘ + M (macOS).
74 | - **iOS**: Press R in iOS Simulator.
75 |
76 | ## Congratulations! :tada:
77 |
78 | You've successfully run and modified your React Native App. :partying_face:
79 |
80 | ### Now what?
81 |
82 | - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
83 | - If you're curious to learn more about React Native, check out the [docs](https://reactnative.dev/docs/getting-started).
84 |
85 | # Troubleshooting
86 |
87 | If you're having issues getting the above steps to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.
88 |
89 | # Learn More
90 |
91 | To learn more about React Native, take a look at the following resources:
92 |
93 | - [React Native Website](https://reactnative.dev) - learn more about React Native.
94 | - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment.
95 | - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**.
96 | - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts.
97 | - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native.
98 |
--------------------------------------------------------------------------------
/apps/example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/debug.keystore
--------------------------------------------------------------------------------
/apps/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
14 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/java/com/exampleapp/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.exampleapp
2 |
3 | import com.facebook.react.ReactActivity
4 | import com.facebook.react.ReactActivityDelegate
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate
7 | import android.os.Bundle;
8 |
9 | class MainActivity : ReactActivity() {
10 |
11 | override fun onCreate(savedInstanceState: Bundle?) {
12 | super.onCreate(null)
13 | }
14 |
15 | /**
16 | * Returns the name of the main component registered from JavaScript. This is used to schedule
17 | * rendering of the component.
18 | */
19 | override fun getMainComponentName(): String = "ExampleApp"
20 |
21 | /**
22 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
23 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
24 | */
25 | override fun createReactActivityDelegate(): ReactActivityDelegate =
26 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
27 | }
28 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/java/com/exampleapp/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package com.exampleapp
2 |
3 | import android.app.Application
4 | import com.facebook.react.PackageList
5 | import com.facebook.react.ReactApplication
6 | import com.facebook.react.ReactHost
7 | import com.facebook.react.ReactNativeHost
8 | import com.facebook.react.ReactPackage
9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
11 | import com.facebook.react.defaults.DefaultReactNativeHost
12 | import com.facebook.react.soloader.OpenSourceMergedSoMapping
13 | import com.facebook.soloader.SoLoader
14 |
15 | class MainApplication : Application(), ReactApplication {
16 |
17 | override val reactNativeHost: ReactNativeHost =
18 | object : DefaultReactNativeHost(this) {
19 | override fun getPackages(): List =
20 | PackageList(this).packages.apply {
21 | // Packages that cannot be autolinked yet can be added manually here, for example:
22 | // add(MyReactNativePackage())
23 | }
24 |
25 | override fun getJSMainModuleName(): String = "index"
26 |
27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
28 |
29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
31 | }
32 |
33 | override val reactHost: ReactHost
34 | get() = getDefaultReactHost(applicationContext, reactNativeHost)
35 |
36 | override fun onCreate() {
37 | super.onCreate()
38 | SoLoader.init(this, OpenSourceMergedSoMapping)
39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
40 | // If you opted-in for the New Architecture, we load the native entry point for this app.
41 | load()
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExampleApp
3 |
4 |
--------------------------------------------------------------------------------
/apps/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/apps/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | buildToolsVersion = "35.0.0"
4 | minSdkVersion = 24
5 | compileSdkVersion = 35
6 | targetSdkVersion = 34
7 | ndkVersion = "27.1.12297006"
8 | kotlinVersion = "2.0.21"
9 | }
10 | repositories {
11 | google()
12 | mavenCentral()
13 | }
14 | dependencies {
15 | classpath("com.android.tools.build:gradle")
16 | classpath("com.facebook.react:react-native-gradle-plugin")
17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
18 | }
19 | }
20 |
21 | apply plugin: "com.facebook.react.rootproject"
22 |
--------------------------------------------------------------------------------
/apps/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Use this property to specify which architecture you want to build.
26 | # You can also override it from the CLI using
27 | # ./gradlew -PreactNativeArchitectures=x86_64
28 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
29 |
30 | # Use this property to enable support to the new architecture.
31 | # This will allow you to use TurboModules and the Fabric render in
32 | # your application. You should enable this flag either if you want
33 | # to write custom TurboModules/Fabric components OR use libraries that
34 | # are providing them.
35 | newArchEnabled=true
36 |
37 | # Use this property to enable or disable the Hermes JS engine.
38 | # If set to false, you will be using JSC instead.
39 | hermesEnabled=true
40 |
--------------------------------------------------------------------------------
/apps/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patlux/react-native-bluetooth-state-manager/4c8c472a8e2649f4571d192339e53dd9d0288708/apps/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/apps/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/apps/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/apps/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement { includeBuild("../../node_modules/@react-native/gradle-plugin") }
2 | plugins { id("com.facebook.react.settings") }
3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
4 | rootProject.name = 'ExampleApp'
5 | include ':app'
6 | includeBuild('../../node_modules/@react-native/gradle-plugin')
--------------------------------------------------------------------------------
/apps/example/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ExampleApp",
3 | "displayName": "ExampleApp"
4 | }
5 |
--------------------------------------------------------------------------------
/apps/example/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | }
4 |
--------------------------------------------------------------------------------
/apps/example/index.js:
--------------------------------------------------------------------------------
1 | import { AppRegistry } from 'react-native'
2 | import App from './src/App'
3 | import { name as appName } from './app.json'
4 |
5 | AppRegistry.registerComponent(appName, () => App)
6 |
--------------------------------------------------------------------------------
/apps/example/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp.xcodeproj/xcshareddata/xcschemes/ExampleApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import React
3 | import React_RCTAppDelegate
4 | import ReactAppDependencyProvider
5 |
6 | @main
7 | class AppDelegate: RCTAppDelegate {
8 | override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
9 | self.moduleName = "ExampleApp"
10 | self.dependencyProvider = RCTAppDependencyProvider()
11 |
12 | // You can add your custom initial props in the dictionary below.
13 | // They will be passed down to the ViewController used by React Native.
14 | self.initialProps = [:]
15 |
16 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
17 | }
18 |
19 | override func sourceURL(for bridge: RCTBridge) -> URL? {
20 | self.bundleURL()
21 | }
22 |
23 | override func bundleURL() -> URL? {
24 | #if DEBUG
25 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
26 | #else
27 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
28 | #endif
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "iphone",
5 | "scale": "2x",
6 | "size": "20x20"
7 | },
8 | {
9 | "idiom": "iphone",
10 | "scale": "3x",
11 | "size": "20x20"
12 | },
13 | {
14 | "idiom": "iphone",
15 | "scale": "2x",
16 | "size": "29x29"
17 | },
18 | {
19 | "idiom": "iphone",
20 | "scale": "3x",
21 | "size": "29x29"
22 | },
23 | {
24 | "idiom": "iphone",
25 | "scale": "2x",
26 | "size": "40x40"
27 | },
28 | {
29 | "idiom": "iphone",
30 | "scale": "3x",
31 | "size": "40x40"
32 | },
33 | {
34 | "idiom": "iphone",
35 | "scale": "2x",
36 | "size": "60x60"
37 | },
38 | {
39 | "idiom": "iphone",
40 | "scale": "3x",
41 | "size": "60x60"
42 | },
43 | {
44 | "idiom": "ios-marketing",
45 | "scale": "1x",
46 | "size": "1024x1024"
47 | }
48 | ],
49 | "info": {
50 | "author": "xcode",
51 | "version": 1
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "version": 1,
4 | "author": "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ExampleApp
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(CURRENT_PROJECT_VERSION)
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSAllowsArbitraryLoads
30 |
31 | NSAllowsLocalNetworking
32 |
33 |
34 | NSLocationWhenInUseUsageDescription
35 |
36 | NSBluetoothAlwaysUsageDescription
37 | Because
38 | UILaunchStoryboardName
39 | LaunchScreen
40 | UIRequiredDeviceCapabilities
41 |
42 | arm64
43 |
44 | UISupportedInterfaceOrientations
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationLandscapeLeft
48 | UIInterfaceOrientationLandscapeRight
49 |
50 | UIViewControllerBasedStatusBarAppearance
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/apps/example/ios/ExampleApp/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryUserDefaults
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | CA92.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryFileTimestamp
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | C617.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyCollectedDataTypes
33 |
34 | NSPrivacyTracking
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/apps/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | j# Resolve react_native_pods.rb with node to allow for hoisting
2 | require Pod::Executable.execute_command('node', ['-p',
3 | 'require.resolve(
4 | "react-native/scripts/react_native_pods.rb",
5 | {paths: [process.argv[1]]},
6 | )', __dir__]).strip
7 |
8 | platform :ios, min_ios_version_supported
9 | prepare_react_native_project!
10 |
11 | linkage = ENV['USE_FRAMEWORKS']
12 | if linkage != nil
13 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
14 | use_frameworks! :linkage => linkage.to_sym
15 | end
16 |
17 | target 'ExampleApp' do
18 | config = use_native_modules!
19 |
20 | use_react_native!(
21 | :path => config[:reactNativePath],
22 | # An absolute path to your application root.
23 | :app_path => "#{Pod::Config.instance.installation_root}/.."
24 | )
25 |
26 | post_install do |installer|
27 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
28 | react_native_post_install(
29 | installer,
30 | config[:reactNativePath],
31 | :mac_catalyst_enabled => false,
32 | # :ccache_enabled => true
33 | )
34 |
35 | installer.pods_project.targets.each do |target|
36 | target.build_configurations.each do |config|
37 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '16.6'
38 | end
39 | end
40 |
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/apps/example/metro.config.js:
--------------------------------------------------------------------------------
1 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config')
2 | const path = require('path')
3 | const root = path.resolve(__dirname, '..', '..')
4 |
5 | /**
6 | * Metro configuration
7 | * https://facebook.github.io/metro/docs/configuration
8 | *
9 | * @type {import('metro-config').MetroConfig}
10 | */
11 | const config = {
12 | watchFolders: [root],
13 | }
14 |
15 | module.exports = mergeConfig(getDefaultConfig(__dirname), config)
16 |
--------------------------------------------------------------------------------
/apps/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-app",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios --simulator='iPhone 16'",
8 | "start": "react-native start --reset-cache",
9 | "pod": "pod install --project-directory=ios && cd ..",
10 | "lint": "TIMING=1 eslint .",
11 | "typecheck": "tsc --noEmit",
12 | "check-format": "prettier --check .",
13 | "format": "prettier --write ."
14 | },
15 | "dependencies": {
16 | "@react-navigation/native": "^7.0.18",
17 | "@react-navigation/native-stack": "^7.3.2",
18 | "@tanstack/react-query": "^5.69.0",
19 | "react": "18.3.1",
20 | "react-native": "0.77.0",
21 | "react-native-nitro-modules": "0.25.2",
22 | "react-native-permissions": "^5.3.0",
23 | "react-native-safe-area-context": "^5.3.0",
24 | "react-native-screens": "^4.9.2",
25 | "react-native-bluetooth-state-manager": "*"
26 | },
27 | "devDependencies": {
28 | "@babel/core": "^7.25.2",
29 | "@babel/preset-env": "^7.25.3",
30 | "@react-native-community/cli": "15.0.1",
31 | "@react-native-community/cli-platform-android": "15.0.1",
32 | "@react-native-community/cli-platform-ios": "15.0.1",
33 | "@react-native/babel-preset": "0.77.0",
34 | "@react-native/eslint-config": "0.77.0",
35 | "@react-native/metro-config": "0.77.0",
36 | "@react-native/typescript-config": "0.77.0",
37 | "@types/react": "^18.2.6",
38 | "eslint": "^8.19.0",
39 | "typescript": "*"
40 | },
41 | "engines": {
42 | "node": ">=18"
43 | },
44 | "prettier": {
45 | "singleQuote": true,
46 | "trailingComma": "all",
47 | "semi": false
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/apps/example/react-native.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const pkg = require('../../packages/react-native-bluetooth-state-manager/package.json')
3 |
4 | /**
5 | * @type {import('@react-native-community/cli-types').Config}
6 | */
7 | module.exports = {
8 | dependencies: {
9 | [pkg.name]: {
10 | root: path.join(
11 | __dirname,
12 | '..',
13 | '..',
14 | 'packages',
15 | 'react-native-bluetooth-state-manager',
16 | ),
17 | },
18 | },
19 | }
20 |
--------------------------------------------------------------------------------
/apps/example/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { QueryClientProvider } from '@tanstack/react-query'
2 | import React from 'react'
3 |
4 | import { createStaticNavigation, DarkTheme } from '@react-navigation/native'
5 | import { createNativeStackNavigator } from '@react-navigation/native-stack'
6 | import { HomeScreen } from './HomeScreen'
7 | import { queryClient } from './queryClient'
8 |
9 | const RootStack = createNativeStackNavigator({
10 | screens: {
11 | Home: HomeScreen,
12 | },
13 | })
14 |
15 | const Navigation = createStaticNavigation(RootStack)
16 |
17 | const App = () => {
18 | return (
19 |
20 |
21 |
22 | )
23 | }
24 |
25 | export default App
26 |
--------------------------------------------------------------------------------
/apps/example/src/HomeScreen.tsx:
--------------------------------------------------------------------------------
1 | import { SafeAreaView } from 'react-native'
2 | import { useMutation } from '@tanstack/react-query'
3 | import React, { useEffect, useState } from 'react'
4 | import { Alert, Button, Platform, Text, View } from 'react-native'
5 | import {
6 | BluetoothStateManager,
7 | useBluetoothState,
8 | } from 'react-native-bluetooth-state-manager'
9 | import { useTheme } from '@react-navigation/native'
10 | import { Permissions } from './Permissions'
11 |
12 | export const HomeScreen = () => {
13 | return (
14 |
21 |
22 |
23 |
24 |
25 |
26 | {Platform.OS === 'android' && (
27 |
28 |
29 |
30 |
31 |
32 | )}
33 |
34 | )
35 | }
36 |
37 | const Divider = () => {
38 | const { colors } = useTheme()
39 | return (
40 |
49 | )
50 | }
51 |
52 | const CurrentState = () => {
53 | const state = useBluetoothState()
54 | return State: {state}
55 | }
56 |
57 | const RequestToEnableBluetooth = () => {
58 | console.log('RequestToEnable()')
59 | const requestToEnableMutation = useMutation({
60 | mutationFn: async () => {
61 | console.log('Start...')
62 | const result = await BluetoothStateManager.requestToEnable()
63 | console.log(`...end. Result = "${result}".`)
64 | return result
65 | },
66 | onError: (error) => {
67 | console.error(error)
68 | Alert.alert('Error', `${error}`)
69 | },
70 | onSuccess: () => {
71 | Alert.alert('Bluetooth enabled')
72 | },
73 | })
74 |
75 | return (
76 |