diff --git a/.dart_tool/package_graph.json b/.dart_tool/package_graph.json
index bcb19d9..bfa363c 100644
--- a/.dart_tool/package_graph.json
+++ b/.dart_tool/package_graph.json
@@ -12,7 +12,7 @@
},
{
"name": "flutter_vibrate",
- "version": "1.3.0",
+ "version": "1.4.0",
"dependencies": [
"flutter"
],
diff --git a/packages/flutter_vibrate/CHANGELOG.md b/packages/flutter_vibrate/CHANGELOG.md
index 44a91a5..25e90d7 100644
--- a/packages/flutter_vibrate/CHANGELOG.md
+++ b/packages/flutter_vibrate/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 1.4.0
+
+* Migrated to Pigeon for type-safe platform channels.
+* Fixed Android permission issue (restored `VIBRATE` permission).
+* Refactored Android implementation to use `View.performHapticFeedback` for compatible feedback.
+* Modernized example app with Material 3 and better UI.
+
## 1.3.0
* Fixing swift version
diff --git a/packages/flutter_vibrate/LICENSE b/packages/flutter_vibrate/LICENSE
index ab6b64b..7a4a3ea 100644
--- a/packages/flutter_vibrate/LICENSE
+++ b/packages/flutter_vibrate/LICENSE
@@ -1,21 +1,202 @@
-MIT License
-Copyright (c) 2018 Clovis NICOLAS
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+ 1. Definitions.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/packages/flutter_vibrate/README.md b/packages/flutter_vibrate/README.md
index 8e2df52..e95cb8f 100644
--- a/packages/flutter_vibrate/README.md
+++ b/packages/flutter_vibrate/README.md
@@ -1,68 +1,122 @@
-[](https://www.buymeacoffee.com/rodydavis)
-[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WSH3GVC49GNNJ)
-
-[](https://github.com/rodydavis/flutter_vibrate)
-[](https://pub.dev/packages/flutter_vibrate)
+# Flutter Vibrate
+[](https://pub.dev/packages/flutter_vibrate)
-# Vibrate
+A Flutter plugin to provide haptic feedback on iOS and Android. This package unifies the haptic feedback APIs, allowing for consistent vibration patterns and feedback types across both platforms.
-A Flutter plugin to vibrate the device.
-This uses all the current Haptic Feedback APIs from Apple and provides similar feedback on Android.
+| Platform | Support |
+| :--- | :---: |
+| Android | ✅ |
+| iOS | ✅ |
+| macOS | ❌ |
+| Web | ❌ |
+| Linux | ❌ |
+| Windows | ❌ |
+
+## Features
+
+- **Device Vibration**: Trigger standard vibrations or custom patterns (Android).
+- **Haptic Feedback**: Access platform-specific haptic feedback constants (Impact, Selection, Success, Warning, Error, etc.).
+- **Type Safety**: Built with Pigeon for type-safe communication between Flutter and native platforms.
+- **Modern Android Support**: Uses `View.performHapticFeedback` for broad compatibility and adheres to modern Android haptic standards.
+- **iOS Haptics**: Uses `UIImpactFeedbackGenerator` and `UINotificationFeedbackGenerator` for rich haptic experiences on iOS 10+.
## Getting Started
-Make sure you add the following permissions to your Android Manifest
-``` xml
-
+### Installation
+
+Add `flutter_vibrate` to your `pubspec.yaml`:
+
+```yaml
+dependencies:
+ flutter_vibrate: ^1.4.0
```
+
+### Android Setup
+
+Add the vibration permission to your `AndroidManifest.xml` (`android/app/src/main/AndroidManifest.xml`):
+
+```xml
+
+
+
+```
+
+> **Note**: While `vibrate()` requires this permission, many haptic feedback types (like selection, impact) may work without it on some Android versions using the View-based API. However, it is recommended to include it for full functionality.
+
+### iOS Setup
+
+No additional configuration is required. The plugin uses `AudioServicesPlaySystemSound` and `UIFeedbackGenerator` which are available by default.
+
## Usage
-``` dart
-// Import package
+
+Import the package:
+
+```dart
import 'package:flutter_vibrate/flutter_vibrate.dart';
```
-### Vibration
-``` dart
+### Basic Vibration
+
+Check for device capabilities and vibrate:
+
+```dart
// Check if the device can vibrate
bool canVibrate = await Vibrate.canVibrate;
-// Vibrate
-// Vibration duration is a constant 500ms because
-// it cannot be set to a specific duration on iOS.
-Vibrate.vibrate();
+if (canVibrate) {
+ // Vibrate for 500ms
+ Vibrate.vibrate();
+}
+```
-// Vibrate with pauses between each vibration
-final Iterable pauses = [
- const Duration(milliseconds: 500),
- const Duration(milliseconds: 1000),
- const Duration(milliseconds: 500),
+### Vibration Patterns
+
+You can create custom patterns by specifying a list of pauses. The pattern alternates between vibrating and pausing.
+
+> **Android**: Supports custom patterns with variable pauses.
+>
+> **iOS**: The OS does not support fine-grained custom patterns. This method will vibrate once for each interval in the list.
+
+```dart
+final Iterable pauses = const [
+ Duration(milliseconds: 500), // Vibrate
+ Duration(milliseconds: 1000), // Wait
+ Duration(milliseconds: 500), // Vibrate
];
-// vibrate - sleep 0.5s - vibrate - sleep 1s - vibrate - sleep 0.5s - vibrate
+
Vibrate.vibrateWithPauses(pauses);
```
+
### Haptic Feedback
-``` dart
-// Choose from any of these available methods
-enum FeedbackType {
- success,
- error,
- warning,
- selection,
- impact,
- heavy,
- medium,
- light
-}
-var _type = FeedbackType.impact;
-Vibrate.feedback(_type);
+Trigger specific haptic feedback types to enhance user interaction:
+
+```dart
+// Impact (light collision)
+Vibrate.feedback(FeedbackType.impact);
+
+// Selection (scroll tick)
+Vibrate.feedback(FeedbackType.selection);
+
+// Success (task completion)
+Vibrate.feedback(FeedbackType.success);
+
+// Warning (potential issue)
+Vibrate.feedback(FeedbackType.warning);
+
+// Error (task failure)
+Vibrate.feedback(FeedbackType.error);
+
+// Heavy Impact
+Vibrate.feedback(FeedbackType.heavy);
+
+// Medium Impact
+Vibrate.feedback(FeedbackType.medium);
+
+// Light Impact
+Vibrate.feedback(FeedbackType.light);
```
-## Documentation
-#### Android
-https://developer.android.com/reference/android/view/HapticFeedbackConstants
-
-#### iOS
-
-https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/
+## Contributing
+Contributions are welcome! If you find a bug or want to add a feature, please file an issue or submit a pull request.
diff --git a/packages/flutter_vibrate/example/README.md b/packages/flutter_vibrate/example/README.md
index a135626..e1eedc9 100644
--- a/packages/flutter_vibrate/example/README.md
+++ b/packages/flutter_vibrate/example/README.md
@@ -1,16 +1,106 @@
-# example
+# flutter_vibrate Example
-A new Flutter project.
+This example app demonstrates how to use the `flutter_vibrate` plugin to trigger device vibrations and haptic feedback.
+
+## API Reference & Usage
+
+Below is an exhaustive list of all exposed methods and haptic feedback types available in the `flutter_vibrate` package.
+
+### 1. Check Capabilities
+
+Check if the current device has the hardware to support vibration.
+
+```dart
+bool canVibrate = await Vibrate.canVibrate;
+```
+
+### 2. Standard Vibration
+
+Trigger a standard vibration (500ms on Android; system default on iOS).
+
+```dart
+Vibrate.vibrate();
+```
+
+### 3. Vibration Patterns (Android)
+
+Trigger a custom vibration pattern by specifying durations for [vibrate, wait, vibrate...].
+*On iOS, this will vibrate once for each duration provided, as fine-grained patterns are not supported.*
+
+```dart
+final Iterable pauses = [
+ const Duration(milliseconds: 500), // Vibrate
+ const Duration(milliseconds: 1000), // Wait
+ const Duration(milliseconds: 500), // Vibrate
+];
+
+Vibrate.vibrateWithPauses(pauses);
+```
+
+### 4. Haptic Feedback
+
+Trigger specific haptic feedback to enhance user interactions.
+
+#### Success
+Indicates that a task has completed successfully.
+```dart
+Vibrate.feedback(FeedbackType.success);
+```
+
+#### Error
+Indicates that a task has failed.
+```dart
+Vibrate.feedback(FeedbackType.error);
+```
+
+#### Warning
+Indicates a warning or potential issue.
+```dart
+Vibrate.feedback(FeedbackType.warning);
+```
+
+#### Selection
+Indicates a selection change (e.g., snapping to a value, scrolling through a list).
+```dart
+Vibrate.feedback(FeedbackType.selection);
+```
+
+#### Impact
+Provides a physical impact feedback (e.g., a collision or thud).
+```dart
+Vibrate.feedback(FeedbackType.impact);
+```
+
+#### Heavy
+Provides a heavy mass impact.
+```dart
+Vibrate.feedback(FeedbackType.heavy);
+```
+
+#### Medium
+Provides a medium mass impact.
+```dart
+Vibrate.feedback(FeedbackType.medium);
+```
+
+#### Light
+Provides a light mass impact.
+```dart
+Vibrate.feedback(FeedbackType.light);
+```
## Getting Started
-This project is a starting point for a Flutter application.
+1. **Run the app**:
+ ```bash
+ flutter run
+ ```
+2. **Explore**: Tap the tiles in the app to feel each of the vibrations and feedbacks listed above.
-A few resources to get you started if this is your first Flutter project:
+## Android Permissions
-- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
-- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
+The example app includes the necessary permission in [`android/app/src/main/AndroidManifest.xml`](android/app/src/main/AndroidManifest.xml):
-For help getting started with Flutter, view our
-[online documentation](https://flutter.dev/docs), which offers tutorials,
-samples, guidance on mobile development, and a full API reference.
+```xml
+
+```
diff --git a/packages/flutter_vibrate/lib/flutter_vibrate.dart b/packages/flutter_vibrate/lib/flutter_vibrate.dart
index aba4e84..052f559 100644
--- a/packages/flutter_vibrate/lib/flutter_vibrate.dart
+++ b/packages/flutter_vibrate/lib/flutter_vibrate.dart
@@ -4,34 +4,60 @@ import 'src/messages.g.dart';
export 'src/messages.g.dart' show VibrateApi;
+/// A set of feedback types that can be used to provide haptic feedback.
enum FeedbackType {
+ /// Indicates a task has completed successfully.
success,
+
+ /// Indicates a task has failed or an error occurred.
error,
+
+ /// Indicates a warning or caution.
warning,
+
+ /// Indicates a selection change (e.g., scrolling through a list).
selection,
+
+ /// Provides a heavy physical impact.
impact,
+
+ /// Provides a heavy vibration.
heavy,
+
+ /// Provides a medium vibration.
medium,
+
+ /// Provides a light vibration.
light,
}
+/// A class that provides access to the device's vibration hardware.
class Vibrate {
static final VibrateApi _api = VibrateApi();
static const Duration _defaultVibrationDuration = Duration(milliseconds: 500);
- /// Vibrate for 500ms on Android, and for the default time on iOS (about 500ms as well)
+ /// Vibrates the device for 500ms on Android, and for the default system vibration duration on iOS.
static Future vibrate() async {
await _api.vibrate(500);
}
- /// Whether the device can actually vibrate or not
+ /// Checks if the device has vibration hardware.
+ ///
+ /// Returns `true` if the device can vibrate, `false` otherwise.
static Future get canVibrate async {
return _api.canVibrate();
}
- /// Vibrates with [pauses] in between each vibration
- /// Will always vibrate once before the first pause
- /// and once after the last pause
+ /// Vibrates the device with a specific pattern of pauses.
+ ///
+ /// The [pauses] iterable defines the duration of silence in between vibrations.
+ /// The pattern will always start with a vibration, followed by the first pause,
+ /// then another vibration, and so on, ending with a final vibration.
+ ///
+ /// For example, if [pauses] is `[Duration(seconds: 1)]`, the device will:
+ /// 1. Vibrate (default duration)
+ /// 2. Wait for 1 second
+ /// 3. Vibrate (default duration)
static Future vibrateWithPauses(Iterable pauses) async {
for (final Duration d in pauses) {
await vibrate();
@@ -44,6 +70,10 @@ class Vibrate {
await vibrate();
}
+ /// Provides haptic feedback corresponding to the specified [type].
+ ///
+ /// This uses the platform's native haptic feedback mechanisms (e.g., `UINotificationFeedbackGenerator` on iOS,
+ /// `View.performHapticFeedback` on Android).
static Future feedback(FeedbackType type) async {
switch (type) {
case FeedbackType.impact:
diff --git a/packages/flutter_vibrate/lib/src/messages.g.dart b/packages/flutter_vibrate/lib/src/messages.g.dart
index f94e64f..6ae3676 100644
--- a/packages/flutter_vibrate/lib/src/messages.g.dart
+++ b/packages/flutter_vibrate/lib/src/messages.g.dart
@@ -15,7 +15,6 @@ PlatformException _createConnectionError(String channelName) {
);
}
-
class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
@@ -41,9 +40,13 @@ class VibrateApi {
/// Constructor for [VibrateApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
- VibrateApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
- : pigeonVar_binaryMessenger = binaryMessenger,
- pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
+ VibrateApi({
+ BinaryMessenger? binaryMessenger,
+ String messageChannelSuffix = '',
+ }) : pigeonVar_binaryMessenger = binaryMessenger,
+ pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty
+ ? '.$messageChannelSuffix'
+ : '';
final BinaryMessenger? pigeonVar_binaryMessenger;
static const MessageCodec