{"id":14971532,"url":"https://github.com/codenameakshay/secure_content","last_synced_at":"2025-10-09T12:34:06.693Z","repository":{"id":62485551,"uuid":"545602742","full_name":"codenameakshay/secure_content","owner":"codenameakshay","description":"Protect your app from screenshots, screen recording \u0026 on recent apps screen. Necessary for bank/payment/security apps. Works for both Android \u0026 iOS, and is in development.","archived":false,"fork":false,"pushed_at":"2025-10-09T10:58:25.000Z","size":11618,"stargazers_count":8,"open_issues_count":1,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-09T12:34:06.025Z","etag":null,"topics":["android","dart","flutter","flutter-plugin","ios"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/secure_content","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codenameakshay.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-10-04T16:58:37.000Z","updated_at":"2025-10-09T10:58:30.000Z","dependencies_parsed_at":"2024-09-03T13:52:18.242Z","dependency_job_id":"ed42a6d9-1458-4f32-9259-0c380c63f2c6","html_url":"https://github.com/codenameakshay/secure_content","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/codenameakshay/secure_content","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codenameakshay%2Fsecure_content","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codenameakshay%2Fsecure_content/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codenameakshay%2Fsecure_content/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codenameakshay%2Fsecure_content/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codenameakshay","download_url":"https://codeload.github.com/codenameakshay/secure_content/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codenameakshay%2Fsecure_content/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001439,"owners_count":26083078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","dart","flutter","flutter-plugin","ios"],"created_at":"2024-09-24T13:45:20.464Z","updated_at":"2025-10-09T12:34:06.662Z","avatar_url":"https://github.com/codenameakshay.png","language":"Dart","readme":"\u003c!--\nThis README describes the package. If you publish this package to pub.dev,\nthis README's contents appear on the landing page for your package.\n\nFor information about how to write a good package README, see the guide for\n[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).\n\nFor general information about developing packages, see the Dart guide for\n[creating packages](https://dart.dev/guides/libraries/create-library-packages)\nand the Flutter guide for\n[developing packages and plugins](https://flutter.dev/developing-packages).\n--\u003e\n\n\u003ch1 align=\"center\"\u003eSecure Content\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eA flutter package which allows Flutter apps to wrap up some widgets with a SecureWidget which can stop user from screen recording or screenshot the widget. Works on both Android \u0026 iOS.\u003c/p\u003e\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://flutter.dev\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Platform-Flutter-02569B?logo=flutter\"\n      alt=\"Platform\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pub.dartlang.org/packages/secure_content\"\u003e\n    \u003cimg src=\"https://img.shields.io/pub/v/secure_content.svg\"\n      alt=\"Pub Package\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/license/aagarwal1012/animated-text-kit?color=red\"\n      alt=\"License: MIT\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.paypal.me/codenameakshay\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Donate-PayPal-00457C?logo=paypal\"\n      alt=\"Donate\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\u003cbr\u003e\n\n## Screenshots\n\n|                                      Android (screen recording)                                       |                   iOS (screenshot)                    |                             iOS (screen recording)                              |                               iOS (app switcher)                                |\n| :---------------------------------------------------------------------------------------------------: | :---------------------------------------------------: | :-----------------------------------------------------------------------------: | :-----------------------------------------------------------------------------: |\n| https://user-images.githubusercontent.com/60510869/154502746-830d9198-8f11-46ba-9246-784def00f610.mp4 | \u003cimg src=\"screenshot/screenshot_ios.PNG\" width=\"300\"\u003e | https://github.com/user-attachments/assets/0b4e10ac-d592-4b5b-92bf-72f51b2cf570 | https://github.com/user-attachments/assets/b6ef5914-eb3a-4e17-be0c-2f00538cffec |\n\n## Features\n\n- 🔒 **Screenshot Protection**: Prevents users from taking screenshots of sensitive content\n- 📹 **Screen Recording Protection**: Blocks screen recording attempts\n- 📱 **App Switcher Protection**: Secures content in the app switcher preview\n- ⚡ **Dynamic Security**: Enable/disable protection on the fly\n- 🎨 **Customizable Overlay**: Define custom widgets to show when content is protected\n- 📢 **Event Callbacks**: Get notified of screenshot and recording attempts\n- 💪 **Cross-Platform**: Works on both Android \u0026 iOS\n- 🔄 **State Aware**: Maintains security across route transitions\n\n## Installation\n\nAdd this to your package's `pubspec.yaml` file:\n\n```yaml\ndependencies:\n  secure_content: ^1.0.1\n```\n\n## Basic Setup\n\n1. First, wrap your MaterialApp with Portal widget:\n\n```dart\nvoid main() {\n  runApp(\n    Portal(\n      child: MaterialApp(\n        home: MyHomePage(),\n      ),\n    ),\n  );\n}\n```\n\n2. Import the package:\n\n```dart\nimport 'package:secure_content/secure_content.dart';\n```\n\n## 🚨 Important Note\n\nThis package requires wrapping your `MaterialApp` with the `Portal` widget from the `flutter_portal` package. This is a crucial step to make the secure content functionality work properly. Here's how to do it:\n\n```dart\nimport 'package:flutter_portal/flutter_portal.dart';\n\n// In your app's root widget:\nreturn Portal(\n  child: MaterialApp(\n    // Your MaterialApp configuration\n  ),\n);\n```\n\nIf you don't wrap your `MaterialApp` with `Portal`, you'll encounter the following error:\n\n```\nPortalNotFoundError: Could not find a Portal above this PortalTarget\n```\n\n## Usage\n\n### Basic Implementation\n\nWrap any widget that needs to be protected with `SecureWidget`:\n\n```dart\nSecureWidget(\n  isSecure: true,\n  builder: (context, onInit, onDispose) =\u003e Text(\n    'This content is protected',\n    style: Theme.of(context).textTheme.headlineMedium,\n  ),\n)\n```\n\n### Advanced Implementation\n\n```dart\nSecureWidget(\n  isSecure: true,\n  onScreenshotCaptured: () {\n    // Handle screenshot attempt\n    print('Screenshot attempted!');\n  },\n  onScreenRecordingStart: () {\n    // Handle recording start\n    print('Screen recording started!');\n  },\n  onScreenRecordingStop: () {\n    // Handle recording stop\n    print('Screen recording stopped!');\n  },\n  builder: (context, onInit, onDispose) =\u003e YourWidget(),\n  overlayWidgetBuilder: (context) =\u003e BackdropFilter(\n    filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),\n    child: const SizedBox(),\n  ),\n  appSwitcherMenuColor: Colors.black,\n  protectInAppSwitcherMenu: true,\n)\n```\n\n## Configuration Options\n\n| Parameter                  | Type                                                        | Description                              |\n| -------------------------- | ----------------------------------------------------------- | ---------------------------------------- |\n| `isSecure`                 | `bool`                                                      | Enable/disable protection                |\n| `builder`                  | `Widget Function(BuildContext, VoidCallback, VoidCallback)` | Builder for the protected content        |\n| `overlayWidgetBuilder`     | `Widget Function(BuildContext)?`                            | Custom overlay when content is protected |\n| `onScreenshotCaptured`     | `VoidCallback?`                                             | Callback for screenshot attempts         |\n| `onScreenRecordingStart`   | `VoidCallback?`                                             | Callback when recording starts           |\n| `onScreenRecordingStop`    | `VoidCallback?`                                             | Callback when recording stops            |\n| `debug`                    | `bool`                                                      | Show overlay widget for debugging        |\n| `protectInAppSwitcherMenu` | `bool`                                                      | Enable protection in app switcher        |\n| `appSwitcherMenuColor`     | `Color`                                                     | Background color in app switcher         |\n\n## Protecting Entire App\n\nTo protect your entire app on Android:\n\n```dart\nfinal secureContent = SecureContent();\n\n// Enable protection\nsecureContent.preventScreenshotAndroid(true);\n\n// Disable protection\nsecureContent.preventScreenshotAndroid(false);\n```\n\n## Platform-Specific Behavior\n\n### Feature Comparison\n\n| Feature                         | iOS                                   | Android                 |\n| ------------------------------- | ------------------------------------- | ----------------------- |\n| Screenshot Prevention           | ✅                                    | ✅                      |\n| Screen Recording Prevention     | ✅ (Shows black screen)               | ✅ (Shows black screen) |\n| Screenshot Detection Callback   | ✅                                    | ❌                      |\n| Screen Recording Start Callback | ✅                                    | ❌                      |\n| Screen Recording Stop Callback  | ✅                                    | ❌                      |\n| App Switcher Protection         | ✅                                    | ✅                      |\n| Custom Overlay Support          | ✅                                    | ✅                      |\n| Dynamic Security Toggle         | ✅                                    | ✅                      |\n| Full App Protection             | ✅ (Add widget to top of widget tree) | ✅                      |\n\n### iOS\n\n- Shows black screen during screen recording\n- Prevents screenshots\n- Provides callbacks for screenshot and screen recording events\n- Customizable protection in app switcher\n- Protection is widget-specific\n\n### Android\n\n- Blocks screenshots\n- Shows black screen during recording\n- No callback support for detection events\n- Supports full app protection through `preventScreenshotAndroid()`\n- Protection can be applied globally or widget-specific\n\n## Best Practices\n\n1. **Platform-Specific Implementation**:\n\n   - For iOS, utilize callbacks to provide user feedback\n   - For Android, consider using global protection if needed\n   - For iOS, use `SecureWidget` at the top of the widget tree, for global protection\n\n   ```dart\n   // iOS-specific implementation\n   SecureWidget(\n     isSecure: true,\n     onScreenshotCaptured: Platform.isIOS ? () {\n       // Only triggered on iOS\n       showAlert('Screenshot attempted');\n     } : null,\n     builder: (context, onInit, onDispose) =\u003e YourWidget(),\n   )\n\n   // Android global protection\n   if (Platform.isAndroid) {\n     SecureContent().preventScreenshotAndroid(true);\n   }\n   ```\n\n2. **Performance**: Only wrap widgets that need protection to maintain optimal performance\n3. **State Management**: Use `isSecure` to dynamically toggle protection\n4. **User Experience**: Provide alternative feedback mechanisms for Android\n5. **Testing**: Test protection in both debug and release modes on both platforms\n\n## Example\n\nA complete example showing different use cases:\n\n```dart\nclass SecureScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: Text('Secure Screen')),\n      body: Column(\n        children: [\n          // Regular content\n          Text('This content can be captured'),\n\n          // Secure content\n          SecureWidget(\n            isSecure: true,\n            onScreenshotCaptured: () {\n              ScaffoldMessenger.of(context).showSnackBar(\n                SnackBar(content: Text('Screenshots not allowed!')),\n              );\n            },\n            builder: (context, onInit, onDispose) =\u003e Container(\n              padding: EdgeInsets.all(16),\n              child: Text('This content is protected'),\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","funding_links":["https://www.paypal.me/codenameakshay"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodenameakshay%2Fsecure_content","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodenameakshay%2Fsecure_content","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodenameakshay%2Fsecure_content/lists"}