Skip to content

Commit db942bf

Browse files
committed
Add support for dual sim phone numbers
1 parent 2252145 commit db942bf

26 files changed

+158
-170
lines changed

android/app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
xmlns:tools="http://schemas.android.com/tools">
44

55

6+
<uses-feature
7+
android:name="android.hardware.telephony"
8+
android:required="false" />
9+
610
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
711
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
812
<uses-permission android:name="android.permission.READ_SMS" />
@@ -72,16 +76,6 @@
7276
</intent-filter>
7377
</receiver>
7478

75-
<receiver android:enabled="true"
76-
android:name=".receivers.SimChangeReceiver"
77-
android:exported="true"
78-
android:permission="android.permission.READ_PHONE_STATE">
79-
<intent-filter>
80-
<action android:name="android.intent.action.SIM_STATE_CHANGED"/>
81-
</intent-filter>
82-
</receiver>
83-
84-
8579
<meta-data
8680
android:name="com.google.firebase.messaging.default_notification_channel_id"
8781
android:value="@string/notification_channel_default" />

android/app/src/main/java/com/httpsms/FirebaseMessagingService.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
5858
}
5959
Thread {
6060
try {
61-
HttpSmsApiService.create(applicationContext).storeHeartbeat(Settings.getOwnerOrDefault(applicationContext))
61+
HttpSmsApiService.create(applicationContext).storeHeartbeat(Settings.getSIM1PhoneNumber(applicationContext))
6262
Settings.setHeartbeatTimestampAsync(applicationContext, System.currentTimeMillis())
6363
} catch (exception: Exception) {
6464
Timber.e(exception)
@@ -88,10 +88,14 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
8888
Settings.setFcmTokenAsync(this, token)
8989

9090
if (Settings.isLoggedIn(this)) {
91-
Timber.d("updating phone with new fcm token")
92-
HttpSmsApiService.create(this).updatePhone(Settings.getOwnerOrDefault(this), token, SmsManagerService.isDualSIM(this))
91+
Timber.d("updating SIM1 phone with new fcm token")
92+
HttpSmsApiService.create(this).updatePhone(Settings.getSIM1PhoneNumber(this), token, Constants.SIM1)
9393
}
9494

95+
if(Settings.isDualSIM(this)) {
96+
Timber.d("updating SIM2 phone with new fcm token")
97+
HttpSmsApiService.create(this).updatePhone(Settings.getSIM2PhoneNumber(this), token, Constants.SIM2)
98+
}
9599
}
96100

97101
private fun initTimber() {

android/app/src/main/java/com/httpsms/HttpSmsApiService.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,12 @@ class HttpSmsApiService(private val apiKey: String, private val baseURL: URI) {
161161
}
162162

163163

164-
fun updatePhone(phoneNumber: String, fcmToken: String, isDualSIM: Boolean): Boolean {
164+
fun updatePhone(phoneNumber: String, fcmToken: String, sim: String): Boolean {
165165
val body = """
166166
{
167167
"fcm_token": "$fcmToken",
168168
"phone_number": "$phoneNumber",
169-
"is_dual_sim": $isDualSIM
169+
"sim": "$sim"
170170
}
171171
""".trimIndent()
172172

android/app/src/main/java/com/httpsms/LoginActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ class LoginActivity : AppCompatActivity() {
7878
) != PackageManager.PERMISSION_GRANTED
7979
) {
8080
Timber.e("cannot get owner because permissions are not granted")
81-
return Settings.getOwner(this)
81+
return Settings.getSIM1PhoneNumber(this)
8282
}
8383

8484
if (telephonyManager.line1Number != null && telephonyManager.line1Number != "") {
85-
Settings.setOwnerAsync(context, telephonyManager.line1Number)
85+
Settings.setSIM1PhoneNumber(context, telephonyManager.line1Number)
8686
}
8787

8888
return telephonyManager.line1Number

android/app/src/main/java/com/httpsms/MainActivity.kt

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.app.NotificationChannel
66
import android.app.NotificationManager
77
import android.content.Context
88
import android.content.Intent
9-
import android.content.IntentFilter
109
import android.content.pm.PackageManager
1110
import android.net.Uri
1211
import android.os.Build
@@ -28,10 +27,8 @@ import androidx.work.NetworkType
2827
import androidx.work.PeriodicWorkRequestBuilder
2928
import androidx.work.WorkManager
3029
import com.google.android.material.button.MaterialButton
31-
import com.google.android.material.dialog.MaterialAlertDialogBuilder
3230
import com.google.android.material.progressindicator.LinearProgressIndicator
3331
import com.google.android.material.switchmaterial.SwitchMaterial
34-
import com.httpsms.receivers.SimChangeReceiver
3532
import com.httpsms.services.StickyNotificationService
3633
import com.httpsms.worker.HeartbeatWorker
3734
import okhttp3.internal.format
@@ -70,7 +67,6 @@ class MainActivity : AppCompatActivity() {
7067
setVersion()
7168
setHeartbeatListener(this)
7269
setBatteryOptimizationListener()
73-
registerReceivers()
7470
}
7571

7672
override fun onResume() {
@@ -164,13 +160,23 @@ class MainActivity : AppCompatActivity() {
164160
}
165161

166162
Thread {
167-
val updated = HttpSmsApiService.create(context).updatePhone(Settings.getOwnerOrDefault(context), Settings.getFcmToken(context) ?: "", SmsManagerService.isDualSIM(this))
163+
val updated = HttpSmsApiService.create(context).updatePhone(Settings.getSIM1PhoneNumber(context), Settings.getFcmToken(context) ?: "", Constants.SIM1)
168164
if (updated) {
169165
Settings.setFcmTokenLastUpdateTimestampAsync(context, currentTimeStamp)
170-
Timber.i("fcm token uploaded successfully")
166+
Timber.i("fcm token uploaded successfully for sim1")
171167
return@Thread
172168
}
173-
Timber.e("could not update fcm token")
169+
Timber.e("could not update fcm token for sim 1")
170+
171+
if (Settings.isDualSIM(context)) {
172+
val sim2Updated = HttpSmsApiService.create(context).updatePhone(Settings.getSIM2PhoneNumber(context), Settings.getFcmToken(context) ?: "", Constants.SIM2)
173+
if (sim2Updated) {
174+
Settings.setFcmTokenLastUpdateTimestampAsync(context, currentTimeStamp)
175+
Timber.i("fcm token uploaded successfully for sim2")
176+
return@Thread
177+
}
178+
Timber.e("could not update fcm token for sim 2")
179+
}
174180
}.start()
175181
}
176182

@@ -190,9 +196,6 @@ class MainActivity : AppCompatActivity() {
190196
findViewById<MaterialButton>(R.id.mainSettingsButton).setOnClickListener { onSettingsClick() }
191197
}
192198

193-
private fun registerReceivers() {
194-
registerReceiver(SimChangeReceiver(), IntentFilter("android.intent.action.SIM_STATE_CHANGED"))
195-
}
196199
private fun onSettingsClick() {
197200
Timber.d("settings button clicked")
198201
val switchActivityIntent = Intent(this, SettingsActivity::class.java)
@@ -220,6 +223,7 @@ class MainActivity : AppCompatActivity() {
220223
Settings.setActiveStatusAsync(context, isChecked)
221224
}
222225
if (isChecked) {
226+
Settings.setIncomingActiveSIM1(context, true)
223227
startStickyNotification(context)
224228
}
225229
}
@@ -268,7 +272,7 @@ class MainActivity : AppCompatActivity() {
268272
}
269273

270274
private fun getPhoneNumber(context: Context): String {
271-
return Settings.getOwnerOrDefault(context)
275+
return Settings.getSIM1PhoneNumber(context)
272276
}
273277

274278
private fun requestPermissions(context:Context) {
@@ -351,7 +355,7 @@ class MainActivity : AppCompatActivity() {
351355
Thread {
352356
var error: String? = null
353357
try {
354-
HttpSmsApiService.create(context).storeHeartbeat(Settings.getOwnerOrDefault(context))
358+
HttpSmsApiService.create(context).storeHeartbeat(Settings.getSIM1PhoneNumber(context))
355359
Settings.setHeartbeatTimestampAsync(applicationContext, System.currentTimeMillis())
356360
} catch (exception: Exception) {
357361
Timber.e(exception)

android/app/src/main/java/com/httpsms/ReceivedReceiver.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,22 @@ class ReceivedReceiver: BroadcastReceiver()
2424
smsBody += smsMessage.messageBody
2525
}
2626

27+
var sim = Constants.SIM1
28+
var owner = Settings.getSIM1PhoneNumber(context)
29+
if (intent.getIntExtra("simSlot", 1) > 1 && Settings.isDualSIM(context)) {
30+
owner = Settings.getSIM2PhoneNumber(context)
31+
sim = Constants.SIM2
32+
}
33+
34+
if (!Settings.isIncomingMessageEnabled(context, sim)) {
35+
Timber.w("[${sim}] is not active for incoming messages")
36+
return
37+
}
38+
2739
handleMessageReceived(
2840
context,
2941
smsSender,
30-
Settings.getOwnerOrDefault(context),
42+
owner,
3143
smsBody
3244
)
3345
}

android/app/src/main/java/com/httpsms/Settings.kt

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import timber.log.Timber
66
import java.net.URI
77

88
object Settings {
9-
private const val DEFAULT_PHONE_NUMBER = "NOT_FOUND"
10-
11-
private const val SETTINGS_OWNER = "SETTINGS_OWNER"
129
private const val SETTINGS_SIM1_PHONE_NUMBER = "SETTINGS_SIM1_PHONE_NUMBER"
1310
private const val SETTINGS_SIM2_PHONE_NUMBER = "SETTINGS_SIM2_PHONE_NUMBER"
1411
private const val SETTINGS_ACTIVE = "SETTINGS_ACTIVE_STATUS"
@@ -22,28 +19,40 @@ object Settings {
2219
private const val SETTINGS_FCM_TOKEN_UPDATE_TIMESTAMP = "SETTINGS_FCM_TOKEN_UPDATE_TIMESTAMP"
2320
private const val SETTINGS_HEARTBEAT_TIMESTAMP = "SETTINGS_HEARTBEAT_TIMESTAMP"
2421

25-
fun getOwner(context: Context): String? {
26-
Timber.d(Settings::getOwner.name)
22+
fun getSIM1PhoneNumber(context: Context): String {
23+
Timber.d(Settings::getSIM1PhoneNumber.name)
2724

2825
val owner = PreferenceManager
2926
.getDefaultSharedPreferences(context)
30-
.getString(this.SETTINGS_OWNER, null)
27+
.getString(this.SETTINGS_SIM1_PHONE_NUMBER, null)
3128

3229
if (owner == null) {
33-
Timber.e("cannot get owner from preference [${this.SETTINGS_OWNER}]")
34-
return null
30+
Timber.e("cannot get owner from preference [${this.SETTINGS_SIM1_PHONE_NUMBER}]")
31+
return ""
3532
}
3633

37-
Timber.d("SETTINGS_OWNER: [$owner]")
34+
Timber.d("SETTINGS_SIM1_PHONE_NUMBER: [$owner]")
3835
return owner
3936
}
4037

41-
fun hasOwner(context: Context): Boolean {
42-
return getOwner(context) != null
38+
fun getSIM2PhoneNumber(context: Context): String {
39+
Timber.d(Settings::getSIM2PhoneNumber.name)
40+
41+
val owner = PreferenceManager
42+
.getDefaultSharedPreferences(context)
43+
.getString(this.SETTINGS_SIM2_PHONE_NUMBER, null)
44+
45+
if (owner == null) {
46+
Timber.e("cannot get owner from preference [${this.SETTINGS_SIM2_PHONE_NUMBER}]")
47+
return ""
48+
}
49+
50+
Timber.d("SETTINGS_SIM2_PHONE_NUMBER: [$owner]")
51+
return owner
4352
}
4453

45-
fun getOwnerOrDefault(context: Context): String {
46-
return getOwner(context) ?: return DEFAULT_PHONE_NUMBER
54+
fun hasOwner(context: Context): Boolean {
55+
return getSIM1PhoneNumber(context) != ""
4756
}
4857

4958
fun getFcmTokenLastUpdateTimestamp(context: Context): Long {
@@ -67,31 +76,21 @@ object Settings {
6776
.apply()
6877
}
6978

70-
71-
fun setOwnerAsync(context: Context, owner: String?) {
72-
Timber.d(Settings::setOwnerAsync.name)
73-
74-
PreferenceManager.getDefaultSharedPreferences(context)
75-
.edit()
76-
.putString(this.SETTINGS_OWNER, owner)
77-
.apply()
78-
}
79-
8079
fun setSIM1PhoneNumber(context: Context, owner: String?) {
81-
Timber.d(Settings::setOwnerAsync.name)
80+
Timber.d(Settings::setSIM1PhoneNumber.name)
8281

8382
PreferenceManager.getDefaultSharedPreferences(context)
8483
.edit()
85-
.putString(this.SETTINGS_OWNER, owner)
84+
.putString(this.SETTINGS_SIM1_PHONE_NUMBER, owner)
8685
.apply()
8786
}
8887

8988
fun setSIM2PhoneNumber(context: Context, owner: String?) {
90-
Timber.d(Settings::setOwnerAsync.name)
89+
Timber.d(Settings::setSIM2PhoneNumber.name)
9190

9291
PreferenceManager.getDefaultSharedPreferences(context)
9392
.edit()
94-
.putString(this.SETTINGS_OWNER, owner)
93+
.putString(this.SETTINGS_SIM2_PHONE_NUMBER, owner)
9594
.apply()
9695
}
9796

@@ -104,7 +103,7 @@ object Settings {
104103
return activeStatus
105104
}
106105

107-
fun getIncomingMessageEnabled(context: Context, sim: String): Boolean {
106+
fun isIncomingMessageEnabled(context: Context, sim: String): Boolean {
108107
var setting = this.SETTINGS_SIM1_INCOMING_ACTIVE
109108
if (sim == Constants.SIM2) {
110109
setting = this.SETTINGS_SIM2_INCOMING_ACTIVE
@@ -162,6 +161,10 @@ object Settings {
162161
return getApiKey(context) != null
163162
}
164163

164+
fun isDualSIM(context: Context): Boolean {
165+
return getSIM1PhoneNumber(context) != "" && getSIM2PhoneNumber(context) != ""
166+
}
167+
165168
private fun getApiKey(context: Context): String?{
166169
Timber.d(Settings::getApiKey.name)
167170

android/app/src/main/java/com/httpsms/SettingsActivity.kt

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,55 @@
11
package com.httpsms
22

3+
import android.content.Context
34
import android.content.Intent
45
import android.os.Bundle
56
import androidx.appcompat.app.AppCompatActivity
6-
import androidx.appcompat.widget.Toolbar
77
import com.google.android.material.appbar.MaterialToolbar
88
import com.google.android.material.button.MaterialButton
99
import com.google.android.material.dialog.MaterialAlertDialogBuilder
10+
import com.google.android.material.switchmaterial.SwitchMaterial
11+
import com.google.android.material.textfield.TextInputEditText
12+
import com.google.android.material.textfield.TextInputLayout
1013
import timber.log.Timber
1114

1215
class SettingsActivity : AppCompatActivity() {
1316
override fun onCreate(savedInstanceState: Bundle?) {
1417
super.onCreate(savedInstanceState)
1518
setContentView(R.layout.activity_settings)
19+
fillSettings(this)
1620
registerListeners()
1721
}
1822

23+
private fun fillSettings(context: Context) {
24+
val phoneNumber = findViewById<TextInputEditText>(R.id.settingsSIM1Input)
25+
phoneNumber.setText(Settings.getSIM1PhoneNumber(context))
26+
phoneNumber.isEnabled = false
27+
28+
val sim1IncomingMessages = findViewById<SwitchMaterial>(R.id.settings_sim1_incoming_messages)
29+
sim1IncomingMessages.isChecked = Settings.isIncomingMessageEnabled(context, Constants.SIM1)
30+
31+
sim1IncomingMessages.setOnCheckedChangeListener{ _, isChecked -> run { Settings.setIncomingActiveSIM1(context, isChecked) } }
32+
33+
if (!Settings.isDualSIM(context)) {
34+
val layout = findViewById<TextInputLayout>(R.id.settingsSIM2Layout)
35+
layout.visibility = TextInputLayout.GONE
36+
val sim2Switch = findViewById<SwitchMaterial>(R.id.settings_sim2_incoming_messages)
37+
sim2Switch.visibility = SwitchMaterial.GONE
38+
return
39+
}
40+
41+
Timber.e("Settings.isDualSIM(context) = ${Settings.isDualSIM(context)}")
42+
43+
val phoneNumberSIM2 = findViewById<TextInputEditText>(R.id.settingsSIM2InputEdit)
44+
phoneNumberSIM2.setText(Settings.getSIM2PhoneNumber(context))
45+
phoneNumberSIM2.isEnabled = false
46+
47+
val sim2IncomingMessages = findViewById<SwitchMaterial>(R.id.settings_sim2_incoming_messages)
48+
sim2IncomingMessages.isChecked = Settings.isIncomingMessageEnabled(context, Constants.SIM2)
49+
50+
sim2IncomingMessages.setOnCheckedChangeListener{ _, isChecked -> run { Settings.setIncomingActiveSIM2(context, isChecked) } }
51+
}
52+
1953
private fun registerListeners() {
2054
appToolbar().setOnClickListener { onBackClicked() }
2155
findViewById<MaterialButton>(R.id.settingsLogoutButton).setOnClickListener { onLogoutClick() }
@@ -46,7 +80,6 @@ class SettingsActivity : AppCompatActivity() {
4680
.setPositiveButton("Logout"){_, _ ->
4781
Timber.d("logging out user")
4882
Settings.setApiKeyAsync(this, null)
49-
Settings.setOwnerAsync(this, null)
5083
Settings.setSIM1PhoneNumber(this, null)
5184
Settings.setSIM2PhoneNumber(this, null)
5285
Settings.setActiveStatusAsync(this, true)

0 commit comments

Comments
 (0)