I am sending push notification to users which when clicking on it opens the app.
My problem is that when the app is already open, clicking on the notification start
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK );
notificationIntent.putExtras(bundle);
PendingIntent pintent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
first of all set a default Task android:taskAffinity="com.example.testp.yourPreferredName"
in your Application
element in the Manifest file. Maintain your android:launchMode="singleTask"
on your SplashActivity
. Now since your SplashActivity is your main entry add this code to both onResume()
, onNewIntent()
and onCreate()
(on a second thought onResume() is not recomended) -follow the comments in the code
//Note these following lines of code will work like magic only if its UPVOTED.
//so upvote before you try it.-or it will crash with SecurityException
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1000);
for(int i =0; i< taskInfo.size(); i++){
String PackageName = taskInfo.get(i).baseActivity.getPackageName();
if(PackageName.equals("packagename.appname")){// suppose stackoverflow.answerer.Elltz
//if the current runing actiivity is not the splash activity. it will be 1
//only if this is the first time your <taskAffinity> is be called as a task
if(taskInfo.get(i).numActivities >1){
//other activities are running, so kill this splash dead!! reload!!
finish();
// i am dying in onCreate..(the user didnt see nothing, that's the good part)
//about this code. its a silent assassin
}
//Operation kill the Splash is done so retreat to base.
break;
}
}
This code will not work on api 21+
; to make it work you need to use AppTask, this will save you extra lines of code as you will not be in a Loop to find your Task
.
Hope it helps
String appPackageName = "";
private void isApplicationInForeground() throws Exception {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final List<ActivityManager.RunningAppProcessInfo> processInfos = am
.getRunningAppProcesses();
ActivityManager.RunningAppProcessInfo processInfo = processInfos
.get(0);
// for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
// getting process at 0th index means our application is on top on all apps or currently open
appPackageName = (Arrays.asList(processInfo.pkgList).get(0));
}
// }
}
else {
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = null;
componentInfo = taskInfo.get(0).topActivity;
appPackageName = componentInfo.getPackageName();
}
}
private void notifyMessage(String text) {
if (appPackageName.contains("com.example.test")) {
// do not notify
}
else {
// create notification and notify user
}
}
Instead of showing the Splash activity on notification click, show your MainActivity because your splash activity will closed after some time but MainActivity will be remain open and
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
And maybe don't start the Splash Activity and reopen (bring to front) the MainActivity and update the UI with a listener that tells you, that you have a new notification (with a flag - boolean or with an Interface to make a listener).
You can use an ordered broadcast to accomplish this.
1) Change your PendingIntent
to start a BroadcastReceiver
which will decide whether to start the activity or do nothing:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, DecisionReceiver.class), 0);
2) Create the decision BroadcastReceiver
:
public class DecisionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.sendOrderedBroadcast(new Intent(MainActivity.NOTIFICATION_ACTION), null, new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (getResultCode() == MainActivity.IS_ALIVE) {
// Activity is in the foreground
}
else {
// Activity is not in the foreground
}
}
}, null, 0, null, null);
}
}
3) Create a BroadcastReceiver
in your activity that will signal that it is alive:
public static final String NOTIFICATION_ACTION = "com.mypackage.myapplication.NOTIFICATION";
public static final int IS_ALIVE = 1;
private BroadcastReceiver mAliveReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
setResultCode(IS_ALIVE);
}
};
// Register onResume, unregister onPause
// Essentially receiver only responds if the activity is the foreground activity
@Override
protected void onResume() {
super.onResume();
registerReceiver(mAliveReceiver, new IntentFilter(NOTIFICATION_ACTION));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mAliveReceiver);
}