Android实现后台返回前台再次显示广告

Android实现后台返回前台再次显示广告

市面上主流的APP都是在启动页做广告展示的,即通常都是叫SplashActivity的是APP的launcher页面,在manifest文件中配置, 2017年以来, 你会发现越来越多的APP在进入后台时隔一定时间后再次回到前台会再次显示广告界面, 3s自动播放, 或者手动点击跳过

1461514126877_.pic.jpg

比如网易云音乐, 淘宝, 京东商城啦, 似乎现在都是很主流的做法了,刚好最近项目中也有这样的需求, 我们也实现了一遍,所以写出来分享下,相互学习借鉴

要实现后台返回前台显示广告的逻辑, 主要的点在于监听APP进入后台的时间点, 和APP从后台返回到前台的时间点

我们是在Application子类中完成的, 定义三个常量记录当前APP状态

 // 正常状态
public static final int STATE_NORMAL = 0;
// 从后台回到前台
public static final int STATE_BACK_TO_FRONT = 1;
// 从前台进入后台
public static final int STATE_FRONT_TO_BACK = 2;

在Application中需要监听Activity的生命周期变化, registerActivityLifecycleCallbacks是application类已经提供好的一个方法, 它可以非常方便的监听整个项目中的所有activity的生命周期

// Application类中的内部类接口
public interface ActivityLifecycleCallbacks {
    void onActivityCreated(Activity activity, Bundle savedInstanceState);
    void onActivityStarted(Activity activity);
    void onActivityResumed(Activity activity);
    void onActivityPaused(Activity activity);
    void onActivityStopped(Activity activity);
    void onActivitySaveInstanceState(Activity activity, Bundle outState);
    void onActivityDestroyed(Activity activity);
}

可以很清晰的看到Activity的生命周期函数都会回调到ActivityLifecycleCallbacks接口来, 我们让Application实现此接口, 并在相应的回调方法中的完成具体的后台状态的监听

定义几个需要用的变量记录相关状态和时间

// APP状态
private static int sAppState = STATE_NORMAL;
// 标记程序是否已进入后台(依据onStop回调)
private boolean flag;
// 标记程序是否已进入后台(依据onTrimMemory回调)
private boolean background;
// 从前台进入后台的时间
private static long frontToBackTime;
// 从后台返回前台的时间
private static long backToFrontTime;

在onResume回调中监听回到前台的判断, 只要activity一旦获取焦点这个方法都会触发,并且会触发多次

@Override
public void onActivityResumed(@NonNull Activity activity) {
        if (background || flag) {
            background = false;
            flag = false;
            sAppState = STATE_BACK_TO_FRONT;
            backToFrontTime = System.currentTimeMillis();
            Log.e(TAG, "onResume: STATE_BACK_TO_FRONT");
            if (canShowAd()) {
                ShowADActivity.show(activity);
            }
        } else {
            sAppState = STATE_NORMAL;
        }
}

在onStop回调中监听程序进入后台的判断

@Override
public void onActivityStopped(@NonNull Activity activity) {
        //判断当前activity是否处于前台
        if (!SystemUtils.isCurAppTop(activity)) {
            // 从前台进入后台
            sAppState = STATE_FRONT_TO_BACK;
            frontToBackTime = System.currentTimeMillis();
            flag = true;
            Log.e(TAG, "onStop: " + "STATE_FRONT_TO_BACK");
        } else {
            // 否则是正常状态
            sAppState = STATE_NORMAL;
        }
 }

在onTrimMemory中监听应用程序的切换,这也是一种监听方式.因为有时候onStop的回调不一定会完全执行(尤其是切换最近使用APP列表时),所以这个方法也是必须的

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    // TRIM_MEMORY_UI_HIDDEN是UI不可见的回调, 通常程序进入后台后都会触发此回调,大部分手机多是回调这个参数
    // TRIM_MEMORY_BACKGROUND也是程序进入后台的回调, 不同厂商不太一样, 魅族手机就是回调这个参数
    if (level == Application.TRIM_MEMORY_UI_HIDDEN || level == TRIM_MEMORY_BACKGROUND) {
        background = true;
    } else if (level == Application.TRIM_MEMORY_COMPLETE) {
        background = !SystemUtils.isCurAppTop(this);
    }
    if (background) {
        frontToBackTime = System.currentTimeMillis();
        sAppState = STATE_FRONT_TO_BACK;
        logcat.e(TAG, "onTrimMemory: TRIM_MEMORY_UI_HIDDEN || TRIM_MEMORY_BACKGROUND");
    } else {
        sAppState = STATE_NORMAL;
    }

}

最后, 就可以得到当前APP的准确状态(sAppState)了, 是否可以再次显示广告

/**
 * 进入后台间隔10分钟以后可以再次显示广告
 *
 * @return 是否能显示广告
 */
public static boolean canShowAd() {
    return sAppState == STATE_BACK_TO_FRONT &&
            (backToFrontTime - frontToBackTime) > 10 * 60 * 1000;
}

测试过程中,发现大部分品牌的手机都是OK的, 但是也有意外的,OPPO R9在切换应用时,一个回调都没触发,一定是Color OS改动太大, 目前尚无法处理.OV手机适配起来就是费劲啊

最后补充一个判断程序是否前台的API

/**
 * 判断当前程序是否前台进程
 *
 * @param context
 * @return
 */
public static boolean isCurAppTop(Context context) {
    if (context == null) {
        return false;
    }
    String curPackageName = context.getPackageName();
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningTaskInfo> list = am.getRunningTasks(1);
    if (list != null && list.size() > 0) {
        RunningTaskInfo info = list.get(0);
        String topPackageName = info.topActivity.getPackageName();
        String basePackageName = info.baseActivity.getPackageName();
        if (topPackageName.equals(curPackageName) && basePackageName.equals(curPackageName)) {
            return true;
        }
    }
    return false;
}

各位大佬们如果有更好的实现,欢迎提供思路!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容