onNewIntent not called on restart

2019-07-08 03:42发布

问题:

I have an alarm clock app, that is using Alarm Manager and a Broadcast Receiver. The app is one single activity and 4 fragments. When an alarm goes off the onReceive method sends an intent to the main activity, the main activity receives this intent in the method onNewIntent and then moves to the correct fragment. Everything works fine, except when an alarm goes off after the app has been closed.

Once I destroy the app, the alarm still goes off and the intent from the broadcast receiver fires, but the onNewIntent method does catch the intent and move the app to the correct fragment.

Here is the Intent that is in the broadcast receiver class that moves to the main activity

Intent alarmIntent = new Intent( context, ClockActivity.class );
                alarmIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
                alarmIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                alarmIntent.putExtra("Alarm Name", receivedAlarm.getmName());
                context.startActivity(alarmIntent);

Here is my onNewIntent method in my main activity that is not getting called when the alarm is called when the app is closed.

    @Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    PhraseFragment phraseFragment = new PhraseFragment();

    String activeName = intent.getStringExtra("Alarm Name");

    Bundle args = new Bundle();
    args.putString("activeName", activeName);
    phraseFragment.setArguments(args);

    getFragmentManager().beginTransaction()
            .replace(R.id.container, phraseFragment)
            .addToBackStack("phrase")
            .commit();

}

回答1:

Its a bit late but maybe this can help someone.

As I see onNewIntent is called when the activity is opened on the background. When you send an intent to an activity that isn't running on the background you can retrieve it through getIntent on onResume().

I would change you code to the following.

@Override
protected void onResume() {
    super.onResume();

    Intent intent = getIntent();
    String activeName = intent.getStringExtra("Alarm Name");

    if (activeName != null){
        PhraseFragment phraseFragment = new PhraseFragment();

        Bundle args = new Bundle();
        args.putString("activeName", activeName);
        phraseFragment.setArguments(args);

        getFragmentManager().beginTransaction()
                .replace(R.id.container, phraseFragment)
               .addToBackStack("phrase")
               .commit();
     }
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

In this case you need to check if the intent you've receive in onResume() contains the data you require.

Note that I haven't found any reference to this in the documentation. Its just the conclusion i got by experimenting.