5

I am trying to follow this answer However, it is not working in simulator nor on my phone so I have questions on the simulator logs and phone and rebooting to simulate this and debug

I have very interesting notes at the bottom that are VERY confusing to me

I am using API 24 and pixel 3 simulator and real samsung 8 phone

I do the typical adds to manifest of

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

and

    <receiver android:name=".biz.alarm.BootupReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

I however never see this log statement...

public class BootupReceiver extends BroadcastReceiver {
  private final static String TAG = "BootupReceiver";

  @Override
  public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    Log.d(TAG, "booted. action="+action);

  }
}

For the simulate, I click the play button and watch my app come up. I then hold the power button and it only gives me a "power off" option when I really just want to restart...odd, so I power off. That seems to exit the simulate completely such that when I click play again on the simulator in Android Studio, it then logs

08/06 19:17:40: Launching 'app' on Pixel 3 API 24.
$ adb shell am start -n "app.mykeepintouch.kit/app.mykeepintouch.kit.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
...
D/MainActivity: onCreate: starting

There is no bootup log for me to reregister notifications. QUESTION 1: Can the simulator not simulate this correctly?

Next, my real phone- Well, the same thing I guess but perhaps there are some logs I can view on the phone itself at least? The post I ran into talked about dumping to sd card but I am plugged into android studio so I would think I could dump logs somehow to android studio?

EDIT: I am using the sample link in that post as well. I did a git clone imported the project, picked API 24 and added a single log in PollReceiver. It worked when I went to bed and did not work the 2nd run when I ran this morning. I will add more info as I debug random scenarios I think of.

WEIRD SCENARIO 1: If I have TWO android studio projects open and open my personal app and then open the sample link app AFTER my project, I see a Toast "Alarms scheduled". I however can find no logs on PollReceiver until that alarm goes off 5 seconds later. I was expecting to see a log from PollReceiver on start but never see that until 5 seconds. Another run of this later yielded no logs (except the toast message popped up so I know it ran that code...very weird). I added a log message then to ScheduledServiceDemoActivity and now I can't reproduce 0 logs like that one time.

WEIRD SCENARIO 2: I REBOOT the phone(or it keeps launching my app and scenario 1 keeps working). Then I ONLY boot the sample link app, nothing ever happens. I wait for 90 seconds and nothing.

This may be why it worked last night before I went to bed as I was in scenario 1.

FINAL GUESSES: I can never get PollReceiver to fire on startup. ScheduledServiceDemoActivity seems to be the true entry point and I never added a service to my above code as I didn't want one...just wanted to be notified of being booted up to reschedule alarms. This then leads me to the possible conclusion the ScheduledServiceDemoActivity is there to fire on certain devices on bootup and the PollReceiver is for other devices on bootup? If so, what simulators can simluate this other bootup scenario?

EDIT (I had another thought) On my samsung phone, I checked the permissions and there is only THREE even though I added these 4 lines in my manifest

<!-- So we can make a phone call out -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- so we can send a text -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- So we can reschedule alarms that went off while powered off -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- read contacts so they can easily choose their friends -->
<uses-permission android:name="android.permission.READ_CONTACTS" />

The receive boot is not in there. is this the issue? OR do phones not list the receive boot completed to users as it might be confusing?

thanks, Dean

Dean Hiller
  • 19,235
  • 25
  • 129
  • 212

3 Answers3

0

Try to add this to your intent-filter in your manifest:

<receiver android:name=".biz.alarm.BootupReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
        </intent-filter>
    </receiver> 

It helped me when I got similar issue with some devices.

