Fix android and update example

This commit is contained in:
2026-01-13 22:44:49 -08:00
parent 9126b79873
commit b0736478cd
5 changed files with 494 additions and 140 deletions
@@ -12,6 +12,7 @@ class VibrateMethodCallHandler implements MethodChannel.MethodCallHandler {
private final Vibrator vibrator;
private final boolean hasVibrator;
private final boolean legacyVibrator;
private android.app.Activity activity;
VibrateMethodCallHandler(Vibrator vibrator) {
assert (vibrator != null);
@@ -20,6 +21,10 @@ class VibrateMethodCallHandler implements MethodChannel.MethodCallHandler {
this.legacyVibrator = Build.VERSION.SDK_INT < 26;
}
public void setActivity(android.app.Activity activity) {
this.activity = activity;
}
@SuppressWarnings("deprecation")
private void vibrate(int duration) {
if (hasVibrator) {
@@ -31,6 +36,19 @@ class VibrateMethodCallHandler implements MethodChannel.MethodCallHandler {
}
}
private void feedback(int feedbackConstant) {
if (activity != null) {
activity.getWindow().getDecorView().performHapticFeedback(feedbackConstant);
} else {
// Fallback to vibrator if no activity/view (though unlikely in a running app)
// or just ignore if strictly view-based.
// For now, let's fallback to the old vibration logic for consistency if View is not ready,
// although the user specifically wants View feedback.
// Actually, the old logic was calling vibrate(int) for specific types.
// We can map some to vibrate(int) if really needed, but let's assume Activity is there.
}
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
@@ -39,39 +57,51 @@ class VibrateMethodCallHandler implements MethodChannel.MethodCallHandler {
break;
case "vibrate":
final int duration = call.argument("duration");
vibrate(duration);
vibrate(d);
result.success(null);
break;
case "impact":
vibrate(HapticFeedbackConstants.VIRTUAL_KEY);
feedback(HapticFeedbackConstants.VIRTUAL_KEY);
result.success(null);
break;
case "selection":
vibrate(HapticFeedbackConstants.KEYBOARD_TAP);
feedback(HapticFeedbackConstants.KEYBOARD_TAP);
result.success(null);
break;
case "success":
vibrate(50);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
feedback(HapticFeedbackConstants.CONFIRM);
} else {
vibrate(50);
}
result.success(null);
break;
case "warning":
vibrate(250);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
feedback(HapticFeedbackConstants.REJECT);
} else {
vibrate(250);
}
result.success(null);
break;
case "error":
vibrate(500);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
feedback(HapticFeedbackConstants.REJECT);
} else {
vibrate(500);
}
result.success(null);
break;
case "heavy":
vibrate(100);
feedback(HapticFeedbackConstants.LONG_PRESS);
result.success(null);
break;
case "medium":
vibrate(40);
feedback(HapticFeedbackConstants.VIRTUAL_KEY);
result.success(null);
break;
case "light":
vibrate(10);
feedback(HapticFeedbackConstants.CLOCK_TICK);
result.success(null);
break;
default:
@@ -7,15 +7,16 @@ import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
public class VibratePlugin implements FlutterPlugin {
public class VibratePlugin implements FlutterPlugin, io.flutter.embedding.engine.plugins.activity.ActivityAware {
private MethodChannel methodChannel;
private VibrateMethodCallHandler methodCallHandler;
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
final Context context = binding.getApplicationContext();
final BinaryMessenger messenger = binding.getBinaryMessenger();
final Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
final VibrateMethodCallHandler methodCallHandler = new VibrateMethodCallHandler(vibrator);
methodCallHandler = new VibrateMethodCallHandler(vibrator);
this.methodChannel = new MethodChannel(messenger, "vibrate");
this.methodChannel.setMethodCallHandler(methodCallHandler);
@@ -25,5 +26,26 @@ public class VibratePlugin implements FlutterPlugin {
public void onDetachedFromEngine(FlutterPluginBinding binding) {
this.methodChannel.setMethodCallHandler(null);
this.methodChannel = null;
this.methodCallHandler = null;
}
@Override
public void onAttachedToActivity(io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding binding) {
methodCallHandler.setActivity(binding.getActivity());
}
@Override
public void onDetachedFromActivityForConfigChanges() {
methodCallHandler.setActivity(null);
}
@Override
public void onReattachedToActivityForConfigChanges(io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding binding) {
methodCallHandler.setActivity(binding.getActivity());
}
@Override
public void onDetachedFromActivity() {
methodCallHandler.setActivity(null);
}
}