Android 实现微信,QQ的程序前后台切换:back键切换后台;点击通知栏恢复前台。

转自:http://blog.csdn.net/sddyljsx/article/details/41390169

实现类似微信,QQ的前后台切换:back键切换后台;点击通知栏恢复前台。

1、back键切换后台的实现:

这个实现需要在主activity重写onbackpressed()方法。代码如下

[java]  view plain copy
  1. @Override  
  2.     public void onBackPressed() {  
  3.         Intent intent= new Intent(Intent.ACTION_MAIN);  
  4.         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  5.         intent.addCategory(Intent.CATEGORY_HOME);  
  6.         startActivity(intent);  
  7.     }  
实现原理其实很简单,本来系统按back键的话是会destroy activity的,在这里,我们重写,改为使用intent启动HOME桌面

public static final String CATEGORY_HOME:
This is the home activity, that is the first activity that is displayed when the device boots. Constant Value: "android.intent.category.HOME"

谷歌的官方文档写的很清楚,这会启动home activity,也就是手机的桌面程序。这样,我们应用的主activity不会destroy,而只是stop。实现了按home键相同的效果。

2、点击通知栏恢复前台

在我们收到消息时,会在通知栏显示消息,并且点击通知栏消息后,程序可以切换到前台。下面是程序的结构:


程序结构如上图所示:MainActivity为主Activity,类似于微信,QQ的主界面;ShowPushActivity显示消息内容,类似于微信,QQ的聊天activity;MyApplication继承Application,实现通知栏的显示等操作;BringToFrontReceiver接受通知栏广播,将程序切换至前台。

[java]  view plain copy
  1. /** 
  2.  * Created by neal on 2014/11/18. 
  3.  */  
  4. public class MyApplication extends Application {  
  5.     @Override  
  6.     public void onCreate() {  
  7.         super.onCreate();  
  8.         NotificationCompat.Builder mBuilder =  
  9.                 new NotificationCompat.Builder(this)  
  10.                         .setSmallIcon(R.drawable.ic_launcher)  
  11.                         .setContentTitle("QQ")  
  12.                         .setContentText("您收到了一条新消息");  
  13.         Intent intent=new Intent(BringToFrontReceiver.ACTION_BRING_TO_FRONT);  
  14.         mBuilder.setContentIntent(PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));  
  15.         mBuilder.setAutoCancel(true);  
  16.         NotificationManager mNotificationManager =  
  17.                 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  18.         // mId allows you to update the notification later on.  
  19.         Notification notification=mBuilder.build();  
  20.         mNotificationManager.notify(1, notification);  
  21.     }  
  22. }  
上述代码实现应用启动后通知栏的显示,用户点击后发送广播到BringToFrontReceiver。模拟收到push消息。
如果我们只是单纯的实现此时将程序切换到前台,我自己想出如下两种实现方式

1、利用activitymanager的 moveTaskToFront 方法:

下面是接受到广播后的代码:

[java]  view plain copy
  1. public class BringToFrontReceiver extends BroadcastReceiver {  
  2.     public static final String ACTION_BRING_TO_FRONT ="neal.pushtest.action.BringToFront";  
  3.     public BringToFrontReceiver() {  
  4.     }  
  5.   
  6.     @Override  
  7.     public void onReceive(Context context, Intent intent) {  
  8.         //获取ActivityManager  
  9.         ActivityManager mAm = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);  
  10.         //获得当前运行的task  
  11.         List<ActivityManager.RunningTaskInfo> taskList = mAm.getRunningTasks(100);  
  12.         for (ActivityManager.RunningTaskInfo rti : taskList) {  
  13.             //找到当前应用的task,并启动task的栈顶activity,达到程序切换到前台  
  14.             if(rti.topActivity.getPackageName().equals(context.getPackageName())) {  
  15.                 mAm.moveTaskToFront(rti.id,0);  
  16.                 return;  
  17.             }  
  18.         }  
  19.         //若没有找到运行的task,用户结束了task或被系统释放,则重新启动mainactivity  
  20.         Intent resultIntent = new Intent(context, MainActivity.class);  
  21.         resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);  
  22.         context.startActivity(resultIntent);  
  23.   
  24.     }  
  25. }   

