jobin
jobin

Reputation: 1527

Android onNewIntent() not triggered when activity is invisible

I have 2 activities, first one being MainActivity. In Manifest launch mode of Second Activity is set as SingleInstance.The button in MainActivity starts SecondActivity, which has a button which triggers notification. The only problem is onNewIntent() method of SecondActivity is not called when SecondActivity is not visible.Why isn't the onNewIntent() method not called when app is in background or SecondActivity is invisble to the user?

Code:

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.globemaster.com.trials">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
       >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SecondActivity"
            android:launchMode="singleInstance"
            android:parentActivityName=".MainActivity"/>
    </application>

</manifest>

Java:

MainActivity.java:

 Intent intent=new Intent(MainActivity.this,SecondActivity.class);
 startActivity(intent);

SecondActivity.java:

public class SecondActivity extends AppCompatActivity {
    int count=0;int id=3;Notification notification;
    NotificationManager notificationManager;
    Intent intent,intent1;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_second);
        findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                intent1=new Intent(getApplicationContext(),SecondActivity.class);
                if (count>1){
                    intent1.putExtra("click",true);
                    }
                PendingIntent pendingIntent=PendingIntent.getActivity(getApplicationContext(),0,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
                if (notificationManager==null)
                {
                    notificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                    }
                Notification.Builder builder=new Notification.Builder(getApplicationContext());
                builder.setSmallIcon(R.drawable.ic_launcher_background);
                builder.setContentTitle("My Notification");
                builder.setContentText("You have "+count+" message");
                builder.setContentIntent(pendingIntent);
                notification=builder.build();
                notificationManager.notify(3,notification);
                }        });
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e("OnNewIntent","Called");
        if (intent!=null&&intent.hasExtra("click")&&intent.getBooleanExtra("click",false))
        {
            Toast.makeText(getApplicationContext(), "Notification Clicked", Toast.LENGTH_SHORT).show();
        }
        else {
            Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();
        }
    }
}

Upvotes: 4

Views: 7685

Answers (1)

msbit
msbit

Reputation: 4320

According to the documentation

This is called for activities that set launchMode to "singleTop" in their package, or if a client used the Intent.FLAG_ACTIVITY_SINGLE_TOP flag when calling startActivity(Intent).

Based on that, you could try either:

  • setting the android:launchMode in the manifest to singleTop; or
  • adding the flag to the Intent via intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) before calling startActivity

If you:

  • need the singleInstance behaviour; and
  • want to be informed when an Activity that is in the background has come to the foreground (for example in the singleInstance case); and
  • don't need the Intent explicitly

then you can implement the onResume method, which will be called when the user returns to the Activity.

Edit after testing

What I've observed in testing is that, if a singleInstance Activity is in the background and Intents are passed to it (via startActivity for example) these are queued until the Activity comes into the foreground, then:

  • onNewIntent is called for each Intent; then
  • onResume is called once

This contradicts the documentation, but could be used to solve your problem.

As noted in the documentation:

Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.

So, if you are happy to process the Intents when the Activity comes to the foreground, you could replace your onNewIntent above with:

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

    setIntent(intent);
}

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

    Intent intent = getIntent();
    if (intent != null && intent.hasExtra("click") && intent.getBooleanExtra("click", false)) {
        Toast.makeText(getApplicationContext(), "Notification Clicked", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(getApplicationContext(), "False", Toast.LENGTH_SHORT).show();
    }
}

Upvotes: 3

Related Questions