Flutter
외부 앱에서 데이터 전달 받기 : receive_sharing_intent(2)_안드로이드 성공
전기Man
2022. 7. 24. 20:57
1. main.dart(시작점)
import 'dart:async';
import 'package:receive_intent/home_screen.dart';
import 'package:receive_intent/init_data.dart';
import 'package:receive_intent/show_data_argument.dart';
import 'package:receive_intent/show_data_screen.dart';
import 'package:flutter/material.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
const String homeRoute = "home";
const String showDataRoute = "showData";
Future<InitData> init() async { //1. 화면 초기화 InitData(this.sharedText, this.routeName)
String sharedText = "";
String routeName = homeRoute;
//This shared intent work when application is closed
String? sharedValue = await ReceiveSharingIntent.getInitialText(); //2. receive_sharing_intent.dart 여기에서 받는 정보
if (sharedValue != null) {
sharedText = sharedValue;
routeName = showDataRoute;
}
return InitData(sharedText, routeName); //3. null이면 homeRoute, 아니면 showDataRoute
}
void main() async {
WidgetsFlutterBinding.ensureInitialized(); //4. 서버나 SharedPreferences 등 비동기로 데이터를 다룬 다음 runApp을 실행해야하는 경우 아래 한줄을 반드시 추가해야합니다.
InitData initData = await init(); //5. 호출..
runApp(MyApp(initData: initData)); //6. 호출된 값을 전달해준다. 네임드 아규먼트로...
}
class MyApp extends StatefulWidget {
const MyApp({Key? key, required this.initData}) : super(key: key); //7. 네임드 아규먼트 생성자..
final InitData initData; //8. 네임드 아규먼트 생성자 변수 선언
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _navKey = GlobalKey<NavigatorState>(); //9. 글로벌키 생성...네비게이터 스테이트를 위해서..
late StreamSubscription _intentDataStreamSubscription; //10. 일종의 스트림 변수 선언
@override
void initState() {
super.initState();
//This shared intent work when application is in memory
_intentDataStreamSubscription = //11. 스티림이란, receive_sharing_intent.dart를 통해서 텍스트를 받는다는 의미 같음.
ReceiveSharingIntent.getTextStream().listen((String value) {
_navKey.currentState!.pushNamed(
showDataRoute, //_navKey는 네비게이션 추적을 위한 키이고, pushNamed를 통해 값을 입력받는다고 이해하자.
arguments: ShowDataArgument(value), //13. ShowDataArgument는 변수 하나를 받는 자료형 정도로 이해하자.
);
});
}
@override
void dispose() {
super.dispose();
_intentDataStreamSubscription.cancel();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navKey, //15. MaterialApp에 있는 네임드아규먼트로, key가 navigation을 추적하게 된다. without context
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.red,
),
onGenerateRoute: (RouteSettings settings) { //name router를 설정하기 위한 프로퍼티
switch (settings.name) { //여기에 name 이란 것은, 아마도 위에서 pushNamed에서 밀어넣어준, showDataRoute가 되는 것이겠지...
case homeRoute:
return MaterialPageRoute(builder: (_) => HomeScreen());
case showDataRoute:
{
if (settings.arguments != null) { //여기의 RouteSettings 와 위의 StreamSubscription 은 서로 바인딩 돼 있는듯
final args = settings.arguments as ShowDataArgument; //변수 하나에 값을 넣어준다.
return MaterialPageRoute(
builder: (BuildContext context) => ShowDataScreen(
sharedText: args.sharedText,)
);// 값을 전달한다.
// builder: (_) 와 builder: (BuildContext context) 같은 의미다.
} else {
return MaterialPageRoute(
builder: (_) => ShowDataScreen(
sharedText: widget.initData.sharedText,
));
}
}
}
},
initialRoute: widget.initData.routeName,
);
}
}
2. init_data.dart
//일종의 자료형이다...
class InitData {
final String sharedText;
final String routeName;
InitData(this.sharedText, this.routeName);
}
3. show_data_argument.dart
class ShowDataArgument {
String sharedText;
ShowDataArgument(this.sharedText);
}
4. 인텐트 전달받을때 화면.dart
import 'package:flutter/material.dart';
class OptionValue { //키 밸류의 자료형을 생성한다.
final int _key;
final String _value;
OptionValue(this._key, this._value); //키 밸류 생성자..
}
class ShowDataScreen extends StatefulWidget {
ShowDataScreen({Key? key, this.sharedText}); //생성될때 sharedText를 넘겨 받는다.
String? sharedText = "";
@override
State<ShowDataScreen> createState() => _ShowDataScreenState();
}
class _ShowDataScreenState extends State<ShowDataScreen> {
int _currentValue = 1; //라디오버튼 초기 값..
final _buttonOptions = [ //맵 자료형 하나 만든다.
OptionValue(1, '아이폰최신정보'),
OptionValue(2, '사고싶은거'),
OptionValue(3, '코딩공부'),
OptionValue(4, '재밌는거'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Show Data Screen"),
),
body: Column(
children: [
Expanded(
child: ListView(
padding: EdgeInsets.all(8.0),
children: _buttonOptions
.map((optionValue) => RadioListTile<int>(
groupValue: _currentValue,
title: Text(optionValue._value),
value: optionValue._key,
onChanged: (val) {
setState(() {
_currentValue = val!;
});
},
))
.toList(),
),
),
SizedBox(height: 20),
Text(widget.sharedText ?? '', //sharedText가 null이면 ''을 출력
style: const TextStyle(fontSize: 20)),
SizedBox(height: 150),
],
));
}
}