moving to flutter comm
This commit is contained in:
parent
193d21a352
commit
276f97427d
33
CHANGELOG.md
33
CHANGELOG.md
@ -1,3 +1,36 @@
|
||||
## 1.0.1
|
||||
|
||||
* Android result added
|
||||
|
||||
## 1.0.0 * 04.29.2019
|
||||
|
||||
* Reduce minSdkVersion to 16
|
||||
* Fix crash on android when `recipients` is empty (substring on empty string)
|
||||
* Add `canSendSMS` API
|
||||
- Checks if device is SMS capable (iOS and Android)
|
||||
- Checks if `smsto:` Intent is resolved and resulting activity exported (Android)
|
||||
* sendSMS: Return error when device is not SMS capable (Android)
|
||||
* Remove unused AndroidX dependency
|
||||
* Use Intent.ACTION_SENDTO and Intent.EXTRA_TEXT to increase message app support coverage
|
||||
|
||||
## 0.2.0 * 04.06.2019
|
||||
|
||||
* Updating example to be desktop aware
|
||||
|
||||
## 0.1.0
|
||||
|
||||
* Fix for Android Multiple People
|
||||
* Fixes Issues #8 and #4
|
||||
|
||||
## 0.0.5
|
||||
|
||||
* Removed SMS Permissions on Android
|
||||
|
||||
## 0.0.4
|
||||
|
||||
* Bug Fix Send Result
|
||||
* Added Can Send Text
|
||||
|
||||
## 0.0.3
|
||||
|
||||
* Bug Fix for iOS Simulator Error
|
||||
|
58
README.md
58
README.md
@ -1,3 +1,59 @@
|
||||
[](https://www.buymeacoffee.com/rodydavis)
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WSH3GVC49GNNJ)
|
||||
|
||||
# flutter_sms
|
||||
|
||||
<h3 align="center">The <i>flutter_sms<i> plugin was moved to <a href='https://github.com/AppleEducate/plugins'>plugins/packages/flutter_sms</a></h3>
|
||||

|
||||
|
||||
## Description
|
||||
|
||||
Flutter Plugin for sending SMS and MMS on Android and iOS. If you send to more than one person it will send as MMS. On the iOS if the number is an iPhone and iMessage is enabled it will send as an iMessage.
|
||||
|
||||
## How To Use
|
||||
|
||||
You can send multiple ways:
|
||||
|
||||
1. Message and No People
|
||||
2. People and No Message
|
||||
3. Message and People
|
||||
|
||||
This will populate the correct fields.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
Make sure to Install and Import the Package.
|
||||
|
||||
``` dart
|
||||
import 'package:flutter_sms/flutter_sms.dart';
|
||||
```
|
||||
|
||||
Create a function for sending messages.
|
||||
|
||||
``` dart
|
||||
void _sendSMS(String message, List<String> recipents) async {
|
||||
String _result = await FlutterSms
|
||||
.sendSMS(message: message, recipients: recipents)
|
||||
.catchError((onError) {
|
||||
print(onError);
|
||||
});
|
||||
print(_result);
|
||||
}
|
||||
```
|
||||
|
||||
You can quickly send the message with this function.
|
||||
|
||||
``` dart
|
||||
String message = "This is a test message!";
|
||||
List<String> recipents = ["1234567890", "5556787676"];
|
||||
|
||||
_sendSMS(message, recipents);
|
||||
```
|
||||
|
||||
## Screenshots
|
||||
|
||||
iOS SMS | Android MMS
|
||||
:-------------------------:|:-------------------------:
|
||||
 | 
