Reputation: 1527
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
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:
android:launchMode
in the manifest to singleTop
; orIntent
via intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
before calling startActivity
If you:
singleInstance
behaviour; andActivity
that is in the background has come to the foreground (for example in the singleInstance
case); andIntent
explicitlythen you can implement the onResume
method, which will be called when the user returns to the Activity
.
What I've observed in testing is that, if a singleInstance
Activity
is in the background and Intent
s 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
; thenonResume
is called onceThis 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 usesetIntent(Intent)
to update it to this new Intent.
So, if you are happy to process the Intent
s 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