diff --git a/CHANGELOG.md b/CHANGELOG.md
index f20f910..126a75a 100644
--- a/CHANGELOG.md
+++ b/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
diff --git a/README.md b/README.md
index 1b78a2d..d7fc234 100644
--- a/README.md
+++ b/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
-
+
+
+## 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 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 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).
diff --git a/android/.classpath b/android/.classpath
old mode 100644
new mode 100755
diff --git a/android/.gitignore b/android/.gitignore
old mode 100644
new mode 100755
diff --git a/android/.idea/.name b/android/.idea/.name
old mode 100644
new mode 100755
diff --git a/android/.idea/caches/build_file_checksums.ser b/android/.idea/caches/build_file_checksums.ser
old mode 100644
new mode 100755
index 1e5713d..17c39c8
Binary files a/android/.idea/caches/build_file_checksums.ser and b/android/.idea/caches/build_file_checksums.ser differ
diff --git a/android/.idea/codeStyles/Project.xml b/android/.idea/codeStyles/Project.xml
old mode 100644
new mode 100755
diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml
old mode 100644
new mode 100755
index 47bd81f..7159109
--- a/android/.idea/gradle.xml
+++ b/android/.idea/gradle.xml
@@ -3,6 +3,9 @@
+
+
+
diff --git a/android/.idea/misc.xml b/android/.idea/misc.xml
old mode 100644
new mode 100755
index b031b27..e6e5f9b
--- a/android/.idea/misc.xml
+++ b/android/.idea/misc.xml
@@ -5,22 +5,32 @@
-
+
+
+
+
+
+
-
+
+
+
+
+
+
diff --git a/android/.idea/modules.xml b/android/.idea/modules.xml
old mode 100644
new mode 100755
index 3a99f9f..d83a68f
--- a/android/.idea/modules.xml
+++ b/android/.idea/modules.xml
@@ -3,6 +3,7 @@
+
\ No newline at end of file
diff --git a/android/.idea/runConfigurations.xml b/android/.idea/runConfigurations.xml
old mode 100644
new mode 100755
diff --git a/android/.project b/android/.project
old mode 100644
new mode 100755
diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs
old mode 100644
new mode 100755
index e889521..6aa97a9
--- a/android/.settings/org.eclipse.buildship.core.prefs
+++ b/android/.settings/org.eclipse.buildship.core.prefs
@@ -1,2 +1,2 @@
-connection.project.dir=
+connection.project.dir=../example/android
eclipse.preferences.version=1
diff --git a/android/app/build.gradle b/android/app/build.gradle
deleted file mode 100644
index 347481e..0000000
--- a/android/app/build.gradle
+++ /dev/null
@@ -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'
-}
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 0820014..0000000
--- a/android/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/android/app/src/main/java/com/appleeducate/fluttersms/MainActivity.java b/android/app/src/main/java/com/appleeducate/fluttersms/MainActivity.java
deleted file mode 100644
index a19d2bb..0000000
--- a/android/app/src/main/java/com/appleeducate/fluttersms/MainActivity.java
+++ /dev/null
@@ -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);
- }
-}
diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml
deleted file mode 100644
index 304732f..0000000
--- a/android/app/src/main/res/drawable/launch_background.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index db77bb4..0000000
Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 17987b7..0000000
Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 09d4391..0000000
Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index d5f1c8d..0000000
Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 4d6372e..0000000
Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
deleted file mode 100644
index 00fa441..0000000
--- a/android/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
diff --git a/android/build.gradle b/android/build.gradle
old mode 100644
new mode 100755
index 8ee3b98..e6955a5
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -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'
-}
diff --git a/android/gradle.properties b/android/gradle.properties
old mode 100644
new mode 100755
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
old mode 100644
new mode 100755
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
old mode 100644
new mode 100755
index 9372d0f..97d7e77
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -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
diff --git a/android/gradlew.bat b/android/gradlew.bat
old mode 100644
new mode 100755
diff --git a/android/settings.gradle b/android/settings.gradle
old mode 100644
new mode 100755
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
old mode 100644
new mode 100755
diff --git a/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java b/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java
old mode 100644
new mode 100755
index e08eedc..41c5be6
--- a/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java
+++ b/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java
@@ -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 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 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;
}
}
diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
index d644ec2..53c754d 100644
--- a/example/android/app/build.gradle
+++ b/example/android/app/build.gradle
@@ -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'
}
diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml
index a1885e9..f2e128a 100644
--- a/example/android/app/src/main/AndroidManifest.xml
+++ b/example/android/app/src/main/AndroidManifest.xml
@@ -6,7 +6,6 @@
to allow setting breakpoints, to provide hot reload, etc.
-->
-