community-cordova-plugin-native-settings 1.0.0
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/.idea/community-cordova-plugin-native-settings.iml +12 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +191 -0
- package/RELEASENOTES.md +13 -0
- package/package.json +22 -0
- package/plugin.xml +48 -0
- package/plugin.xml.backup +42 -0
- package/src/android/NativeSettings.java +161 -0
- package/src/ios/NativeSettings.h +8 -0
- package/src/ios/NativeSettings.m +199 -0
- package/types/index.d.ts +32 -0
- package/www/settings.js +29 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$">
|
|
5
|
+
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
+
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
+
</content>
|
|
9
|
+
<orderEntry type="inheritedJdk" />
|
|
10
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
+
</component>
|
|
12
|
+
</module>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/community-cordova-plugin-native-settings.iml" filepath="$PROJECT_DIR$/.idea/community-cordova-plugin-native-settings.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
package/.idea/vcs.xml
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
[](https://www.npmjs.com/package/community-cordova-plugin-native-settings)
|
|
2
|
+
|
|
3
|
+
# community-cordova-plugin-native-settings
|
|
4
|
+
|
|
5
|
+
I dedicate a considerable amount of my free time to developing and maintaining many cordova plugins for the community ([See the list with all my maintained plugins][community_plugins]).
|
|
6
|
+
To help ensure this plugin is kept updated,
|
|
7
|
+
new features are added and bugfixes are implemented quickly,
|
|
8
|
+
please donate a couple of dollars (or a little more if you can stretch) as this will help me to afford to dedicate time to its maintenance.
|
|
9
|
+
Please consider donating if you're using this plugin in an app that makes you money,
|
|
10
|
+
or if you're asking for new features or priority bug fixes. Thank you!
|
|
11
|
+
|
|
12
|
+
[](https://github.com/sponsors/eyalin)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Community Cordova Plugin Native Settings
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
This Cordova plugin provides a simple way to open native device settings screens on Android and iOS platforms. It allows your app to deep-link into specific system settings pages (Wi‑Fi, Bluetooth, Location, etc.) with a clean Promise-based API.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
To install the plugin in your Cordova project, use the following command:
|
|
23
|
+
```bash
|
|
24
|
+
cordova plugin add community-cordova-plugin-native-settings
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
The plugin provides a Promise-based API (also compatible with callbacks) to open various system settings screens.
|
|
29
|
+
|
|
30
|
+
### Basic JavaScript Usage
|
|
31
|
+
```javascript
|
|
32
|
+
document.addEventListener('deviceready', onDeviceReady, false);
|
|
33
|
+
|
|
34
|
+
function onDeviceReady() {
|
|
35
|
+
// Open Wi‑Fi settings
|
|
36
|
+
cordova.plugins.settings.open('wifi')
|
|
37
|
+
.then(() => console.log('Wi‑Fi settings opened'))
|
|
38
|
+
.catch(err => console.error('Failed to open settings:', err));
|
|
39
|
+
|
|
40
|
+
// Open settings in a new task (Android only)
|
|
41
|
+
cordova.plugins.settings.open({ setting: 'wifi', newTask: true })
|
|
42
|
+
.then(() => console.log('Settings opened in new task'))
|
|
43
|
+
.catch(err => console.error('Error:', err));
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### TypeScript/Angular Usage
|
|
48
|
+
```typescript
|
|
49
|
+
import { INativeSettings } from 'community-cordova-plugin-native-settings';
|
|
50
|
+
|
|
51
|
+
declare const cordova: any;
|
|
52
|
+
|
|
53
|
+
@Injectable({
|
|
54
|
+
providedIn: 'root'
|
|
55
|
+
})
|
|
56
|
+
export class SettingsService {
|
|
57
|
+
private settings: INativeSettings;
|
|
58
|
+
|
|
59
|
+
constructor() {
|
|
60
|
+
this.settings = cordova.plugins.settings;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async openWifiSettings(newTask: boolean = false): Promise<void> {
|
|
64
|
+
try {
|
|
65
|
+
await this.settings.open({ setting: 'wifi', newTask });
|
|
66
|
+
console.log('Wi‑Fi settings opened');
|
|
67
|
+
} catch (err) {
|
|
68
|
+
console.error('Failed to open settings:', err);
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async isWifiSettingsAvailable(): Promise<boolean> {
|
|
74
|
+
return await this.settings.isAvailable('wifi');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## API Reference
|
|
80
|
+
|
|
81
|
+
### Methods
|
|
82
|
+
|
|
83
|
+
#### open(options: string | INativeSettingsOptions): Promise<void>
|
|
84
|
+
Opens the requested settings page.
|
|
85
|
+
|
|
86
|
+
Parameters:
|
|
87
|
+
- `options`: Either a string (setting name) or an object with:
|
|
88
|
+
- `setting`: The settings page to open
|
|
89
|
+
- `newTask`: (Android only) Whether to open in a new task
|
|
90
|
+
|
|
91
|
+
#### isAvailable(setting: string): Promise<boolean>
|
|
92
|
+
Checks if a specific settings page is available on the current device.
|
|
93
|
+
|
|
94
|
+
Parameters:
|
|
95
|
+
- `setting`: The settings page to check
|
|
96
|
+
|
|
97
|
+
### Supported Settings
|
|
98
|
+
|
|
99
|
+
#### Android
|
|
100
|
+
- 'wifi' - Wi‑Fi settings
|
|
101
|
+
- 'location' - Location settings
|
|
102
|
+
- 'bluetooth' - Bluetooth settings
|
|
103
|
+
- 'accessibility' - Accessibility settings
|
|
104
|
+
- 'add_account' - Add account settings
|
|
105
|
+
- 'airplane_mode' - Airplane mode settings
|
|
106
|
+
- 'apn' - APN settings
|
|
107
|
+
- 'application_details' - App details
|
|
108
|
+
- 'application_development' - Development settings
|
|
109
|
+
- 'application' - Application settings
|
|
110
|
+
- 'battery_optimization' - Battery optimization
|
|
111
|
+
- 'device_info' - Device info
|
|
112
|
+
- 'display' - Display settings
|
|
113
|
+
- 'keyboard' - Keyboard settings
|
|
114
|
+
- 'manage_all_applications' - All apps
|
|
115
|
+
- 'manage_applications' - App management
|
|
116
|
+
- 'memory_card' - Memory card
|
|
117
|
+
- 'network' - Network settings
|
|
118
|
+
- 'nfc' - NFC settings
|
|
119
|
+
- 'notification' - Notification settings
|
|
120
|
+
- 'security' - Security settings
|
|
121
|
+
- 'sound' - Sound settings
|
|
122
|
+
- 'sync' - Sync settings
|
|
123
|
+
- 'usage' - Usage settings
|
|
124
|
+
- 'user_dictionary' - User dictionary
|
|
125
|
+
- 'voice_input' - Voice input settings
|
|
126
|
+
- 'vpn' - VPN settings
|
|
127
|
+
|
|
128
|
+
#### iOS
|
|
129
|
+
- 'wifi' - Wi‑Fi settings
|
|
130
|
+
- 'bluetooth' - Bluetooth settings
|
|
131
|
+
- 'location' - Location settings
|
|
132
|
+
- 'settings' - App settings
|
|
133
|
+
- 'about' - About settings
|
|
134
|
+
- 'accessibility' - Accessibility settings
|
|
135
|
+
- 'account' - Account settings
|
|
136
|
+
- 'airplane_mode' - Airplane mode
|
|
137
|
+
- 'battery' - Battery settings
|
|
138
|
+
- 'browser' - Browser settings
|
|
139
|
+
- 'date' - Date settings
|
|
140
|
+
- 'facetime' - FaceTime settings
|
|
141
|
+
- 'keyboard' - Keyboard settings
|
|
142
|
+
- 'locale' - Language settings
|
|
143
|
+
- 'music' - Music settings
|
|
144
|
+
- 'notification' - Notification settings
|
|
145
|
+
- 'photos' - Photos settings
|
|
146
|
+
- 'profile' - Profile settings
|
|
147
|
+
- 'sounds' - Sound settings
|
|
148
|
+
- 'storage' - Storage settings
|
|
149
|
+
- 'wallpaper' - Wallpaper settings
|
|
150
|
+
|
|
151
|
+
**Note**: Some iOS URL schemes are unofficial and may not work on all iOS versions. The plugin will fall back to opening the app's settings page in such cases.
|
|
152
|
+
|
|
153
|
+
## Platform Specifics
|
|
154
|
+
- **Android**: Provides comprehensive access to system settings through Android's Settings API
|
|
155
|
+
- **iOS**: Uses URL schemes to deep-link into settings; some settings may fall back to the app settings page due to iOS restrictions
|
|
156
|
+
|
|
157
|
+
## Contributing
|
|
158
|
+
Contributions to the plugin are welcome! Please follow the standard fork and pull request workflow.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
This project is licensed under the MIT License.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
[community_plugins]: https://github.com/EYALIN?tab=repositories&q=community&type=&language=&sort=
|
|
165
|
+
|
|
166
|
+
Android (uses android.provider.Settings actions):
|
|
167
|
+
|
|
168
|
+
- accessibility, account, airplane_mode, apn, application_details, application_development, application
|
|
169
|
+
- battery_optimization, bluetooth, captioning, cast, data_roaming, date, display, dream
|
|
170
|
+
- keyboard, keyboard_subtype, storage, locale, location, manage_all_applications, manage_applications
|
|
171
|
+
- memory_card, network, nfcsharing, nfc_payment, nfc_settings, print, privacy, quick_launch
|
|
172
|
+
- search, security, settings, show_regulatory_info, sound, sync, usage, user_dictionary
|
|
173
|
+
- voice_input, wifi_ip, wifi, wireless
|
|
174
|
+
|
|
175
|
+
iOS (deep-links; availability varies by iOS version):
|
|
176
|
+
|
|
177
|
+
- about, accessibility, account, airplane_mode, autolock, battery, bluetooth, cellular, date
|
|
178
|
+
- facetime, keyboard, language, location, music, notifications (falls back to app settings), photos
|
|
179
|
+
- privacy, reset, ringtone, safari, sound, software_update, storage, vpn, wallpaper, wifi
|
|
180
|
+
|
|
181
|
+
Note: iOS deep-linking uses App-Prefs / UIApplicationOpenSettingsURLString fallbacks. Apple may restrict or change these schemes in new iOS releases.
|
|
182
|
+
|
|
183
|
+
## Contributing
|
|
184
|
+
|
|
185
|
+
Contributions are welcome. Please open issues or PRs against the repository.
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT
|
|
190
|
+
|
|
191
|
+
[community_plugins]: https://github.com/search?q=topic%3Acordova-plugin+org%3Aeyalin&type=Repositories
|
package/RELEASENOTES.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Release Notes
|
|
2
|
+
|
|
3
|
+
### 1.0.0 (Nov 07, 2025)
|
|
4
|
+
* Initial release as a community plugin
|
|
5
|
+
* Added Promise-based API
|
|
6
|
+
* Added TypeScript support
|
|
7
|
+
* Added isAvailable method
|
|
8
|
+
* Improved error handling
|
|
9
|
+
* Added comprehensive documentation
|
|
10
|
+
* Added support for opening settings in new task (Android)
|
|
11
|
+
* Modernized codebase and API design
|
|
12
|
+
* Added full type definitions
|
|
13
|
+
* Improved iOS compatibility
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
{
|
|
3
|
+
"name": "community-cordova-plugin-native-settings",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "A Cordova plugin to open native device settings screens",
|
|
6
|
+
"types": "./types/index.d.ts",
|
|
7
|
+
"cordova": {
|
|
8
|
+
"id": "community-cordova-plugin-native-settings",
|
|
9
|
+
"platforms": ["android", "ios"]
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/eyalin/community-cordova-plugin-native-settings.git"
|
|
14
|
+
},
|
|
15
|
+
"keywords": ["ecosystem:cordova","cordova-android","cordova-ios","settings","native-settings","preferences"],
|
|
16
|
+
"author": "EYALIN",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"bugs": { "url": "https://github.com/eyalin/community-cordova-plugin-native-settings/issues" },
|
|
19
|
+
"homepage": "https://github.com/eyalin/community-cordova-plugin-native-settings#readme",
|
|
20
|
+
"funding": { "type": "github", "url": "https://github.com/sponsors/eyalin" }
|
|
21
|
+
}
|
|
22
|
+
|
package/plugin.xml
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
3
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
id="community-cordova-plugin-native-settings"
|
|
5
|
+
version="1.0.0">
|
|
6
|
+
<name>Cordova Plugin Native Settings</name>
|
|
7
|
+
<description>A Cordova plugin to open native device settings screens</description>
|
|
8
|
+
<license>MIT</license>
|
|
9
|
+
<keywords>cordova,settings,native,preferences,options,android,ios</keywords>
|
|
10
|
+
<repo>https://github.com/eyalin/community-cordova-plugin-native-settings.git</repo>
|
|
11
|
+
<issue>https://github.com/eyalin/community-cordova-plugin-native-settings/issues</issue>
|
|
12
|
+
|
|
13
|
+
<engines>
|
|
14
|
+
<engine name="cordova" version=">=4.0.0" />
|
|
15
|
+
</engines>
|
|
16
|
+
|
|
17
|
+
<js-module src="www/settings.js" name="SettingsPlugin">
|
|
18
|
+
<clobbers target="SettingsPlugin" />
|
|
19
|
+
</js-module>
|
|
20
|
+
|
|
21
|
+
<!-- android -->
|
|
22
|
+
<platform name="android">
|
|
23
|
+
<config-file target="res/xml/config.xml" parent="/*">
|
|
24
|
+
<feature name="NativeSettings">
|
|
25
|
+
<param name="android-package" value="com.ionicframework.plugins.nativesettings.NativeSettings" />
|
|
26
|
+
</feature>
|
|
27
|
+
</config-file>
|
|
28
|
+
<source-file src="src/android/NativeSettings.java" target-dir="src/com/ionicframework/plugins/nativesettings" />
|
|
29
|
+
</platform>
|
|
30
|
+
|
|
31
|
+
<!-- ios -->
|
|
32
|
+
<platform name="ios">
|
|
33
|
+
<config-file target="config.xml" parent="/*">
|
|
34
|
+
<feature name="NativeSettings">
|
|
35
|
+
<param name="ios-package" value="NativeSettings" />
|
|
36
|
+
</feature>
|
|
37
|
+
</config-file>
|
|
38
|
+
|
|
39
|
+
<!-- Add App-Prefs to LSApplicationQueriesSchemes -->
|
|
40
|
+
<config-file target="*-Info.plist" parent="LSApplicationQueriesSchemes">
|
|
41
|
+
<array>
|
|
42
|
+
<string>App-Prefs</string>
|
|
43
|
+
</array>
|
|
44
|
+
</config-file>
|
|
45
|
+
<header-file src="src/ios/NativeSettings.h" />
|
|
46
|
+
<source-file src="src/ios/NativeSettings.m" />
|
|
47
|
+
</platform>
|
|
48
|
+
</plugin>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
3
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
id="community-cordova-plugin-native-settings"
|
|
5
|
+
version="1.0.0">
|
|
6
|
+
<name>Cordova Plugin Native Settings</name>
|
|
7
|
+
<description>A Cordova plugin to open native device settings screens</description>
|
|
8
|
+
<license>MIT</license>
|
|
9
|
+
<keywords>cordova,settings,native,preferences,options,android,ios</keywords>
|
|
10
|
+
<repo>https://github.com/eyalin/community-cordova-plugin-native-settings.git</repo>
|
|
11
|
+
<issue>https://github.com/eyalin/community-cordova-plugin-native-settings/issues</issue>
|
|
12
|
+
|
|
13
|
+
<engines>
|
|
14
|
+
<engine name="cordova" version=">=4.0.0" />
|
|
15
|
+
</engines>
|
|
16
|
+
|
|
17
|
+
<js-module src="www/settings.js" name="SettingsPlugin">
|
|
18
|
+
<clobbers target="cordova.plugins.settings" />
|
|
19
|
+
<clobbers target="NativeSettings" />
|
|
20
|
+
</js-module>
|
|
21
|
+
|
|
22
|
+
<!-- android -->
|
|
23
|
+
<platform name="android">
|
|
24
|
+
<config-file target="res/xml/config.xml" parent="/*">
|
|
25
|
+
<feature name="NativeSettings">
|
|
26
|
+
<param name="android-package" value="com.ionicframework.plugins.nativesettings.NativeSettings" />
|
|
27
|
+
</feature>
|
|
28
|
+
</config-file>
|
|
29
|
+
<source-file src="src/android/NativeSettings.java" target-dir="src/com/ionicframework/plugins/nativesettings" />
|
|
30
|
+
</platform>
|
|
31
|
+
|
|
32
|
+
<!-- ios -->
|
|
33
|
+
<platform name="ios">
|
|
34
|
+
<config-file target="config.xml" parent="/*">
|
|
35
|
+
<feature name="NativeSettings">
|
|
36
|
+
<param name="ios-package" value="NativeSettings" />
|
|
37
|
+
</feature>
|
|
38
|
+
</config-file>
|
|
39
|
+
<header-file src="src/ios/NativeSettings.h" />
|
|
40
|
+
<source-file src="src/ios/NativeSettings.m" />
|
|
41
|
+
</platform>
|
|
42
|
+
</plugin>
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
package com.ionicframework.plugins.nativesettings;
|
|
2
|
+
|
|
3
|
+
import org.apache.cordova.CallbackContext;
|
|
4
|
+
import org.apache.cordova.CordovaPlugin;
|
|
5
|
+
import org.apache.cordova.PluginResult;
|
|
6
|
+
import org.json.JSONArray;
|
|
7
|
+
import org.json.JSONException;
|
|
8
|
+
|
|
9
|
+
import android.content.Intent;
|
|
10
|
+
import android.content.Context;
|
|
11
|
+
import android.net.Uri;
|
|
12
|
+
import android.os.Build;
|
|
13
|
+
import android.provider.Settings;
|
|
14
|
+
import java.util.HashMap;
|
|
15
|
+
import java.util.Map;
|
|
16
|
+
|
|
17
|
+
public class NativeSettings extends CordovaPlugin {
|
|
18
|
+
private static final Map<String, String> settingsMap = new HashMap<>();
|
|
19
|
+
|
|
20
|
+
static {
|
|
21
|
+
// Initialize settings map
|
|
22
|
+
settingsMap.put("accessibility", Settings.ACTION_ACCESSIBILITY_SETTINGS);
|
|
23
|
+
settingsMap.put("account", Settings.ACTION_ADD_ACCOUNT);
|
|
24
|
+
settingsMap.put("airplane_mode", Settings.ACTION_AIRPLANE_MODE_SETTINGS);
|
|
25
|
+
settingsMap.put("apn", Settings.ACTION_APN_SETTINGS);
|
|
26
|
+
settingsMap.put("application_details", Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
|
27
|
+
settingsMap.put("application_development", Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
|
28
|
+
settingsMap.put("application", Settings.ACTION_APPLICATION_SETTINGS);
|
|
29
|
+
settingsMap.put("bluetooth", Settings.ACTION_BLUETOOTH_SETTINGS);
|
|
30
|
+
// Android settings map - expanded
|
|
31
|
+
settingsMap.put("battery_optimization", Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
|
|
32
|
+
settingsMap.put("captioning", Settings.ACTION_CAPTIONING_SETTINGS);
|
|
33
|
+
settingsMap.put("cast", Settings.ACTION_CAST_SETTINGS);
|
|
34
|
+
settingsMap.put("data_roaming", Settings.ACTION_DATA_ROAMING_SETTINGS);
|
|
35
|
+
settingsMap.put("date", Settings.ACTION_DATE_SETTINGS);
|
|
36
|
+
settingsMap.put("about", Settings.ACTION_DEVICE_INFO_SETTINGS);
|
|
37
|
+
settingsMap.put("display", Settings.ACTION_DISPLAY_SETTINGS);
|
|
38
|
+
settingsMap.put("dream", Settings.ACTION_DREAM_SETTINGS);
|
|
39
|
+
settingsMap.put("home", Settings.ACTION_HOME_SETTINGS);
|
|
40
|
+
settingsMap.put("keyboard", Settings.ACTION_INPUT_METHOD_SETTINGS);
|
|
41
|
+
settingsMap.put("keyboard_subtype", Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
|
|
42
|
+
settingsMap.put("storage", Settings.ACTION_INTERNAL_STORAGE_SETTINGS);
|
|
43
|
+
settingsMap.put("locale", Settings.ACTION_LOCALE_SETTINGS);
|
|
44
|
+
settingsMap.put("location", Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
|
45
|
+
settingsMap.put("manage_all_applications", Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS);
|
|
46
|
+
settingsMap.put("manage_applications", Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
|
|
47
|
+
settingsMap.put("memory_card", Settings.ACTION_MEMORY_CARD_SETTINGS);
|
|
48
|
+
settingsMap.put("network", Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
|
|
49
|
+
settingsMap.put("nfcsharing", Settings.ACTION_NFCSHARING_SETTINGS);
|
|
50
|
+
settingsMap.put("nfc_payment", Settings.ACTION_NFC_PAYMENT_SETTINGS);
|
|
51
|
+
settingsMap.put("nfc_settings", Settings.ACTION_NFC_SETTINGS);
|
|
52
|
+
settingsMap.put("print", Settings.ACTION_PRINT_SETTINGS);
|
|
53
|
+
settingsMap.put("privacy", Settings.ACTION_PRIVACY_SETTINGS);
|
|
54
|
+
settingsMap.put("quick_launch", Settings.ACTION_QUICK_LAUNCH_SETTINGS);
|
|
55
|
+
settingsMap.put("search", Settings.ACTION_SEARCH_SETTINGS);
|
|
56
|
+
settingsMap.put("security", Settings.ACTION_SECURITY_SETTINGS);
|
|
57
|
+
settingsMap.put("settings", Settings.ACTION_SETTINGS);
|
|
58
|
+
settingsMap.put("show_regulatory_info", Settings.ACTION_SHOW_REGULATORY_INFO);
|
|
59
|
+
settingsMap.put("sound", Settings.ACTION_SOUND_SETTINGS);
|
|
60
|
+
settingsMap.put("sync", Settings.ACTION_SYNC_SETTINGS);
|
|
61
|
+
settingsMap.put("usage", Settings.ACTION_USAGE_ACCESS_SETTINGS);
|
|
62
|
+
settingsMap.put("user_dictionary", Settings.ACTION_USER_DICTIONARY_SETTINGS);
|
|
63
|
+
settingsMap.put("voice_input", Settings.ACTION_VOICE_INPUT_SETTINGS);
|
|
64
|
+
settingsMap.put("wifi_ip", Settings.ACTION_WIFI_IP_SETTINGS);
|
|
65
|
+
settingsMap.put("wifi", Settings.ACTION_WIFI_SETTINGS);
|
|
66
|
+
settingsMap.put("wireless", Settings.ACTION_WIRELESS_SETTINGS);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Override
|
|
70
|
+
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
71
|
+
if (action.equals("open")) {
|
|
72
|
+
return openSettings(args, callbackContext);
|
|
73
|
+
} else if (action.equals("isAvailable")) {
|
|
74
|
+
return checkAvailability(args, callbackContext);
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private boolean openSettings(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
80
|
+
if (args == null || args.length() == 0) {
|
|
81
|
+
callbackContext.error("Setting name is required");
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
String settingName = args.getString(0);
|
|
86
|
+
boolean newTask = args.length() > 1 && args.getBoolean(1);
|
|
87
|
+
|
|
88
|
+
Intent intent = getSettingsIntent(settingName);
|
|
89
|
+
if (intent == null) {
|
|
90
|
+
callbackContext.error("Invalid setting: " + settingName);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
if (newTask) {
|
|
96
|
+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
97
|
+
}
|
|
98
|
+
this.cordova.getActivity().startActivity(intent);
|
|
99
|
+
callbackContext.success();
|
|
100
|
+
return true;
|
|
101
|
+
} catch (Exception e) {
|
|
102
|
+
callbackContext.error("Failed to open settings: " + e.getMessage());
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private boolean checkAvailability(JSONArray args, CallbackContext callbackContext) throws JSONException {
|
|
108
|
+
if (args == null || args.length() == 0) {
|
|
109
|
+
callbackContext.error("Setting name is required");
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
String settingName = args.getString(0);
|
|
114
|
+
Intent intent = getSettingsIntent(settingName);
|
|
115
|
+
|
|
116
|
+
callbackContext.success(intent != null ? 1 : 0);
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private Intent getSettingsIntent(String setting) {
|
|
121
|
+
Context context = this.cordova.getActivity().getApplicationContext();
|
|
122
|
+
Uri packageUri = Uri.parse("package:" + context.getPackageName());
|
|
123
|
+
|
|
124
|
+
String action = settingsMap.get(setting);
|
|
125
|
+
if (action != null) {
|
|
126
|
+
if (action.equals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)) {
|
|
127
|
+
return new Intent(action, packageUri);
|
|
128
|
+
}
|
|
129
|
+
return new Intent(action);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Special cases
|
|
133
|
+
switch (setting) {
|
|
134
|
+
case "notification_id":
|
|
135
|
+
return getNotificationSettingsIntent(context);
|
|
136
|
+
case "store":
|
|
137
|
+
return new Intent(Intent.ACTION_VIEW,
|
|
138
|
+
Uri.parse("market://details?id=" + context.getPackageName()));
|
|
139
|
+
// Add more special cases...
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private Intent getNotificationSettingsIntent(Context context) {
|
|
146
|
+
Intent intent = new Intent();
|
|
147
|
+
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
|
|
148
|
+
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
|
|
149
|
+
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
|
|
150
|
+
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
151
|
+
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
|
|
152
|
+
intent.putExtra("app_package", context.getPackageName());
|
|
153
|
+
intent.putExtra("app_uid", context.getApplicationInfo().uid);
|
|
154
|
+
} else {
|
|
155
|
+
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
|
156
|
+
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
|
157
|
+
intent.setData(Uri.parse("package:" + context.getPackageName()));
|
|
158
|
+
}
|
|
159
|
+
return intent;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#import "NativeSettings.h"
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
|
|
4
|
+
@implementation NativeSettings
|
|
5
|
+
|
|
6
|
+
- (void)open:(CDVInvokedUrlCommand*)command {
|
|
7
|
+
CDVPluginResult* pluginResult = nil;
|
|
8
|
+
NSString* setting = [command.arguments objectAtIndex:0];
|
|
9
|
+
|
|
10
|
+
if (!setting) {
|
|
11
|
+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Setting name is required"];
|
|
12
|
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
NSURL* url = [self getSettingsURL:setting];
|
|
17
|
+
if (!url) {
|
|
18
|
+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Invalid setting"];
|
|
19
|
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
NSString* urlString = [url absoluteString];
|
|
23
|
+
NSLog(@"NativeSettings: attempting to open settings URL: %@", urlString);
|
|
24
|
+
|
|
25
|
+
if (@available(iOS 10.0, *)) {
|
|
26
|
+
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
|
|
27
|
+
CDVPluginResult* result = nil;
|
|
28
|
+
if (success) {
|
|
29
|
+
// Return the actual URL that was opened for debugging
|
|
30
|
+
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:urlString];
|
|
31
|
+
} else {
|
|
32
|
+
NSString* msg = [NSString stringWithFormat:@"Failed to open settings: %@", urlString];
|
|
33
|
+
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:msg];
|
|
34
|
+
}
|
|
35
|
+
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
|
|
36
|
+
}];
|
|
37
|
+
} else {
|
|
38
|
+
BOOL success = [[UIApplication sharedApplication] openURL:url];
|
|
39
|
+
if (success) {
|
|
40
|
+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:urlString];
|
|
41
|
+
} else {
|
|
42
|
+
NSString* msg = [NSString stringWithFormat:@"Failed to open settings: %@", urlString];
|
|
43
|
+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:msg];
|
|
44
|
+
}
|
|
45
|
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
- (void)isAvailable:(CDVInvokedUrlCommand*)command {
|
|
50
|
+
NSString* setting = [command.arguments objectAtIndex:0];
|
|
51
|
+
BOOL isAvailable = NO;
|
|
52
|
+
|
|
53
|
+
if (setting) {
|
|
54
|
+
NSURL* url = [self getSettingsURL:setting];
|
|
55
|
+
if (url) {
|
|
56
|
+
if (@available(iOS 10.0, *)) {
|
|
57
|
+
isAvailable = [[UIApplication sharedApplication] canOpenURL:url];
|
|
58
|
+
} else {
|
|
59
|
+
isAvailable = YES; // Assume available on older iOS versions
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:isAvailable];
|
|
65
|
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
- (NSURL*)getSettingsURL:(NSString*)setting {
|
|
69
|
+
// iOS settings mappings (App-Prefs:root=...) - many of these URL schemes are unofficial
|
|
70
|
+
// and may not work on all iOS versions. We fall back to UIApplicationOpenSettingsURLString
|
|
71
|
+
// (app-specific settings) where appropriate.
|
|
72
|
+
// Helper to prefer App-Prefs URLs when the system allows them, otherwise fallback
|
|
73
|
+
// to the official UIApplicationOpenSettingsURLString which opens the app's settings.
|
|
74
|
+
NSURL* (^prefURLIfAvailable)(NSString*) = ^NSURL*(NSString* urlString) {
|
|
75
|
+
// On iOS 13+, try to use the official Settings URLs first
|
|
76
|
+
if (@available(iOS 13.0, *)) {
|
|
77
|
+
// There's no public UIApplication method `settingsURLString:` — construct the URL
|
|
78
|
+
// from the provided App-Prefs string and verify it can be opened when possible.
|
|
79
|
+
NSURL* url = [NSURL URLWithString:urlString];
|
|
80
|
+
if (@available(iOS 10.0, *)) {
|
|
81
|
+
if (![[UIApplication sharedApplication] canOpenURL:url]) {
|
|
82
|
+
return nil;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return url;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// On older iOS, try App-Prefs scheme
|
|
89
|
+
NSURL* url = [NSURL URLWithString:urlString];
|
|
90
|
+
if (@available(iOS 10.0, *)) {
|
|
91
|
+
// If we can't open App-Prefs URL, return nil to show "not available"
|
|
92
|
+
// instead of falling back to app settings
|
|
93
|
+
if (![[UIApplication sharedApplication] canOpenURL:url]) {
|
|
94
|
+
return nil;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return url;
|
|
98
|
+
};
|
|
99
|
+
if ([setting isEqualToString:@"about"]) {
|
|
100
|
+
return [NSURL URLWithString:UIApplicationOpenSettingsURLString];
|
|
101
|
+
}
|
|
102
|
+
else if ([setting isEqualToString:@"accessibility"]) {
|
|
103
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=ACCESSIBILITY");
|
|
104
|
+
}
|
|
105
|
+
else if ([setting isEqualToString:@"account"]) {
|
|
106
|
+
return prefURLIfAvailable(@"App-Prefs:root=ACCOUNT_SETTINGS");
|
|
107
|
+
}
|
|
108
|
+
else if ([setting isEqualToString:@"airplane_mode"]) {
|
|
109
|
+
return prefURLIfAvailable(@"App-Prefs:root=AIRPLANE_MODE");
|
|
110
|
+
}
|
|
111
|
+
else if ([setting isEqualToString:@"autolock"]) {
|
|
112
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=AUTOLOCK");
|
|
113
|
+
}
|
|
114
|
+
else if ([setting isEqualToString:@"battery"]) {
|
|
115
|
+
return prefURLIfAvailable(@"App-Prefs:root=BATTERY_USAGE");
|
|
116
|
+
}
|
|
117
|
+
else if ([setting isEqualToString:@"bluetooth"]) {
|
|
118
|
+
return prefURLIfAvailable(@"App-Prefs:root=Bluetooth");
|
|
119
|
+
}
|
|
120
|
+
else if ([setting isEqualToString:@"browser"]) {
|
|
121
|
+
return prefURLIfAvailable(@"App-Prefs:root=Safari");
|
|
122
|
+
}
|
|
123
|
+
else if ([setting isEqualToString:@"cellular"] || [setting isEqualToString:@"cellular_usage"]) {
|
|
124
|
+
return prefURLIfAvailable(@"App-Prefs:root=MOBILE_DATA_SETTINGS_ID");
|
|
125
|
+
}
|
|
126
|
+
else if ([setting isEqualToString:@"date"]) {
|
|
127
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=DATE_AND_TIME");
|
|
128
|
+
}
|
|
129
|
+
else if ([setting isEqualToString:@"facetime"]) {
|
|
130
|
+
return prefURLIfAvailable(@"App-Prefs:root=FACETIME");
|
|
131
|
+
}
|
|
132
|
+
else if ([setting isEqualToString:@"keyboard"]) {
|
|
133
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=Keyboard");
|
|
134
|
+
}
|
|
135
|
+
else if ([setting isEqualToString:@"language"]) {
|
|
136
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=LANGUAGE_AND_REGION");
|
|
137
|
+
}
|
|
138
|
+
else if ([setting isEqualToString:@"location"]) {
|
|
139
|
+
return prefURLIfAvailable(@"App-Prefs:root=Privacy&path=LOCATION");
|
|
140
|
+
}
|
|
141
|
+
else if ([setting isEqualToString:@"music"]) {
|
|
142
|
+
return prefURLIfAvailable(@"App-Prefs:root=Music");
|
|
143
|
+
}
|
|
144
|
+
else if ([setting isEqualToString:@"network"]) {
|
|
145
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=Network");
|
|
146
|
+
}
|
|
147
|
+
else if ([setting isEqualToString:@"notification_id"] || [setting isEqualToString:@"notifications"]) {
|
|
148
|
+
// iOS provides app-specific notification settings via the app settings page
|
|
149
|
+
return [NSURL URLWithString:UIApplicationOpenSettingsURLString];
|
|
150
|
+
}
|
|
151
|
+
else if ([setting isEqualToString:@"phone"]) {
|
|
152
|
+
return prefURLIfAvailable(@"App-Prefs:root=Phone");
|
|
153
|
+
}
|
|
154
|
+
else if ([setting isEqualToString:@"photos"]) {
|
|
155
|
+
return prefURLIfAvailable(@"App-Prefs:root=Photos");
|
|
156
|
+
}
|
|
157
|
+
else if ([setting isEqualToString:@"privacy"]) {
|
|
158
|
+
return prefURLIfAvailable(@"App-Prefs:root=Privacy");
|
|
159
|
+
}
|
|
160
|
+
else if ([setting isEqualToString:@"reset"]) {
|
|
161
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=Reset");
|
|
162
|
+
}
|
|
163
|
+
else if ([setting isEqualToString:@"ringtone"]) {
|
|
164
|
+
return prefURLIfAvailable(@"App-Prefs:root=Sounds&path=Ringtone");
|
|
165
|
+
}
|
|
166
|
+
else if ([setting isEqualToString:@"root"]) {
|
|
167
|
+
return prefURLIfAvailable(@"App-Prefs:root");
|
|
168
|
+
}
|
|
169
|
+
else if ([setting isEqualToString:@"safari"]) {
|
|
170
|
+
return prefURLIfAvailable(@"App-Prefs:root=Safari");
|
|
171
|
+
}
|
|
172
|
+
else if ([setting isEqualToString:@"sound"]) {
|
|
173
|
+
return prefURLIfAvailable(@"App-Prefs:root=Sounds");
|
|
174
|
+
}
|
|
175
|
+
else if ([setting isEqualToString:@"software_update"]) {
|
|
176
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=SOFTWARE_UPDATE_LINK");
|
|
177
|
+
}
|
|
178
|
+
else if ([setting isEqualToString:@"storage"]) {
|
|
179
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=STORAGE");
|
|
180
|
+
}
|
|
181
|
+
else if ([setting isEqualToString:@"vpn"]) {
|
|
182
|
+
return prefURLIfAvailable(@"App-Prefs:root=General&path=VPN");
|
|
183
|
+
}
|
|
184
|
+
else if ([setting isEqualToString:@"wallpaper"]) {
|
|
185
|
+
return prefURLIfAvailable(@"App-Prefs:root=Wallpaper");
|
|
186
|
+
}
|
|
187
|
+
else if ([setting isEqualToString:@"wifi"]) {
|
|
188
|
+
return prefURLIfAvailable(@"App-Prefs:root=WIFI");
|
|
189
|
+
}
|
|
190
|
+
else if ([setting isEqualToString:@"store"]) {
|
|
191
|
+
// App Store cannot be opened to app-specific settings via App-Prefs; open app settings instead
|
|
192
|
+
return [NSURL URLWithString:UIApplicationOpenSettingsURLString];
|
|
193
|
+
}
|
|
194
|
+
// If nothing matches, return nil to indicate not supported
|
|
195
|
+
|
|
196
|
+
return nil;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@end
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface INativeSettingsOptions {
|
|
2
|
+
setting: string;
|
|
3
|
+
/**
|
|
4
|
+
* On Android, open the settings screen in a new task (so it appears as a separate app in Recents)
|
|
5
|
+
*/
|
|
6
|
+
newTask?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class SettingsManager {
|
|
10
|
+
/**
|
|
11
|
+
* Open device settings screen
|
|
12
|
+
* @param options Settings options or setting string
|
|
13
|
+
*/
|
|
14
|
+
open(options: INativeSettingsOptions | string): Promise<void>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check if specific settings page is available
|
|
18
|
+
* @param setting The settings page to check
|
|
19
|
+
*/
|
|
20
|
+
isAvailable(setting: string): Promise<boolean>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// For global access
|
|
24
|
+
declare global {
|
|
25
|
+
const SettingsPlugin: SettingsManager;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// For TypeScript/Angular imports
|
|
29
|
+
declare module 'community-cordova-plugin-native-settings' {
|
|
30
|
+
export { SettingsManager, INativeSettingsOptions };
|
|
31
|
+
export default SettingsPlugin;
|
|
32
|
+
}
|
package/www/settings.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
var exec = require('cordova/exec');
|
|
2
|
+
|
|
3
|
+
class SettingsManager {
|
|
4
|
+
open(options) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
const setting = typeof options === 'string' ? options : options.setting;
|
|
7
|
+
const newTask = typeof options === 'object' ? !!options.newTask : false;
|
|
8
|
+
|
|
9
|
+
exec(function() {
|
|
10
|
+
resolve();
|
|
11
|
+
}, function(error) {
|
|
12
|
+
reject(error);
|
|
13
|
+
}, "NativeSettings", "open", [setting, newTask]);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
isAvailable(setting) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
exec(function(result) {
|
|
20
|
+
resolve(!!result);
|
|
21
|
+
}, function(error) {
|
|
22
|
+
reject(error);
|
|
23
|
+
}, "NativeSettings", "isAvailable", [setting]);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Create and export a singleton instance as SettingsPlugin
|
|
29
|
+
module.exports = new SettingsManager();
|