share_intent_package 1.0.25
share_intent_package: ^1.0.25 copied to clipboard
Zero-configuration Flutter share intent plugin. Receive shared content from other apps with one-command setup. Fully automated iOS ShareExtension + Android intent filters.
example/lib/main.dart
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:share_intent_package/share_intent_package.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Share Intent Test',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const ShareTestPage(),
);
}
}
class ShareTestPage extends StatefulWidget {
const ShareTestPage({super.key});
@override
State<ShareTestPage> createState() => _ShareTestPageState();
}
class _ShareTestPageState extends State<ShareTestPage> {
StreamSubscription? _subscription;
SharedData? _sharedData;
String _status = 'Waiting for shared content...';
@override
void initState() {
super.initState();
_initSharing();
}
Future<void> _initSharing() async {
try {
// Initialize the plugin
await ShareIntentPackage.instance.init();
// Get initial sharing data (if app was opened via share)
final initial = await ShareIntentPackage.instance.getInitialSharing();
if (initial != null && initial.hasContent) {
setState(() {
_sharedData = initial;
_status = 'Received initial shared content!';
});
}
// Listen for shares while app is running
_subscription = ShareIntentPackage.instance.getMediaStream().listen((
data,
) {
setState(() {
_sharedData = data;
_status = 'Received new shared content!';
});
});
setState(() {
if (_sharedData == null) {
_status = 'Plugin initialized. Share something to this app!';
}
});
} catch (e) {
setState(() {
_status = 'Error initializing: $e';
});
}
}
@override
void dispose() {
_subscription?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Share Intent Test'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Status Card
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Status',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
Text(_status),
],
),
),
),
const SizedBox(height: 16),
// Shared Data Card
if (_sharedData != null) ...[
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Shared Content',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 16),
// Content Type
_buildInfoRow('Type', _getContentType()),
const SizedBox(height: 8),
// MIME Type
if (_sharedData!.mimeType != null)
_buildInfoRow('MIME Type', _sharedData!.mimeType!),
// Text Content
if (_sharedData!.text != null) ...[
const SizedBox(height: 8),
_buildInfoRow('Text', _sharedData!.text!),
],
// File Paths
if (_sharedData!.filePaths.isNotEmpty) ...[
const SizedBox(height: 16),
Text(
'Files (${_sharedData!.filePaths.length}):',
style: Theme.of(context).textTheme.titleSmall,
),
const SizedBox(height: 8),
..._sharedData!.filePaths.map((path) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
path,
style: Theme.of(context).textTheme.bodySmall,
),
const SizedBox(height: 8),
// Show image preview if it's an image
if (_isImageFile(path))
ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.file(
File(path),
height: 200,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return Container(
height: 100,
color: Colors.grey[300],
child: const Center(
child: Text('Could not load image'),
),
);
},
),
),
const SizedBox(height: 16),
],
);
}),
],
],
),
),
),
] else ...[
Card(
child: Padding(
padding: const EdgeInsets.all(32),
child: Center(
child: Column(
children: [
Icon(Icons.share, size: 64, color: Colors.grey[400]),
const SizedBox(height: 16),
Text(
'No shared content yet',
style: Theme.of(context).textTheme.titleMedium
?.copyWith(color: Colors.grey[600]),
),
const SizedBox(height: 8),
Text(
'Share an image, text, or URL from another app to test',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium
?.copyWith(color: Colors.grey[500]),
),
],
),
),
),
),
],
const SizedBox(height: 24),
// Instructions Card
Card(
color: Colors.blue[50],
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.info_outline, color: Colors.blue[700]),
const SizedBox(width: 8),
Text(
'How to Test',
style: Theme.of(context).textTheme.titleMedium
?.copyWith(color: Colors.blue[700]),
),
],
),
const SizedBox(height: 12),
Text(
'1. Open your photo gallery or browser\n'
'2. Select an image, video, or copy a URL\n'
'3. Tap the share button\n'
'4. Select this app from the share menu\n'
'5. The shared content will appear here',
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_sharedData = null;
_status = 'Cleared. Waiting for shared content...';
});
},
tooltip: 'Clear',
child: const Icon(Icons.clear),
),
);
}
Widget _buildInfoRow(String label, String value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 80,
child: Text(
'$label:',
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(child: Text(value)),
],
);
}
String _getContentType() {
if (_sharedData == null) return 'Unknown';
if (_sharedData!.isImage) return 'Image';
if (_sharedData!.isVideo) return 'Video';
if (_sharedData!.isUrl) return 'URL';
if (_sharedData!.isText) return 'Text';
if (_sharedData!.isMedia) return 'File';
return 'Unknown';
}
bool _isImageFile(String path) {
final lower = path.toLowerCase();
return lower.endsWith('.jpg') ||
lower.endsWith('.jpeg') ||
lower.endsWith('.png') ||
lower.endsWith('.gif') ||
lower.endsWith('.webp') ||
lower.endsWith('.bmp');
}
}