@capawesome/capacitor-haptics 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/CapawesomeCapacitorHaptics.podspec +17 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +457 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/Haptics.java +284 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/HapticsPlugin.java +239 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/CustomException.java +20 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/CustomExceptions.java +18 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/ImpactOptions.java +24 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/NotificationOptions.java +24 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/PerformAndroidHapticOptions.java +29 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/PlayPatternOptions.java +89 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/options/VibrateOptions.java +26 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/results/IsAvailableResult.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/Callback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/EmptyCallback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/NonEmptyResultCallback.java +7 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/interfaces/Result.java +7 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +665 -0
- package/dist/esm/definitions.d.ts +363 -0
- package/dist/esm/definitions.js +150 -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 +21 -0
- package/dist/esm/web.js +100 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +263 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +266 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Classes/Options/ImpactOptions.swift +29 -0
- package/ios/Plugin/Classes/Options/NotificationOptions.swift +25 -0
- package/ios/Plugin/Classes/Options/PlayPatternOptions.swift +54 -0
- package/ios/Plugin/Classes/Results/IsAvailableResult.swift +16 -0
- package/ios/Plugin/Enums/CustomError.swift +50 -0
- package/ios/Plugin/Haptics.swift +115 -0
- package/ios/Plugin/HapticsPlugin.swift +155 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Protocols/Result.swift +5 -0
- package/package.json +96 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.os.Build;
|
|
5
|
+
import android.os.VibrationEffect;
|
|
6
|
+
import android.os.Vibrator;
|
|
7
|
+
import android.os.VibratorManager;
|
|
8
|
+
import android.view.HapticFeedbackConstants;
|
|
9
|
+
import android.view.View;
|
|
10
|
+
import androidx.annotation.NonNull;
|
|
11
|
+
import androidx.annotation.Nullable;
|
|
12
|
+
import androidx.annotation.RequiresApi;
|
|
13
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.CustomExceptions;
|
|
14
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.ImpactOptions;
|
|
15
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.NotificationOptions;
|
|
16
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.PerformAndroidHapticOptions;
|
|
17
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.PlayPatternOptions;
|
|
18
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.VibrateOptions;
|
|
19
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.results.IsAvailableResult;
|
|
20
|
+
import io.capawesome.capacitorjs.plugins.haptics.interfaces.EmptyCallback;
|
|
21
|
+
import io.capawesome.capacitorjs.plugins.haptics.interfaces.NonEmptyResultCallback;
|
|
22
|
+
import java.util.ArrayList;
|
|
23
|
+
import java.util.Collections;
|
|
24
|
+
import java.util.List;
|
|
25
|
+
|
|
26
|
+
public class Haptics {
|
|
27
|
+
|
|
28
|
+
private static final long TRANSIENT_EVENT_DURATION = 30;
|
|
29
|
+
|
|
30
|
+
@NonNull
|
|
31
|
+
private final HapticsPlugin plugin;
|
|
32
|
+
|
|
33
|
+
@Nullable
|
|
34
|
+
private final Vibrator vibrator;
|
|
35
|
+
|
|
36
|
+
public Haptics(@NonNull HapticsPlugin plugin) {
|
|
37
|
+
this.plugin = plugin;
|
|
38
|
+
this.vibrator = Haptics.getVibrator(plugin.getContext());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public void impact(@NonNull ImpactOptions options, @NonNull EmptyCallback callback) throws Exception {
|
|
42
|
+
performImpactEffect(options.getStyle());
|
|
43
|
+
callback.success();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public void isAvailable(@NonNull NonEmptyResultCallback<IsAvailableResult> callback) {
|
|
47
|
+
boolean available = vibrator != null && vibrator.hasVibrator();
|
|
48
|
+
callback.success(new IsAvailableResult(available));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public void notification(@NonNull NotificationOptions options, @NonNull EmptyCallback callback) throws Exception {
|
|
52
|
+
performNotificationEffect(options.getType());
|
|
53
|
+
callback.success();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public void performAndroidHaptic(@NonNull PerformAndroidHapticOptions options, @NonNull EmptyCallback callback) throws Exception {
|
|
57
|
+
int constant = getHapticFeedbackConstantForType(options.getType());
|
|
58
|
+
View webView = plugin.getBridge().getWebView();
|
|
59
|
+
webView.post(() -> webView.performHapticFeedback(constant));
|
|
60
|
+
callback.success();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public void playPattern(@NonNull PlayPatternOptions options, @NonNull EmptyCallback callback) throws Exception {
|
|
64
|
+
if (vibrator != null) {
|
|
65
|
+
List<PlayPatternOptions.Event> events = sortEventsByTime(options.getEvents());
|
|
66
|
+
try {
|
|
67
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && supportsComposition(events)) {
|
|
68
|
+
playComposition(events);
|
|
69
|
+
} else {
|
|
70
|
+
playTimeline(events);
|
|
71
|
+
}
|
|
72
|
+
} catch (RuntimeException exception) {
|
|
73
|
+
throw CustomExceptions.PATTERN_PLAYBACK_FAILED;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
callback.success();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public void selectionChanged(@NonNull EmptyCallback callback) {
|
|
80
|
+
performTickEffect();
|
|
81
|
+
callback.success();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public void selectionEnd(@NonNull EmptyCallback callback) {
|
|
85
|
+
callback.success();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public void selectionStart(@NonNull EmptyCallback callback) {
|
|
89
|
+
callback.success();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public void vibrate(@NonNull VibrateOptions options, @NonNull EmptyCallback callback) {
|
|
93
|
+
vibrateOneShot(options.getDuration(), VibrationEffect.DEFAULT_AMPLITUDE);
|
|
94
|
+
callback.success();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private int getHapticFeedbackConstantForType(@NonNull String type) throws Exception {
|
|
98
|
+
switch (type) {
|
|
99
|
+
case "CLOCK_TICK":
|
|
100
|
+
return HapticFeedbackConstants.CLOCK_TICK;
|
|
101
|
+
case "CONFIRM":
|
|
102
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
|
103
|
+
? HapticFeedbackConstants.CONFIRM
|
|
104
|
+
: HapticFeedbackConstants.CONTEXT_CLICK;
|
|
105
|
+
case "CONTEXT_CLICK":
|
|
106
|
+
return HapticFeedbackConstants.CONTEXT_CLICK;
|
|
107
|
+
case "KEYBOARD_TAP":
|
|
108
|
+
return HapticFeedbackConstants.KEYBOARD_TAP;
|
|
109
|
+
case "LONG_PRESS":
|
|
110
|
+
return HapticFeedbackConstants.LONG_PRESS;
|
|
111
|
+
case "REJECT":
|
|
112
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ? HapticFeedbackConstants.REJECT : HapticFeedbackConstants.LONG_PRESS;
|
|
113
|
+
case "TOGGLE_OFF":
|
|
114
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
|
115
|
+
? HapticFeedbackConstants.TOGGLE_OFF
|
|
116
|
+
: HapticFeedbackConstants.CLOCK_TICK;
|
|
117
|
+
case "TOGGLE_ON":
|
|
118
|
+
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
|
|
119
|
+
? HapticFeedbackConstants.TOGGLE_ON
|
|
120
|
+
: HapticFeedbackConstants.CLOCK_TICK;
|
|
121
|
+
case "VIRTUAL_KEY":
|
|
122
|
+
return HapticFeedbackConstants.VIRTUAL_KEY;
|
|
123
|
+
default:
|
|
124
|
+
throw CustomExceptions.TYPE_INVALID;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Nullable
|
|
129
|
+
private static Vibrator getVibrator(@NonNull Context context) {
|
|
130
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
131
|
+
VibratorManager vibratorManager = (VibratorManager) context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
|
|
132
|
+
return vibratorManager == null ? null : vibratorManager.getDefaultVibrator();
|
|
133
|
+
}
|
|
134
|
+
return (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private void performImpactEffect(@NonNull String style) throws Exception {
|
|
138
|
+
switch (style) {
|
|
139
|
+
case "HEAVY":
|
|
140
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
141
|
+
vibratePredefined(VibrationEffect.EFFECT_HEAVY_CLICK);
|
|
142
|
+
} else {
|
|
143
|
+
vibrateOneShot(60, 255);
|
|
144
|
+
}
|
|
145
|
+
break;
|
|
146
|
+
case "LIGHT":
|
|
147
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
148
|
+
vibratePredefined(VibrationEffect.EFFECT_TICK);
|
|
149
|
+
} else {
|
|
150
|
+
vibrateOneShot(20, 100);
|
|
151
|
+
}
|
|
152
|
+
break;
|
|
153
|
+
case "MEDIUM":
|
|
154
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
155
|
+
vibratePredefined(VibrationEffect.EFFECT_CLICK);
|
|
156
|
+
} else {
|
|
157
|
+
vibrateOneShot(40, 180);
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
case "RIGID":
|
|
161
|
+
vibrateOneShot(25, 255);
|
|
162
|
+
break;
|
|
163
|
+
case "SOFT":
|
|
164
|
+
vibrateOneShot(50, 100);
|
|
165
|
+
break;
|
|
166
|
+
default:
|
|
167
|
+
throw CustomExceptions.STYLE_INVALID;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private void performNotificationEffect(@NonNull String type) throws Exception {
|
|
172
|
+
long[] timings;
|
|
173
|
+
int[] amplitudes;
|
|
174
|
+
switch (type) {
|
|
175
|
+
case "ERROR":
|
|
176
|
+
timings = new long[] { 0, 40, 60, 40, 60, 60 };
|
|
177
|
+
amplitudes = new int[] { 0, 200, 0, 200, 0, 255 };
|
|
178
|
+
break;
|
|
179
|
+
case "SUCCESS":
|
|
180
|
+
timings = new long[] { 0, 40, 80, 60 };
|
|
181
|
+
amplitudes = new int[] { 0, 180, 0, 255 };
|
|
182
|
+
break;
|
|
183
|
+
case "WARNING":
|
|
184
|
+
timings = new long[] { 0, 60, 100, 60 };
|
|
185
|
+
amplitudes = new int[] { 0, 200, 0, 200 };
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
throw CustomExceptions.TYPE_INVALID;
|
|
189
|
+
}
|
|
190
|
+
vibrateWaveform(timings, amplitudes);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private void performTickEffect() {
|
|
194
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
|
195
|
+
vibratePredefined(VibrationEffect.EFFECT_TICK);
|
|
196
|
+
} else {
|
|
197
|
+
vibrateOneShot(10, 80);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
@RequiresApi(api = Build.VERSION_CODES.R)
|
|
202
|
+
private void playComposition(@NonNull List<PlayPatternOptions.Event> sortedEvents) {
|
|
203
|
+
if (vibrator == null) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
VibrationEffect.Composition composition = VibrationEffect.startComposition();
|
|
207
|
+
long currentTime = 0;
|
|
208
|
+
for (PlayPatternOptions.Event event : sortedEvents) {
|
|
209
|
+
long startTime = Math.max(event.getTimeMs(), currentTime);
|
|
210
|
+
composition.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, event.getIntensity(), (int) (startTime - currentTime));
|
|
211
|
+
currentTime = startTime;
|
|
212
|
+
}
|
|
213
|
+
vibrator.vibrate(composition.compose());
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private void playTimeline(@NonNull List<PlayPatternOptions.Event> sortedEvents) {
|
|
217
|
+
long[] timings = new long[sortedEvents.size() * 2];
|
|
218
|
+
int[] amplitudes = new int[sortedEvents.size() * 2];
|
|
219
|
+
long currentTime = 0;
|
|
220
|
+
int index = 0;
|
|
221
|
+
for (PlayPatternOptions.Event event : sortedEvents) {
|
|
222
|
+
long startTime = Math.max(event.getTimeMs(), currentTime);
|
|
223
|
+
long duration = event.isTransient() ? TRANSIENT_EVENT_DURATION : event.getDurationMs();
|
|
224
|
+
timings[index] = startTime - currentTime;
|
|
225
|
+
amplitudes[index] = 0;
|
|
226
|
+
index++;
|
|
227
|
+
timings[index] = duration;
|
|
228
|
+
amplitudes[index] = Math.min(255, Math.round(event.getIntensity() * 255));
|
|
229
|
+
index++;
|
|
230
|
+
currentTime = startTime + duration;
|
|
231
|
+
}
|
|
232
|
+
vibrateWaveform(timings, amplitudes);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@NonNull
|
|
236
|
+
private List<PlayPatternOptions.Event> sortEventsByTime(@NonNull List<PlayPatternOptions.Event> events) {
|
|
237
|
+
List<PlayPatternOptions.Event> sortedEvents = new ArrayList<>(events);
|
|
238
|
+
Collections.sort(sortedEvents, (a, b) -> Long.compare(a.getTimeMs(), b.getTimeMs()));
|
|
239
|
+
return sortedEvents;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@RequiresApi(api = Build.VERSION_CODES.R)
|
|
243
|
+
private boolean supportsComposition(@NonNull List<PlayPatternOptions.Event> events) {
|
|
244
|
+
if (vibrator == null) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
for (PlayPatternOptions.Event event : events) {
|
|
248
|
+
if (!event.isTransient()) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return vibrator.areAllPrimitivesSupported(VibrationEffect.Composition.PRIMITIVE_CLICK);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private void vibrateOneShot(long duration, int amplitude) {
|
|
256
|
+
if (vibrator == null) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
260
|
+
vibrator.vibrate(VibrationEffect.createOneShot(duration, amplitude));
|
|
261
|
+
} else {
|
|
262
|
+
vibrator.vibrate(duration);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@RequiresApi(api = Build.VERSION_CODES.Q)
|
|
267
|
+
private void vibratePredefined(int effectId) {
|
|
268
|
+
if (vibrator == null) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
vibrator.vibrate(VibrationEffect.createPredefined(effectId));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private void vibrateWaveform(@NonNull long[] timings, @NonNull int[] amplitudes) {
|
|
275
|
+
if (vibrator == null) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
279
|
+
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, -1));
|
|
280
|
+
} else {
|
|
281
|
+
vibrator.vibrate(timings, -1);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics;
|
|
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.haptics.classes.CustomException;
|
|
10
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.ImpactOptions;
|
|
11
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.NotificationOptions;
|
|
12
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.PerformAndroidHapticOptions;
|
|
13
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.PlayPatternOptions;
|
|
14
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.options.VibrateOptions;
|
|
15
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.results.IsAvailableResult;
|
|
16
|
+
import io.capawesome.capacitorjs.plugins.haptics.interfaces.EmptyCallback;
|
|
17
|
+
import io.capawesome.capacitorjs.plugins.haptics.interfaces.NonEmptyResultCallback;
|
|
18
|
+
import io.capawesome.capacitorjs.plugins.haptics.interfaces.Result;
|
|
19
|
+
|
|
20
|
+
@CapacitorPlugin(name = "Haptics")
|
|
21
|
+
public class HapticsPlugin extends Plugin {
|
|
22
|
+
|
|
23
|
+
public static final String ERROR_UNKNOWN_ERROR = "An unknown error has occurred.";
|
|
24
|
+
public static final String TAG = "HapticsPlugin";
|
|
25
|
+
|
|
26
|
+
private Haptics implementation;
|
|
27
|
+
|
|
28
|
+
@Override
|
|
29
|
+
public void load() {
|
|
30
|
+
super.load();
|
|
31
|
+
this.implementation = new Haptics(this);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@PluginMethod
|
|
35
|
+
public void impact(PluginCall call) {
|
|
36
|
+
try {
|
|
37
|
+
ImpactOptions options = new ImpactOptions(call);
|
|
38
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
39
|
+
@Override
|
|
40
|
+
public void success() {
|
|
41
|
+
resolveCall(call);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Override
|
|
45
|
+
public void error(Exception exception) {
|
|
46
|
+
rejectCall(call, exception);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
implementation.impact(options, callback);
|
|
50
|
+
} catch (Exception exception) {
|
|
51
|
+
rejectCall(call, exception);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@PluginMethod
|
|
56
|
+
public void isAvailable(PluginCall call) {
|
|
57
|
+
try {
|
|
58
|
+
NonEmptyResultCallback<IsAvailableResult> callback = new NonEmptyResultCallback<>() {
|
|
59
|
+
@Override
|
|
60
|
+
public void success(@NonNull IsAvailableResult result) {
|
|
61
|
+
resolveCall(call, result);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Override
|
|
65
|
+
public void error(Exception exception) {
|
|
66
|
+
rejectCall(call, exception);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
implementation.isAvailable(callback);
|
|
70
|
+
} catch (Exception exception) {
|
|
71
|
+
rejectCall(call, exception);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@PluginMethod
|
|
76
|
+
public void notification(PluginCall call) {
|
|
77
|
+
try {
|
|
78
|
+
NotificationOptions options = new NotificationOptions(call);
|
|
79
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
80
|
+
@Override
|
|
81
|
+
public void success() {
|
|
82
|
+
resolveCall(call);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Override
|
|
86
|
+
public void error(Exception exception) {
|
|
87
|
+
rejectCall(call, exception);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
implementation.notification(options, callback);
|
|
91
|
+
} catch (Exception exception) {
|
|
92
|
+
rejectCall(call, exception);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@PluginMethod
|
|
97
|
+
public void performAndroidHaptic(PluginCall call) {
|
|
98
|
+
try {
|
|
99
|
+
PerformAndroidHapticOptions options = new PerformAndroidHapticOptions(call);
|
|
100
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
101
|
+
@Override
|
|
102
|
+
public void success() {
|
|
103
|
+
resolveCall(call);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Override
|
|
107
|
+
public void error(Exception exception) {
|
|
108
|
+
rejectCall(call, exception);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
implementation.performAndroidHaptic(options, callback);
|
|
112
|
+
} catch (Exception exception) {
|
|
113
|
+
rejectCall(call, exception);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@PluginMethod
|
|
118
|
+
public void playPattern(PluginCall call) {
|
|
119
|
+
try {
|
|
120
|
+
PlayPatternOptions options = new PlayPatternOptions(call);
|
|
121
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
122
|
+
@Override
|
|
123
|
+
public void success() {
|
|
124
|
+
resolveCall(call);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@Override
|
|
128
|
+
public void error(Exception exception) {
|
|
129
|
+
rejectCall(call, exception);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
implementation.playPattern(options, callback);
|
|
133
|
+
} catch (Exception exception) {
|
|
134
|
+
rejectCall(call, exception);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@PluginMethod
|
|
139
|
+
public void selectionChanged(PluginCall call) {
|
|
140
|
+
try {
|
|
141
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
142
|
+
@Override
|
|
143
|
+
public void success() {
|
|
144
|
+
resolveCall(call);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@Override
|
|
148
|
+
public void error(Exception exception) {
|
|
149
|
+
rejectCall(call, exception);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
implementation.selectionChanged(callback);
|
|
153
|
+
} catch (Exception exception) {
|
|
154
|
+
rejectCall(call, exception);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@PluginMethod
|
|
159
|
+
public void selectionEnd(PluginCall call) {
|
|
160
|
+
try {
|
|
161
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
162
|
+
@Override
|
|
163
|
+
public void success() {
|
|
164
|
+
resolveCall(call);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@Override
|
|
168
|
+
public void error(Exception exception) {
|
|
169
|
+
rejectCall(call, exception);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
implementation.selectionEnd(callback);
|
|
173
|
+
} catch (Exception exception) {
|
|
174
|
+
rejectCall(call, exception);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@PluginMethod
|
|
179
|
+
public void selectionStart(PluginCall call) {
|
|
180
|
+
try {
|
|
181
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
182
|
+
@Override
|
|
183
|
+
public void success() {
|
|
184
|
+
resolveCall(call);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@Override
|
|
188
|
+
public void error(Exception exception) {
|
|
189
|
+
rejectCall(call, exception);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
implementation.selectionStart(callback);
|
|
193
|
+
} catch (Exception exception) {
|
|
194
|
+
rejectCall(call, exception);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@PluginMethod
|
|
199
|
+
public void vibrate(PluginCall call) {
|
|
200
|
+
try {
|
|
201
|
+
VibrateOptions options = new VibrateOptions(call);
|
|
202
|
+
EmptyCallback callback = new EmptyCallback() {
|
|
203
|
+
@Override
|
|
204
|
+
public void success() {
|
|
205
|
+
resolveCall(call);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
@Override
|
|
209
|
+
public void error(Exception exception) {
|
|
210
|
+
rejectCall(call, exception);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
implementation.vibrate(options, callback);
|
|
214
|
+
} catch (Exception exception) {
|
|
215
|
+
rejectCall(call, exception);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private void rejectCall(@NonNull PluginCall call, @NonNull Exception exception) {
|
|
220
|
+
String message = exception.getMessage();
|
|
221
|
+
if (message == null) {
|
|
222
|
+
message = ERROR_UNKNOWN_ERROR;
|
|
223
|
+
}
|
|
224
|
+
String code = null;
|
|
225
|
+
if (exception instanceof CustomException) {
|
|
226
|
+
code = ((CustomException) exception).getCode();
|
|
227
|
+
}
|
|
228
|
+
Logger.error(TAG, message, exception);
|
|
229
|
+
call.reject(message, code);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private void resolveCall(@NonNull PluginCall call) {
|
|
233
|
+
call.resolve();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private void resolveCall(@NonNull PluginCall call, @NonNull Result result) {
|
|
237
|
+
call.resolve(result.toJSObject());
|
|
238
|
+
}
|
|
239
|
+
}
|
package/android/src/main/java/io/capawesome/capacitorjs/plugins/haptics/classes/CustomException.java
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics.classes;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import androidx.annotation.Nullable;
|
|
5
|
+
|
|
6
|
+
public class CustomException extends Exception {
|
|
7
|
+
|
|
8
|
+
@Nullable
|
|
9
|
+
private final String code;
|
|
10
|
+
|
|
11
|
+
public CustomException(@Nullable String code, @NonNull String message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.code = code;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@Nullable
|
|
17
|
+
public String getCode() {
|
|
18
|
+
return code;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics.classes;
|
|
2
|
+
|
|
3
|
+
public class CustomExceptions {
|
|
4
|
+
|
|
5
|
+
public static final CustomException DURATION_INVALID = new CustomException(null, "duration must be greater than 0.");
|
|
6
|
+
public static final CustomException EVENTS_MISSING = new CustomException(null, "events must be provided.");
|
|
7
|
+
public static final CustomException INTENSITY_INVALID = new CustomException(null, "intensity must be between 0 and 1.");
|
|
8
|
+
public static final CustomException INTENSITY_MISSING = new CustomException(null, "intensity must be provided.");
|
|
9
|
+
public static final CustomException PATTERN_PLAYBACK_FAILED = new CustomException(
|
|
10
|
+
"PATTERN_PLAYBACK_FAILED",
|
|
11
|
+
"The haptic pattern could not be played."
|
|
12
|
+
);
|
|
13
|
+
public static final CustomException STYLE_INVALID = new CustomException(null, "style must be one of the supported values.");
|
|
14
|
+
public static final CustomException TIME_INVALID = new CustomException(null, "time must be greater than or equal to 0.");
|
|
15
|
+
public static final CustomException TIME_MISSING = new CustomException(null, "time must be provided.");
|
|
16
|
+
public static final CustomException TYPE_INVALID = new CustomException(null, "type must be one of the supported values.");
|
|
17
|
+
public static final CustomException TYPE_MISSING = new CustomException(null, "type must be provided.");
|
|
18
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics.classes.options;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.PluginCall;
|
|
5
|
+
|
|
6
|
+
public class ImpactOptions {
|
|
7
|
+
|
|
8
|
+
@NonNull
|
|
9
|
+
private final String style;
|
|
10
|
+
|
|
11
|
+
public ImpactOptions(@NonNull PluginCall call) {
|
|
12
|
+
this.style = ImpactOptions.getStyleFromCall(call);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@NonNull
|
|
16
|
+
public String getStyle() {
|
|
17
|
+
return style;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@NonNull
|
|
21
|
+
private static String getStyleFromCall(@NonNull PluginCall call) {
|
|
22
|
+
return call.getString("style", "MEDIUM");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics.classes.options;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.PluginCall;
|
|
5
|
+
|
|
6
|
+
public class NotificationOptions {
|
|
7
|
+
|
|
8
|
+
@NonNull
|
|
9
|
+
private final String type;
|
|
10
|
+
|
|
11
|
+
public NotificationOptions(@NonNull PluginCall call) {
|
|
12
|
+
this.type = NotificationOptions.getTypeFromCall(call);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@NonNull
|
|
16
|
+
public String getType() {
|
|
17
|
+
return type;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@NonNull
|
|
21
|
+
private static String getTypeFromCall(@NonNull PluginCall call) {
|
|
22
|
+
return call.getString("type", "SUCCESS");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package io.capawesome.capacitorjs.plugins.haptics.classes.options;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import com.getcapacitor.PluginCall;
|
|
5
|
+
import io.capawesome.capacitorjs.plugins.haptics.classes.CustomExceptions;
|
|
6
|
+
|
|
7
|
+
public class PerformAndroidHapticOptions {
|
|
8
|
+
|
|
9
|
+
@NonNull
|
|
10
|
+
private final String type;
|
|
11
|
+
|
|
12
|
+
public PerformAndroidHapticOptions(@NonNull PluginCall call) throws Exception {
|
|
13
|
+
this.type = PerformAndroidHapticOptions.getTypeFromCall(call);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@NonNull
|
|
17
|
+
public String getType() {
|
|
18
|
+
return type;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@NonNull
|
|
22
|
+
private static String getTypeFromCall(@NonNull PluginCall call) throws Exception {
|
|
23
|
+
String type = call.getString("type");
|
|
24
|
+
if (type == null) {
|
|
25
|
+
throw CustomExceptions.TYPE_MISSING;
|
|
26
|
+
}
|
|
27
|
+
return type;
|
|
28
|
+
}
|
|
29
|
+
}
|