Android切换前后台,点击通知进入当前页面

  在上一节讲述了,本人使用的怎么判断App退到后台的两种方式,这里主要讲述当App退出到后台的后,怎么点击通知回到原来按下HOME键之前的前台页面.

  首先,先展示效果,有图才有真相


  效果如上图,当我们按下back键或者HOME键的时候.程序退到后台,弹出通知,点开通知回到当前页面.
  在上节中,我有讲述到判断程序退到后台的两种方式.
 第一种方式:在BaseActivity中onPause方法中判断程序退出后台之后,进入广播页面:
 
    
  1. public class BaseActivity extends AppCompatActivity {
  2. private static final String TAG = "BaseActivity";
  3. @Override
  4. protected void onCreate(@Nullable Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. AppManager.getInstance().addActivity(this);
  7. }
  8. @Override
  9. protected void onPause() {
  10. super.onPause();
  11. if(!isAppOnForeground()){
  12. Toast.makeText(getApplicationContext(), TAG+"onPause:",
  13. Toast.LENGTH_SHORT).show();
  14. }else {
  15. Log.e(TAG, "onPause: "+"弹出通知");
  16. //第一种方式退到后台
  17. Intent _intent = new Intent(DemoBroadcastReceiver.ACTION_NOTIFY_MESSAGE);
  18. _intent.setClass(getApplicationContext(), DemoBroadcastReceiver.class);
  19. sendBroadcast(_intent);
  20. }
  21. }
第二种方式,在Application中中onStopActivity方法中判断程序退出后台之后,进入广播页面:
 
     
  1. @Override
  2. public void onActivityStopped(Activity activity) {
  3. countActivity--;
  4. L.i("onActivityStopped", "countActivity=" + countActivity);
  5. if (countActivity <= 0) {
  6. if (WDRTCSysConfig.getInstance().isCalling()) {
  7. Intent _intent = new Intent(WDBroadcastReceiver.ACTION_ENABLE_MESSAGES);
  8. _intent.setClass(getApplicationContext(), WDBroadcastReceiver.class);
  9. sendBroadcast(_intent);
  10. }
  11. }
  12. . }
不管是方法一或者 方法 二:都是进入广播服务中,进行判断然后弹出Notification通知出来.主要代码如下:
 
    
  1. @Override
  2. public void onReceive(Context context, Intent intent) {
  3. switch (intent.getAction()) {
  4. case ACTION_NOTIFY_MESSAGE:
  5. String name = null;
  6. String avatar = null;
  7. //方法一:从系统的Stack中拿到当前的Activity
  8. /* ActivityManager mActivityManager = ((ActivityManager) context.getApplicationContext()
  9. .getSystemService(Context.ACTIVITY_SERVICE));
  10. List<ActivityManager.RunningTaskInfo> taskInfos = mActivityManager.getRunningTasks(1);
  11. Class<?> _class = taskInfos.get(0).topActivity.getClass();
  12. */
  13. //方法二:从AppManger的Stack中拿到当前的Activity
  14. Class<?> _class = AppManager.getInstance().currentActivity().getClass();
  15. if (_class != null) {
  16. if (null != reflectionActivity()) {
  17. //拿到反射的数据
  18. Bundle _bundle = reflectionActivity();
  19. if (_bundle != null) {
  20. name = _bundle.getString("name");
  21. avatar = _bundle.getString("avatar");
  22. }
  23. }
  24. NotificationUtils _notifyUtils = NotificationUtils.getInstance();
  25. _notifyUtils.init(context.getApplicationContext(), _class);
  26. _notifyUtils.showNotification("从" + name + "退出到后台");
  27. }
  28. break;
  29. }
  30. }

注意上面代码:有两种方式拿到当前的Activity. 这两个这里先简单介绍,后面详细解释
稍微注意下第21行:这里主要通过反射拿到当前Activity要传给通知栏显示的信息,;
而通知栏的主要代码如下:没什么好解释的

 
    
  1. public void showNotification(@NonNull String contentText){
  2. PendingIntent _pendingIntent = PendingIntent.getActivity(mContext, notifId, mNotificationIntent,
  3. PendingIntent.FLAG_UPDATE_CURRENT);
  4. NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
  5. builder.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(),R.mipmap.ic_launcher))
  6. .setSmallIcon(R.mipmap.ic_launcher)
  7. .setContentTitle("通知测试")
  8. .setContentText(contentText)
  9. .setSubText(mContext.getString(R.string.notice_click_into))
  10. .setPriority(Notification.PRIORITY_HIGH)
  11. .setVibrate(new long[]{0, 0, 0, 10})
  12. //.setFullScreenIntent(_pendingIntent, true)
  13. .setContentIntent(_pendingIntent);
  14. //在什么状态下显示通知,比如锁屏状态
  15. if (Build.VERSION.SDK_INT >= 21) {
  16. builder.setVisibility(Notification.VISIBILITY_PUBLIC);
  17. builder.setCategory(Notification.CATEGORY_MESSAGE);
  18. }
  19. mNotification = builder.build();
  20. mNotificationManager.notify(notifId, mNotification);
  21. }
 关于怎样获取当前的Activity,这里是主要的关键,这里我使用了两种方法:
