0

I would like to notify the incoming sms message. I implemented the BroadcastReceiver for SMS receiver. And I also implemented the service for BOOT_COMPLETED action. Because the receiver cannot be registered if the device is reboot. When I launch the apps, that only call onReceiver once. But I reboot the device and start the BOOT_COMPLETED service. That will make the onReceive method call twice. But I don't know why. I confirm I only register the receiver once.

ps: When I reboot the device, I received the log order is enable receiver, register receiver, enable receive, onReceived, onReceived

Here is my code:

AutoStartService.java

public class AutoStartService extends Service {
    private SmsReceiver smsReceiver;
    public static boolean isStarted = false;
    @Override
    public void onCreate() {
        super.onCreate();
        isStarted = true;
        if(!SmsReceiver.isEnableReceiver && smsReceiver == null) {
            smsReceiver = new SmsReceiver();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
            registerReceiver(smsReceiver, intentFilter);
            Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
            Log.e("AAA", "register receiver");
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isStarted = false;
        Toast.makeText(this, "Service Destroy", Toast.LENGTH_LONG).show();
    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

BootCompleteReceiver.java

public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(!AutoStartService.isStarted) {
            new Handler().postDelayed(() -> {
                Intent service = new Intent(context, AutoStartService.class);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    context.startForegroundService(service);
                } else {
                    context.startService(service);
                }
            }, 500);
        }
    }
}

SmsReceiver.java

public class SmsReceiver extends BroadcastReceiver implements SmsHelper.SmsHelperDelegate {
    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    public static boolean isEnableReceiver = false;

    public SmsReceiver() {
        super();
        isEnableReceiver = true;
        Log.e("AAA", "enable receiver");
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(SMS_RECEIVED)) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                Log.e("SmsReceiver", "onReceived");
            }
        }
    }

AndroidManifest.xml

<receiver android:name=".receiver.SmsReceiver" android:enabled="true" android:exported="true">
     <intent-filter android:priority="2147483647">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
     </intent-filter>
</receiver>
<service android:name=".receiver.AutoStartService" android:exported="true"/>
<receiver android:name=".receiver.BootCompleteReceiver" android:exported="true">
     <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT" />
     </intent-filter>
</receiver>
Wong Manlok
  • 387
  • 4
  • 17
  • Do you have a `` element for `SmsReceiver` in your manifest? – Mike M. Jun 29 '22 at 03:18
  • Thanks for your reply. Yes, I added. I can receive the incoming sms but don't know why onReceive method will be called twice when reboot the device – Wong Manlok Jun 29 '22 at 03:20
  • Yeah, that's the problem. That's actually statically registering the `SmsReceiver` class, which should be all you need. Why are you using that `Service` and the boot Receiver, exactly? I'm not sure what you mean by "Because the receiver cannot be registered if the device is reboot." – Mike M. Jun 29 '22 at 03:21
  • I need the notify the incoming message anytime. But I find out the receiver will be removed when I reboot the device. So I implemented the BOOT_COMPLETE receiver. – Wong Manlok Jun 29 '22 at 03:24
  • I don't want to launch the apps to register the receiver when I reboot the device. – Wong Manlok Jun 29 '22 at 03:26
  • Nah, Receivers statically registered in the manifest are not disabled just because of a reboot. As long as you've launched your app at least once after installation, the Receiver will remain registered, unless the app is forcibly stopped. If that happens, though, your boot Receiver won't work either. – Mike M. Jun 29 '22 at 03:27
  • Oh...Thanks for your detail explanation. I just removed the BOOT_COMPLETE receiver and reboot the device. It received the incoming message once. – Wong Manlok Jun 29 '22 at 03:41
  • I would like ask you a question. When I register the receive I will show the push notification to inform the user the sms receiver is running. Now I removed the BOOT_COMPLETE receiver. When I reboot the device, the push notification is not shown. So do you know how to resolve this issue. – Wong Manlok Jun 29 '22 at 03:41
  • Do you mean that you had a `Notification` for the foreground `Service`? If so, that's not really necessary anymore, since you don't have a constantly running `Service`. If you'd still like to have one, you can post your own `Notification` from the boot Receiver without the `Service`. You would simply make it _ongoing_, so it can't be swiped away by the user. Is that what you mean? – Mike M. Jun 29 '22 at 03:48
  • yes. Just tell the user the receiver is running – Wong Manlok Jun 29 '22 at 03:49
  • Yeah, you can certainly do that; just [add a `setOngoing(true)` call](https://stackoverflow.com/q/21795336) to [a regularly posted `Notification`](https://stackoverflow.com/q/43093260) in your `BOOT_COMPLETED` Receiver. That will cause it to remain posted until you cancel it programmatically. I should mention, though, that an SMS Receiver won't really be running the whole time. A new instance will be created for each message, and it only runs long enough to finish `onReceive()`, basically. – Mike M. Jun 29 '22 at 03:56
  • Thanks you answer. I would like to ask the last question. I force stopped the application in the device setting. So do you know how to restart the receiver if force stopped – Wong Manlok Jun 29 '22 at 04:11
  • To bring an app out of the stopped state, one of its components must be explicitly started. For most apps, that means the only way to do it is by launching its main `Activity`. Basically, it's not going to work again until the user runs your app next. – Mike M. Jun 29 '22 at 04:19

0 Answers0