Alex Rmcf
  • 804
  • 7
  • 14
  • I assume you mean to PollReceiver, and that had no effect for me in scenario 1 or 2 in logs showing up on boot. Instead, it seems the main thing that does get triggered on boot is ScheduledServiceDemoActivity so perhaps I just use that piece of the demo BUT I am wondering if this is because of incompatibilities across devices so it's complex to account for many versions. – Dean Hiller Aug 07 '20 at 13:21
  • I edited my answer. I had app which suppose to start service after device reboot. But this did not work on all devices. Later I found that for some of them you need this additional line of code – Alex Rmcf Aug 07 '20 at 17:36
  • sorry @Alex Rmcf, still didn't work in API 24 so I am going down the service route now as I have no idea how else to get it to work. I may look into this JobScheduler I just learned about as well..anything to get my notification alarms rescheduled so users don't get pissed off when they don't get notifications. (only 50 hours in to learning android so perhaps I am not even on the right trail/best way of doing this). – Dean Hiller Aug 09 '20 at 04:23
0

You should look into setExactAndAllowWhileIdle From what I understand it will execute regardless of if the phone is in doze or not and exactly at the specified time.

You answered their own question here but because that answer utilizes the WorkManager API which "is intended for work that is deferrable—that is, not required to run immediately—and required to run reliably even if the app exits or the device restarts" (source) I feel that utilizing AlarmManager is the best way to handle what it seems that you are trying to do.

However, it should be noted that this will still require the alarms to be re-registered on every boot, which may seem difficult given OP's questions and concerns, but I have addressed those below. Though, you should be careful about what you do if you boot after an alarm was supposed to trigger. For example, suppose you are making an reminder app that you would like to be able to schedule notifications to go of and happen stance your phone powers off just before a reminder was supposed to be triggered and it powers on 5 minutes after it was supposed to be triggered. Do you still trigger the notification? Do you reschedule it with AlarmManager? Do you just ignore it all together? If you do trigger it, do you want it to be triggered before the user unlocks there device or is after they unlock the device acceptable?

The above questions are things that would change the exact implementation, however the basics are the same across the board.

  1. Register an intent receiver with the system
    <application>
        <!-- ... -->
        <receiver android:name="RECEIVER_NAME">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> this action is sent before the user unlocks their device-->
            </intent-filter>
        </receiver>
        <!-- ... -->
    </application>
    
  2. Re-register alarms with the AlarmManager in the BroadcastReceiver
        public class PollReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(final Context context, Intent intent) {
                if (intent.getAction() != null) {
                    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
                        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                        Intent i = new Intent(context, PollReceiver.class);//this will send the intent back to this class, you can make another broadcast receiver for handling the alarm going off though
                        i.setAction("ALARM_ACTION");
                        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, i, 0);
                        long triggerTime = System.currentTimeMillis() + 60000; //replace this with when you want your alarm to go off (this will trigger 1 minute from now)
                        AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
                    } else if (intent.getAction().equals("ALARM_ACTION")) {
                        //Show notification or make noise, whatever you are supposed to do when the alarm goes off
                    }
                }
            }
        }
    

Addressing the various questions/concerns throughout the question

QUESTION 1: Can the simulator not simulate [reboots] correctly?

It can, however, the issue is that you are running the project to start the emulator, which is not how a phone is powered on. Rather than pressing the run button in Android Studio to start the emulator, you should start the emulator by itself via Tools > AVD Manager > Play Button (under the actions column for the corresponding AVD) or see below for a way to restart the AVD while it is running.

I would think I could dump logs somehow to android studio?

Yes, you can, at the bottom of Android Studio there should be a tab named Logcat. This tab is where any connected virtual devices or physical devices will output logs (you will have to specify which device you would like to view if there are multiple connected). Also, there is the option to use the command line, via adb logcat, or it is also possible via the command line to trigger a reboot via adb reboot. You can also combine the two so that as soon as the phone is able to have adb connected you start listening to logcat, via adb reboot && adb wait-for-device logcat. This works for both physical devices as well as the emulator, the only issue is that this outputs the logs for everything, if you want to search for specific text you can use adb reboot && adb wait-for-device logcat | grep "string-to-search-for" (Windows can replace "grep" with "findstr")

