I am trying to intercept SMS messages delivered to my device. I wrote an app to do that a year or so ago, and I find it is no longer catching messages (even though code is unchanged).
I don't believe it is permission-related. I tried compiling under SDK 23 (requiring runtime permissions) and SDK 22 (no runtime permissions). (In the case of 23, I verified that permission RECEIVE_SMS is successfully granted).
Most questions/answers about this issue are quite old. IMHO The answers didn't seem enlightened, e.g. adding BROADCAST_SMS permission, invoking native code, etc.
My approach was to implement a broadcast receiver. Code excepts below.
BROADCAST RECEIVER
// SmsRecv.java - SMS Receiver
package com.ramrod.SmsReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class SmsRecv extends BroadcastReceiver {
//@ Handler for received sms messages
@Override
public void onReceive(
Context ctx,
Intent intent)
{
// NEVER REACHED!
Main.toast( "SMS RECEIVED." );
// PROCESS MESSAGE HERE...
}
MANIFEST
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ramrod.SmsReceiver"
android:versionCode="100"
android:versionName="1.00">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:icon="@drawable/icon"
android:label="SmsReceiver"
android:theme="@android:style/Theme"
>
<activity android:name=".Main"
android:label="SmsReceiver"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SmsRecv"
android:exported="true"
android:enabled="true"
>
<intent-filter android:priority="999999" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
BUILD.GRADLE
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "27.0.3"
defaultConfig {
applicationId "com.ramrod.SmsReceiver"
minSdkVersion 23
targetSdkVersion 23
}
...
Tested on Samsung S7 running Oreo V8.0.0. I tested this by sending text messages from another phone. These were received correctly but never triggered SmsRecv().
In my reading, I encountered the notion that now an SMS broadcast receiver will no longer work unless it is the default SMS app on the device (huh?).
Any suggestions greatly appreciated.
I finally figured out what was wrong. Apparently, Android version Oreo+ does not deliver implicit broadcasts any more* (i.e., those specified in the manifest file <receiver>). You now must explicitly register your receiver (i.e., with registerReceiver()) in your code.
(*Note: Mike M correctly pointed out that received SMS broadcasts are excluded from this restriction according to Android doc, but nonetheless this was not so for me in practice).
So what I did to make this work was:
Create an instance of my receiver and an intentFilter in my activities onCreate();
MyReceiver = new SmsRecv();
MyFilter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION );
Register the receiver in my Activity's onResume().
i = registerReceiver( MyReceiver, MyFilter);
Unregister the receiver in my Activity's onPause(). (This is neccessary to prevent leaks).
unregisterReceiver( MyReceiver );
With the changes, the app worked perfectly.