Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send SMS in Android without opening a messaging app #44

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
## SendSMS
Use this RN component to send an SMS with a callback (completed/cancelled/error). iOS and Android are both supported.

Currently, only user-initiated sending of an SMS is supported. This means you can't use `react-native-sms` to send an SMS in the background-- this package displays the native SMS view (populated with any recipients/body you want), and gives a callback describing the status of the SMS (completed/cancelled/error). PRs are welcome!
Currently, only user-initiated sending of an SMS is supported.
This means you can't use `react-native-sms` to send an SMS in the background -- this package displays the native SMS view (populated with any recipients/body you want), and gives a callback describing the status of the SMS (completed/cancelled/error). PRs are welcome!
### Update
A new prop was added to enable direct sending of SMS from Android. see documentation below.

## How to install
1. `npm install react-native-sms --save`

## Getting things set up

The compiler needs to know how to find your sweet new module! (Make sure rnpm is installed via `npm install rnpm -g`)
The compiler needs to know how to find your sweet new module!

`rnpm link react-native-sms`
`react-native link react-native-sms`

### Additional Android Setup

Expand All @@ -29,7 +32,7 @@ import android.content.Intent; // <-- include if not already there
import com.tkporter.sendsms.SendSMSPackage;
```

Inside MainActivity (place entire function if it's not there already)
Inside **`MainActivity`** (place entire function if it's not there already)
```Java
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Expand All @@ -39,7 +42,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
```

Then head to your [MyApp]Application.java (`MyApp/android/app/src/main/java/so/many/dirs/MyAppApplication.java`)
Then head to your **`[MyApp]Application.java`** (`MyApp/android/app/src/main/java/so/many/dirs/MyAppApplication.java`)

Make sure `import com.tkporter.sendsms.SendSMSPackage;` is there

Expand All @@ -56,15 +59,16 @@ protected List<ReactPackage> getPackages() {
}
```

Navigate to your `AndroidManifest.xml` (at `MyApp/android/app/src/main/AndroidManifest.xml`), and add this near the top with the other permssions
FYI: this permission will automatically be merged into your built `AndroidManifest.xml` (at `MyApp/android/app/src/main/AndroidManifest.xml`)
```XML
<uses-permission android:name="android.permission.READ_SMS" />
```

Ensure your launchMode for `.MainActivity` is
If `direct_send` is `false` or undefined - then ensure your launchMode for `MainActivity` is
```XML
android:launchMode="singleTask"
```
in order for the "back" button to return to your app after the message window is closed.

## Using the module

Expand All @@ -85,6 +89,11 @@ Provides the phone number recipients to show by default

`successTypes` (Array (strings), Andriod only, required)

`direct_send` (boolean, optional)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you change this to directSend to keep with the camelCase pattern?


If true, the Android app will send the SMS directly (without a native messaging app).
It will loop on the recepients and send one by one.

An array of types that would trigger a "completed" response when using android

Possible values:
Expand Down
9 changes: 5 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
buildscript {
repositories {
jcenter()
google()
}

dependencies {
classpath 'com.android.tools.build:gradle:1.1.3'
classpath 'com.android.tools.build:gradle:3.0.1'
}
}

apply plugin: 'com.android.library'

android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
compileSdkVersion 26
buildToolsVersion "26.0.3"

defaultConfig {
minSdkVersion 16
targetSdkVersion 22
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
Expand Down
5 changes: 4 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.tkporter.sendsms">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tkporter.sendsms">

<uses-permission android:name="android.permission.SEND_SMS" />
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this still prompt users of apps that are not using the direct-send feature to use this permission?

</manifest>
46 changes: 40 additions & 6 deletions android/src/main/java/com/tkporter/sendsms/SendSMSModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
import android.content.Intent;
import android.os.Build;
import android.provider.Telephony;
import android.telephony.SmsManager;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReadableMap;

public class SendSMSModule extends ReactContextBaseJavaModule implements ActivityEventListener {

private static final int REQUEST_CODE = 5235;
private final ReactApplicationContext reactContext;
private Callback callback = null;
private static final int REQUEST_CODE = 5235;

public SendSMSModule(ReactApplicationContext reactContext) {
super(reactContext);
Expand Down Expand Up @@ -56,6 +57,12 @@ public void sendCallback(Boolean completed, Boolean cancelled, Boolean error) {
public void send(ReadableMap options, final Callback callback) {
try {
this.callback = callback;

if (options.hasKey("direct_send") ? options.getBoolean("direct_send") : false) {
sendDirect(options, callback);
return;
}

new SendSMSObserver(reactContext, this, options).start();

String body = options.hasKey("body") ? options.getString("body") : "";
Expand All @@ -66,11 +73,11 @@ public void send(ReadableMap options, final Callback callback) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(reactContext);
sendIntent = new Intent(Intent.ACTION_SEND);
if (defaultSmsPackageName != null){
if (defaultSmsPackageName != null) {
sendIntent.setPackage(defaultSmsPackageName);
}
sendIntent.setType("text/plain");
}else {
} else {
sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setType("vnd.android-dir/mms-sms");
}
Expand All @@ -83,7 +90,7 @@ public void send(ReadableMap options, final Callback callback) {
if (recipients != null) {
//Samsung for some reason uses commas and not semicolons as a delimiter
String separator = ";";
if(android.os.Build.MANUFACTURER.equalsIgnoreCase("Samsung")){
if (android.os.Build.MANUFACTURER.equalsIgnoreCase("Samsung")) {
separator = ",";
}
String recipientString = "";
Expand All @@ -102,4 +109,31 @@ public void send(ReadableMap options, final Callback callback) {
}
}

/**
* todo: do it in a background process
*
* @param options
* @param callback
*/
private void sendDirect(ReadableMap options, Callback callback) {

String msg = options.hasKey("body") ? options.getString("body") : "";

ReadableArray recipients = options.hasKey("recipients") ? options.getArray("recipients") : null;
for (int i = 0; i < recipients.size(); i++) {
String phoneNo = recipients.getString(i);

try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, msg, null, null);
} catch (Exception ex) {
ex.printStackTrace();
sendCallback(false, false, true);
return;
}
}

sendCallback(true, false, false);

}
}