Android切换前后台点击通知进入当前页面
Spig跟着fly学前端 人气:0在上一节讲述了,本人使用的怎么判断App退到后台的两种方式,这里主要讲述当App退出到后台的后,怎么点击通知回到原来按下HOME键之前的前台页面.
首先,先展示效果,有图才有真相
效果如上图,当我们按下back键或者HOME键的时候.程序退到后台,弹出通知,点开通知回到当前页面. 在上节中,我有讲述到判断程序退到后台的两种方式. 第一种方式:在BaseActivity中onPause方法中判断程序退出后台之后,进入广播页面:
public class BaseActivity extends AppCompatActivity { private static final String TAG = "BaseActivity"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); AppManager.getInstance().addActivity(this); } @Override protected void onPause() { super.onPause(); if(!isAppOnForeground()){ Toast.makeText(getApplicationContext(), TAG+"onPause:", Toast.LENGTH_SHORT).show(); }else { Log.e(TAG, "onPause: "+"弹出通知"); //第一种方式退到后台 Intent _intent = new Intent(DemoBroadcastReceiver.ACTION_NOTIFY_MESSAGE); _intent.setClass(getApplicationContext(), DemoBroadcastReceiver.class); sendBroadcast(_intent); } }
第二种方式,在Application中中onStopActivity方法中判断程序退出后台之后,进入广播页面:
@Override public void onActivityStopped(Activity activity) { countActivity--; L.i("onActivityStopped", "countActivity=" + countActivity); if (countActivity <= 0) { if (WDRTCSysConfig.getInstance().isCalling()) { Intent _intent = new Intent(WDBroadcastReceiver.ACTION_ENABLE_MESSAGES); _intent.setClass(getApplicationContext(), WDBroadcastReceiver.class); sendBroadcast(_intent); } } }
不管是方法一或者 方法 二:都是进入广播服务中,进行判断然后弹出Notification通知出来.主要代码如下:
@Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { case ACTION_NOTIFY_MESSAGE: String name = null; String avatar = null; //方法一:从系统的Stack中拿到当前的Activity /* ActivityManager mActivityManager = ((ActivityManager) context.getApplicationContext() .getSystemService(Context.ACTIVITY_SERVICE)); List<ActivityManager.RunningTaskInfo> taskInfos = mActivityManager.getRunningTasks(1); Class<?> _class = taskInfos.get(0).topActivity.getClass(); */ //方法二:从AppManger的Stack中拿到当前的Activity Class<?> _class = AppManager.getInstance().currentActivity().getClass(); if (_class != null) { if (null != reflectionActivity()) { //拿到反射的数据 Bundle _bundle = reflectionActivity(); if (_bundle != null) { name = _bundle.getString("name"); avatar = _bundle.getString("avatar"); } } NotificationUtils _notifyUtils = NotificationUtils.getInstance(); _notifyUtils.init(context.getApplicationContext(), _class); _notifyUtils.showNotification("从" + name + "退出到后台"); } break; } }
注意上面代码:有两种方式拿到当前的Activity. 这两个这里先简单介绍,后面详细解释 稍微注意下第21行:这里主要通过反射拿到当前Activity要传给通知栏显示的信息,; 而通知栏的主要代码如下:没什么好解释的
public void showNotification(@NonNull String contentText){ PendingIntent _pendingIntent = PendingIntent.getActivity(mContext, notifId, mNotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext); builder.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(),R.mipmap.ic_launcher)) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("通知测试") .setContentText(contentText) .setSubText(mContext.getString(R.string.notice_click_into)) .setPriority(Notification.PRIORITY_HIGH) .setVibrate(new long[]{0, 0, 0, 10}) //.setFullScreenIntent(_pendingIntent, true) .setContentIntent(_pendingIntent); //在什么状态下显示通知,比如锁屏状态 if (Build.VERSION.SDK_INT >= 21) { builder.setVisibility(Notification.VISIBILITY_PUBLIC); builder.setCategory(Notification.CATEGORY_MESSAGE); } mNotification = builder.build(); mNotificationManager.notify(notifId, mNotification); }
关于怎样获取当前的Activity,这里是主要的关键,这里我使用了两种方法: 方法二: 我自己手动建立了一个Activity的Stack的工具栏,然后对Activity进行增删操作处理,主要代码如下:
public class AppManager { private static AppManager instance; private static Stack<Activity> activityStack; public static AppManager getInstance() { if (instance == null) { //懒汉双层锁,保证线程安全 synchronized (AppManager.class) { if (instance == null) { instance = new AppManager(); } } } return instance; } /** * 添加Activity到stack中 */ public void addActivity(Activity activity) { if (activityStack == null) { activityStack = new Stack<>(); } if (activityStack.contains(activity)) { activityStack.remove(activity); } activityStack.add(activity); } /** * 获取stack中当前的Activity */ public Activity currentActivity() { if (null != activityStack && null != activityStack.lastElement()) { return activityStack.lastElement(); } return null; } /** * 移除当前的Activity */ public void finishActivity() { if (null != activityStack && null != activityStack.lastElement()) { finishActivity(activityStack.lastElement()); } } }
这是一个单例,然后在BaseActivity的onCreate中调用Add方法,在Activity要finish的时候,调用这里的finishActivity方法,而CurrentActivity就是我们需要的当前的Activity;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); AppManager.getInstance().addActivity(this); }
另外还有一种方式就是获取当前Activity的方法,就是程序系统本身就有一个Stack的,我们可以通过管理 ActivityManager. getRunningTasks(1) 来拿到当前的Activity,这是我在网上看到的.
ActivityManager mActivityManager = ((ActivityManager) _app .getSystemService(Context.ACTIVITY_SERVICE)); List<RunningTaskInfo> taskInfos = mActivityManager.getRunningTasks(1); Class<?> intentActivity = taskInfos.get(0).topActivity.getClass();
但是由于 mActivityManager . getRunningTasks ( 1 ) 在 API21以后是过期的,而且需要一个task的配置权限.本人没有使用它,来进行处理.好了,大致的程序就是这些,具体的可以下载demo; 点击这里:Demo下载
加载全部内容