@capawesome/capacitor-silent-mode 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapawesomeCapacitorSilentMode.podspec +17 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +242 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/SilentMode.java +90 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/SilentModePlugin.java +112 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/classes/events/SilentModeChangeEvent.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/classes/results/GetRingerModeResult.java +23 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/classes/results/IsSilentResult.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/interfaces/Callback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/interfaces/NonEmptyResultCallback.java +7 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/interfaces/Result.java +7 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +222 -0
- package/dist/esm/definitions.d.ts +92 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +6 -0
- package/dist/esm/web.js +10 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +24 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +27 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Classes/Events/SilentModeChangeEvent.swift +16 -0
- package/ios/Plugin/Classes/Results/IsSilentResult.swift +16 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Protocols/Result.swift +5 -0
- package/ios/Plugin/SilentMode.swift +177 -0
- package/ios/Plugin/SilentModePlugin.swift +74 -0
- package/package.json +91 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'CapawesomeCapacitorSilentMode'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '15.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.swift_version = '5.1'
|
|
17
|
+
end
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Robin Genz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/Package.swift
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// swift-tools-version: 5.9
|
|
2
|
+
import PackageDescription
|
|
3
|
+
|
|
4
|
+
let package = Package(
|
|
5
|
+
name: "CapawesomeCapacitorSilentMode",
|
|
6
|
+
platforms: [.iOS(.v15)],
|
|
7
|
+
products: [
|
|
8
|
+
.library(
|
|
9
|
+
name: "CapawesomeCapacitorSilentMode",
|
|
10
|
+
targets: ["SilentModePlugin"])
|
|
11
|
+
],
|
|
12
|
+
dependencies: [
|
|
13
|
+
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
|
|
14
|
+
],
|
|
15
|
+
targets: [
|
|
16
|
+
.target(
|
|
17
|
+
name: "SilentModePlugin",
|
|
18
|
+
dependencies: [
|
|
19
|
+
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
20
|
+
.product(name: "Cordova", package: "capacitor-swift-pm")
|
|
21
|
+
],
|
|
22
|
+
path: "ios/Plugin"),
|
|
23
|
+
.testTarget(
|
|
24
|
+
name: "SilentModePluginTests",
|
|
25
|
+
dependencies: ["SilentModePlugin"],
|
|
26
|
+
path: "ios/PluginTests")
|
|
27
|
+
]
|
|
28
|
+
)
|
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# @capawesome/capacitor-silent-mode
|
|
2
|
+
|
|
3
|
+
Capacitor plugin to detect whether the device is in silent mode.
|
|
4
|
+
|
|
5
|
+
<div class="capawesome-z29o10a">
|
|
6
|
+
<a href="https://cloud.capawesome.io/" target="_blank">
|
|
7
|
+
<img alt="Deliver Live Updates to your Capacitor app with Capawesome Cloud" src="https://cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
|
|
8
|
+
</a>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- 🔇 **Silent detection**: Check whether the device is currently in silent mode.
|
|
14
|
+
- 🔔 **Ringer mode**: Read the exact ringer mode (normal, vibrate or silent) on Android.
|
|
15
|
+
- 👂 **Change events**: Listen for changes to the silent mode state.
|
|
16
|
+
- 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
|
|
17
|
+
- 🔁 **Up-to-date**: Always supports the latest Capacitor version.
|
|
18
|
+
|
|
19
|
+
Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!
|
|
20
|
+
|
|
21
|
+
## Newsletter
|
|
22
|
+
|
|
23
|
+
Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).
|
|
24
|
+
|
|
25
|
+
## Compatibility
|
|
26
|
+
|
|
27
|
+
| Plugin Version | Capacitor Version | Status |
|
|
28
|
+
| -------------- | ----------------- | -------------- |
|
|
29
|
+
| 0.x.x | >=8.x.x | Active support |
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
You can use our **AI-Assisted Setup** to install the plugin.
|
|
34
|
+
Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx skills add capawesome-team/skills --skill capacitor-plugins
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Then use the following prompt:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-silent-mode` plugin in my project.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install @capawesome/capacitor-silent-mode
|
|
50
|
+
npx cap sync
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This plugin is only available on **Android** and **iOS**. On the Web, all methods reject as unimplemented.
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
No configuration required for this plugin.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { SilentMode } from '@capawesome/capacitor-silent-mode';
|
|
63
|
+
|
|
64
|
+
const isSilent = async () => {
|
|
65
|
+
const { silent } = await SilentMode.isSilent();
|
|
66
|
+
return silent;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const getRingerMode = async () => {
|
|
70
|
+
const { mode } = await SilentMode.getRingerMode();
|
|
71
|
+
return mode;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const addSilentModeChangeListener = async () => {
|
|
75
|
+
await SilentMode.addListener('silentModeChange', event => {
|
|
76
|
+
console.log('Silent mode changed:', event.silent);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const removeAllListeners = async () => {
|
|
81
|
+
await SilentMode.removeAllListeners();
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API
|
|
86
|
+
|
|
87
|
+
<docgen-index>
|
|
88
|
+
|
|
89
|
+
* [`getRingerMode()`](#getringermode)
|
|
90
|
+
* [`isSilent()`](#issilent)
|
|
91
|
+
* [`addListener('silentModeChange', ...)`](#addlistenersilentmodechange-)
|
|
92
|
+
* [`removeAllListeners()`](#removealllisteners)
|
|
93
|
+
* [Interfaces](#interfaces)
|
|
94
|
+
* [Type Aliases](#type-aliases)
|
|
95
|
+
|
|
96
|
+
</docgen-index>
|
|
97
|
+
|
|
98
|
+
<docgen-api>
|
|
99
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
100
|
+
|
|
101
|
+
### getRingerMode()
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
getRingerMode() => Promise<GetRingerModeResult>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Get the current ringer mode of the device.
|
|
108
|
+
|
|
109
|
+
Only available on Android.
|
|
110
|
+
|
|
111
|
+
**Returns:** <code>Promise<<a href="#getringermoderesult">GetRingerModeResult</a>></code>
|
|
112
|
+
|
|
113
|
+
**Since:** 0.1.0
|
|
114
|
+
|
|
115
|
+
--------------------
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
### isSilent()
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
isSilent() => Promise<IsSilentResult>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Get the current silent mode state of the device.
|
|
125
|
+
|
|
126
|
+
On Android, the device is considered silent if the ringer mode is not set
|
|
127
|
+
to normal (that is, either vibrate or silent).
|
|
128
|
+
|
|
129
|
+
On iOS, there is no public API to read the ring/silent switch. The state is
|
|
130
|
+
therefore determined using a heuristic that plays a short muted system sound
|
|
131
|
+
and measures how long it takes to complete. The result may be inaccurate
|
|
132
|
+
while other audio is playing.
|
|
133
|
+
|
|
134
|
+
Only available on Android and iOS.
|
|
135
|
+
|
|
136
|
+
**Returns:** <code>Promise<<a href="#issilentresult">IsSilentResult</a>></code>
|
|
137
|
+
|
|
138
|
+
**Since:** 0.1.0
|
|
139
|
+
|
|
140
|
+
--------------------
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
### addListener('silentModeChange', ...)
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
addListener(eventName: 'silentModeChange', listenerFunc: (event: SilentModeChangeEvent) => void) => Promise<PluginListenerHandle>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Listen for changes to the silent mode state of the device.
|
|
150
|
+
|
|
151
|
+
The device is only observed while at least one listener is attached.
|
|
152
|
+
|
|
153
|
+
On iOS, the state is polled on a timer while the app is in the foreground
|
|
154
|
+
and the listener is not called while the app is in the background.
|
|
155
|
+
|
|
156
|
+
Only available on Android and iOS.
|
|
157
|
+
|
|
158
|
+
| Param | Type |
|
|
159
|
+
| ------------------ | ------------------------------------------------------------------------------------------- |
|
|
160
|
+
| **`eventName`** | <code>'silentModeChange'</code> |
|
|
161
|
+
| **`listenerFunc`** | <code>(event: <a href="#silentmodechangeevent">SilentModeChangeEvent</a>) => void</code> |
|
|
162
|
+
|
|
163
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
164
|
+
|
|
165
|
+
**Since:** 0.1.0
|
|
166
|
+
|
|
167
|
+
--------------------
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
### removeAllListeners()
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
removeAllListeners() => Promise<void>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Remove all listeners for this plugin.
|
|
177
|
+
|
|
178
|
+
**Since:** 0.1.0
|
|
179
|
+
|
|
180
|
+
--------------------
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
### Interfaces
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
#### GetRingerModeResult
|
|
187
|
+
|
|
188
|
+
| Prop | Type | Description | Since |
|
|
189
|
+
| ---------- | ------------------------------------------------- | -------------------------------------- | ----- |
|
|
190
|
+
| **`mode`** | <code><a href="#ringermode">RingerMode</a></code> | The current ringer mode of the device. | 0.1.0 |
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
#### IsSilentResult
|
|
194
|
+
|
|
195
|
+
| Prop | Type | Description | Since |
|
|
196
|
+
| ------------ | -------------------- | ----------------------------------------------- | ----- |
|
|
197
|
+
| **`silent`** | <code>boolean</code> | Whether the device is currently in silent mode. | 0.1.0 |
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
#### PluginListenerHandle
|
|
201
|
+
|
|
202
|
+
| Prop | Type |
|
|
203
|
+
| ------------ | ----------------------------------------- |
|
|
204
|
+
| **`remove`** | <code>() => Promise<void></code> |
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
#### SilentModeChangeEvent
|
|
208
|
+
|
|
209
|
+
| Prop | Type | Description | Since |
|
|
210
|
+
| ------------ | -------------------- | ----------------------------------------------- | ----- |
|
|
211
|
+
| **`silent`** | <code>boolean</code> | Whether the device is currently in silent mode. | 0.1.0 |
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
### Type Aliases
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
#### RingerMode
|
|
218
|
+
|
|
219
|
+
The ringer mode of the device.
|
|
220
|
+
|
|
221
|
+
- `normal`: The device plays sounds and rings for incoming calls.
|
|
222
|
+
- `silent`: The device is silent and does not vibrate.
|
|
223
|
+
- `vibrate`: The device is silent but vibrates.
|
|
224
|
+
|
|
225
|
+
<code>'normal' | 'silent' | 'vibrate'</code>
|
|
226
|
+
|
|
227
|
+
</docgen-api>
|
|
228
|
+
|
|
229
|
+
## Silent Mode Detection
|
|
230
|
+
|
|
231
|
+
Keep the following platform differences in mind when detecting silent mode:
|
|
232
|
+
|
|
233
|
+
- **Android**: The silent mode state is derived from the [ringer mode](https://developer.android.com/reference/android/media/AudioManager#getRingerMode()). A device is considered silent whenever the ringer mode is not `normal`, which means that the vibrate mode also counts as silent. Use `getRingerMode()` if you need to distinguish between the vibrate and silent modes.
|
|
234
|
+
- **iOS**: There is no public API to read the state of the ring/silent switch. The plugin therefore relies on a heuristic that plays a short muted system sound and measures how long it takes to complete. As a result, the detection may be inaccurate while other audio is playing or when the audio session category overrides the switch. The `silentModeChange` listener polls this heuristic on a timer while the app is in the foreground and pauses while the app is in the background.
|
|
235
|
+
|
|
236
|
+
## Changelog
|
|
237
|
+
|
|
238
|
+
See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/silent-mode/CHANGELOG.md).
|
|
239
|
+
|
|
240
|
+
## License
|
|
241
|
+
|
|
242
|
+
See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/silent-mode/LICENSE).
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
repositories {
|
|
10
|
+
google()
|
|
11
|
+
mavenCentral()
|
|
12
|
+
}
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.13.0'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
apply plugin: 'com.android.library'
|
|
19
|
+
|
|
20
|
+
android {
|
|
21
|
+
namespace = "io.capawesome.capacitorjs.plugins.silentmode"
|
|
22
|
+
compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
|
|
23
|
+
defaultConfig {
|
|
24
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
|
|
25
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
|
|
26
|
+
versionCode 1
|
|
27
|
+
versionName "1.0"
|
|
28
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
29
|
+
}
|
|
30
|
+
buildTypes {
|
|
31
|
+
release {
|
|
32
|
+
minifyEnabled false
|
|
33
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
lintOptions {
|
|
37
|
+
abortOnError = false
|
|
38
|
+
}
|
|
39
|
+
compileOptions {
|
|
40
|
+
sourceCompatibility JavaVersion.VERSION_21
|
|
41
|
+
targetCompatibility JavaVersion.VERSION_21
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
repositories {
|
|
46
|
+
google()
|
|
47
|
+
mavenCentral()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
dependencies {
|
|
52
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
53
|
+
implementation project(':capacitor-android')
|
|
54
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
55
|
+
testImplementation "junit:junit:$junitVersion"
|
|
56
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
57
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
58
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.silentmode;
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.Intent;
|
|
6
|
+
import android.content.IntentFilter;
|
|
7
|
+
import android.media.AudioManager;
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
import androidx.core.content.ContextCompat;
|
|
10
|
+
import io.capawesome.capacitorjs.plugins.silentmode.classes.events.SilentModeChangeEvent;
|
|
11
|
+
import io.capawesome.capacitorjs.plugins.silentmode.classes.results.GetRingerModeResult;
|
|
12
|
+
import io.capawesome.capacitorjs.plugins.silentmode.classes.results.IsSilentResult;
|
|
13
|
+
import io.capawesome.capacitorjs.plugins.silentmode.interfaces.NonEmptyResultCallback;
|
|
14
|
+
|
|
15
|
+
public class SilentMode {
|
|
16
|
+
|
|
17
|
+
@NonNull
|
|
18
|
+
private final SilentModePlugin plugin;
|
|
19
|
+
|
|
20
|
+
@NonNull
|
|
21
|
+
private final AudioManager audioManager;
|
|
22
|
+
|
|
23
|
+
private boolean isObserving = false;
|
|
24
|
+
|
|
25
|
+
private boolean lastSilent = false;
|
|
26
|
+
|
|
27
|
+
private final BroadcastReceiver ringerModeReceiver = new BroadcastReceiver() {
|
|
28
|
+
@Override
|
|
29
|
+
public void onReceive(Context context, Intent intent) {
|
|
30
|
+
handleRingerModeChanged();
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
public SilentMode(@NonNull SilentModePlugin plugin) {
|
|
35
|
+
this.plugin = plugin;
|
|
36
|
+
this.audioManager = (AudioManager) plugin.getContext().getSystemService(Context.AUDIO_SERVICE);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public void getRingerMode(@NonNull NonEmptyResultCallback<GetRingerModeResult> callback) {
|
|
40
|
+
String mode = mapRingerMode(audioManager.getRingerMode());
|
|
41
|
+
callback.success(new GetRingerModeResult(mode));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public void isSilent(@NonNull NonEmptyResultCallback<IsSilentResult> callback) {
|
|
45
|
+
callback.success(new IsSilentResult(isSilent()));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public void startObserving() {
|
|
49
|
+
if (isObserving) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
lastSilent = isSilent();
|
|
53
|
+
IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
|
|
54
|
+
ContextCompat.registerReceiver(plugin.getContext(), ringerModeReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);
|
|
55
|
+
isObserving = true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public void stopObserving() {
|
|
59
|
+
if (!isObserving) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
plugin.getContext().unregisterReceiver(ringerModeReceiver);
|
|
63
|
+
isObserving = false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private void handleRingerModeChanged() {
|
|
67
|
+
boolean silent = isSilent();
|
|
68
|
+
if (silent == lastSilent) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
lastSilent = silent;
|
|
72
|
+
plugin.notifySilentModeChangeListeners(new SilentModeChangeEvent(silent));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private boolean isSilent() {
|
|
76
|
+
return audioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@NonNull
|
|
80
|
+
private String mapRingerMode(int ringerMode) {
|
|
81
|
+
switch (ringerMode) {
|
|
82
|
+
case AudioManager.RINGER_MODE_SILENT:
|
|
83
|
+
return "silent";
|
|
84
|
+
case AudioManager.RINGER_MODE_VIBRATE:
|
|
85
|
+
return "vibrate";
|
|
86
|
+
default:
|
|
87
|
+
return "normal";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
package/android/src/main/java/io/capawesome/capacitorjs/plugins/silentmode/SilentModePlugin.java
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.silentmode;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.Logger;
|
|
5
|
+
import com.getcapacitor.Plugin;
|
|
6
|
+
import com.getcapacitor.PluginCall;
|
|
7
|
+
import com.getcapacitor.PluginMethod;
|
|
8
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
9
|
+
import io.capawesome.capacitorjs.plugins.silentmode.classes.events.SilentModeChangeEvent;
|
|
10
|
+
import io.capawesome.capacitorjs.plugins.silentmode.classes.results.GetRingerModeResult;
|
|
11
|
+
import io.capawesome.capacitorjs.plugins.silentmode.classes.results.IsSilentResult;
|
|
12
|
+
import io.capawesome.capacitorjs.plugins.silentmode.interfaces.NonEmptyResultCallback;
|
|
13
|
+
import io.capawesome.capacitorjs.plugins.silentmode.interfaces.Result;
|
|
14
|
+
|
|
15
|
+
@CapacitorPlugin(name = "SilentMode")
|
|
16
|
+
public class SilentModePlugin extends Plugin {
|
|
17
|
+
|
|
18
|
+
public static final String EVENT_SILENT_MODE_CHANGE = "silentModeChange";
|
|
19
|
+
|
|
20
|
+
public static final String TAG = "SilentModePlugin";
|
|
21
|
+
|
|
22
|
+
private static final String ERROR_UNKNOWN_ERROR = "An unknown error occurred.";
|
|
23
|
+
|
|
24
|
+
private SilentMode implementation;
|
|
25
|
+
|
|
26
|
+
@Override
|
|
27
|
+
public void load() {
|
|
28
|
+
implementation = new SilentMode(this);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Override
|
|
32
|
+
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
|
|
33
|
+
public void addListener(PluginCall call) {
|
|
34
|
+
super.addListener(call);
|
|
35
|
+
implementation.startObserving();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@PluginMethod
|
|
39
|
+
public void getRingerMode(PluginCall call) {
|
|
40
|
+
try {
|
|
41
|
+
NonEmptyResultCallback<GetRingerModeResult> callback = new NonEmptyResultCallback<>() {
|
|
42
|
+
@Override
|
|
43
|
+
public void success(@NonNull GetRingerModeResult result) {
|
|
44
|
+
resolveCall(call, result);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Override
|
|
48
|
+
public void error(@NonNull Exception exception) {
|
|
49
|
+
rejectCall(call, exception);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
implementation.getRingerMode(callback);
|
|
54
|
+
} catch (Exception exception) {
|
|
55
|
+
rejectCall(call, exception);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@PluginMethod
|
|
60
|
+
public void isSilent(PluginCall call) {
|
|
61
|
+
try {
|
|
62
|
+
NonEmptyResultCallback<IsSilentResult> callback = new NonEmptyResultCallback<>() {
|
|
63
|
+
@Override
|
|
64
|
+
public void success(@NonNull IsSilentResult result) {
|
|
65
|
+
resolveCall(call, result);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@Override
|
|
69
|
+
public void error(@NonNull Exception exception) {
|
|
70
|
+
rejectCall(call, exception);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
implementation.isSilent(callback);
|
|
75
|
+
} catch (Exception exception) {
|
|
76
|
+
rejectCall(call, exception);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public void notifySilentModeChangeListeners(@NonNull SilentModeChangeEvent event) {
|
|
81
|
+
notifyListeners(EVENT_SILENT_MODE_CHANGE, event.toJSObject());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@Override
|
|
85
|
+
@PluginMethod
|
|
86
|
+
public void removeAllListeners(PluginCall call) {
|
|
87
|
+
super.removeAllListeners(call);
|
|
88
|
+
implementation.stopObserving();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Override
|
|
92
|
+
@PluginMethod(returnType = PluginMethod.RETURN_NONE)
|
|
93
|
+
public void removeListener(PluginCall call) {
|
|
94
|
+
super.removeListener(call);
|
|
95
|
+
if (!hasListeners(EVENT_SILENT_MODE_CHANGE)) {
|
|
96
|
+
implementation.stopObserving();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private void rejectCall(@NonNull PluginCall call, @NonNull Exception exception) {
|
|
101
|
+
String message = exception.getMessage();
|
|
102
|
+
if (message == null) {
|
|
103
|
+
message = ERROR_UNKNOWN_ERROR;
|
|
104
|
+
}
|
|
105
|
+
Logger.error(TAG, message, exception);
|
|
106
|
+
call.reject(message);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private void resolveCall(@NonNull PluginCall call, @NonNull Result result) {
|
|
110
|
+
call.resolve(result.toJSObject());
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.silentmode.classes.events;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.JSObject;
|
|
5
|
+
import io.capawesome.capacitorjs.plugins.silentmode.interfaces.Result;
|
|
6
|
+
|
|
7
|
+
public class SilentModeChangeEvent implements Result {
|
|
8
|
+
|
|
9
|
+
private final boolean silent;
|
|
10
|
+
|
|
11
|
+
public SilentModeChangeEvent(boolean silent) {
|
|
12
|
+
this.silent = silent;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@Override
|
|
16
|
+
@NonNull
|
|
17
|
+
public JSObject toJSObject() {
|
|
18
|
+
JSObject result = new JSObject();
|
|
19
|
+
result.put("silent", silent);
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.silentmode.classes.results;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.JSObject;
|
|
5
|
+
import io.capawesome.capacitorjs.plugins.silentmode.interfaces.Result;
|
|
6
|
+
|
|
7
|
+
public class GetRingerModeResult implements Result {
|
|
8
|
+
|
|
9
|
+
@NonNull
|
|
10
|
+
private final String mode;
|
|
11
|
+
|
|
12
|
+
public GetRingerModeResult(@NonNull String mode) {
|
|
13
|
+
this.mode = mode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Override
|
|
17
|
+
@NonNull
|
|
18
|
+
public JSObject toJSObject() {
|
|
19
|
+
JSObject result = new JSObject();
|
|
20
|
+
result.put("mode", mode);
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.silentmode.classes.results;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.JSObject;
|
|
5
|
+
import io.capawesome.capacitorjs.plugins.silentmode.interfaces.Result;
|
|
6
|
+
|
|
7
|
+
public class IsSilentResult implements Result {
|
|
8
|
+
|
|
9
|
+
private final boolean silent;
|
|
10
|
+
|
|
11
|
+
public IsSilentResult(boolean silent) {
|
|
12
|
+
this.silent = silent;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@Override
|
|
16
|
+
@NonNull
|
|
17
|
+
public JSObject toJSObject() {
|
|
18
|
+
JSObject result = new JSObject();
|
|
19
|
+
result.put("silent", silent);
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
File without changes
|