方法二: 我自己手动建立了一个Activity的Stack的工具栏,然后对Activity进行增删操作处理,主要代码如下:
 
    
  1. public class AppManager {
  2. private static AppManager instance;
  3. private static Stack<Activity> activityStack;
  4. public static AppManager getInstance() {
  5. if (instance == null) {
  6. //懒汉双层锁,保证线程安全
  7. synchronized (AppManager.class) {
  8. if (instance == null) {
  9. instance = new AppManager();
  10. }
  11. }
  12. }
  13. return instance;
  14. }
  15. /**
  16. * 添加Activity到stack中
  17. */
  18. public void addActivity(Activity activity) {
  19. if (activityStack == null) {
  20. activityStack = new Stack<>();
  21. }
  22. if (activityStack.contains(activity)) {
  23. activityStack.remove(activity);
  24. }
  25. activityStack.add(activity);
  26. }
  27. /**
  28. * 获取stack中当前的Activity
  29. */
  30. public Activity currentActivity() {
  31. if (null != activityStack && null != activityStack.lastElement()) {
  32. return activityStack.lastElement();
  33. }
  34. return null;
  35. }
  36. /**
  37. * 移除当前的Activity
  38. */
  39. public void finishActivity() {
  40. if (null != activityStack && null != activityStack.lastElement()) {
  41. finishActivity(activityStack.lastElement());
  42. }
  43. }
  44. }
这是一个单例,然后在BaseActivity的onCreate中调用Add方法,在Activity要finish的时候,调用这里的finishActivity方法,而CurrentActivity就是我们需要的当前的Activity;
 
    
  1. @Override
  2. protected void onCreate(@Nullable Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. AppManager.getInstance().addActivity(this);
  5. }
另外还有一种方式就是获取当前Activity的方法,就是程序系统本身就有一个Stack的,我们可以通过管理 ActivityManager. getRunningTasks(1) 来拿到当前的Activity,这是我在网上看到的.
 
    
  1. ActivityManager mActivityManager = ((ActivityManager) _app
  2. .getSystemService(Context.ACTIVITY_SERVICE));
  3. List<RunningTaskInfo> taskInfos = mActivityManager.getRunningTasks(1);
  4. Class<?> intentActivity = taskInfos.get(0).topActivity.getClass();
但是由于  mActivityManager . getRunningTasks ( 1 ) API21以后是过期的,而且需要一个task的配置权限.本人没有使用它,来进行处理.好了,大致的程序就是这些,具体的可以下载demo;
点击这里:Demo下载

猜你喜欢

转载自blog.csdn.net/zybieku/article/details/52588282