WEIRD SCENARIO 1: If I have TWO android studio projects open and open my personal app and then open the sample link app AFTER my project, I see a Toast "Alarms scheduled". I however can find no logs on PollReceiver until that alarm goes off 5 seconds later. I was expecting to see a log from PollReceiver on start but never see that until 5 seconds. Another run of this later yielded no logs (except the toast message popped up so I know it ran that code...very weird). I added a log message then to ScheduledServiceDemoActivity and now I can't reproduce 0 logs like that one time.

The behavior you describe in the first part is correct and should happen regardless of how many Android Studio projects you have open and which app is run first. The application makes a repeating alarm that will go off in 5 seconds and then every 15 minutes after. If you added the log to the onReceive method, you won't see it until that method is called, which it isn't until the alarm goes off. As for the second part, where you didn't get any logs, you may not have let the application run for 5 seconds so no logs would be printed. It should be noted that when you run the application through Android Studio it is not exactly the same as if you run it from the phone by clicking on the icon. Which would also explain why you were unable to recreate it after adding the log into the activity.

WEIRD SCENARIO 2: I REBOOT the phone(or it keeps launching my app and scenario 1 keeps working). Then I ONLY boot the sample link app, nothing ever happens. I wait for 90 seconds and nothing.

The sample application should trigger a log approximately every 15 minutes, not 90 seconds (900,000ms not 90,000ms). However, the sample application should trigger a log 5 seconds (not exactly 5 seconds though because of the way Android works) after starting the app, or after a reboot.

I can never get PollReceiver to fire on startup. ScheduledServiceDemoActivity seems to be the true entry point and I never added a service to my above code as I didn't want one...just wanted to be notified of being booted up to reschedule alarms. This then leads me to the possible conclusion the ScheduledServiceDemoActivity is there to fire on certain devices on bootup and the PollReceiver is for other devices on bootup? If so, what simulators can simluate this other bootup scenario?

You should really familiarize yourself with the application lifecycle and activity lifecycle. ScheduledServiceDemoActivity is there to be what opens when you start the application via running in Android Studio or by pressing its icon on the launcher, but the BroadcastReceiver is also another entry point for the application. In this case, it is triggered when Android sends an Intent with the action ACTION_BOOT_COMPLETED. ScheduledServiceDemoActivity will never be started on boot. The bundled AVD can properly simulate the bootup scenario and it will trigger PollReceiver.

EDIT (I had another thought) On my samsung phone, I checked the permissions and there is only THREE even though I added these 4 lines in my manifest

<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- so we can send a text -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- So we can reschedule alarms that went off while powered off -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- read contacts so they can easily choose their friends -->
<uses-permission android:name="android.permission.READ_CONTACTS" />

The receive boot is not in there. is this the issue? OR do phones not list the receive boot completed to users as it might be confusing?

Most variants of Android (if not all) that come on devices will not display the permissions that are considered "normal" by Google. Essentially the only permissions that will be displayed there are the ones that are not automatically granted at install time and are considered "dangerous" as they can impact the user's stored data or the behavior of other apps.

undermark5
  • 775
  • 6
  • 17
-1

Well, I found the answer

Android 8/9 Notification scheduling

I had no idea you have to google for versions.

Dean Hiller
  • 19,235
  • 25
  • 129
  • 212
  • can you close this then cus if the answer already exists better to rate that and close this so people don't try to answer a question that is not valid anymore. – PedroAGSantos Aug 17 '20 at 09:21
  • @PedroAGSantos Does closing it still allow it to end up in google results? I mean, as humans, we all enter different google search terms leading us to miss the real post we want BUT when we land on a post that funnels us to the correct post, I personally LOVE that!!!!! rather than missing it over and over. For instance, googling BootupReceiver will lead to this post(NOT the other post) then you can finally find it through this post. – Dean Hiller Aug 17 '20 at 13:58
  • maybe you can suggest an edit in the other post so there is this visibility I'm more in favor of having the answers organized many times the answer is outdated and I also edit and update. I also maybe you can edit the question to contain some more info. your Question is very well structured. – PedroAGSantos Aug 17 '20 at 14:32