Android实现点击通知栏后,先启动应用再打开目标Activity

主要是两种情况:

1、app中HomeActivity存在。

2、app中HomeActivity不存在,此时进程可能存在,也可能由于没有活动界面,进程被系统回收了。

如果所有Activity都不存在了,不管进程存不存在,ActivityManager.getAppTasks()

和ActivityManager.getRunningTasks(100)都是空;只要进程存在,不管是否有Acitivity存在,

ActivityManager.getRunningAppProcesses()中都会包含该进程。

一个定时提醒比较完善的处理方式:

1、AlarmManager -> BroadcastReceiver

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent("com.xxx.xxx.action.MSG_WARN");
            intent.putExtra("msg_object", bbsMsgWarn);
            int requestCode = (int)(alarmTime + bbsMsgWarn.getMsgId()); //int) SystemClock.uptimeMillis();
            // The hashcode works as an identifier here. By using the same, the alarm will be overwrriten
            PendingIntent sender = PendingIntent.getBroadcast(context, requestCode, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, sender);
            } else {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTime, sender);
            }

2、BroadcastReceiver -> Notification

public class BBSMsgWarnReceiver extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent)
    {
        final String action = intent.getAction();
        if("com.xxx.xxx.action.MSG_WARN".equals(action))
        {
            Object object = intent.getSerializableExtra("msg_object");

            if(object instanceof BBSMsgWarnResponse.BBSMsgWarn)
            {
                BBSMsgWarnResponse.BBSMsgWarn bbsMsgWarn = (BBSMsgWarnResponse.BBSMsgWarn)object;
//                Log.i("aaaaaaaaaaaaa", "BBSMsgWarnReceiver.BBSMsgWarn2: " + bbsMsgWarn.getJumpUrl());
                BBSMsgNotifier.getInstance().notifyBBSMsgWarn(bbsMsgWarn.getPushTitle(), bbsMsgWarn.getPushContent(), bbsMsgWarn.getPushContent(), bbsMsgWarn.getJumpType(), bbsMsgWarn.getJumpUrl());
            }
        }
    }
}

3、Notification -> Activity

		Intent intent = new Intent(mContext, JumpActivity.class);
		intent.putExtra("jumpType", jumpType);
		intent.putExtra("jumpUrl", jumpUrl);
		int requestCode = (int) SystemClock.uptimeMillis();
		// The hashcode works as an identifier here. By using the same, the alarm will be overwrriten
