You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

327 lines
10 KiB

2 years ago
<p align="center">
<a href="https://pub.dev/packages/telephony" alt="Pub">
<img src="https://img.shields.io/pub/v/telephony" /></a>
<a href="https://github.com/shounakmulay/Telephony/releases" alt="Release">
<img src="https://img.shields.io/github/v/release/shounakmulay/telephony" /></a>
<a href="https://github.com/shounakmulay/Telephony/actions/workflows/Telephony_CI.yml?query=branch%3Adevelop" alt="Build">
<img src="https://github.com/shounakmulay/telephony/actions/workflows/Telephony_CI.yml/badge.svg?branch=develop" /></a>
</p>
# Telephony
|:exclamation: This plugin currently only works on Android Platform|
|------------------------------------------------------------------|
A Flutter plugin to use telephony features such as
- Send SMS Messages
- Query SMS Messages
- Listen for incoming SMS
- Retrieve various network parameters
- Start phone calls
This plugin tries to replicate some of the functionality provided by Android's [Telephony](https://developer.android.com/reference/android/provider/Telephony) class.
Check the [Features section](#Features) to see the list of implemented and missing features.
## Get Started
### :bulb: View the **[entire documentation here](https://telephony.shounakmulay.dev/)**.
## Usage
To use this plugin add `telephony` as a [dependency in your pubspec.yaml file](https://flutter.dev/docs/development/packages-and-plugins/using-packages).
##### Versions [0.0.9](https://pub.dev/packages/telephony/versions/0.0.9) and lower are not null safe.
##### Versions [0.1.0](https://pub.dev/packages/telephony/versions/0.1.0) and above opt into null safety.
### Setup
Import the `telephony` package
```dart
import 'package:telephony/telephony.dart';
```
Retrieve the singleton instance of `telephony` by calling
```dart
final Telephony telephony = Telephony.instance;
```
### [Permissions](https://shounakmulay.gitbook.io/telephony/permissions)
**Although this plugin will check and ask for permissions at runtime, it is advisable to _manually ask for permissions_ before calling any other functions.**
The plugin will only request those permission that are listed in the `AndroidManifest.xml`.
Manually request permission using
```dart
bool permissionsGranted = await telephony.requestPhoneAndSmsPermissions;
```
You can also request SMS or Phone permissions separately using `requestSmsPermissions` or `requestPhonePermissions` respectively.
### [Send SMS](https://shounakmulay.gitbook.io/telephony/sending-an-sms)
:exclamation: Requires `SEND_SMS` permission.
Add the following permission in your `AndroidManifest.xml`
```xml
<uses-permission android:name="android.permission.SEND_SMS"/>
```
SMS can either be sent directly or via the default SMS app.
#### Send SMS directly from your app:
```dart
telephony.sendSms(
to: "1234567890",
message: "May the force be with you!"
);
```
If you want to listen to the status of the message being sent, provide `SmsSendStatusListener` to the `sendSms` function.
```dart
final SmsSendStatusListener listener = (SendStatus status) {
// Handle the status
};
telephony.sendSms(
to: "1234567890",
message: "May the force be with you!",
statusListener: listener
);
```
If the body of the message is longer than the standard SMS length limit of `160 characters`, you can send a multipart SMS by setting the `isMultipart` flag.
#### Send SMS via the default SMS app:
```dart
telephony.sendSmsByDefaultApp(to: "1234567890", message: "May the force be with you!");
```
### [Query SMS](https://shounakmulay.gitbook.io/telephony/query-sms)
:exclamation: Requires `READ_SMS` permission.
Add the following permission in your `AndroidManifest.xml`
```xml
<uses-permission android:name="android.permission.READ_SMS"/>
```
Use one of `getInboxSms()`, `getSentSms()` or `getDraftSms()` functions to query the messages on device.
You can provide the list of `SmsColumns` that need to be returned by the query.
If not explicitly specified, defaults to `[
SmsColumn.ID,
SmsColumn.ADDRESS,
SmsColumn.BODY,
SmsColumn.DATE
]`
Provide a `SmsFilter` to filter the results of the query. Functions like a `SQL WHERE` clause.
Provide a list of `OrderBy` objects to sort the results. The level of importance is determined by the position of `OrderBy` in the list.
All paramaters are optional.
```dart
List<SmsMessage> messages = await telephony.getInboxSms(
columns: [SmsColumn.ADDRESS, SmsColumn.BODY],
filter: SmsFilter.where(SmsColumn.ADDRESS)
.equals("1234567890")
.and(SmsColumn.BODY)
.like("starwars"),
sortOrder: [OrderBy(SmsColumn.ADDRESS, sort: Sort.ASC),
OrderBy(SmsColumn.BODY)]
);
```
### [Query Conversations](https://shounakmulay.gitbook.io/telephony/query-conversations)
:exclamation: Requires `READ_SMS` permission.
Add the following permission in your `AndroidManifest.xml`
```xml
<uses-permission android:name="android.permission.READ_SMS"/>
```
Works similar to [SMS queries](#query-sms).
All columns are returned with every query. They are `[
ConversationColumn.SNIPPET,
ConversationColumn.THREAD_ID,
ConversationColumn.MSG_COUNT
]`
Uses `ConversationFilter` instead of `SmsFilter`.
```dart
List<SmsConversation> messages = await telephony.getConversations(
filter: ConversationFilter.where(ConversationColumn.MSG_COUNT)
.equals("4")
.and(ConversationColumn.THREAD_ID)
.greaterThan("12"),
sortOrder: [OrderBy(ConversationColumn.THREAD_ID, sort: Sort.ASC)]
);
```
### [Listen to incoming SMS](https://shounakmulay.gitbook.io/telephony/listen-incoming-sms)
:exclamation: Requires `RECEIVE_SMS` permission.
1. To listen to incoming SMS add the `RECEIVE_SMS` permission to your `AndroidManifest.xml` file and register the `BroadcastReceiver`.
```xml
<manifest>
<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>
```
2. Create a **top-level static function** to handle incoming messages when app is not is foreground.
:warning: Avoid heavy computations in the background handler as Android system may kill long running operations in the background.
```dart
backgrounMessageHandler(SmsMessage message) async {
//Handle background message
}
void main() {
runApp(MyApp());
}
```
3. Call `listenIncomingSms` with a foreground `MessageHandler` and pass in the static `backgrounMessageHandler`.
```dart
telephony.listenIncomingSms(
onNewMessage: (SmsMessage message) {
// Handle message
},
onBackgroundMessage: backgroundMessageHandler
);
```
Preferably should be called early in app lifecycle.
4. If you do not wish to receive incoming SMS when the app is in background, just do not pass the `onBackgroundMessage` paramater.
Alternatively if you prefer to expecility disable background execution, set the `listenInBackground` flag to `false`.
```dart
telephony.listenIncomingSms(
onNewMessage: (SmsMessage message) {
// Handle message
},
listenInBackground: false
);
```
5. As of the `1.12` release of Flutter, plugins are automatically registered. This will allow you to use plugins as you normally do even in the background execution context.
```dart
backgrounMessageHandler(SmsMessage message) async {
// Handle background message
// Use plugins
Vibration.vibrate(duration: 500);
}
```
### [Network data and metrics](https://shounakmulay.gitbook.io/telephony/network-data-and-metrics)
Fetch various metrics such as `network type`, `sim state`, etc.
```dart
// Check if a device is capable of sending SMS
bool canSendSms = await telephony.isSmsCapable;
// Get sim state
SimState simState = await telephony.simState;
```
Check out the [detailed documentation](https://shounakmulay.gitbook.io/telephony/network-data-and-metrics) to know all possible metrics and their values.
### Executing in background
If you want to call the `telephony` methods in background, you can do in the following ways.
#### 1. Using only `Telephony.instance`
If you want to continue using `Telephony.instance` in the background, you will need to make sure that once the app comes back to the front, it again calls `Telephony.instance`.
```dart
backgrounMessageHandler(SmsMessage message) async {
// Handle background message
Telephony.instance.sendSms(to: "123456789", message: "Message from background")
}
void main() {
runApp(MyApp());
}
class _MyAppState extends State<MyApp> {
String _message;
// This will not work as the instance will be replaced by
// the one in background.
final telephony = Telephony.instance;
@override
void initState() {
super.initState();
// You should make sure call to instance is made every time
// app comes to foreground
final inbox = Telephony.instance.getInboxSms()
}
```
#### 2. Use `backgroundInstance`
If you cannot make sure that the call to instance would be made every time app comes to foreground, or if you would prefer to maintain a separate background instance,
you can use `Telephony.backgroundInstance` in the background execution context.
```dart
backgrounMessageHandler(SmsMessage message) async {
// Handle background message
Telephony.backgroundInstance.sendSms(to: "123456789", message: "Message from background")
}
void main() {
runApp(MyApp());
}
class _MyAppState extends State<MyApp> {
String _message;
final telephony = Telephony.instance;
@override
void initState() {
super.initState();
final inbox = telephony.getInboxSms()
}
```
## Features
- [x] [Send SMS](#send-sms)
- [x] [Query SMS](#query-sms)
- [x] Inbox
- [x] Sent
- [x] Draft
- [x] [Query Conversations](#query-conversations)
- [x] [Listen to incoming SMS](#listen-to-incoming-sms)
- [x] When app is in foreground
- [x] When app is in background
- [x] [Network data and metrics](#network-data-and-metrics)
- [x] Cellular data state
- [x] Call state
- [x] Data activity
- [x] Network operator
- [x] Network operator name
- [x] Data network type
- [x] Phone type
- [x] Sim operator
- [x] Sim operator name
- [x] Sim state
- [x] Network roaming
- [x] Signal strength
- [x] Service state
- [x] Start Phone Call
- [ ] Schedule a SMS
- [ ] SMS Retriever API