|
||||
|
||||
You can find other [screenshots here](https://github.com/AppleEducate/flutter_sms/tree/master/screenshots).
|
||||
|
0
android/.classpath
Normal file → Executable file
0
android/.classpath
Normal file → Executable file
0
android/.gitignore
vendored
Normal file → Executable file
0
android/.gitignore
vendored
Normal file → Executable file
0
android/.idea/.name
Normal file → Executable file
0
android/.idea/.name
Normal file → Executable file
BIN
android/.idea/caches/build_file_checksums.ser
Normal file → Executable file
BIN
android/.idea/caches/build_file_checksums.ser
Normal file → Executable file
Binary file not shown.
0
android/.idea/codeStyles/Project.xml
Normal file → Executable file
0
android/.idea/codeStyles/Project.xml
Normal file → Executable file
3
android/.idea/gradle.xml
Normal file → Executable file
3
android/.idea/gradle.xml
Normal file → Executable file
@ -3,6 +3,9 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<compositeConfiguration>
|
||||
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
||||
</compositeConfiguration>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
|
14
android/.idea/misc.xml
Normal file → Executable file
14
android/.idea/misc.xml
Normal file → Executable file
@ -5,22 +5,32 @@
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="5">
|
||||
<list size="10">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
||||
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
|
||||
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<list size="9">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
||||
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
|
||||
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
|
||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
|
1
android/.idea/modules.xml
Normal file → Executable file
1
android/.idea/modules.xml
Normal file → Executable file
@ -3,6 +3,7 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/flutter_sms.iml" filepath="$PROJECT_DIR$/flutter_sms.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/flutter_sms.iml" filepath="$PROJECT_DIR$/flutter_sms.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
0
android/.idea/runConfigurations.xml
Normal file → Executable file
0
android/.idea/runConfigurations.xml
Normal file → Executable file
0
android/.project
Normal file → Executable file
0
android/.project
Normal file → Executable file
2
android/.settings/org.eclipse.buildship.core.prefs
Normal file → Executable file
2
android/.settings/org.eclipse.buildship.core.prefs
Normal file → Executable file
@ -1,2 +1,2 @@
|
||||
connection.project.dir=
|
||||
connection.project.dir=../example/android
|
||||
eclipse.preferences.version=1
|
||||
|
@ -1,62 +0,0 @@
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
throw new GradleException("versionCode not found. Define flutter.versionCode in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
throw new GradleException("versionName not found. Define flutter.versionName in the local.properties file.")
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.appleeducate.fluttersms"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 27
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
implementation 'com.android.support:support-v4:27.1.0'
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.appleeducate.fluttersms">
|
||||
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="flutter_sms"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- This keeps the window background of the activity showing
|
||||
until Flutter renders its first frame. It can be removed if
|
||||
there is no splash screen (such as the default splash screen
|
||||
defined in @style/LaunchTheme). -->
|
||||
<meta-data
|
||||
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
|
||||
android:value="true" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
@ -1,13 +0,0 @@
|
||||
package com.appleeducate.fluttersms;
|
||||
|
||||
import android.os.Bundle;
|
||||
import io.flutter.app.FlutterActivity;
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
GeneratedPluginRegistrant.registerWith(this);
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
Binary file not shown.
Before Width: | Height: | Size: 544 B |
Binary file not shown.
Before Width: | Height: | Size: 442 B |
Binary file not shown.
Before Width: | Height: | Size: 721 B |
Binary file not shown.
Before Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
</resources>
|
13
android/build.gradle
Normal file → Executable file
13
android/build.gradle
Normal file → Executable file
@ -5,10 +5,11 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,23 +17,21 @@ rootProject.allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
compileSdkVersion 28
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
targetSdkVersion 28
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api 'com.android.support:appcompat-v7:27.1.0'
|
||||
}
|
||||
|
0
android/gradle.properties
Normal file → Executable file
0
android/gradle.properties
Normal file → Executable file
0
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file → Executable file
0
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file → Executable file
4
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file → Executable file
4
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file → Executable file
@ -1,6 +1,6 @@
|
||||
#Fri Jun 23 08:50:38 CEST 2017
|
||||
#Thu Mar 28 08:00:16 EDT 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
|
0
android/gradlew.bat
vendored
Normal file → Executable file
0
android/gradlew.bat
vendored
Normal file → Executable file
0
android/settings.gradle
Normal file → Executable file
0
android/settings.gradle
Normal file → Executable file
0
android/src/main/AndroidManifest.xml
Normal file → Executable file
0
android/src/main/AndroidManifest.xml
Normal file → Executable file
137
android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java
Normal file → Executable file
137
android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java
Normal file → Executable file
@ -1,116 +1,89 @@
|
||||
package com.appleeducate.fluttersms;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.telephony.SmsManager;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
//import android.support.v4.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.ArrayList;
|
||||
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener;
|
||||
|
||||
/** FlutterSmsPlugin */
|
||||
public class FlutterSmsPlugin implements MethodCallHandler {
|
||||
public class FlutterSmsPlugin implements MethodCallHandler, ActivityResultListener {
|
||||
private static final int REQUEST_CODE_SEND_SMS = 0315;
|
||||
|
||||
|
||||
Activity activity;
|
||||
|
||||
/** Plugin registration. */
|
||||
public static void registerWith(Registrar registrar) {
|
||||
final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_sms");
|
||||
channel.setMethodCallHandler(new FlutterSmsPlugin(registrar.activity()));
|
||||
channel.setMethodCallHandler(new FlutterSmsPlugin(registrar));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, Result result) {
|
||||
if (call.method.equals("sendSMS")) {
|
||||
String message = call.argument("message");
|
||||
ArrayList<String> recipients = call.argument("recipients");
|
||||
String smsPermission = "SEND_SMS";
|
||||
if (!checkPermission(smsPermission)) {
|
||||
requestPermission(smsPermission);
|
||||
if (!checkPermission(smsPermission)) {
|
||||
openSettings();
|
||||
} else {
|
||||
sendSMS(recipients, message);
|
||||
}
|
||||
} else {
|
||||
sendSMS(recipients, message);
|
||||
if (!canSendSMS()) {
|
||||
result.error(
|
||||
"device_not_capable",
|
||||
"The current device is not capable of sending text messages.",
|
||||
"A device may be unable to send messages if it does not support messaging or if it is not currently configured to send messages. This only applies to the ability to send text messages via iMessage, SMS, and MMS.");
|
||||
return;
|
||||
}
|
||||
result.success("Sent!");
|
||||
|
||||
String message = call.argument("message");
|
||||
String recipients = call.argument("recipients");
|
||||
sendSMS(result, recipients, message);
|
||||
//result.success("SMS Sent!");
|
||||
} else if (call.method.equals("canSendSMS")) {
|
||||
result.success(canSendSMS());
|
||||
} else {
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
private FlutterSmsPlugin(Activity activity) {
|
||||
this.activity = activity;
|
||||
private FlutterSmsPlugin(Registrar registrar) {
|
||||
this.activity = registrar.activity();
|
||||
registrar.addActivityResultListener(this);
|
||||
}
|
||||
|
||||
private void sendSMS(ArrayList<String> phones, String message) {
|
||||
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
|
||||
sendIntent.putExtra("sms_body", message);
|
||||
sendIntent.setData(Uri.parse("sms:" + phones));
|
||||
activity.startActivity(sendIntent);
|
||||
private boolean canSendSMS() {
|
||||
if (!activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY))
|
||||
return false;
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SENDTO);
|
||||
intent.setData(Uri.parse("smsto:"));
|
||||
ActivityInfo activityInfo =
|
||||
intent.resolveActivityInfo(activity.getPackageManager(), intent.getFlags());
|
||||
if (activityInfo == null || !activityInfo.exported) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkPermission(String permission) {
|
||||
permission = getManifestPermission(permission);
|
||||
Log.i("SimplePermission", "Checking permission : " + permission);
|
||||
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(activity, permission);
|
||||
private Result result;
|
||||
|
||||
private void sendSMS(Result result, String phones, String message) {
|
||||
this.result = result;
|
||||
Intent intent = new Intent(Intent.ACTION_SENDTO);
|
||||
intent.setData(Uri.parse("smsto:" + phones));
|
||||
intent.putExtra("sms_body", message);
|
||||
intent.putExtra(Intent.EXTRA_TEXT, message);
|
||||
// intent.putExtra(Intent.EXTRA_STREAM, attachment);
|
||||
activity.startActivityForResult(intent, REQUEST_CODE_SEND_SMS);
|
||||
}
|
||||
|
||||
private void requestPermission(String permission) {
|
||||
permission = getManifestPermission(permission);
|
||||
Log.i("SimplePermission", "Requesting permission : " + permission);
|
||||
String[] perm = { permission };
|
||||
ActivityCompat.requestPermissions(activity, perm, 0);
|
||||
}
|
||||
|
||||
private String getManifestPermission(String permission) {
|
||||
String res;
|
||||
switch (permission) {
|
||||
case "SEND_SMS":
|
||||
res = Manifest.permission.SEND_SMS;
|
||||
break;
|
||||
default:
|
||||
res = "ERROR";
|
||||
break;
|
||||
@Override
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if(requestCode == REQUEST_CODE_SEND_SMS && result!=null){
|
||||
result.success("finished");
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private void openSettings() {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.parse("package:" + activity.getPackageName()));
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
activity.startActivity(intent);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
compileSdkVersion 28
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
@ -34,11 +34,11 @@ android {
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.appleeducate.fluttersmsexample"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 27
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 28
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -56,6 +56,6 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
|
||||
}
|
||||
|
@ -6,7 +6,6 @@
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
|
@ -5,7 +5,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.2'
|
||||
classpath 'com.android.tools.build:gradle:3.3.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
|
||||
|
@ -19,4 +19,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: 7765ea4305eaab0b3dfd384c7de11902aa3195fd
|
||||
|
||||
COCOAPODS: 1.5.0
|
||||
COCOAPODS: 1.5.3
|
||||
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Original</string>
|
||||
</dict>
|
||||
</plist>
|
@ -3,7 +3,34 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter_sms/flutter_sms.dart';
|
||||
|
||||
void main() => runApp(new MyApp());
|
||||
import 'dart:io' show Platform;
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// The existing imports
|
||||
// !! Keep your existing impots here !!
|
||||
|
||||
/// main is entry point of Flutter application
|
||||
void main() {
|
||||
// Desktop platforms aren't a valid platform.
|
||||
_setTargetPlatformForDesktop();
|
||||
|
||||
return runApp(MyApp());
|
||||
}
|
||||
|
||||
/// If the current platform is desktop, override the default platform to
|
||||
/// a supported platform (iOS for macOS, Android for Linux and Windows).
|
||||
/// Otherwise, do nothing.
|
||||
void _setTargetPlatformForDesktop() {
|
||||
TargetPlatform targetPlatform;
|
||||
if (Platform.isMacOS) {
|
||||
targetPlatform = TargetPlatform.iOS;
|
||||
} else if (Platform.isLinux || Platform.isWindows) {
|
||||
targetPlatform = TargetPlatform.android;
|
||||
}
|
||||
if (targetPlatform != null) {
|
||||
debugDefaultTargetPlatformOverride = targetPlatform;
|
||||
}
|
||||
}
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
@override
|
||||
@ -13,6 +40,7 @@ class MyApp extends StatefulWidget {
|
||||
class _MyAppState extends State<MyApp> {
|
||||
TextEditingController _controllerPeople, _controllerMessage;
|
||||
String _message, body;
|
||||
String _canSendSMSMessage = "Check is not run.";
|
||||
List<String> people = [];
|
||||
|
||||
@override
|
||||
@ -27,9 +55,19 @@ class _MyAppState extends State<MyApp> {
|
||||
}
|
||||
|
||||
void _sendSMS(String message, List<String> recipents) async {
|
||||
String _result =
|
||||
await FlutterSms.sendSMS(message: message, recipients: recipents);
|
||||
setState(() => _message = _result);
|
||||
try {
|
||||
String _result =
|
||||
await FlutterSms.sendSMS(message: message, recipients: recipents);
|
||||
setState(() => _message = _result);
|
||||
} catch (error) {
|
||||
setState(() => _message = error.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void _canSendSMS() async {
|
||||
bool _result = await FlutterSms.canSendSMS();
|
||||
setState(() => _canSendSMSMessage =
|
||||
_result ? 'This unit can send SMS' : 'This unit cannot send SMS');
|
||||
}
|
||||
|
||||
Widget _phoneTile(String name) {
|
||||
@ -99,6 +137,7 @@ class _MyAppState extends State<MyApp> {
|
||||
title: TextField(
|
||||
controller: _controllerPeople,
|
||||
decoration: InputDecoration(labelText: "Add Phone Number"),
|
||||
keyboardType: TextInputType.number,
|
||||
onChanged: (String value) => setState(() {}),
|
||||
),
|
||||
trailing: IconButton(
|
||||
@ -139,7 +178,7 @@ class _MyAppState extends State<MyApp> {
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.send),
|
||||
onPressed: () {
|
||||
if ((people == null || people.isEmpty) ||
|
||||
if ((people == null || people.isEmpty) &&
|
||||
(body == null || body.isEmpty)) {
|
||||
setState(() =>
|
||||
_message = "At Least 1 Person or Message Required");
|
||||
@ -163,6 +202,31 @@ class _MyAppState extends State<MyApp> {
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Text(
|
||||
"Can send SMS",
|
||||
style: Theme.of(context).textTheme.title,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Text(_canSendSMSMessage,
|
||||
style: Theme.of(context).textTheme.body1)),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
|
||||
child: RaisedButton(
|
||||
color: Theme.of(context).accentColor,
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text("RUN CHECK",
|
||||
style: Theme.of(context).accentTextTheme.button),
|
||||
onPressed: () {
|
||||
_canSendSMS();
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -25,12 +25,12 @@ public class SwiftFlutterSmsPlugin: NSObject, FlutterPlugin, UINavigationControl
|
||||
)
|
||||
#else
|
||||
if (MFMessageComposeViewController.canSendText()) {
|
||||
self.result = result
|
||||
let controller = MFMessageComposeViewController()
|
||||
controller.body = _arguments["message"] as? String
|
||||
controller.recipients = _arguments["recipients"] as? [String]
|
||||
controller.messageComposeDelegate = self
|
||||
UIApplication.shared.keyWindow?.rootViewController?.present(controller, animated: true, completion: nil)
|
||||
// result(message)
|
||||
} else {
|
||||
result(FlutterError(
|
||||
code: "device_not_capable",
|
||||
@ -40,6 +40,18 @@ public class SwiftFlutterSmsPlugin: NSObject, FlutterPlugin, UINavigationControl
|
||||
)
|
||||
}
|
||||
#endif
|
||||
|
||||
case "canSendSMS":
|
||||
#if targetEnvironment(simulator)
|
||||
result(false)
|
||||
#else
|
||||
if (MFMessageComposeViewController.canSendText()) {
|
||||
result(true)
|
||||
} else {
|
||||
result(false)
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
break
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -6,22 +7,26 @@ import 'package:flutter/services.dart';
|
||||
class FlutterSms {
|
||||
static const MethodChannel _channel = const MethodChannel('flutter_sms');
|
||||
|
||||
static Future<String> get platformVersion async {
|
||||
final String version = await _channel.invokeMethod('getPlatformVersion');
|
||||
return version;
|
||||
}
|
||||
|
||||
static Future<String> sendSMS({
|
||||
@required String message,
|
||||
@required List<String> recipients,
|
||||
}) async {
|
||||
var mapData = Map();
|
||||
var mapData = Map<dynamic, dynamic>();
|
||||
mapData["message"] = message;
|
||||
mapData["recipients"] = recipients;
|
||||
final String result = await _channel.invokeMethod('sendSMS', mapData);
|
||||
// String _log = "SMS Message: $message";
|
||||
// for (var person in recipients) _log += "\nSent: $person";
|
||||
// final String result = _log;
|
||||
if (Platform.isIOS) {
|
||||
mapData["recipients"] = recipients;
|
||||
final String result = await _channel.invokeMethod('sendSMS', mapData);
|
||||
return result;
|
||||
} else {
|
||||
String _phones = recipients.join(",");
|
||||
mapData["recipients"] = _phones;
|
||||
final String result = await _channel.invokeMethod('sendSMS', mapData);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> canSendSMS() async {
|
||||
final bool result = await _channel.invokeMethod('canSendSMS');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
name: flutter_sms
|
||||
description: A Flutter plugin to Send SMS and MMS on iOS and Android. If iMessage is enabled it will send as iMessage on iOS. This plugin must be tested on a real device on iOS.
|
||||
version: 0.0.3
|
||||
version: 1.0.1
|
||||
author: Rody Davis <rody.davis.jr@gmail.com>
|
||||
homepage: https://github.com/AppleEducate/flutter_sms
|
||||
homepage: https://github.com/AppleEducate/plugins
|
||||
|
||||
|
||||
environment:
|
||||
sdk: ">=2.0.0-dev.28.0 <3.0.0"
|
||||
flutter: ">=0.1.4 <2.0.0"
|
||||
sdk: ">=2.0.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
Loading…
Reference in New Issue
Block a user