@simplysm/capacitor-plugin-intent 12.16.52 → 14.0.4
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/README.md +69 -139
- package/android/build.gradle +1 -0
- package/android/src/main/kotlin/kr/co/simplysm/capacitor/intent/IntentPlugin.kt +365 -0
- package/dist/Intent.d.ts +29 -18
- package/dist/Intent.d.ts.map +1 -0
- package/dist/Intent.js +41 -22
- package/dist/Intent.js.map +1 -0
- package/dist/IntentPlugin.d.ts +72 -0
- package/dist/IntentPlugin.d.ts.map +1 -0
- package/dist/IntentPlugin.js +2 -0
- package/dist/IntentPlugin.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -0
- package/dist/web/IntentWeb.d.ts +7 -5
- package/dist/web/IntentWeb.d.ts.map +1 -0
- package/dist/web/IntentWeb.js +17 -13
- package/dist/web/IntentWeb.js.map +1 -0
- package/package.json +15 -10
- package/src/Intent.ts +56 -25
- package/src/IntentPlugin.ts +81 -0
- package/src/index.ts +2 -1
- package/src/web/IntentWeb.ts +27 -16
- package/android/src/main/java/kr/co/simplysm/capacitor/intent/IntentPlugin.java +0 -376
- package/dist/IIntentPlugin.d.ts +0 -63
- package/dist/IIntentPlugin.js +0 -1
- package/src/IIntentPlugin.ts +0 -65
- package/tests/slice1-directory-and-config.spec.ts +0 -50
- package/tests/slice2-java-renaming.spec.ts +0 -34
- package/tests/slice3-typescript-renaming.spec.ts +0 -76
- package/tests/slice4-docs-and-deprecation.spec.ts +0 -31
- package/tests/slice5-start-activity-for-result-android.spec.md +0 -98
- package/tests/slice5-start-activity-for-result-types.spec.ts +0 -40
- package/tests/slice6-start-activity-for-result-web.spec.ts +0 -34
- package/tsconfig.json +0 -8
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @simplysm/capacitor-plugin-intent
|
|
2
2
|
|
|
3
|
-
Capacitor Intent
|
|
3
|
+
Capacitor Intent plugin for Android broadcast communication and activity results.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -8,196 +8,126 @@ Capacitor Intent Plugin -- Android intent send/receive for industrial devices (b
|
|
|
8
8
|
npm install @simplysm/capacitor-plugin-intent
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
**Peer dependencies:**
|
|
12
|
-
|
|
13
|
-
- `@capacitor/core` ^7.4.4
|
|
14
|
-
|
|
15
11
|
## API Overview
|
|
16
12
|
|
|
13
|
+
### Intent
|
|
14
|
+
|
|
17
15
|
| API | Type | Description |
|
|
18
16
|
|-----|------|-------------|
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
17
|
+
| `IntentResult` | Interface | Data received from a broadcast or launch intent |
|
|
18
|
+
| `StartActivityForResultOptions` | Interface | Options for starting an Android activity and awaiting its result |
|
|
19
|
+
| `StartActivityForResultResult` | Interface | Result returned from a started activity |
|
|
20
|
+
| `IntentPlugin` | Interface | Native plugin interface for intent operations |
|
|
21
|
+
| `Intent` | Class | Static API for broadcast send/receive, launch intents, and activity results |
|
|
24
22
|
|
|
25
|
-
##
|
|
23
|
+
## Interfaces
|
|
26
24
|
|
|
27
|
-
###
|
|
25
|
+
### IntentResult
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
export interface IIntentResult {
|
|
33
|
-
/** Intent action */
|
|
34
|
-
action?: string;
|
|
35
|
-
/** Extra data */
|
|
36
|
-
extras?: Record<string, unknown>;
|
|
37
|
-
}
|
|
38
|
-
```
|
|
27
|
+
Data received from a broadcast or launch intent.
|
|
39
28
|
|
|
40
29
|
| Field | Type | Description |
|
|
41
30
|
|-------|------|-------------|
|
|
42
|
-
| `action` | `string \| undefined` | The intent action string |
|
|
43
|
-
| `extras` | `Record<string, unknown> \| undefined` |
|
|
44
|
-
|
|
45
|
-
###
|
|
46
|
-
|
|
47
|
-
Options for
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
export interface IStartActivityForResultOptions {
|
|
51
|
-
/** Intent action */
|
|
52
|
-
action: string;
|
|
53
|
-
/** Data URI */
|
|
54
|
-
uri?: string;
|
|
55
|
-
/** Extra data */
|
|
56
|
-
extras?: Record<string, unknown>;
|
|
57
|
-
/** Target package name */
|
|
58
|
-
package?: string;
|
|
59
|
-
/** Target component class name */
|
|
60
|
-
component?: string;
|
|
61
|
-
/** MIME type */
|
|
62
|
-
type?: string;
|
|
63
|
-
}
|
|
64
|
-
```
|
|
31
|
+
| `action` | `string \| undefined` | The intent action string (e.g. `"com.example.SCAN_RESULT"`) |
|
|
32
|
+
| `extras` | `Record<string, unknown> \| undefined` | Key-value map of intent extras |
|
|
33
|
+
|
|
34
|
+
### StartActivityForResultOptions
|
|
35
|
+
|
|
36
|
+
Options for launching an Android activity and awaiting its result.
|
|
65
37
|
|
|
66
38
|
| Field | Type | Description |
|
|
67
39
|
|-------|------|-------------|
|
|
68
|
-
| `action` | `string` | Intent action (
|
|
69
|
-
| `uri` | `string \| undefined` | Data URI |
|
|
70
|
-
| `extras` | `Record<string, unknown> \| undefined` | Extra
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
export interface IActivityResult {
|
|
81
|
-
/** Activity result code (RESULT_OK = -1, RESULT_CANCELED = 0) */
|
|
82
|
-
resultCode: number;
|
|
83
|
-
/** Result data URI */
|
|
84
|
-
data?: string;
|
|
85
|
-
/** Result extras */
|
|
86
|
-
extras?: Record<string, unknown>;
|
|
87
|
-
}
|
|
88
|
-
```
|
|
40
|
+
| `action` | `string \| undefined` | Intent action (e.g. `"android.intent.action.VIEW"`) |
|
|
41
|
+
| `uri` | `string \| undefined` | Data URI to pass to the intent |
|
|
42
|
+
| `extras` | `Record<string, unknown> \| undefined` | Extra key-value pairs to include |
|
|
43
|
+
| `type` | `string \| undefined` | MIME type (e.g. `"image/*"`) |
|
|
44
|
+
| `packageName` | `string \| undefined` | Target package name for an explicit intent |
|
|
45
|
+
| `className` | `string \| undefined` | Target class name for an explicit intent |
|
|
46
|
+
| `flags` | `number \| undefined` | Intent flags bitmask |
|
|
47
|
+
|
|
48
|
+
### StartActivityForResultResult
|
|
49
|
+
|
|
50
|
+
Result returned when a launched activity finishes.
|
|
89
51
|
|
|
90
52
|
| Field | Type | Description |
|
|
91
53
|
|-------|------|-------------|
|
|
92
|
-
| `resultCode` | `number` |
|
|
93
|
-
| `data` | `string \| undefined` |
|
|
94
|
-
| `extras` | `Record<string, unknown> \| undefined` | Result extras |
|
|
95
|
-
|
|
96
|
-
### `IIntentPlugin`
|
|
97
|
-
|
|
98
|
-
Low-level Capacitor plugin interface. Use `Intent` instead for a simplified API.
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
export interface IIntentPlugin {
|
|
102
|
-
subscribe(
|
|
103
|
-
options: { filters: string[] },
|
|
104
|
-
callback: (result: IIntentResult) => void,
|
|
105
|
-
): Promise<{ id: string }>;
|
|
106
|
-
unsubscribe(options: { id: string }): Promise<void>;
|
|
107
|
-
unsubscribeAll(): Promise<void>;
|
|
108
|
-
send(options: { action: string; extras?: Record<string, unknown> }): Promise<void>;
|
|
109
|
-
getLaunchIntent(): Promise<IIntentResult>;
|
|
110
|
-
startActivityForResult(options: IStartActivityForResultOptions): Promise<IActivityResult>;
|
|
111
|
-
}
|
|
112
|
-
```
|
|
54
|
+
| `resultCode` | `number` | Android result code (`RESULT_OK = -1`, `RESULT_CANCELED = 0`) |
|
|
55
|
+
| `data` | `{ action?: string; uri?: string; extras?: Record<string, unknown> } \| undefined` | Optional data returned by the activity, including its action, URI, and extras |
|
|
113
56
|
|
|
114
|
-
|
|
115
|
-
|--------|------------|---------|-------------|
|
|
116
|
-
| `subscribe` | `options: { filters: string[] }, callback` | `Promise<{ id: string }>` | Register an intent receiver with action filters |
|
|
117
|
-
| `unsubscribe` | `options: { id: string }` | `Promise<void>` | Remove a specific intent receiver by ID |
|
|
118
|
-
| `unsubscribeAll` | -- | `Promise<void>` | Remove all intent receivers |
|
|
119
|
-
| `send` | `options: { action, extras? }` | `Promise<void>` | Send an intent with action and optional extras |
|
|
120
|
-
| `getLaunchIntent` | -- | `Promise<IIntentResult>` | Get the intent that launched the app |
|
|
121
|
-
| `startActivityForResult` | `options: IStartActivityForResultOptions` | `Promise<IActivityResult>` | Start an activity and receive its result |
|
|
57
|
+
### IntentPlugin
|
|
122
58
|
|
|
123
|
-
|
|
59
|
+
Native plugin interface for intent operations.
|
|
124
60
|
|
|
125
|
-
|
|
61
|
+
| Method | Signature | Description |
|
|
62
|
+
|--------|-----------|-------------|
|
|
63
|
+
| `subscribe` | `(options: { filters: string[] }, callback: (result: IntentResult) => void) => Promise<{ id: string }>` | Register a broadcast receiver for the given action filters |
|
|
64
|
+
| `unsubscribe` | `(options: { id: string }) => Promise<void>` | Unregister a broadcast receiver by subscription ID |
|
|
65
|
+
| `unsubscribeAll` | `() => Promise<void>` | Unregister all broadcast receivers |
|
|
66
|
+
| `send` | `(options: { action: string; extras?: Record<string, unknown> }) => Promise<void>` | Send a broadcast intent |
|
|
67
|
+
| `getLaunchIntent` | `() => Promise<IntentResult>` | Get the intent that launched the current activity |
|
|
68
|
+
| `addListener` | `(eventName: "newIntent", listenerFunc: (data: IntentResult) => void) => Promise<PluginListenerHandle>` | Listen for new intents delivered to the activity |
|
|
69
|
+
| `removeAllListeners` | `() => Promise<void>` | Remove all event listeners |
|
|
70
|
+
| `startActivityForResult` | `(options: StartActivityForResultOptions) => Promise<StartActivityForResultResult>` | Start an activity and await its result |
|
|
126
71
|
|
|
127
|
-
|
|
128
|
-
export abstract class Intent {
|
|
129
|
-
static async subscribe(
|
|
130
|
-
filters: string[],
|
|
131
|
-
callback: (result: IIntentResult) => void,
|
|
132
|
-
): Promise<() => Promise<void>>;
|
|
72
|
+
## Classes
|
|
133
73
|
|
|
134
|
-
|
|
74
|
+
### Intent
|
|
135
75
|
|
|
136
|
-
|
|
137
|
-
action: string;
|
|
138
|
-
extras?: Record<string, unknown>;
|
|
139
|
-
}): Promise<void>;
|
|
76
|
+
Android Intent plugin for broadcast send/receive and launch intent handling. Designed for industrial devices such as barcode scanners and PDAs.
|
|
140
77
|
|
|
141
|
-
|
|
78
|
+
All methods are static.
|
|
142
79
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
|
150
|
-
|
|
151
|
-
| `
|
|
152
|
-
| `unsubscribeAll` | -- | `Promise<void>` | Remove all registered intent receivers |
|
|
153
|
-
| `send` | `options: { action: string; extras?: Record<string, unknown> }` | `Promise<void>` | Send an intent with action and optional extras |
|
|
154
|
-
| `getLaunchIntent` | -- | `Promise<IIntentResult>` | Retrieve the intent that launched the application |
|
|
155
|
-
| `startActivityForResult` | `options: IStartActivityForResultOptions` | `Promise<IActivityResult>` | Start an activity and receive its result |
|
|
80
|
+
| Method | Signature | Description |
|
|
81
|
+
|--------|-----------|-------------|
|
|
82
|
+
| `subscribe` | `static async subscribe(filters: string[], callback: (result: IntentResult) => void): Promise<() => Promise<void>>` | Register a broadcast receiver for the given action filters. Returns an async unsubscribe function. |
|
|
83
|
+
| `unsubscribeAll` | `static async unsubscribeAll(): Promise<void>` | Unregister all active broadcast receivers |
|
|
84
|
+
| `send` | `static async send(options: { action: string; extras?: Record<string, unknown> }): Promise<void>` | Send a broadcast intent with the specified action and optional extras |
|
|
85
|
+
| `getLaunchIntent` | `static async getLaunchIntent(): Promise<IntentResult>` | Retrieve the intent that launched the current activity |
|
|
86
|
+
| `addListener` | `static async addListener(eventName: "newIntent", callback: (result: IntentResult) => void): Promise<PluginListenerHandle>` | Add a listener for new intents delivered to the activity via `onNewIntent` |
|
|
87
|
+
| `removeAllListeners` | `static async removeAllListeners(): Promise<void>` | Remove all registered event listeners |
|
|
88
|
+
| `startActivityForResult` | `static async startActivityForResult(options: StartActivityForResultOptions): Promise<StartActivityForResultResult>` | Start an Android activity and return its result when it finishes |
|
|
156
89
|
|
|
157
90
|
## Usage Examples
|
|
158
91
|
|
|
159
|
-
### Subscribe to
|
|
92
|
+
### Subscribe to barcode scanner broadcasts
|
|
160
93
|
|
|
161
|
-
```
|
|
94
|
+
```ts
|
|
162
95
|
import { Intent } from "@simplysm/capacitor-plugin-intent";
|
|
163
96
|
|
|
164
97
|
const unsubscribe = await Intent.subscribe(
|
|
165
|
-
["com.
|
|
98
|
+
["com.example.scanner.BARCODE_RESULT"],
|
|
166
99
|
(result) => {
|
|
167
|
-
|
|
168
|
-
|
|
100
|
+
const barcode = result.extras?.["barcode"] as string;
|
|
101
|
+
handleBarcode(barcode);
|
|
169
102
|
},
|
|
170
103
|
);
|
|
171
104
|
|
|
172
|
-
// Later,
|
|
105
|
+
// Later, stop listening
|
|
173
106
|
await unsubscribe();
|
|
174
107
|
```
|
|
175
108
|
|
|
176
|
-
### Send
|
|
109
|
+
### Send a broadcast
|
|
177
110
|
|
|
178
|
-
```
|
|
111
|
+
```ts
|
|
179
112
|
import { Intent } from "@simplysm/capacitor-plugin-intent";
|
|
180
113
|
|
|
181
114
|
await Intent.send({
|
|
182
|
-
action: "com.
|
|
183
|
-
extras: {
|
|
184
|
-
"com.symbol.datawedge.api.SOFT_SCAN_TRIGGER": "TOGGLE_SCANNING",
|
|
185
|
-
},
|
|
115
|
+
action: "com.example.ACTION_TRIGGER_SCAN",
|
|
116
|
+
extras: { mode: "continuous" },
|
|
186
117
|
});
|
|
187
118
|
```
|
|
188
119
|
|
|
189
120
|
### Start an activity for result
|
|
190
121
|
|
|
191
|
-
```
|
|
122
|
+
```ts
|
|
192
123
|
import { Intent } from "@simplysm/capacitor-plugin-intent";
|
|
193
124
|
|
|
194
125
|
const result = await Intent.startActivityForResult({
|
|
195
|
-
action: "android.intent.action.
|
|
126
|
+
action: "android.intent.action.PICK",
|
|
196
127
|
type: "image/*",
|
|
197
128
|
});
|
|
198
129
|
|
|
199
|
-
if (result.resultCode === -1) {
|
|
200
|
-
|
|
201
|
-
console.log("Selected:", result.data);
|
|
130
|
+
if (result.resultCode === -1 && result.data?.uri) {
|
|
131
|
+
loadImage(result.data.uri);
|
|
202
132
|
}
|
|
203
133
|
```
|
package/android/build.gradle
CHANGED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
package kr.co.simplysm.capacitor.intent
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver
|
|
4
|
+
import android.content.ComponentName
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import android.content.Intent
|
|
7
|
+
import android.content.IntentFilter
|
|
8
|
+
import android.net.Uri
|
|
9
|
+
import android.os.Build
|
|
10
|
+
import android.os.Bundle
|
|
11
|
+
import android.os.Parcelable
|
|
12
|
+
import android.util.Log
|
|
13
|
+
import androidx.activity.result.ActivityResult
|
|
14
|
+
import com.getcapacitor.JSArray
|
|
15
|
+
import com.getcapacitor.JSObject
|
|
16
|
+
import com.getcapacitor.Plugin
|
|
17
|
+
import com.getcapacitor.PluginCall
|
|
18
|
+
import com.getcapacitor.PluginMethod
|
|
19
|
+
import com.getcapacitor.annotation.ActivityCallback
|
|
20
|
+
import com.getcapacitor.annotation.CapacitorPlugin
|
|
21
|
+
import org.json.JSONArray
|
|
22
|
+
import org.json.JSONException
|
|
23
|
+
import org.json.JSONObject
|
|
24
|
+
import java.util.UUID
|
|
25
|
+
|
|
26
|
+
@CapacitorPlugin(name = "Intent")
|
|
27
|
+
class IntentPlugin : Plugin() {
|
|
28
|
+
|
|
29
|
+
companion object {
|
|
30
|
+
private const val TAG = "IntentPlugin"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private val receivers = mutableMapOf<String, BroadcastReceiver>()
|
|
34
|
+
|
|
35
|
+
override fun handleOnNewIntent(intent: Intent) {
|
|
36
|
+
super.handleOnNewIntent(intent)
|
|
37
|
+
notifyListeners("newIntent", intentToJson(intent))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@PluginMethod(returnType = PluginMethod.RETURN_CALLBACK)
|
|
41
|
+
fun subscribe(call: PluginCall) {
|
|
42
|
+
try {
|
|
43
|
+
val filters = call.getArray("filters")
|
|
44
|
+
|
|
45
|
+
if (filters == null || filters.length() == 0) {
|
|
46
|
+
call.reject("filters is required")
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
call.setKeepAlive(true)
|
|
51
|
+
|
|
52
|
+
val receiverId = UUID.randomUUID().toString()
|
|
53
|
+
|
|
54
|
+
val intentFilter = IntentFilter()
|
|
55
|
+
for (i in 0 until filters.length()) {
|
|
56
|
+
intentFilter.addAction(filters.getString(i))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
val receiver = object : BroadcastReceiver() {
|
|
60
|
+
override fun onReceive(context: Context, intent: Intent) {
|
|
61
|
+
val result = intentToJson(intent)
|
|
62
|
+
result.put("id", receiverId)
|
|
63
|
+
call.resolve(result)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
68
|
+
context.registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED)
|
|
69
|
+
} else {
|
|
70
|
+
context.registerReceiver(receiver, intentFilter)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
receivers[receiverId] = receiver
|
|
74
|
+
|
|
75
|
+
val ret = JSObject()
|
|
76
|
+
ret.put("id", receiverId)
|
|
77
|
+
call.resolve(ret)
|
|
78
|
+
} catch (e: Exception) {
|
|
79
|
+
Log.e(TAG, "subscribe failed", e)
|
|
80
|
+
call.reject("subscribe failed: " + e.message)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
@PluginMethod
|
|
85
|
+
fun unsubscribe(call: PluginCall) {
|
|
86
|
+
try {
|
|
87
|
+
val id = call.getString("id")
|
|
88
|
+
if (id == null) {
|
|
89
|
+
call.reject("id is required")
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
val receiver = receivers.remove(id)
|
|
94
|
+
if (receiver != null) {
|
|
95
|
+
context.unregisterReceiver(receiver)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
call.resolve()
|
|
99
|
+
} catch (e: Exception) {
|
|
100
|
+
Log.e(TAG, "unsubscribe failed", e)
|
|
101
|
+
call.reject("unsubscribe failed: " + e.message)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@PluginMethod
|
|
106
|
+
fun unsubscribeAll(call: PluginCall) {
|
|
107
|
+
try {
|
|
108
|
+
for (receiver in receivers.values) {
|
|
109
|
+
try {
|
|
110
|
+
context.unregisterReceiver(receiver)
|
|
111
|
+
} catch (ignored: Exception) {
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
receivers.clear()
|
|
115
|
+
call.resolve()
|
|
116
|
+
} catch (e: Exception) {
|
|
117
|
+
Log.e(TAG, "unsubscribeAll failed", e)
|
|
118
|
+
call.reject("unsubscribeAll failed: " + e.message)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@PluginMethod
|
|
123
|
+
fun send(call: PluginCall) {
|
|
124
|
+
try {
|
|
125
|
+
val action = call.getString("action")
|
|
126
|
+
if (action == null) {
|
|
127
|
+
call.reject("action is required")
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
val intent = Intent(action)
|
|
132
|
+
|
|
133
|
+
val extras = call.getObject("extras")
|
|
134
|
+
if (extras != null) {
|
|
135
|
+
populateExtras(intent, extras)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
context.sendBroadcast(intent)
|
|
139
|
+
call.resolve()
|
|
140
|
+
} catch (e: Exception) {
|
|
141
|
+
Log.e(TAG, "send failed", e)
|
|
142
|
+
call.reject("send failed: " + e.message)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@PluginMethod
|
|
147
|
+
fun getLaunchIntent(call: PluginCall) {
|
|
148
|
+
try {
|
|
149
|
+
val intent = activity.intent
|
|
150
|
+
call.resolve(intentToJson(intent))
|
|
151
|
+
} catch (e: Exception) {
|
|
152
|
+
Log.e(TAG, "getLaunchIntent failed", e)
|
|
153
|
+
call.reject("getLaunchIntent failed: " + e.message)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@PluginMethod
|
|
158
|
+
fun startActivityForResult(call: PluginCall) {
|
|
159
|
+
try {
|
|
160
|
+
val intent = buildIntent(call)
|
|
161
|
+
startActivityForResult(call, intent, "handleActivityResult")
|
|
162
|
+
} catch (e: Exception) {
|
|
163
|
+
Log.e(TAG, "startActivityForResult failed", e)
|
|
164
|
+
call.reject("startActivityForResult failed: " + e.message)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@ActivityCallback
|
|
169
|
+
private fun handleActivityResult(call: PluginCall?, result: ActivityResult) {
|
|
170
|
+
if (call == null) {
|
|
171
|
+
return
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
val json = JSObject()
|
|
175
|
+
json.put("resultCode", result.resultCode)
|
|
176
|
+
|
|
177
|
+
val data = result.data
|
|
178
|
+
if (data != null) {
|
|
179
|
+
val dataJson = JSObject()
|
|
180
|
+
if (data.action != null) {
|
|
181
|
+
dataJson.put("action", data.action)
|
|
182
|
+
}
|
|
183
|
+
if (data.data != null) {
|
|
184
|
+
dataJson.put("uri", data.data.toString())
|
|
185
|
+
}
|
|
186
|
+
val extras = data.extras
|
|
187
|
+
if (extras != null) {
|
|
188
|
+
dataJson.put("extras", bundleToJson(extras))
|
|
189
|
+
}
|
|
190
|
+
json.put("data", dataJson)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
call.resolve(json)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private fun buildIntent(call: PluginCall): Intent {
|
|
197
|
+
val intent = Intent()
|
|
198
|
+
|
|
199
|
+
val action = call.getString("action")
|
|
200
|
+
if (action != null) {
|
|
201
|
+
intent.action = action
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
val uri = call.getString("uri")
|
|
205
|
+
val type = call.getString("type")
|
|
206
|
+
when {
|
|
207
|
+
uri != null && type != null -> intent.setDataAndType(Uri.parse(uri), type)
|
|
208
|
+
uri != null -> intent.data = Uri.parse(uri)
|
|
209
|
+
type != null -> intent.type = type
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
val extras = call.getObject("extras")
|
|
213
|
+
if (extras != null) {
|
|
214
|
+
populateExtras(intent, extras)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
val packageName = call.getString("packageName")
|
|
218
|
+
val className = call.getString("className")
|
|
219
|
+
when {
|
|
220
|
+
packageName != null && className != null ->
|
|
221
|
+
intent.component = ComponentName(packageName, className)
|
|
222
|
+
packageName != null -> intent.setPackage(packageName)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
val flags = call.getInt("flags")
|
|
226
|
+
if (flags != null) {
|
|
227
|
+
intent.addFlags(flags)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return intent
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@Throws(JSONException::class)
|
|
234
|
+
private fun populateExtras(intent: Intent, extras: JSObject) {
|
|
235
|
+
val keys = extras.keys()
|
|
236
|
+
while (keys.hasNext()) {
|
|
237
|
+
val key = keys.next()
|
|
238
|
+
val value = extras.get(key)
|
|
239
|
+
|
|
240
|
+
when (value) {
|
|
241
|
+
is String -> intent.putExtra(key, value)
|
|
242
|
+
is Int -> intent.putExtra(key, value)
|
|
243
|
+
is Long -> intent.putExtra(key, value)
|
|
244
|
+
is Double -> intent.putExtra(key, value)
|
|
245
|
+
is Boolean -> intent.putExtra(key, value)
|
|
246
|
+
is JSONArray -> {
|
|
247
|
+
val strArr = Array(value.length()) { i -> value.getString(i) }
|
|
248
|
+
intent.putExtra(key, strArr)
|
|
249
|
+
}
|
|
250
|
+
is JSONObject -> {
|
|
251
|
+
val bundle = jsonToBundle(value)
|
|
252
|
+
intent.putExtra(key, bundle)
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
@Throws(JSONException::class)
|
|
259
|
+
private fun jsonToBundle(json: JSONObject): Bundle {
|
|
260
|
+
val bundle = Bundle()
|
|
261
|
+
val keys = json.keys()
|
|
262
|
+
while (keys.hasNext()) {
|
|
263
|
+
val key = keys.next()
|
|
264
|
+
val value = json.get(key)
|
|
265
|
+
|
|
266
|
+
when (value) {
|
|
267
|
+
is String -> bundle.putString(key, value)
|
|
268
|
+
is Int -> bundle.putInt(key, value)
|
|
269
|
+
is Long -> bundle.putLong(key, value)
|
|
270
|
+
is Double -> bundle.putDouble(key, value)
|
|
271
|
+
is Boolean -> bundle.putBoolean(key, value)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return bundle
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private fun intentToJson(intent: Intent?): JSObject {
|
|
278
|
+
val json = JSObject()
|
|
279
|
+
|
|
280
|
+
if (intent == null) {
|
|
281
|
+
return json
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
json.put("action", intent.action)
|
|
286
|
+
|
|
287
|
+
val extras = intent.extras
|
|
288
|
+
if (extras != null) {
|
|
289
|
+
json.put("extras", bundleToJson(extras))
|
|
290
|
+
}
|
|
291
|
+
} catch (e: Exception) {
|
|
292
|
+
Log.e(TAG, "intentToJson failed", e)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return json
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private fun bundleToJson(bundle: Bundle?): JSObject {
|
|
299
|
+
val json = JSObject()
|
|
300
|
+
|
|
301
|
+
if (bundle == null) {
|
|
302
|
+
return json
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
for (key in bundle.keySet()) {
|
|
306
|
+
try {
|
|
307
|
+
val value = bundle.get(key)
|
|
308
|
+
|
|
309
|
+
when (value) {
|
|
310
|
+
null -> json.put(key, JSONObject.NULL)
|
|
311
|
+
is String -> json.put(key, value)
|
|
312
|
+
is Int -> json.put(key, value)
|
|
313
|
+
is Long -> json.put(key, value)
|
|
314
|
+
is Double -> json.put(key, value)
|
|
315
|
+
is Float -> json.put(key, value.toDouble())
|
|
316
|
+
is Boolean -> json.put(key, value)
|
|
317
|
+
is Bundle -> json.put(key, bundleToJson(value))
|
|
318
|
+
is Array<*> -> {
|
|
319
|
+
if (value.isArrayOf<String>()) {
|
|
320
|
+
val arr = JSArray()
|
|
321
|
+
@Suppress("UNCHECKED_CAST")
|
|
322
|
+
for (s in value as Array<String>) {
|
|
323
|
+
arr.put(s)
|
|
324
|
+
}
|
|
325
|
+
json.put(key, arr)
|
|
326
|
+
} else if (value.isArrayOf<Parcelable>()) {
|
|
327
|
+
val arr = JSArray()
|
|
328
|
+
@Suppress("UNCHECKED_CAST")
|
|
329
|
+
for (p in value as Array<Parcelable>) {
|
|
330
|
+
arr.put(p.toString())
|
|
331
|
+
}
|
|
332
|
+
json.put(key, arr)
|
|
333
|
+
} else {
|
|
334
|
+
json.put(key, value.toString())
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
is IntArray -> {
|
|
338
|
+
val arr = JSArray()
|
|
339
|
+
for (i in value) {
|
|
340
|
+
arr.put(i)
|
|
341
|
+
}
|
|
342
|
+
json.put(key, arr)
|
|
343
|
+
}
|
|
344
|
+
is Parcelable -> json.put(key, value.toString())
|
|
345
|
+
else -> json.put(key, value.toString())
|
|
346
|
+
}
|
|
347
|
+
} catch (e: Exception) {
|
|
348
|
+
Log.w(TAG, "bundleToJson key failed: $key", e)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return json
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
override fun handleOnDestroy() {
|
|
356
|
+
for (receiver in receivers.values) {
|
|
357
|
+
try {
|
|
358
|
+
context.unregisterReceiver(receiver)
|
|
359
|
+
} catch (ignored: Exception) {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
receivers.clear()
|
|
363
|
+
super.handleOnDestroy()
|
|
364
|
+
}
|
|
365
|
+
}
|