Skip to content

Commit 28d40e0

Browse files
authored
Merge pull request #8 from vernu/feature/receive-sms
Receive Messages Feature
2 parents ec4a92e + 43f1e98 commit 28d40e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1822
-425
lines changed

README.md

+9-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ from their application via a REST API. It utilizes android phones as SMS gateway
1111
## Usage
1212

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

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

3135
```
3236

android/app/build.gradle

+14-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ android {
1010
applicationId "com.vernu.sms"
1111
minSdk 24
1212
targetSdk 32
13-
versionCode 9
14-
versionName "2.2.0"
13+
versionCode 10
14+
versionName "2.3.0"
1515

1616
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17+
18+
// javaCompileOptions {
19+
// annotationProcessorOptions {
20+
// arguments["room.schemaLocation"] = "$projectDir/schemas"
21+
// }
22+
// }
1723
}
1824

1925
buildTypes {
@@ -46,4 +52,9 @@ dependencies {
4652
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
4753
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
4854
implementation 'com.journeyapps:zxing-android-embedded:4.1.0'
49-
}
55+
56+
// def room_version = "2.4.2"
57+
// implementation "androidx.room:room-runtime:$room_version"
58+
// annotationProcessor "androidx.room:room-compiler:$room_version"
59+
}
60+

android/app/src/main/AndroidManifest.xml

+33-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,17 @@
33
xmlns:tools="http://schemas.android.com/tools"
44
package="com.vernu.sms">
55

6+
<uses-feature
7+
android:name="android.hardware.telephony"
8+
android:required="false" />
9+
610
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
711
<uses-permission android:name="android.permission.SEND_SMS" />
12+
<uses-permission android:name="android.permission.READ_SMS" />
13+
<uses-permission android:name="android.permission.RECEIVE_SMS" />
14+
<uses-permission android:name="android.provider.Telephony.SMS_RECEIVED" />
15+
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
16+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
817
<application
918
android:allowBackup="true"
1019
android:icon="@mipmap/ic_launcher"
@@ -21,8 +30,31 @@
2130
<action android:name="com.google.firebase.MESSAGING_EVENT" />
2231
</intent-filter>
2332
</service>
33+
<service
34+
android:name=".services.StickyNotificationService"
35+
android:enabled="true"
36+
android:exported="false">
37+
</service>
38+
<receiver
39+
android:name=".receivers.SMSBroadcastReceiver"
40+
android:exported="true">
41+
<intent-filter
42+
android:priority="2147483647">
43+
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
44+
</intent-filter>
45+
</receiver>
46+
47+
<receiver android:enabled="true"
48+
android:name=".receivers.BootCompletedReceiver"
49+
android:exported="true"
50+
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
51+
<intent-filter>
52+
<action android:name="android.intent.action.BOOT_COMPLETED"/>
53+
</intent-filter>
54+
</receiver>
55+
2456
<activity
25-
android:name="com.vernu.sms.activities.MainActivity"
57+
android:name=".activities.MainActivity"
2658
android:exported="true">
2759
<intent-filter>
2860
<action android:name="android.intent.action.MAIN" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.vernu.sms;
2+
3+
import com.vernu.sms.services.GatewayApiService;
4+
5+
import retrofit2.Retrofit;
6+
import retrofit2.converter.gson.GsonConverterFactory;
7+
8+
public class ApiManager {
9+
private static GatewayApiService apiService;
10+
11+
public static GatewayApiService getApiService() {
12+
if (apiService == null) {
13+
apiService = createApiService();
14+
}
15+
return apiService;
16+
}
17+
18+
private static GatewayApiService createApiService() {
19+
// OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
20+
// HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
21+
// loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
22+
// httpClient.addInterceptor(loggingInterceptor);
23+
24+
Retrofit retrofit = new Retrofit.Builder()
25+
.baseUrl(AppConstants.API_BASE_URL)
26+
// .client(httpClient.build())
27+
.addConverterFactory(GsonConverterFactory.create())
28+
.build();
29+
apiService = retrofit.create(GatewayApiService.class);
30+
31+
return retrofit.create(GatewayApiService.class);
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.vernu.sms;
2+
3+
import android.Manifest;
4+
5+
public class AppConstants {
6+
public static final String API_BASE_URL = "https://api.textbee.dev/api/v1/";
7+
public static final String[] requiredPermissions = new String[]{
8+
Manifest.permission.SEND_SMS,
9+
Manifest.permission.READ_SMS,
10+
Manifest.permission.RECEIVE_SMS,
11+
Manifest.permission.READ_PHONE_STATE
12+
};
13+
public static final String SHARED_PREFS_DEVICE_ID_KEY = "DEVICE_ID";
14+
public static final String SHARED_PREFS_API_KEY_KEY = "API_KEY";
15+
public static final String SHARED_PREFS_GATEWAY_ENABLED_KEY = "GATEWAY_ENABLED";
16+
public static final String SHARED_PREFS_PREFERRED_SIM_KEY = "PREFERRED_SIM";
17+
public static final String SHARED_PREFS_RECEIVE_SMS_ENABLED_KEY = "RECEIVE_SMS_ENABLED";
18+
public static final String SHARED_PREFS_TRACK_SENT_SMS_STATUS_KEY = "TRACK_SENT_SMS_STATUS";
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.vernu.sms;
2+
3+
import android.Manifest;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.content.pm.PackageManager;
7+
import android.os.Build;
8+
import android.telephony.SubscriptionInfo;
9+
import android.telephony.SubscriptionManager;
10+
11+
import androidx.core.app.ActivityCompat;
12+
import androidx.core.content.ContextCompat;
13+
14+
import com.vernu.sms.services.StickyNotificationService;
15+
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
19+
public class TextBeeUtils {
20+
public static boolean isPermissionGranted(Context context, String permission) {
21+
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
22+
}
23+
24+
public static List<SubscriptionInfo> getAvailableSimSlots(Context context) {
25+
26+
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
27+
return new ArrayList<>();
28+
}
29+
30+
SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
31+
return subscriptionManager.getActiveSubscriptionInfoList();
32+
33+
}
34+
35+
public static void startStickyNotificationService(Context context) {
36+
37+
if(!isPermissionGranted(context, Manifest.permission.RECEIVE_SMS)){
38+
return;
39+
}
40+
41+
Intent notificationIntent = new Intent(context, StickyNotificationService.class);
42+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
43+
context.startForegroundService(notificationIntent);
44+
} else {
45+
context.startService(notificationIntent);
46+
}
47+
}
48+
49+
public static void stopStickyNotificationService(Context context) {
50+
Intent notificationIntent = new Intent(context, StickyNotificationService.class);
51+
context.stopService(notificationIntent);
52+
}
53+
}

0 commit comments

Comments
 (0)