share_intent_package 1.0.23
share_intent_package: ^1.0.23 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 '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(primarySwatch: Colors.blue),
home: const MyHomePage(title: 'Share Intent Test'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SharedData? _sharedData;
StreamSubscription? _intentDataStreamSubscription;
bool _isListening = false;
String _status = 'Waiting for share intents...';
@override
void initState() {
super.initState();
_initShareIntent();
}
@override
void dispose() {
_intentDataStreamSubscription?.cancel();
super.dispose();
}
void _initShareIntent() async {
try {
print('📱 Initializing ShareIntentPackage...');
// Get any existing shared data
final initialData = await ShareIntentPackage.instance.getInitialSharing();
if (initialData != null && initialData.hasContent) {
setState(() {
_sharedData = initialData;
_status = 'Found shared item on startup';
});
print('📱 Initial shared data: $initialData');
}
// Listen for new share intents
_intentDataStreamSubscription = ShareIntentPackage.instance
.getMediaStream()
.listen(
(SharedData data) {
print('📱 Received share intent stream data: $data');
if (mounted) {
setState(() {
_sharedData = data.hasContent ? data : null;
_isListening = true;
_status = data.hasContent
? 'Received shared item'
: 'Listening for share intents...';
});
}
},
onError: (error) {
print('❌ Share intent stream error: $error');
if (mounted) {
setState(() {
_status = 'Error: $error';
});
}
},
);
setState(() {
_isListening = true;
_status = _sharedData?.hasContent == true
? 'Found shared item on startup'
: 'Listening for share intents...';
});
} catch (e) {
print('❌ Failed to initialize ShareIntentPackage: $e');
setState(() {
_status = 'Failed to initialize: $e';
});
}
}
void _refreshSharedData() async {
try {
final data = await ShareIntentPackage.instance.getInitialSharing();
setState(() {
_sharedData = data;
_status = data?.hasContent == true
? 'Refreshed: Found shared item'
: 'No shared data found';
});
print('📱 Refreshed shared data: $data');
} catch (e) {
print('❌ Failed to refresh shared data: $e');
setState(() {
_status = 'Refresh failed: $e';
});
}
}
void _clearSharedData() async {
try {
setState(() {
_sharedData = null;
_status = 'Shared data cleared';
});
print('📱 Shared data cleared');
} catch (e) {
print('❌ Failed to clear shared data: $e');
setState(() {
_status = 'Clear failed: $e';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title), backgroundColor: Colors.blue),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// Status Section
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
_isListening
? Icons.radio_button_checked
: Icons.radio_button_off,
color: _isListening ? Colors.green : Colors.red,
),
const SizedBox(width: 8),
const Text(
'Listener Status',
style: TextStyle(fontWeight: FontWeight.bold),
),
],
),
const SizedBox(height: 8),
Text(_status),
],
),
),
),
const SizedBox(height: 16),
// Action Buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton.icon(
onPressed: _refreshSharedData,
icon: const Icon(Icons.refresh),
label: const Text('Refresh'),
),
ElevatedButton.icon(
onPressed: _clearSharedData,
icon: const Icon(Icons.clear),
label: const Text('Clear'),
),
],
),
const SizedBox(height: 16),
// Shared Data Section
const Text(
'Received Share Intents:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Expanded(
child: _sharedData?.hasContent != true
? const Card(
child: Center(
child: Padding(
padding: EdgeInsets.all(32.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.share, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text(
'No shared data yet',
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
),
SizedBox(height: 8),
Text(
'Share something from another app to test!',
style: TextStyle(
fontSize: 14,
color: Colors.grey,
),
textAlign: TextAlign.center,
),
],
),
),
),
)
: Card(
margin: const EdgeInsets.symmetric(vertical: 4),
child: ExpansionTile(
leading: Icon(
_getIconForMimeType(_sharedData!.mimeType),
color: Colors.blue,
),
title: const Text('Shared Content'),
subtitle: Text(
'Type: ${_sharedData!.mimeType ?? 'unknown'}',
),
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDetailRow(
'MIME Type',
_sharedData!.mimeType,
),
const SizedBox(height: 8),
_buildDetailRow('Text', _sharedData!.text),
const SizedBox(height: 8),
_buildDetailRow(
'File Paths',
_sharedData!.filePaths.join(', '),
),
const SizedBox(height: 8),
_buildDetailRow(
'Is URL',
_sharedData!.isUrl.toString(),
),
const SizedBox(height: 8),
_buildDetailRow(
'Is Image',
_sharedData!.isImage.toString(),
),
const SizedBox(height: 8),
_buildDetailRow(
'Is Video',
_sharedData!.isVideo.toString(),
),
const SizedBox(height: 8),
const Text(
'Raw Data:',
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 4),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
),
child: Text(
_sharedData.toString(),
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 12,
),
),
),
],
),
),
],
),
),
),
],
),
),
);
}
Widget _buildDetailRow(String label, dynamic value) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 80,
child: Text(
'$label:',
style: const TextStyle(fontWeight: FontWeight.bold),
),
),
Expanded(
child: Text(
value?.toString() ?? 'null',
style: const TextStyle(fontFamily: 'monospace'),
),
),
],
);
}
IconData _getIconForMimeType(String? mimeType) {
if (mimeType == null) return Icons.help;
if (mimeType.startsWith('image/')) {
return Icons.image;
} else if (mimeType.startsWith('video/')) {
return Icons.video_file;
} else if (mimeType.startsWith('audio/')) {
return Icons.audio_file;
} else if (mimeType.startsWith('text/')) {
return Icons.text_snippet;
} else {
return Icons.insert_drive_file;
}
}
}