OTTBox开机广告

前言:前段时间做在OTT盒子项目,被安排实现以下开机广告功能,就像市面上多数智能电视一样。

开始做时遇到2个问题,第一开机时是没有网络的,怎么实时播放广告呢。第二开机过程中怎么启动播放器进行广告播放呢。

针对这2个问题,我下面详细描述下我做的处理。

1、广告视频的下载以及与服务器的交互。

由于OTT在开机过程中是没有网络的所以我们必须有一个核心service在第一次开机后通过接收BOOT_COMPLETED以及CONNECTIVITY_CHANGE广播进行自启动来和服务器进行交互,从而将所需要的广告视频资源下载到本地,然后将每次的播放行为上报给服务器方便记录。

public class AdvertiseService extends Service implements Handler.Callback {
    private static final int MSG_GETLIST = 1;
    private static final int MSG_UPLOADLOG = 2;
    private static final int MSG_ADMASTER = 3;
    public static long GETLIST_INTERVAL = 30 * 60 * 1000;
    public static long ADMASTER_INTERVAL = 1 * 60 * 1000;
    private Handler mHandler = new Handler(this);
    public AdvertiseService() {
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Constants.setDir(getApplicationContext());
        mHandler.sendEmptyMessageDelayed(MSG_UPLOADLOG, 2 * 60 * 1000);
        mHandler.sendEmptyMessageDelayed(MSG_GETLIST, 3 * 60 * 1000);
        if (Utils.isNetworkConnected(this) && mNeedUploadLog) {
            AdmasterSdk.init(this, Utils.getAdMasterUrl(this));
            AdmasterSdk.setLogState(true);
            AdmasterSdk.onExpose(Utils.getAdMasterUrl(this));
        } else {
            mHandler.sendEmptyMessageDelayed(MSG_ADMASTER, 500);
        }
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Utils.log(LOGD, "onStartCommand --> enter, intent: " + intent + ", flags: " + flags + ", startId: " + startId + "!");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    @Override
    public boolean handleMessage(Message msg) {
        Utils.log(LOGW, "handleMessage,  msg = " + msg.what);
        switch (msg.what) {
            case MSG_GETLIST:
                Utils.getListService(this);
                mHandler.sendEmptyMessageDelayed(MSG_GETLIST, GETLIST_INTERVAL);
                break;
            case MSG_UPLOADLOG:
                Utils.getIpService(this);
                Utils.getLocationService(this);
                break;
            case MSG_ADMASTER:
                if (Utils.isNetworkConnected(this) && mNeedUploadLog) {
                    AdmasterSdk.init(this, Utils.getAdMasterUrl(this));
                    AdmasterSdk.setLogState(true);
                    AdmasterSdk.onExpose(Utils.getAdMasterUrl(this));
                } else {
                    mHandler.sendEmptyMessageDelayed(MSG_ADMASTER, ADMASTER_INTERVAL);
                }
                break;
        }
        return false;
    }

}

service还是比较简单的主要是做一些和服务器的交互,获取广告位id,获取相关公网ip等主要信息,从而将盒子的广告信息注册到服务器将最新的广告视频带下来。通过服务器返回的result中带的下载链接,将广告下载下来。

2、广告顺利下载下来了那怎么让系统在launcher起来时自动播放呢?

通过查阅android系统源码,发现启动应用是在ActivityManagerService.java中。通过修改getHomeIntent()方法将启动的应用改成自己的MeidaPlayerActiviy就能在开机完成后不是启动laucnher而是我们的广告播放器。具体代码如下

Intent getHomeIntent() {
        if (SystemProperties.get("persist.sys.ad.exist").equals("1")) {
            Intent skyIntent = SkyBootIntentOem.getInstance().getHomeIntent();
            if (skyIntent != null) {
                return skyIntent;
            }
        }
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;

 }

在SkyBootIntentOem类中定义要启动的intent。

public Intent getHomeIntent(){
        if (!isFirst) {
            return null;
        }
        Intent intent = new Intent("com.phicomm.phitvadvertisement.AdvertiseMainActivity");
        isFirst = false;
        return intent;

}

这样理论上就能在开机时顺利优先启动我们所自定义的MeidaPlayerActiviy来播放广告了。但是尝试了多次后发现虽然代码调用了相关的intent但是应用却没有起来。在查阅了诸多资料后发现原来是MeidaPlayerActiviy这个appliction有一个关键属性没有加。。。android:directBootAware="true"就是这个属性。

由于activitymanagerservice启动应用时系统还没有完全起来,所以要优先启动应用就必须加上这个属性。

有了这个属性后开机广告应用顺利完成,剩下的就是bug的修复了。

之后我会将完整代码提交到github上,有兴趣的小伙伴可以看下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值