I have implemented the starting point of a SMS forwarding app for my personal use. I don't trust SMS forwarding apps in the play store, believe it or not :-)
So, everything works as expected, but only for a certain time, that I cannot exactly define. I think it is about 1-2 hrs.
Then the app will just stop working. If I open the phone and touch the app it will work again for some time.
I pushed the project here, it is really just a Broadcast Receiver right now. The file in question is smsreceiver.kt
https://github.com/asciimo71/smsforwarder
The app does no special "keep me alive" things. I tried to find information in the BroadcastReceiver about that, but I couldn't find things that I would relate to my issue.
Maybe also of interest? I am running this on A50
As far as I understand the BroadcastReceiver, it will plug itself into the background and be alerted as soon as the subscribed intent happens. This is the receiver class and the manifest. The remaining application is a plain app frame from Android Studio.
Maybe I should add, that I think it has something to do with the energy-saver system of Android, but I don't know how to make the receiver responsive regardless of the battery-level. As long as the messages are received, I want them to be forwarded. During my tests, the phone was on a charger and the battery was always 100% full.
class SmsReceiver : BroadcastReceiver() {
private var mLastTimeReceived = 0L
override fun onReceive(p0: Context?, intent: Intent?) {
val currentTimeMillis = System.currentTimeMillis()
if (currentTimeMillis - mLastTimeReceived > 200) {
mLastTimeReceived = currentTimeMillis
val msgFrom: String?
val msgText: String?
val msgs = Intents.getMessagesFromIntent(intent) as Array<SmsMessage?>
msgText = msgs.joinToString(separator = "") {
it?.displayMessageBody ?: it?.messageBody ?: "-body missing-"
}
msgFrom = msgs[0]?.originatingAddress
val outgoingText = "${msgText} - forward from ${msgFrom} @ ${java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(msgs[0]?.timestampMillis ?: 0L)}"
Log.d(TAG, "onReceive: $outgoingText ${msgFrom ?: "no From"}")
val smsManager = SmsManager.getDefault()
try {
val parts = smsManager.divideMessage(outgoingText)
smsManager.sendMultipartTextMessage(
OUTGOING_PHONE,
null,
parts,
null, null
)
} catch (e: Throwable) {
Log.d(TAG, "send: error", e)
}
} else {
Log.d(TAG, "skipped onReceive - received messages too fast")
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.SMSForwarder"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.SMSForwarder.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>