diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 5c7247b..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e0f15db --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/README.md b/README.md index a66112d..4a86347 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,64 @@ # flutter_sms -A Flutter plugin for Sending SMS on Android and iOS. +![alt text](repo/blob/master/screenshots/ios_blank.PNG) -## Getting Started +## Description -For help getting started with Flutter, view our online -[documentation](https://flutter.io/). +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. -For help on editing plugin code, view the [documentation](https://flutter.io/developing-packages/#edit-plugin-package). +## How To Use + +You can send multiple ways: + +1. Message and No People +2. People and No Message +3. Message and People + +This will prefil the correct fields. + +## Setup + +### Android + +Add this to your AndroidManifest.xml + +``` xml + +``` + +### iOS + +Good to go! + +## Example + +Make sure to Install and Import the Package. + +``` dart +import 'package:flutter_sms/flutter_sms.dart'; +``` + +Create a function for sending messages. + +``` dart +String _message = ""; + +void _sendSMS(String message, List recipents) async { + String _result = + await FlutterSms.sendSMS(message: message, recipients: recipents); + setState(() => _message = _result); +} +``` + +You can quickly send the message with this function. + +``` dart +_sendSMS("Here is a test Message", ["5555543454", "78467477788"]) +``` + +## Screenshots + +![alt text](repo/blob/master/screenshots/ios_sms.PNG) +![alt text](repo/blob/master/screenshots/android_mms.png) + +You can find other [screenshots here](repo/blob/screenshots). \ No newline at end of file diff --git a/android/.classpath b/android/.classpath new file mode 100644 index 0000000..eb19361 --- /dev/null +++ b/android/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/android/.idea/.name b/android/.idea/.name new file mode 100644 index 0000000..f44ac10 --- /dev/null +++ b/android/.idea/.name @@ -0,0 +1 @@ +flutter_sms \ No newline at end of file diff --git a/android/.idea/caches/build_file_checksums.ser b/android/.idea/caches/build_file_checksums.ser new file mode 100644 index 0000000..1e5713d Binary files /dev/null and b/android/.idea/caches/build_file_checksums.ser differ diff --git a/android/.idea/codeStyles/Project.xml b/android/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/android/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml new file mode 100644 index 0000000..47bd81f --- /dev/null +++ b/android/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/android/.idea/misc.xml b/android/.idea/misc.xml new file mode 100644 index 0000000..b031b27 --- /dev/null +++ b/android/.idea/misc.xml @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/android/.idea/modules.xml b/android/.idea/modules.xml new file mode 100644 index 0000000..3a99f9f --- /dev/null +++ b/android/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/android/.idea/runConfigurations.xml b/android/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/android/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/android/.project b/android/.project new file mode 100644 index 0000000..4a844b2 --- /dev/null +++ b/android/.project @@ -0,0 +1,23 @@ + + + flutter_sms + Project flutter_sms created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..e889521 --- /dev/null +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/android/app/build.gradle b/android/app/build.gradle index b945b9b..347481e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -58,4 +58,5 @@ 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/build.gradle b/android/build.gradle index 04eabf9..8ee3b98 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -32,3 +32,7 @@ android { disable 'InvalidPackage' } } + +dependencies { + api 'com.android.support:appcompat-v7:27.1.0' +} diff --git a/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java b/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java index 9fc36a6..e08eedc 100644 --- a/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java +++ b/android/src/main/java/com/appleeducate/fluttersms/FlutterSmsPlugin.java @@ -5,21 +5,112 @@ 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; /** FlutterSmsPlugin */ public class FlutterSmsPlugin implements MethodCallHandler { + Activity activity; + /** Plugin registration. */ public static void registerWith(Registrar registrar) { final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_sms"); - channel.setMethodCallHandler(new FlutterSmsPlugin()); + channel.setMethodCallHandler(new FlutterSmsPlugin(registrar.activity())); } @Override public void onMethodCall(MethodCall call, Result result) { - if (call.method.equals("getPlatformVersion")) { - result.success("Android " + android.os.Build.VERSION.RELEASE); + 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); + } + result.success("Sent!"); } else { result.notImplemented(); } } + + private FlutterSmsPlugin(Activity activity) { + this.activity = activity; + } + + 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 checkPermission(String permission) { + permission = getManifestPermission(permission); + Log.i("SimplePermission", "Checking permission : " + permission); + return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(activity, permission); + } + + 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; + } + 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); + } } diff --git a/example/android/.project b/example/android/.project new file mode 100644 index 0000000..3964dd3 --- /dev/null +++ b/example/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/example/android/.settings/org.eclipse.buildship.core.prefs b/example/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..e889521 --- /dev/null +++ b/example/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/example/android/app/.classpath b/example/android/app/.classpath new file mode 100644 index 0000000..eb19361 --- /dev/null +++ b/example/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/example/android/app/.project b/example/android/app/.project new file mode 100644 index 0000000..ac485d7 --- /dev/null +++ b/example/android/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/example/android/app/.settings/org.eclipse.buildship.core.prefs b/example/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..b1886ad --- /dev/null +++ b/example/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 901a681..a1885e9 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ to allow setting breakpoints, to provide hot reload, etc. --> + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c2851..0000000 --- a/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist deleted file mode 100644 index 0cc5d59..0000000 --- a/ios/Runner/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - flutter_sms - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/ios/Runner/main.m b/ios/Runner/main.m deleted file mode 100644 index dff6597..0000000 --- a/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/ios/ServiceDefinitions.json b/ios/ServiceDefinitions.json deleted file mode 100644 index 3c470ca..0000000 --- a/ios/ServiceDefinitions.json +++ /dev/null @@ -1 +0,0 @@ -{"services":[]} \ No newline at end of file diff --git a/lib/flutter_sms.dart b/lib/flutter_sms.dart index e519a98..52317f8 100644 --- a/lib/flutter_sms.dart +++ b/lib/flutter_sms.dart @@ -1,13 +1,27 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; class FlutterSms { - static const MethodChannel _channel = - const MethodChannel('flutter_sms'); + static const MethodChannel _channel = const MethodChannel('flutter_sms'); static Future get platformVersion async { final String version = await _channel.invokeMethod('getPlatformVersion'); return version; } + + static Future sendSMS({ + @required String message, + @required List recipients, + }) async { + var mapData = Map(); + 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; + return result; + } } diff --git a/screenshots/android_blank.png b/screenshots/android_blank.png new file mode 100644 index 0000000..7741708 Binary files /dev/null and b/screenshots/android_blank.png differ diff --git a/screenshots/android_mms.png b/screenshots/android_mms.png new file mode 100644 index 0000000..1f29b11 Binary files /dev/null and b/screenshots/android_mms.png differ diff --git a/screenshots/android_multiple.png b/screenshots/android_multiple.png new file mode 100644 index 0000000..13cba58 Binary files /dev/null and b/screenshots/android_multiple.png differ diff --git a/screenshots/android_single.png b/screenshots/android_single.png new file mode 100644 index 0000000..66af6a3 Binary files /dev/null and b/screenshots/android_single.png differ diff --git a/screenshots/android_sms.png b/screenshots/android_sms.png new file mode 100644 index 0000000..e2133b4 Binary files /dev/null and b/screenshots/android_sms.png differ diff --git a/screenshots/ios_blank.PNG b/screenshots/ios_blank.PNG new file mode 100644 index 0000000..aa5ba1c Binary files /dev/null and b/screenshots/ios_blank.PNG differ diff --git a/screenshots/ios_mms.PNG b/screenshots/ios_mms.PNG new file mode 100644 index 0000000..bf5833e Binary files /dev/null and b/screenshots/ios_mms.PNG differ diff --git a/screenshots/ios_multiple.PNG b/screenshots/ios_multiple.PNG new file mode 100644 index 0000000..78057fb Binary files /dev/null and b/screenshots/ios_multiple.PNG differ diff --git a/screenshots/ios_single.PNG b/screenshots/ios_single.PNG new file mode 100644 index 0000000..79184b1 Binary files /dev/null and b/screenshots/ios_single.PNG differ diff --git a/screenshots/ios_sms.PNG b/screenshots/ios_sms.PNG new file mode 100644 index 0000000..797834d Binary files /dev/null and b/screenshots/ios_sms.PNG differ