Skip to content

Commit 9dd3cbc

Browse files
committed
Add code snippets for haptics in Android docs
Provides a more robust and maintainable set of source code, compared to the manually-created snippets currently published on https://developer.android.com/develop/ui/views/haptics/custom-haptic-effects
1 parent 3ef4201 commit 9dd3cbc

File tree

4 files changed

+287
-0
lines changed

4 files changed

+287
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.example.snippets.ui.haptics;
2+
3+
import android.Manifest;
4+
import android.app.Activity;
5+
import android.os.Build;
6+
import android.os.VibrationEffect;
7+
import android.os.Vibrator;
8+
9+
import androidx.annotation.RequiresApi;
10+
import androidx.annotation.RequiresPermission;
11+
12+
@RequiresApi(api = Build.VERSION_CODES.M)
13+
public class CustomVibrationPatternsJava extends Activity {
14+
Vibrator vibrator = getApplicationContext().getSystemService(Vibrator.class);
15+
16+
// [START android_ui_haptics_ramp_up]
17+
@RequiresApi(Build.VERSION_CODES.O)
18+
@RequiresPermission(Manifest.permission.VIBRATE)
19+
private void rampUpPattern(Vibrator vibrator) {
20+
long[] timings = new long[] {
21+
50, 50, 50, 50, 50, 100, 350, 25, 25, 25, 25, 200 };
22+
int[] amplitudes = new int[] {
23+
33, 51, 75, 113, 170, 255, 0, 38, 62, 100, 160, 255 };
24+
int repeatIndex = -1; // Don't repeat.
25+
26+
vibrator.vibrate(VibrationEffect.createWaveform(
27+
timings, amplitudes, repeatIndex));
28+
}
29+
// [END android_ui_haptics_ramp_up]
30+
31+
@RequiresApi(api = Build.VERSION_CODES.O)
32+
@RequiresPermission(Manifest.permission.VIBRATE)
33+
// [START android_ui_haptics_repeat]
34+
private void startVibrating() {
35+
long[] timings = new long[] { 50, 50, 100, 50, 50 };
36+
int[] amplitudes = new int[] { 64, 128, 255, 128, 64 };
37+
int repeat = 1; // Repeat from the second entry, index = 1.
38+
VibrationEffect repeatingEffect = VibrationEffect.createWaveform(
39+
timings, amplitudes, repeat);
40+
// repeatingEffect can be used in multiple places.
41+
42+
vibrator.vibrate(repeatingEffect);
43+
}
44+
45+
// [START_EXCLUDE]
46+
@RequiresPermission(Manifest.permission.VIBRATE)
47+
// [END_EXCLUDE]
48+
private void stopVibrating() {
49+
vibrator.cancel();
50+
}
51+
// [END android_ui_haptics_repeat]
52+
53+
54+
// [START android_ui_haptics_fallback]
55+
@RequiresApi(api = Build.VERSION_CODES.O)
56+
@RequiresPermission(Manifest.permission.VIBRATE)
57+
private void patternWithFallback() {
58+
long[] smoothTimings = new long[] { 50, 50, 100, 50, 50 };
59+
long[] onOffTimings = new long[] { 50, 100 };
60+
int[] amplitudes = new int[] { 64, 128, 255, 128, 64 };
61+
int repeatIndex = -1; // Don't repeat.
62+
63+
if (vibrator.hasAmplitudeControl()) {
64+
vibrator.vibrate(VibrationEffect.createWaveform(
65+
smoothTimings, amplitudes, repeatIndex));
66+
} else {
67+
vibrator.vibrate(VibrationEffect.createWaveform(
68+
onOffTimings, repeatIndex));
69+
}
70+
}
71+
// [END android_ui_haptics_fallback]
72+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.example.snippets.ui.haptics;
2+
3+
import android.Manifest;
4+
import android.app.Activity;
5+
import android.os.Build;
6+
import android.os.VibrationEffect;
7+
import android.os.Vibrator;
8+
9+
import androidx.annotation.RequiresApi;
10+
import androidx.annotation.RequiresPermission;
11+
12+
@RequiresApi(Build.VERSION_CODES.S)
13+
public class CustomVibrationCompositionsJava extends Activity {
14+
Vibrator vibrator = getApplicationContext().getSystemService(Vibrator.class);
15+
16+
@RequiresPermission(Manifest.permission.VIBRATE)
17+
// [START android_ui_haptics_composed_vibration_effect]
18+
private void createComposedVibrationEffect() {
19+
vibrator.vibrate(
20+
VibrationEffect.startComposition()
21+
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_SLOW_RISE)
22+
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
23+
.compose());
24+
}
25+
// [END android_ui_haptics_composed_vibration_effect]
26+
27+
@RequiresPermission(Manifest.permission.VIBRATE)
28+
// [START android_ui_haptics_gap_between_primitives]
29+
private void gapBetweenPrimitives() {
30+
int delayMs = 100;
31+
vibrator.vibrate(
32+
VibrationEffect.startComposition()
33+
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.8f)
34+
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.6f)
35+
.addPrimitive(
36+
VibrationEffect.Composition.PRIMITIVE_THUD, 1.0f, delayMs)
37+
.compose());
38+
}
39+
// [END android_ui_haptics_gap_between_primitives]
40+
41+
@RequiresPermission(Manifest.permission.VIBRATE)
42+
private void checkPrimitivesSupport() {
43+
// [START android_ui_haptics_check_single_primitive_support]
44+
int primitive = VibrationEffect.Composition.PRIMITIVE_LOW_TICK;
45+
46+
if (vibrator.areAllPrimitivesSupported(primitive)) {
47+
vibrator.vibrate(VibrationEffect.startComposition()
48+
.addPrimitive(primitive).compose());
49+
} else {
50+
// Play a predefined effect or custom pattern as a fallback.
51+
}
52+
// [END android_ui_haptics_check_single_primitive_support]
53+
54+
// [START android_ui_haptics_check_multiple_primitives_support]
55+
boolean[] supported = vibrator.arePrimitivesSupported(
56+
VibrationEffect.Composition.PRIMITIVE_LOW_TICK,
57+
VibrationEffect.Composition.PRIMITIVE_TICK,
58+
VibrationEffect.Composition.PRIMITIVE_CLICK);
59+
// [END android_ui_haptics_check_multiple_primitives_support]
60+
}
61+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.example.snippets.ui.haptics
2+
3+
import android.Manifest
4+
import android.app.Activity
5+
import android.os.Build
6+
import android.os.VibrationEffect
7+
import android.os.Vibrator
8+
import androidx.annotation.RequiresApi
9+
import androidx.annotation.RequiresPermission
10+
11+
class CustomVibrationPatterns : Activity() {
12+
@RequiresApi(Build.VERSION_CODES.M)
13+
val vibrator = applicationContext.getSystemService(Vibrator::class.java) as Vibrator
14+
15+
// [START android_ui_haptics_ramp_up]
16+
@RequiresPermission(Manifest.permission.VIBRATE)
17+
@RequiresApi(Build.VERSION_CODES.O)
18+
fun rampUpPattern(vibrator: Vibrator) {
19+
val timings: LongArray = longArrayOf(
20+
50, 50, 50, 50, 50, 100, 350, 25, 25, 25, 25, 200
21+
)
22+
val amplitudes: IntArray = intArrayOf(
23+
33, 51, 75, 113, 170, 255, 0, 38, 62, 100, 160, 255
24+
)
25+
val repeatIndex = -1 // Don't repeat.
26+
27+
vibrator.vibrate(
28+
VibrationEffect.createWaveform(
29+
timings, amplitudes, repeatIndex
30+
)
31+
)
32+
}
33+
// [END android_ui_haptics_ramp_up]
34+
35+
@RequiresPermission(Manifest.permission.VIBRATE)
36+
@RequiresApi(Build.VERSION_CODES.O)
37+
// [START android_ui_haptics_repeat]
38+
fun startRepeatVibration() {
39+
val timings: LongArray = longArrayOf(50, 50, 100, 50, 50)
40+
val amplitudes: IntArray = intArrayOf(64, 128, 255, 128, 64)
41+
val repeat = 1 // Repeat from the second entry, index = 1.
42+
val repeatingEffect = VibrationEffect.createWaveform(
43+
timings, amplitudes, repeat)
44+
// repeatingEffect can be used in multiple places.
45+
46+
vibrator.vibrate(repeatingEffect)
47+
}
48+
49+
// [START_EXCLUDE]
50+
@RequiresPermission(Manifest.permission.VIBRATE)
51+
@RequiresApi(Build.VERSION_CODES.M)
52+
// [END_EXCLUDE]
53+
fun stopRepeatVibrator() {
54+
vibrator.cancel()
55+
}
56+
// [END android_ui_haptics_repeat]
57+
58+
@RequiresApi(api = Build.VERSION_CODES.O)
59+
@RequiresPermission(Manifest.permission.VIBRATE)
60+
// [START android_ui_haptics_fallback]
61+
private fun patternWithFallback() {
62+
val smoothTimings = longArrayOf(50, 50, 100, 50, 50)
63+
val onOffTimings = longArrayOf(50, 100)
64+
val amplitudes = intArrayOf(64, 128, 255, 128, 64)
65+
val repeatIndex = -1 // Don't repeat.
66+
67+
if (vibrator.hasAmplitudeControl()) {
68+
vibrator.vibrate(
69+
VibrationEffect.createWaveform(
70+
smoothTimings, amplitudes, repeatIndex
71+
)
72+
)
73+
} else {
74+
vibrator.vibrate(
75+
VibrationEffect.createWaveform(
76+
onOffTimings, repeatIndex
77+
)
78+
)
79+
}
80+
}
81+
// [END android_ui_haptics_fallback]
82+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.example.snippets.ui.haptics;
2+
3+
import android.Manifest;
4+
import android.app.Activity;
5+
import android.os.Build;
6+
import android.os.VibrationEffect;
7+
import android.os.Vibrator;
8+
9+
import androidx.annotation.RequiresApi;
10+
import androidx.annotation.RequiresPermission;
11+
12+
@RequiresApi(api = Build.VERSION_CODES.M)
13+
public class CustomVibrationPatternsJava extends Activity {
14+
Vibrator vibrator = getApplicationContext().getSystemService(Vibrator.class);
15+
16+
// [START android_ui_haptics_ramp_up]
17+
@RequiresApi(Build.VERSION_CODES.O)
18+
@RequiresPermission(Manifest.permission.VIBRATE)
19+
private void rampUpPattern(Vibrator vibrator) {
20+
long[] timings = new long[] {
21+
50, 50, 50, 50, 50, 100, 350, 25, 25, 25, 25, 200 };
22+
int[] amplitudes = new int[] {
23+
33, 51, 75, 113, 170, 255, 0, 38, 62, 100, 160, 255 };
24+
int repeatIndex = -1; // Don't repeat.
25+
26+
vibrator.vibrate(VibrationEffect.createWaveform(
27+
timings, amplitudes, repeatIndex));
28+
}
29+
// [END android_ui_haptics_ramp_up]
30+
31+
@RequiresApi(api = Build.VERSION_CODES.O)
32+
@RequiresPermission(Manifest.permission.VIBRATE)
33+
// [START android_ui_haptics_repeat]
34+
private void startVibrating() {
35+
long[] timings = new long[] { 50, 50, 100, 50, 50 };
36+
int[] amplitudes = new int[] { 64, 128, 255, 128, 64 };
37+
int repeat = 1; // Repeat from the second entry, index = 1.
38+
VibrationEffect repeatingEffect = VibrationEffect.createWaveform(
39+
timings, amplitudes, repeat);
40+
// repeatingEffect can be used in multiple places.
41+
42+
vibrator.vibrate(repeatingEffect);
43+
}
44+
45+
// [START_EXCLUDE]
46+
@RequiresPermission(Manifest.permission.VIBRATE)
47+
// [END_EXCLUDE]
48+
private void stopVibrating() {
49+
vibrator.cancel();
50+
}
51+
// [END android_ui_haptics_repeat]
52+
53+
54+
// [START android_ui_haptics_fallback]
55+
@RequiresApi(api = Build.VERSION_CODES.O)
56+
@RequiresPermission(Manifest.permission.VIBRATE)
57+
private void patternWithFallback() {
58+
long[] smoothTimings = new long[] { 50, 50, 100, 50, 50 };
59+
long[] onOffTimings = new long[] { 50, 100 };
60+
int[] amplitudes = new int[] { 64, 128, 255, 128, 64 };
61+
int repeatIndex = -1; // Don't repeat.
62+
63+
if (vibrator.hasAmplitudeControl()) {
64+
vibrator.vibrate(VibrationEffect.createWaveform(
65+
smoothTimings, amplitudes, repeatIndex));
66+
} else {
67+
vibrator.vibrate(VibrationEffect.createWaveform(
68+
onOffTimings, repeatIndex));
69+
}
70+
}
71+
// [END android_ui_haptics_fallback]
72+
}

0 commit comments

Comments
 (0)