package com.novelbook.android.AD; import android.Manifest; import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.provider.Settings; import android.support.annotation.MainThread; import android.support.annotation.Nullable; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import com.bytedance.sdk.openadsdk.AdSlot; import com.bytedance.sdk.openadsdk.TTAdNative; import com.bytedance.sdk.openadsdk.TTSplashAd; import com.google.android.gms.ads.AdListener; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.InterstitialAd; import com.google.android.gms.ads.MobileAds; import com.novelbook.android.AD.toutiao.TTAdManagerHolder; import com.novelbook.android.AD.toutiao.WeakHandler; import com.novelbook.android.Main2Activity; import com.novelbook.android.R; import com.novelbook.android.utils.CommonUtil; import com.novelbook.android.utils.Constants; import com.qq.e.ads.splash.SplashAD; import com.qq.e.ads.splash.SplashADListener; import com.qq.e.comm.util.AdError; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import butterknife.BindView; import butterknife.ButterKnife; import static com.novelbook.android.bean.AdSetting.getAppID; /** * 开屏广告Activity示例 */ public class SplashActivity extends Activity implements WeakHandler.IHandler, SplashADListener { private static final String TAG = SplashActivity.class.getSimpleName(); @Nullable @BindView(R.id.splash_container) ViewGroup mSplashContainer; @Nullable @BindView(R.id.textTile) TextView tvTitle; //--------tencent---> private SplashAD splashAD; @Nullable @BindView(R.id.skip_view) TextView skipView; //private ImageView splashHolder; @Nullable @BindView(R.id.splash_holder) TextView splashHolder; private static final String SKIP_TEXT = "点击跳过 %d"; public boolean canJump = false; /** * 为防止无广告时造成视觉上类似于"闪退"的情况,设定无广告时页面跳转根据需要延迟一定时间,demo * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久,仅供参考,开发者可自定义延时逻辑,如果开发者采用demo * 中给出的延时逻辑,也建议开发者考虑自定义minSplashTimeWhenNoAD的值(单位ms) **/ private int minSplashTimeWhenNoAD = 2000; /** * 记录拉取广告的时间 */ private long fetchSplashADTime = 0; private Handler handler = new Handler(Looper.getMainLooper()); //<-----tencent----- //------toutiao---> private TTAdNative mTTAdNative; //是否强制跳转到主页面 private boolean mForceGoMain; public static final String EXTR_LUNCHER="luncher"; //开屏广告加载发生超时但是SDK没有及时回调结果的时候,做的一层保护。 private final WeakHandler mHandler = new WeakHandler(this); //开屏广告加载超时时间,建议大于1000,这里为了冷启动第一次加载到广告并且展示,示例设置了2000ms private static final int AD_TIME_OUT = 2000; private static final int MSG_GO_MAIN = 1; //开屏广告是否已经加载 private boolean mHasLoaded; //-toutiao---<--- //---admob---> private InterstitialAd mInterstitialAd; @SuppressWarnings("RedundantCast") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); boolean isGoToMain= getIntent().getBooleanExtra(EXTR_LUNCHER,true); if(!Constants.AD_SETTING.isShowAdsense() ||isGoToMain && !Constants.AD_SETTING.getSplash().isShow() ){ goToMainActivity(); return; } int rid =R.layout.ad_toutiao_activity_splash; int splashSource=Constants.AD_TENCENT_QQ; if(isGoToMain) { if (Constants.AD_SETTING.getSplash().getSource() == Constants.AD_TENCENT_QQ) { rid = R.layout.ad_qq_activity_splash; } else if (Constants.AD_SETTING.getSplash().getSource() == Constants.AD_TOUTIAO) { rid = R.layout.ad_toutiao_activity_splash; splashSource=Constants.AD_TOUTIAO; } else{ goToMainActivity();return; } }else{ if (Constants.AD_SETTING.getSplash2().getSource() == Constants.AD_TENCENT_QQ) { rid = R.layout.ad_qq_activity_splash; } else if (Constants.AD_SETTING.getSplash2().getSource() == Constants.AD_TOUTIAO) { // rid = R.layout.ad_toutiao_activity_splash; // goToMainActivity(); finish();//头条不可作为返回全屏广告 return; }else if (Constants.AD_SETTING.getSplash2() .getSource() == Constants.AD_MOB) { // goToMainActivity(); // return; rid = R.layout.activity_blank; splashSource=Constants.AD_MOB; } } setContentView(rid); ButterKnife.bind(this); //在合适的时机申请权限,如read_phone_state,防止获取不了imei时候,下载类广告没有填充的问题 //在开屏时候申请不太合适,因为该页面倒计时结束或者请求超时会跳转,在该页面申请权限,体验不好 // TTAdManagerHolder.getInstance(this).requestPermissionIfNecessary(this); //定时,AD_TIME_OUT时间到时执行,如果开屏广告没有加载则跳转到主页面 getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY // | View.SYSTEM_UI_FLAG_IMMERSIVE ); if(tvTitle!=null) tvTitle.setText(R.string.app_name); //加载开屏广告 if(splashSource == Constants.AD_TOUTIAO ) { mHandler.sendEmptyMessageDelayed(MSG_GO_MAIN, AD_TIME_OUT); //step2:创建TTAdNative对象 try { mTTAdNative = TTAdManagerHolder.get().createAdNative(this); } catch (Exception e) { goToMainActivity(); return; } loadSplashAd(); }else if(splashSource == Constants.AD_TENCENT_QQ ){ if (Build.VERSION.SDK_INT >= 23) { checkAndRequestPermission(); } else { // 如果是Android6.0以下的机器,默认在安装时获得了所有权限,可以直接调用SDK fetchSplashAD(this, mSplashContainer, skipView, getAppID(Constants.AD_TENCENT_QQ), getPosId(), this, 0); } }else if(splashSource == Constants.AD_MOB ){ getAdMob(); /* if (Build.VERSION.SDK_INT >= 23) { checkAndRequestPermissionAdmob(); } else { // 如果是Android6.0以下的机器,默认在安装时获得了所有权限,可以直接调用SDK getAdMob(); }*/ } } /** * 跳转到主页面 */ private void goToMainActivity() { boolean isGoToMain= getIntent().getBooleanExtra(EXTR_LUNCHER,true); if(isGoToMain) { Intent intent = new Intent(SplashActivity.this, Main2Activity.class); startActivity(intent); } if(mSplashContainer!=null) { mSplashContainer.removeAllViews(); } SplashAdManager.clearPages(); this.finish(); } @Override protected void onResume() { //判断是否该跳转到主页面 if (mForceGoMain) { mHandler.removeCallbacksAndMessages(null); goToMainActivity(); } super.onResume(); if (canJump) { next(); } canJump = true; } @Override protected void onStop() { super.onStop(); mForceGoMain = true; } @Override protected void onPause() { super.onPause(); canJump = false; } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); } /** * 加载开屏广告 */ private void loadSplashAd() { //step3:创建开屏广告请求参数AdSlot,具体参数含义参考文档 AdSlot adSlot = new AdSlot.Builder() .setCodeId(Constants.AD_SETTING.getSplash().getSlotId(Constants.AD_TOUTIAO) ) .setSupportDeepLink(true) .setImageAcceptedSize(Constants.SCREEN_WIDTH_PIX, Constants.SCREEN_HEIGHT_PIX) .build(); //step4:请求广告,调用开屏广告异步请求接口,对请求回调的广告作渲染处理 mTTAdNative.loadSplashAd(adSlot, new TTAdNative.SplashAdListener() { @Override @MainThread public void onError(int code, String message) { Log.d(TAG, message); mHasLoaded = true; showToast(message); goToMainActivity(); } @Override @MainThread public void onTimeout() { mHasLoaded = true; showToast("开屏广告加载超时"); goToMainActivity(); } @Override @MainThread public void onSplashAdLoad(TTSplashAd ad) { Log.d(TAG, "开屏广告请求成功"); SplashAdManager.setSplashTime(); mHasLoaded = true; mHandler.removeCallbacksAndMessages(null); if (ad == null) { return; } //获取SplashView View view = ad.getSplashView(); mSplashContainer.removeAllViews(); //把SplashView 添加到ViewGroup中,注意开屏广告view:width >=70%屏幕宽;height >=50%屏幕宽 mSplashContainer.addView(view); //设置不开启开屏广告倒计时功能以及不显示跳过按钮,如果这么设置,您需要自定义倒计时逻辑 //ad.setNotAllowSdkCountdown(); //设置SplashView的交互监听器 ad.setSplashInteractionListener(new TTSplashAd.AdInteractionListener() { @Override public void onAdClicked(View view, int type) { Log.d(TAG, "onAdClicked"); showToast("开屏广告点击"); } @Override public void onAdShow(View view, int type) { Log.d(TAG, "onAdShow"); showToast("开屏广告展示"); } @Override public void onAdSkip() { Log.d(TAG, "onAdSkip"); showToast("开屏广告跳过"); goToMainActivity(); } @Override public void onAdTimeOver() { Log.d(TAG, "onAdTimeOver"); showToast("开屏广告倒计时结束"); goToMainActivity(); } }); } }, AD_TIME_OUT); } private void showToast(String msg) { //TToast.show(this, msg); Log.d(TAG, "loadBannerAd: " + msg); } @Override public void handleMsg(Message msg) { if (msg.what == MSG_GO_MAIN) { if (!mHasLoaded) { showToast("广告已超时,跳到主页面"); goToMainActivity(); } } } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK|| keyCode == KeyEvent.KEYCODE_HOME) { return true; } return super.onKeyUp(keyCode,event); } //-----qq ad begin------> /** * * ----------非常重要---------- * * Android6.0以上的权限适配简单示例: * * 如果targetSDKVersion >= 23,那么必须要申请到所需要的权限,再调用广点通SDK,否则广点通SDK不会工作。 * * Demo代码里是一个基本的权限申请示例,请开发者根据自己的场景合理地编写这部分代码来实现权限申请。 * 注意:下面的`checkSelfPermission`和`requestPermissions`方法都是在Android6.0的SDK中增加的API,如果您的App还没有适配到Android6.0以上,则不需要调用这些方法,直接调用广点通SDK即可。 */ @TargetApi(Build.VERSION_CODES.M) private void checkAndRequestPermission() { List lackedPermission = new ArrayList(); if (!(checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.READ_PHONE_STATE); } if (!(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } if (!(checkSelfPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) == PackageManager.PERMISSION_GRANTED)) { CommonUtil.checkPermission(this,Manifest.permission.REQUEST_INSTALL_PACKAGES,10,"更新程序内容需此权限,请允许"); //lackedPermission.add(Manifest.permission.REQUEST_INSTALL_PACKAGES); } /*if (!(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.ACCESS_FINE_LOCATION); }*/ for(String s: lackedPermission){ Log.e(TAG, "checkAndRequestPermission: lack permission "+s ); } // 权限都已经有了,那么直接调用SDK if (lackedPermission.size() == 0) { fetchSplashAD(this, mSplashContainer, skipView, getAppID(Constants.AD_TENCENT_QQ), getPosId(), this, 0); } else { // 请求所缺少的权限,在onRequestPermissionsResult中再看是否获得权限,如果获得权限就可以调用SDK,否则不要调用SDK。 String[] requestPermissions = new String[lackedPermission.size()]; lackedPermission.toArray(requestPermissions); requestPermissions(requestPermissions, 1024); } } private boolean hasAllPermissionsGranted(int[] grantResults) { for (int grantResult : grantResults) { if (grantResult == PackageManager.PERMISSION_DENIED) { return false; } } return true; } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 1024 && hasAllPermissionsGranted(grantResults)) { fetchSplashAD(this, mSplashContainer, skipView, getAppID(Constants.AD_TENCENT_QQ), getPosId(), this, 0); } else { // 如果用户没有授权,那么应该说明意图,引导用户去设置里面授权。 Toast.makeText(this, "应用缺少必要的权限!请点击\"权限\",打开所需要的权限。", Toast.LENGTH_LONG).show(); Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivity(intent); finish(); goToMainActivity(); } } /** * 拉取开屏广告,开屏广告的构造方法有3种,详细说明请参考开发者文档。 * * @param activity 展示广告的activity * @param adContainer 展示广告的大容器 * @param skipContainer 自定义的跳过按钮:传入该view给SDK后,SDK会自动给它绑定点击跳过事件。SkipView的样式可以由开发者自由定制,其尺寸限制请参考activity_splash.xml或者接入文档中的说明。 * @param appId 应用ID * @param posId 广告位ID * @param adListener 广告状态监听器 * @param fetchDelay 拉取广告的超时时长:取值范围[3000, 5000],设为0表示使用广点通SDK默认的超时时长。 */ private void fetchSplashAD(Activity activity, ViewGroup adContainer, View skipContainer, String appId, String posId, SplashADListener adListener, int fetchDelay) { fetchSplashADTime = System.currentTimeMillis(); Map tags = new HashMap<>(); tags.put("tag_s1", "value_s1"); tags.put("tag_s2", "value_s2"); splashAD = new SplashAD(activity, adContainer, skipContainer, appId, posId, adListener, fetchDelay, tags); // 如果不需要传tag,使用如下构造函数 // splashAD = new SplashAD(activity, adContainer, skipContainer, appId, posId, adListener, fetchDelay); } @Override public void onADPresent() { Log.i("AD_DEMO", "SplashADPresent"); SplashAdManager.setSplashTime(); splashHolder.setVisibility(View.INVISIBLE); // 广告展示后一定要把预设的开屏图片隐藏起来 } @Override public void onADClicked() { Log.i("AD_DEMO", "SplashADClicked clickUrl: " + (splashAD.getExt() != null ? splashAD.getExt().get("clickUrl") : "")); } /** * 倒计时回调,返回广告还将被展示的剩余时间。 * 通过这个接口,开发者可以自行决定是否显示倒计时提示,或者还剩几秒的时候显示倒计时 * * @param millisUntilFinished 剩余毫秒数 */ @Override public void onADTick(long millisUntilFinished) { Log.i("AD_DEMO", "SplashADTick " + millisUntilFinished + "ms"); skipView.setText(String.format(SKIP_TEXT, Math.round(millisUntilFinished / 1000f))); } @Override public void onADExposure() { Log.i("AD_DEMO", "SplashADExposure"); } @Override public void onADDismissed() { Log.i("AD_DEMO", "SplashADDismissed"); next(); } @Override public void onNoAD(AdError error) { Log.i( "AD_DEMO", String.format("LoadSplashADFail, eCode=%d, errorMsg=%s", error.getErrorCode(), error.getErrorMsg())); /** * 为防止无广告时造成视觉上类似于"闪退"的情况,设定无广告时页面跳转根据需要延迟一定时间,demo * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久,仅供参考,开发者可自定义延时逻辑,如果开发者采用demo * 中给出的延时逻辑,也建议开发者考虑自定义minSplashTimeWhenNoAD的值 **/ long alreadyDelayMills = System.currentTimeMillis() - fetchSplashADTime;//从拉广告开始到onNoAD已经消耗了多少时间 long shouldDelayMills = alreadyDelayMills > minSplashTimeWhenNoAD ? 0 : minSplashTimeWhenNoAD - alreadyDelayMills;//为防止加载广告失败后立刻跳离开屏可能造成的视觉上类似于"闪退"的情况,根据设置的minSplashTimeWhenNoAD // 计算出还需要延时多久 handler.postDelayed(new Runnable() { @Override public void run() { SplashActivity.this.finish(); goToMainActivity(); } }, shouldDelayMills); } /** * 设置一个变量来控制当前开屏页面是否可以跳转,当开屏广告为普链类广告时,点击会打开一个广告落地页,此时开发者还不能打开自己的App主页。当从广告落地页返回以后, * 才可以跳转到开发者自己的App主页;当开屏广告是App类广告时只会下载App。 */ private void next() { if (canJump) { goToMainActivity(); this.finish(); } else { canJump = true; } } private String getPosId() { return Constants.AD_SETTING.getSplash().getSlotId(Constants.AD_TENCENT_QQ); } //----qq ad end <--- void getAdMob(){ MobileAds.initialize(this,"ca-app-pub-3940256099942544~3347511713"); mInterstitialAd = new InterstitialAd(this); mInterstitialAd.setAdListener(new AdListener() { @Override public void onAdLoaded() { // Code to be executed when an ad finishes loading. Log.d(TAG, "onAdLoaded: "); SplashAdManager.setSplashTime(); mInterstitialAd.show(); } @Override public void onAdFailedToLoad(int errorCode) { // Code to be executed when an ad request fails. Log.d(TAG, "onAdFailedToLoad: "); goToMainActivity(); } @Override public void onAdOpened() { // Code to be executed when the ad is displayed. Log.d(TAG, "onAdOpened: "); } @Override public void onAdClicked() { // Code to be executed when the user clicks on an ad. Log.d(TAG, "onAdClicked: "); } @Override public void onAdLeftApplication() { // Code to be executed when the user has left the app. Log.d(TAG, "onAdLeftApplication: "); } @Override public void onAdClosed() { // Code to be executed when the interstitial ad is closed. Log.d(TAG, "onAdClosed: "); goToMainActivity(); } }); mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712"); mInterstitialAd.loadAd(new AdRequest.Builder().build()); } @TargetApi(Build.VERSION_CODES.M) private void checkAndRequestPermissionAdmob() { List lackedPermission = new ArrayList(); if (!(checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.READ_PHONE_STATE); } if (!(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } if (!(checkSelfPermission(Manifest.permission.REQUEST_INSTALL_PACKAGES) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.REQUEST_INSTALL_PACKAGES); } /*if (!(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) { lackedPermission.add(Manifest.permission.ACCESS_FINE_LOCATION); }*/ // 权限都已经有了,那么直接调用SDK if (lackedPermission.size() == 0) { getAdMob(); } else { // 请求所缺少的权限,在onRequestPermissionsResult中再看是否获得权限,如果获得权限就可以调用SDK,否则不要调用SDK。 String[] requestPermissions = new String[lackedPermission.size()]; lackedPermission.toArray(requestPermissions); requestPermissions(requestPermissions, 1024); } } }