判断手机是否退到后台,这是我们在Android开发中实现一些功能时,经常会考虑的问题,比如:按HOME,BACK键时,程序退到后台,消息以Notification形式弹出 ,或者程序在服务中把App退到后台,弹出服务浮窗,点击后回到当前页面等,这些也是实现及时通讯,服务推送过程经常遇到的,比如QQ,微信消息提醒,网络电话通知展示等.
废话不多说,直接上图:
如果需要判断程序进入后台,然后显示通知,弹出通知之后,直接进入HOME键之前页面,情点击下一节
程序后台切换前台,点击通知进入当前页面
DEMO下载地址为:点击下载demo
判断手机是否退到后台,本人查阅各种资料,发现实现其实很简单,目前自己主要实现方式有两种:
方式一:
/**
* 程序是否在前台运行
*
*/
public boolean isAppOnForeground() {
ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
String packageName = getApplicationContext().getPackageName();
/**
* 获取Android设备中所有正在运行的App
*/
List appProcesses = activityManager
.getRunningAppProcesses();
if (appProcesses == null)
return false;
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
// The name of the process that this object is associated with.
if (appProcess.processName.equals(packageName)
&& appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return true;
}
}
return false;
}
这是我在网上找到的例子,主要的实现原理就是,使用ActivityManager,首先拿到自己App的包名,再拿到Android设备中所有正在运行的App包名,然后对所有的App进行遍历,通过判断正在运行的App中包名有没有和自己的App相等,从而判断自己的App是否退到后台.
@Override
protected void onPause() {
super.onPause();
if(!isAppOnForeground()){
Toast.makeText(getApplicationContext(), TAG+"onPause:",
Toast.LENGTH_SHORT).show();
}else {
sendBroadcast(new Intent(NotificationIntentReceiver.ACTION_ENABLE_MESSAGES)
.setClass(this, NotificationIntentReceiver.class));
Toast.makeText(getApplicationContext(), TAG+"后台运行1",
Toast.LENGTH_SHORT).show();
}
}
然后在onPause()方法中,进行判断,上面代码中实现的是,App退出后台就发送广播,然后在广播中执行Notification,然后在回到Activity时,在onResume()中清除应该清除Notification.
方法二:
这种方法主要是根据Application中实现ActivityLifecycleCallbacks回调,ActivityLifecycleCallbacks是4.0以后新增的,主要用于监听Activity的状态,这里主要关注onActivityStarted(Activity activity)和onActivityStopped(Activity activity)两个方法,简单的解释:Activity在start时会走onActivityStarted方法,而Activity在退出后台时,则会走onActivityStopped方法,所以我们可以通过这种方法实现:
int countActivity = 0;
@Override
public void onActivityStarted(Activity activity) {
countActivity++;
}
@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);
}
}
. }
上面的代码主要原理是:我在自定义的Application中定义一个变量,主要是模拟Stack
ActivityLifecycleCallbacks的实现重写的方法如下:
public class DemoApplication extends Application implements Application.ActivityLifecycleCallbacks{
@Override
public void onCreate() {
super.onCreate();
//全局管理Activity生命周期
registerActivityLifecycleCallbacks(this);
}
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
那么问题来了 应用退出和应用进入 这两个事件 如何过滤掉呢
/**
* 判断应用是否在运行
* @param context
* @return
*/
public boolean isRun(Context context){
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List list = am.getRunningTasks(100);
boolean isAppRunning = false;
String MY_PKG_NAME = "com.ad";
//100表示取的最大的任务数,info.topActivity表示当前正在运行的Activity,info.baseActivity表系统后台有此进程在运行
for (RunningTaskInfo info : list) {
if (info.topActivity.getPackageName().equals(MY_PKG_NAME) || info.baseActivity.getPackageName().equals(MY_PKG_NAME)) {
isAppRunning = true;
Log.i("ActivityService isRun()",info.topActivity.getPackageName() + " info.baseActivity.getPackageName()="+info.baseActivity.getPackageName());
break;
}
}
Log.i("ActivityService isRun()", "com.ad 程序 ...isAppRunning......"+isAppRunning);
return isAppRunning;
}
再用上这个工具类就可以了 完整代码我贴一下
private int countActivity = 0;
//是否进入后台
private boolean isBackground=false;
//全局管理 生命周期
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
countActivity++;
if(countActivity==1&& isBackground){
Log.e(TAG, "onActivityStarted: 应用进入前台" );
isBackground=false;
//说明应用重新进入了前台
}
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
countActivity--;
LogUtils.e(TAG, "onActivityStarted: "+isRun(activity));
if (countActivity <= 0&&!isBackground&&isRun(activity)) {
Log.e(TAG, "onActivityStarted: 应用进入后" );
isBackground =true;
//说明应用进入了后台
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}