Implementing Flutter BLoC to Handle Receive Sharing Intent
3 min readNov 19, 2024
In this tutorial, we will use Flutter’s BLoC (Business Logic Component) pattern to receive and display shared files. We’ll integrate the receive_sharing_intent
package to listen for incoming shared media and show them in a dynamic list.
Setup the Project
Dependencies
Add these dependencies to your pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.0.0
receive_sharing_intent: ^1.5.1
freezed_annotation: ^2.2.0
dartz: ^0.10.1
injectable: ^2.1.0
json_annotation: ^4.7.0
dev_dependencies:
build_runner: ^2.3.3
freezed: ^2.2.0
Code Implementation
Main Application
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'application/counter/counter_bloc.dart';
import 'application/internet_connection/internet_connection_bloc.dart';
import 'application/reciveshare/reciveshare_bloc.dart';
import 'domain/core/dependencies_injection/injectable.dart';
import 'presentation/home_page.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
configureDependencies(); // Dependency injection setup
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => getIt<ReciveshareBloc>()),
],
child: MaterialApp(
home: HomePage(),
),
);
}
}
Home Page (UI)
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import '../application/reciveshare/reciveshare_bloc.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ReceiveSharingIntent.instance.getMediaStream().listen(
(sharedFiles) {
context
.read<ReciveshareBloc>()
.add(ReciveshareEvent.getShareData(sharedData: sharedFiles));
},
onError: (err) => print("Error receiving shared files: $err"),
);
ReceiveSharingIntent.instance.getInitialMedia().then((initialFiles) {
context
.read<ReciveshareBloc>()
.add(ReciveshareEvent.getShareData(sharedData: initialFiles));
ReceiveSharingIntent.instance.reset();
});
});
return Scaffold(
appBar: AppBar(title: const Text("Receive Shared Files")),
body: BlocConsumer<ReciveshareBloc, ReciveshareState>(
listener: (context, state) {},
builder: (context, state) {
return state.recivesharedata.isEmpty
? const Center(child: Text("No Shared Files"))
: ListView.builder(
itemCount: state.recivesharedata.length,
itemBuilder: (context, index) {
final file = state.recivesharedata[index];
return ListTile(
leading: file.file != null
? Image.file(File(file.file!))
: const Icon(Icons.file_copy),
title: Text(file.file ?? "No file path"),
subtitle: Text(file.text ?? "No additional data"),
);
},
);
},
),
);
}
}
ReciveShare Bloc
Events
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
part 'reciveshare_event.freezed.dart';
@freezed
class ReciveshareEvent with _$ReciveshareEvent {
const factory ReciveshareEvent.getShareData({
required List<SharedMediaFile> sharedData,
}) = _GetShareData;
}
State
import 'package:freezed_annotation/freezed_annotation.dart';
import '../model/reciveshare_model.dart';
part 'reciveshare_state.freezed.dart';
@freezed
class ReciveshareState with _$ReciveshareState {
const factory ReciveshareState({
required List<ReciveshareModel> recivesharedata,
}) = _ReciveshareState;
factory ReciveshareState.initial() =>
const ReciveshareState(recivesharedata: []);
}
Bloc
import 'package:bloc/bloc.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc_test/domain/failures/main_failures.dart';
import 'package:flutter_bloc_test/domain/reciveshare/model/resiveshare_model.dart';
import 'package:flutter_bloc_test/domain/reciveshare/reciveshare_service.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
part 'reciveshare_event.dart';
part 'reciveshare_state.dart';
part 'reciveshare_bloc.freezed.dart';
@injectable
class ReciveshareBloc extends Bloc<ReciveshareEvent, ReciveshareState> {
final GetreciveshareService getreciveshareService;
ReciveshareBloc(this.getreciveshareService)
: super(ReciveshareState.initial()) {
on<_GetShareData>((event, emit) async {
Either<MainFailures, List<ResiveshareModel>> dd =
await getreciveshareService.getReciveShareData(
reciveShareData: event.SharedData);
dd.fold(
(l) {},
(r) {
emit(state.copyWith(recivesharedata: r));
},
);
});
}
}
Service and Model
Model
class ReciveshareModel {
final String? file;
final String? text;
ReciveshareModel({this.file, this.text});
factory ReciveshareModel.fromJson(Map<String, dynamic> json) {
return ReciveshareModel(
file: json['file'] as String?,
text: json['text'] as String?,
);
}
Map<String, dynamic> toJson() => {
'file': file,
'text': text,
};
}
Service
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc_test/domain/reciveshare/model/resiveshare_model.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import '../failures/main_failures.dart';
abstract class GetreciveshareService {
Future<Either<MainFailures, List<ResiveshareModel>>> getReciveShareData(
{required List<SharedMediaFile> reciveShareData});
}
Impl
import 'dart:async';
import 'package:dartz/dartz.dart';
import 'package:flutter_bloc_test/domain/failures/main_failures.dart';
import 'package:flutter_bloc_test/domain/reciveshare/model/resiveshare_model.dart';
import 'package:flutter_bloc_test/domain/reciveshare/reciveshare_service.dart';
import 'package:injectable/injectable.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
@LazySingleton(as: GetreciveshareService)
class ReciveShareImpl implements GetreciveshareService {
@override
Future<Either<MainFailures, List<ResiveshareModel>>> getReciveShareData(
{required reciveShareData}) {
List<ResiveshareModel> RecivedData = [];
reciveShareData.forEach((dd) {
print(dd.toMap());
var data = {
"file": dd.path.toString(),
"text": dd.type.toString(),
"url": "",
};
RecivedData.add(ResiveshareModel.fromJson(data));
});
return Future.value(Right(RecivedData));
}
}
Conclusion
This single-page application demonstrates how to use Flutter’s BLoC architecture to handle shared files. Customize the UI and logic further as per your requirements.