[java]  view plain copy
  1. <uses-permission android:name="android.permission.GET_TASKS"/>  
  2. <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>  
  3. <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>  
  4. <uses-permission android:name="android.permission.REORDER_TASKS"/>  

原理就是首先获取当前应用的task,然后利用moveTaskToFront,将该task切换到前台。若是没有活动的task,则重新启动程序。

但是moveTaskToFront只支持到3.0,那么3.0一下怎么实现呢,看方法2

2、自己利用startactivity实现:

除了moveTaskToFront,我们也可以自己利用task与back stack的一些性质来实现,如果对于task与back stack不是特别了解,可以看一下我写的这两篇文章

http://blog.csdn.net/sddyljsx/article/details/41293909

http://blog.csdn.net/sddyljsx/article/details/41315347

下面是接受到广播后的代码:

[java]  view plain copy
  1. public class BringToFrontReceiver extends BroadcastReceiver {  
  2.     public static final String ACTION_BRING_TO_FRONT ="neal.pushtest.action.BringToFront";  
  3.     public BringToFrontReceiver() {  
  4.     }  
  5.   
  6.     @Override  
  7.     public void onReceive(Context context, Intent intent) {  
  8.         //获取ActivityManager  
  9.         ActivityManager mAm = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);  
  10.         //获得当前运行的task  
  11.         List<ActivityManager.RunningTaskInfo> taskList = mAm.getRunningTasks(100);  
  12.         for (ActivityManager.RunningTaskInfo rti : taskList) {  
  13.             //找到当前应用的task,并启动task的栈顶activity,达到程序切换到前台  
  14.             if(rti.topActivity.getPackageName().equals(context.getPackageName())) {  
  15.                 try {  
  16.                     Intent  resultIntent = new Intent(context, Class.forName(rti.topActivity.getClassName()));  
  17.                     resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);  
  18.                     context.startActivity(resultIntent);  
  19.                 }catch (ClassNotFoundException e) {  
  20.                     e.printStackTrace();  
  21.                 }  
  22.                 return;  
  23.             }  
  24.         }  
  25.         //若没有找到运行的task,用户结束了task或被系统释放,则重新启动mainactivity  
  26.         Intent resultIntent = new Intent(context, MainActivity.class);  
  27.         resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);  
  28.         context.startActivity(resultIntent);  
  29.   
  30.     }  
  31. }  

权限

[java]  view plain copy
  1. <uses-permission android:name="android.permission.GET_TASKS"/>  
  2. <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>  
  3. <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>  

首先获取当前应用的task,然后获得task的栈顶activity,也就是最后打开的activity的名称,然后启动它,既可以切换到前台了。核心是这句话:

[java]  view plain copy
  1. resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);  

因为是singletop,所以activity不会重新创建,而是调用onnewintent方法。若是没有活动的task,则重新启动程序。这种方法不存在版本兼容问题,需要的权限还要少一个。

然而当我们观察微信,QQ的话,其点击通知栏不仅仅是将程序切换到前台,而且还会打开消息的对话activity。这个实现其实比只是切换到前台简单多了:

接收到广播后的处理:

[java]  view plain copy
  1. public class BringToFrontReceiver extends BroadcastReceiver {  
  2.     public static final String ACTION_BRING_TO_FRONT ="neal.pushtest.action.BringToFront";  
  3.     public BringToFrontReceiver() {  
  4.     }  
  5.   
  6.     @Override  
  7.     public void onReceive(Context context, Intent intent) {  
  8.        Intent resultIntent = new Intent(context, ShowPushActivity.class);  
  9.         resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);  
  10.         context.startActivity(resultIntent);  
  11.     }  
  12. }  
假设我们这里的ShowPushActivity为聊天的activity,那么只需要启动这个activity,并且加上flag:resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);就可以实现目的了。

这样ShowPushActivity会在后台的task启动,并且会将task带入前台。如果已经有一个ShowPushActivity,不会重新创建,而是调用onnewintent启动activity。

通过上面的介绍我们实现了类似微信,QQ的前后台切换:back键切换后台;点击通知栏恢复前台。其中恢复前台提供了两种方法,是我自己看官方文档,得到的启发,得到了实现。我觉得只要自己肯于静下心来研究Android的官方文档很多问题都可以迎刃而解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值