主要是两种情况:
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();
}