Starting app only if its not currently running

后端 未结 11 1602
我寻月下人不归
我寻月下人不归 2020-12-02 23:07

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

相关标签:
11条回答
  • 2020-12-02 23:32

    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);
    
    0 讨论(0)
  • 2020-12-02 23:33

    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

    0 讨论(0)
  • 2020-12-02 23:35
    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  
        }
    }
    
    0 讨论(0)
  • 2020-12-02 23:35

    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"
    
    0 讨论(0)
  • 2020-12-02 23:38
    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).

    0 讨论(0)
  • 2020-12-02 23:40

    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);
    }
    
    0 讨论(0)
提交回复
热议问题