Skip to content

Commit

Permalink
Merge pull request #8 from vernu/feature/receive-sms
Browse files Browse the repository at this point in the history
Receive Messages Feature
  • Loading branch information
vernu committed Apr 20, 2024
2 parents ec4a92e + 43f1e98 commit 28d40e0
Show file tree
Hide file tree
Showing 57 changed files with 1,822 additions and 425 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ from their application via a REST API. It utilizes android phones as SMS gateway
## Usage

1. Go to [textbee.dev](https://textbee.dev) and register or login with your account
2. Install the app on your android phone from [textbee.dev/android](https://textbee.dev/android)
2. Install the app on your android phone from [dl.textbee.dev](https://dl.textbee.dev)
3. Open the app and grant the permissions for SMS
4. Go to [textbee.dev/dashboard](https://textbee.dev/dashboard) and click register device/ generate API Key
5. Scan the QR code with the app or enter the API key manually
Expand All @@ -23,10 +23,14 @@ from their application via a REST API. It utilizes android phones as SMS gateway
const API_KEY = 'YOUR_API_KEY';
const DEVICE_ID = 'YOUR_DEVICE_ID';

await axios.post(`https://api.textbee.dev/api/v1/gateway/devices/${DEVICE_ID}/sendSMS?apiKey=${API_KEY}`, {
receivers: [ '+251912345678' ],
smsBody: 'Hello World!',
})
await axios.post(`https://api.textbee.dev/api/v1/gateway/devices/${DEVICE_ID}/sendSMS`, {
recipients: [ '+251912345678' ],
message: 'Hello World!',
}, {
headers: {
'x-api-key': API_KEY,
},
});

```

Expand Down
17 changes: 14 additions & 3 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ android {
applicationId "com.vernu.sms"
minSdk 24
targetSdk 32
versionCode 9
versionName "2.2.0"
versionCode 10
versionName "2.3.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

// javaCompileOptions {
// annotationProcessorOptions {
// arguments["room.schemaLocation"] = "$projectDir/schemas"
// }
// }
}

buildTypes {
Expand Down Expand Up @@ -46,4 +52,9 @@ dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
}

// def room_version = "2.4.2"
// implementation "androidx.room:room-runtime:$room_version"
// annotationProcessor "androidx.room:room-compiler:$room_version"
}

34 changes: 33 additions & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.vernu.sms">

<uses-feature
android:name="android.hardware.telephony"
android:required="false" />

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.provider.Telephony.SMS_RECEIVED" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
Expand All @@ -21,8 +30,31 @@
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name=".services.StickyNotificationService"
android:enabled="true"
android:exported="false">
</service>
<receiver
android:name=".receivers.SMSBroadcastReceiver"
android:exported="true">
<intent-filter
android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>

<receiver android:enabled="true"
android:name=".receivers.BootCompletedReceiver"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

<activity
android:name="com.vernu.sms.activities.MainActivity"
android:name=".activities.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
33 changes: 33 additions & 0 deletions android/app/src/main/java/com/vernu/sms/ApiManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.vernu.sms;

import com.vernu.sms.services.GatewayApiService;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiManager {
private static GatewayApiService apiService;

public static GatewayApiService getApiService() {
if (apiService == null) {
apiService = createApiService();
}
return apiService;
}

private static GatewayApiService createApiService() {
// OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
// HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
// loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
// httpClient.addInterceptor(loggingInterceptor);

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(AppConstants.API_BASE_URL)
// .client(httpClient.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
apiService = retrofit.create(GatewayApiService.class);

return retrofit.create(GatewayApiService.class);
}
}
19 changes: 19 additions & 0 deletions android/app/src/main/java/com/vernu/sms/AppConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.vernu.sms;

import android.Manifest;

public class AppConstants {
public static final String API_BASE_URL = "https://api.textbee.dev/api/v1/";
public static final String[] requiredPermissions = new String[]{
Manifest.permission.SEND_SMS,
Manifest.permission.READ_SMS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.READ_PHONE_STATE
};
public static final String SHARED_PREFS_DEVICE_ID_KEY = "DEVICE_ID";
public static final String SHARED_PREFS_API_KEY_KEY = "API_KEY";
public static final String SHARED_PREFS_GATEWAY_ENABLED_KEY = "GATEWAY_ENABLED";
public static final String SHARED_PREFS_PREFERRED_SIM_KEY = "PREFERRED_SIM";
public static final String SHARED_PREFS_RECEIVE_SMS_ENABLED_KEY = "RECEIVE_SMS_ENABLED";
public static final String SHARED_PREFS_TRACK_SENT_SMS_STATUS_KEY = "TRACK_SENT_SMS_STATUS";
}
53 changes: 53 additions & 0 deletions android/app/src/main/java/com/vernu/sms/TextBeeUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.vernu.sms;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.vernu.sms.services.StickyNotificationService;

import java.util.ArrayList;
import java.util.List;

public class TextBeeUtils {
public static boolean isPermissionGranted(Context context, String permission) {
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}

public static List<SubscriptionInfo> getAvailableSimSlots(Context context) {

if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return new ArrayList<>();
}

SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
return subscriptionManager.getActiveSubscriptionInfoList();

}

public static void startStickyNotificationService(Context context) {

if(!isPermissionGranted(context, Manifest.permission.RECEIVE_SMS)){
return;
}

Intent notificationIntent = new Intent(context, StickyNotificationService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(notificationIntent);
} else {
context.startService(notificationIntent);
}
}

public static void stopStickyNotificationService(Context context) {
Intent notificationIntent = new Intent(context, StickyNotificationService.class);
context.stopService(notificationIntent);
}
}
Loading

0 comments on commit 28d40e0

Please sign in to comment.