//		PendingIntent sender = PendingIntent.getBroadcast(mContext, requestCode, intent,
//				PendingIntent.FLAG_UPDATE_CURRENT);
		PendingIntent sender = PendingIntent.getActivity(mContext, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		notifyMsg(notificationKey, title, ticker, content, sender);

4、JumpActivity.java

public class JumpActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        String jumpType = intent.getStringExtra("jumpType");
        String jumpUrl = intent.getStringExtra("jumpUrl");

            //比较完善的逻辑是:
//            if(进程存在)//通过ActivityManager.getRunningAppProcesses()判断
//            {
//                if(activity栈存在)//通过ActivityManager.getRunningTasks(100)()或者manager.getAppTasks();判断
//                {
//                    直接打开目标activity
//                }
//                else
//                {
//                    依次打开homeactivity,目标activity//startActivities
//                }
//            }
//            else
//            {
//                先启动splashactivity,在打开homeactivity,再打开目标activity   //最终目标的activity通过Intent(intent是Parcelable)依次传给splashactivity,homeactivity
//            }
            if (isAppRunning(JumpActivity.this)) {
                //这里通过拦截器跳转,就根据jumpType判断了
                BBSUIUtil.openShareWebView(this, 0, jumpUrl);
            } else {
                //进入启动界面
                Intent intent1 = new Intent(JumpActivity.this, SplashActivity.class);
                //SplashActivity中传给HomeActivity,HomeActivity中有一个方法handleIntentData,根据Uri uri = Intent.getData(),调用拦截器
                intent1.setData(Uri.parse(jumpUrl));
                startActivities(new Intent[]{intent1});

                //这里也可以设置一个Bundle,在SplashActivity中传入HomeActivity,
                //中有一个方法handleIntentData,intent.getBundleExtra(ExtraName.HOME_DATA);
                //如果是用Bundle传的数据,则
                intent1.setData(Uri.parse(jumpUrl));
                Bundle bundle = new Bundle();
                bundle.putParcelable("to_activity", new Intent());//这里的intent是从通知栏传过来的,目标activity的intent
                intent1.putExtra(ExtraName.HOME_DATA, bundle);
                startActivities(new Intent[]{intent1});


            }
        

        finish();
    }

    private static boolean isAppRunning(Context context) {
        try {
            ActivityManager manager = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);

            if(AndroidSDKVersionUtils.hasMarshmallow())
            {
                List<ActivityManager.AppTask> appTasksList = manager.getAppTasks();
                if(appTasksList != null && appTasksList.size() > 0)
                {
                    for (ActivityManager.AppTask appTask : appTasksList) {
                        ActivityManager.RecentTaskInfo taskInfo = appTask.getTaskInfo();
                        if(taskInfo == null) continue;

                        ComponentName componentName = taskInfo.topActivity;//有可能是null,比如当activity都关闭的情况下,闹钟打开广播,在onReceive中调用
                        String currentPackageName = componentName.getPackageName();
                        if(!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(context.getPackageName()))
                        {
//                        ActivityManager.RunningTaskInfo info = runningTaskInfoList.get(0);//该activity刚启动,把该任务栈推到了第一位。为了保险起见,应该用for循环根据报名过滤,参考Util.isRunningAtFront
                            return taskInfo.numActivities > 1 && !TextUtils.equals(taskInfo.baseActivity.getClassName(), JumpActivity.class.getName());
                        }
                    }
                }
            }
            else
            {
                //进程中的所有Activity都已经退出了,不管进程有没有被系统回收时,此时不会在该列表中。
                //但是manager.getRunningAppProcesses()中可能有, 因为进程有可能还没被回收
                List<ActivityManager.RunningTaskInfo> runningTaskInfoList = manager.getRunningTasks(100);
                if(runningTaskInfoList != null && runningTaskInfoList.size() > 0)
                {
                    for (ActivityManager.RunningTaskInfo runningTaskInfo : runningTaskInfoList) {
                        ComponentName componentName = runningTaskInfo.topActivity;
                        String currentPackageName = componentName.getPackageName();
                        if(!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(context.getPackageName()))
                        {
//                        ActivityManager.RunningTaskInfo info = runningTaskInfoList.get(0);//该activity刚启动,把改任务栈推到了第一位。为了保险起见,应该用for循环根据报名过滤,参考Util.isRunningAtFront
                            return runningTaskInfo.numActivities > 1 && !TextUtils.equals(runningTaskInfo.baseActivity.getClassName(), JumpActivity.class.getName());
                        }
                    }
                }
            }
        } catch (Exception e) {
        }
        return false;
    }
}

5、消息model

    public static interface MsgWarn extends Serializable {

        /** 提醒通知标题*/
        public String getPushTitle();

        /** 提醒通知内容*/
        public String getPushContent();

        /** 提醒消息类型,可以定义假的消息类型,根据自己需要在MessageType.java中,已FAKE_开头,取值是负值*/
        public String getJumpType();

        /** 提醒消息跳转url*/
        public String getJumpUrl();

        /** 提醒时间*/
        public long getAlarmTime();

        /** 重置提醒时间*/
        public void setAlarmTime(long alarmTime);

        /** 消息id  可选*/
        public int getMsgId();

        /** 重复闹钟 时间间隔 可选, 默认是0,不重复*/
        public long getIntervalMillis();

        /** push通知是否要replace,还是互补干扰*/
        public boolean isReplace();

    }

转载于:https://my.oschina.net/bruces/blog/734664

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值