友盟推送——判断app启动还是未启动

我们怎么判断一个app是处于前台后台,还是未启动状态,一般都会通过判断app的进程是否存活,如果进程存活说明是在后台或者前台,进程不存活,则说明app被杀死。
这里给一个工具类,判断应用是否已经启动

public class SystemUtils {
    /**
     * 判断应用是否已经启动
     * @param context 一个context
     * @param packageName 要判断应用的包名
     * @return boolean
     */
    public static boolean isAppAlive(Context context, String packageName){
        ActivityManager activityManager =
                (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        List processInfos
                = activityManager.getRunningAppProcesses();
        for(int i = 0; i < processInfos.size(); i++){
            if(processInfos.get(i).processName.equals(packageName)){
                Log.i("NotificationLaunch",
                        String.format("the %s is running, isAppAlive return true", packageName));
                return true;
            }
        }
        Log.i("NotificationLaunch",
                String.format("the %s is not running, isAppAlive return false", packageName));
        return false;
    }

之前在做友盟推送,想要实现的是如果app处于前台或者后台,那么就点开推送,直接跳转到想要的界面;如果app未启动,那么点开推送,就先启动app,再跳转到想要的界面。

并且友盟提供给了我们几个回调的方法

//1.每当有通知送达时,均会回调getNotification方法,因此可以通过监听此方法来判断通知是否送达。
UmengMessageHandler umengMessageHandler = new UmengMessageHandler() {
            @Override
            public Notification getNotification(Context context, UMessage uMessage) {
                return super.getNotification(context, uMessage);
            }
        };
        mPushAgent.setMessageHandler(umengMessageHandler);

第二个回调是自定义的通知打开动作,还有其他的,具体可以看友盟的官方文档。

//2.自定义通知打开动作,当用户点击了推送后,触发该回调
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {
            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
               }
        };
        mPushAgent.setNotificationClickHandler(notificationClickHandler);

并且友盟的官方文档中也要求我们最好在application中注册,并重写它部分的回调方法,因为有些如果写在activity中,可能app会收不到推送,具体还是请看友盟的官方文档,写的还是很详细,清楚的。

当有消息推送到的时候,那么第一个回调就会触发,在该回调方法中,我可以通过发送广播,然后提醒某些界面更新UI,类似于未读信息的小红点显示。
当用户点击了推送后,第二个回调就会触发,一开始的时候,我是在回调方法中发送一个广播,然后在广播里先调用一开始的工具类判断app是否存活,然后再对其做相应的处理,但是当我打印log后,发现不管怎么样,打印出来的都是isAppAlive return true,一直是存活的,于是发现并不适用,除非你开一个service服务,一直在后台监听,然后通过静态注册的广播来通知,我是这么觉得的,因为我的广播是写在application中的dealWithCustomAction回调方法中的,当收到推送,点击推送通知时,其实友盟已经把应用在后台唤醒了,所以我每次打印的log都是isAppAlive return true。所以发现以上的方案只能pass掉了。

于是乎我从另一个角度入手——activity的任务栈。
1.当应用未启动时,那么该应用的任务栈为空,因为并没有任何的activity入栈。
2.当应用启动后,或者在后台,那么我们一个应用的栈底一般都是MainActivity,虽然启动都是从Splash开始,但是进到MainActivity就
finish掉了,所以启动应用后栈底通常都是MainActivity.
3.遍历任务栈,如果发现栈底是MainActivity,就说明应用在前台或者后台,否则应用未启动。

//通过activity的任务栈查找来判断app是否在前台
                ActivityManager mAm = (ActivityManager) App.this.getSystemService(Context.ACTIVITY_SERVICE);
                List.RunningTaskInfo> runningTasks = mAm.getRunningTasks(100);
                for (ActivityManager.RunningTaskInfo runningTask : runningTasks) {
                    android.util.Log.e("run", runningTask.baseActivity.getClassName());
                    if (MAINACTTIVITY_CLASSNAME.equals(runningTask.baseActivity.getClassName())) {
                        isRun = true;
                        break;

                    }
                }

并且我用了一个变量来记录应用是在前台还是后台,如果找到了就直接break出来,不用继续遍历了,如果不知道自己MainActivity的全类名,可以通过上面的log打印出来看看。

你可能感兴趣的:(android)