diff --git a/zhuike/build.gradle b/zhuike/build.gradle index 59429c9..e69610a 100644 --- a/zhuike/build.gradle +++ b/zhuike/build.gradle @@ -39,6 +39,7 @@ android { buildConfigField "boolean", "LOG_DEBUG", "true" buildConfigField "String", "MAIN_HOST", '"http://xiaoshuofenxiang.com/api/"' buildConfigField "String", "API_HOST", '"{\\"master\\":[\\"http:\\\\/\\\\/g.xiaoshuofenxiang.com\\"],\\"page\\":[\\"http:\\\\/\\\\/p.xiaoshuofenxiang.com\\"],\\"report\\":[\\"http:\\\\/\\\\/r.xiaoshuofenxiang.com\\"],\\"search\\":[\\"http:\\\\/\\\\/s.xiaoshuofenxiang.com\\"],\\"novel\\":[\\"http:\\\\/\\\\/n.xiaoshuofenxiang.com\\"],\\"novelsbydot\\":[\\"http:\\\\/\\\\/nbd.xiaoshuofenxiang.com\\"],\\"user\\":[\\"http:\\\\/\\\\/u.xiaoshuofenxiang.com\\"]}"' + buildConfigField "String","AD_TOUTIAO_APP_ID",'"5019267"' buildConfigField "String","AD_SLOT_TOUTIAO_SPLASH_ID",'"819267134"' buildConfigField "String","AD_SLOT_TOUTIAO_BANNER_ID",'"919267016"' buildConfigField "String","AD_SLOT_TOUTIAO_BANNER_NATIVE_ID",'"919267816"' diff --git a/zhuike/src/main/java/com/novelbook/android/AD/SplashAdManager.java b/zhuike/src/main/java/com/novelbook/android/AD/SplashAdManager.java index 75c4b05..6980510 100644 --- a/zhuike/src/main/java/com/novelbook/android/AD/SplashAdManager.java +++ b/zhuike/src/main/java/com/novelbook/android/AD/SplashAdManager.java @@ -9,14 +9,19 @@ import android.os.Build; import android.os.Bundle; import android.util.Log; +import com.novelbook.android.AD.toutiao.SplashActivity; import com.novelbook.android.Main2Activity; +import com.novelbook.android.utils.Constants; import java.util.Date; public class SplashAdManager implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 { private boolean mIsBackground; private static long lastAd =0; - private static long interVal = 5*60*1000; //间隔5分钟 + private static long interVal = Constants.AD_SPLASH_INVTERVAL; + private static int pages =0; + + /****** * 使用方式:在Application中直接构造即可 * @param application @@ -43,7 +48,7 @@ public class SplashAdManager implements Application.ActivityLifecycleCallbacks, public void onActivityCreated(Activity activity, Bundle savedInstanceState) { if(activity instanceof Main2Activity){ - showAd(activity); + // showAd(activity); Log.d("zzr", " 启动应用"); } } @@ -104,13 +109,28 @@ public class SplashAdManager implements Application.ActivityLifecycleCallbacks, } - void showAd(Activity activity){ + static void showAd(Activity activity){ if(canShowAd()) { lastAd = new Date().getTime(); - activity.startActivity(new Intent(activity, AdvertisementViewActivity.class)); + Intent intent = new Intent(activity, SplashActivity.class); + intent.putExtra(SplashActivity.EXTR_LUNCHER, false); + activity.startActivity(intent); } } - boolean canShowAd(){ - return new Date().getTime() -lastAd >interVal; + static boolean canShowAd(){ + long in = new Date().getTime() -lastAd; + Log.d("zzr", "canShowAd: interval is, " +in + ", canshow? "+ (in >interVal)); + return in >interVal; + } + public static void setSplashTime(){ lastAd = new Date().getTime(); } + public static void clearPages(){ + pages =0; + } + public static void plusPage(Activity activity){ + pages++; + if(pages >Constants.AD_SPLASH_PAGES){ + showAd(activity); + + } } } diff --git a/zhuike/src/main/java/com/novelbook/android/AD/toutiao/SplashActivity.java b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/SplashActivity.java new file mode 100644 index 0000000..24c8369 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/SplashActivity.java @@ -0,0 +1,203 @@ +package com.novelbook.android.AD.toutiao; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Message; +import android.support.annotation.MainThread; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.FrameLayout; + +import com.bytedance.sdk.openadsdk.AdSlot; +import com.bytedance.sdk.openadsdk.TTAdNative; +import com.bytedance.sdk.openadsdk.TTSplashAd; +import com.novelbook.android.AD.SplashAdManager; +import com.novelbook.android.BuildConfig; +import com.novelbook.android.Main2Activity; +import com.novelbook.android.R; +import com.novelbook.android.utils.Constants; + + +/** + * 开屏广告Activity示例 + */ +public class SplashActivity extends Activity implements WeakHandler.IHandler { + private static final String TAG = SplashActivity.class.getSimpleName(); + private TTAdNative mTTAdNative; + private FrameLayout mSplashContainer; + //是否强制跳转到主页面 + 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; + + @SuppressWarnings("RedundantCast") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.ad_toutiao_activity_splash); + mSplashContainer = (FrameLayout) findViewById(R.id.splash_container); + //step2:创建TTAdNative对象 + mTTAdNative = TTAdManagerHolder.get().createAdNative(this); + //在合适的时机申请权限,如read_phone_state,防止获取不了imei时候,下载类广告没有填充的问题 + //在开屏时候申请不太合适,因为该页面倒计时结束或者请求超时会跳转,在该页面申请权限,体验不好 + // TTAdManagerHolder.getInstance(this).requestPermissionIfNecessary(this); + //定时,AD_TIME_OUT时间到时执行,如果开屏广告没有加载则跳转到主页面 + mHandler.sendEmptyMessageDelayed(MSG_GO_MAIN, 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 + ); + + //加载开屏广告 + loadSplashAd(); + } + + @Override + protected void onResume() { + //判断是否该跳转到主页面 + if (mForceGoMain) { + mHandler.removeCallbacksAndMessages(null); + goToMainActivity(); + } + super.onResume(); + } + + @Override + protected void onStop() { + super.onStop(); + mForceGoMain = true; + } + + /** + * 加载开屏广告 + */ + private void loadSplashAd() { + //step3:创建开屏广告请求参数AdSlot,具体参数含义参考文档 + AdSlot adSlot = new AdSlot.Builder() + .setCodeId(BuildConfig.AD_SLOT_TOUTIAO_SPLASH_ID) + .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 goToMainActivity() { + if( !getIntent().hasExtra(EXTR_LUNCHER)){ + Intent intent = new Intent(SplashActivity.this, Main2Activity.class); + startActivity(intent); + } + mSplashContainer.removeAllViews(); + SplashAdManager.clearPages(); + this.finish(); + } + + 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) { + + return true; + + } + return super.onKeyUp(keyCode,event); + } +} diff --git a/zhuike/src/main/java/com/novelbook/android/AD/toutiao/TTAdManagerHolder.java b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/TTAdManagerHolder.java new file mode 100644 index 0000000..63f3219 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/TTAdManagerHolder.java @@ -0,0 +1,60 @@ +package com.novelbook.android.AD.toutiao; + +import android.content.Context; +import android.util.Log; + +import com.bytedance.sdk.openadsdk.TTAdConfig; +import com.bytedance.sdk.openadsdk.TTAdConstant; +import com.bytedance.sdk.openadsdk.TTAdManager; +import com.bytedance.sdk.openadsdk.TTAdSdk; +import com.novelbook.android.BuildConfig; +import com.novelbook.android.utils.Constants; + +/** + * 可以用一个单例来保存TTAdManager实例,在需要初始化sdk的时候调用 + */ +public class TTAdManagerHolder { + + private static boolean sInit; + + public static TTAdManager get() { + if (!sInit) { + throw new RuntimeException("TTAdSdk is not init, please check."); + } + return TTAdSdk.getAdManager(); + } + + public static void init(Context context) { + doInit(context); + } + + //step1:接入网盟广告sdk的初始化操作,详情见接入文档和穿山甲平台说明 + private static void doInit(Context context) { + if (!sInit) { + TTAdSdk.init(context, buildConfig(context)); + sInit = true; + } + } + + private static TTAdConfig buildConfig(Context context) { + + Log.d("adinit", "buildConfig:Constants.SEX= "+Constants.SEX ); + return new TTAdConfig.Builder() + .appId(BuildConfig.AD_TOUTIAO_APP_ID) + .useTextureView(false) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView + .appName("如意小说") + .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK) + .allowShowNotify(true) //是否允许sdk展示通知栏提示 + .allowShowPageWhenScreenLock(true) //是否在锁屏场景支持展示广告落地页 + .debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用 + .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_4G) //允许直接下载的网络状态集合 + .supportMultiProcess(false) //是否支持多进程,true支持 + .gender(Constants.SEX==1 ? TTAdConstant.GENDER_MALE : TTAdConstant.GENDER_FEMALE) // TTAdConstant.GENDER_UNKNOWN) + // .age(20) //TODO: 年龄收集 + .build(); + + } + public static void initOnSexChange(Context context){ + buildConfig(context); + } +} diff --git a/zhuike/src/main/java/com/novelbook/android/AD/toutiao/TToast.java b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/TToast.java new file mode 100644 index 0000000..c4cc568 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/TToast.java @@ -0,0 +1,44 @@ +package com.novelbook.android.AD.toutiao; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +/** + * Create by hanweiwei on 11/07/2018 + */ +public final class TToast { + private static Toast sToast; + + public static void show(Context context, String msg) { + show(context, msg, Toast.LENGTH_SHORT); + } + + public static void show(Context context, String msg, int duration) { + Toast toast = getToast(context); + if (toast != null) { + toast.setDuration(duration); + toast.setText(String.valueOf(msg)); + toast.show(); + } else { + Log.i("TToast", "toast msg: " + String.valueOf(msg)); + } + } + + @SuppressLint("ShowToast") + private static Toast getToast(Context context) { + if (context == null) { + return sToast; + } + if (sToast == null) { + synchronized (TToast.class) { + if (sToast == null) { + sToast = Toast.makeText(context.getApplicationContext(), "", Toast.LENGTH_SHORT); + } + } + } + return sToast; + } + +} diff --git a/zhuike/src/main/java/com/novelbook/android/AD/toutiao/WeakHandler.java b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/WeakHandler.java new file mode 100644 index 0000000..0705196 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/WeakHandler.java @@ -0,0 +1,33 @@ +package com.novelbook.android.AD.toutiao; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import java.lang.ref.WeakReference; + +public class WeakHandler extends Handler { + + public interface IHandler { + void handleMsg(Message msg); + } + + private final WeakReference mRef; + + public WeakHandler(IHandler handler) { + mRef = new WeakReference<>(handler); + } + + public WeakHandler(Looper looper, IHandler handler) { + super(looper); + mRef = new WeakReference<>(handler); + } + + @SuppressWarnings("unused") + @Override + public void handleMessage(Message msg) { + IHandler handler = mRef.get(); + if (handler != null && msg != null) + handler.handleMsg(msg); + } +} \ No newline at end of file diff --git a/zhuike/src/main/java/com/novelbook/android/Main2Activity.java b/zhuike/src/main/java/com/novelbook/android/Main2Activity.java index 723f4ec..cad470a 100644 --- a/zhuike/src/main/java/com/novelbook/android/Main2Activity.java +++ b/zhuike/src/main/java/com/novelbook/android/Main2Activity.java @@ -30,6 +30,7 @@ import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; +import com.novelbook.android.AD.toutiao.TTAdManagerHolder; import com.novelbook.android.Fragments.BasicFragment; import com.novelbook.android.Fragments.Fragment_Shelf; import com.novelbook.android.Fragments.Fragment_bookStore; @@ -443,7 +444,7 @@ private int bottomSelectedIndex; // return super.onKeyUp(keyCode, event); // return false; - finish(); + // finish(); app.exit(); } } @@ -486,6 +487,7 @@ private int bottomSelectedIndex; private void setSexOption(){ int s = rgSex.getCheckedRadioButtonId() == R.id.radioButtonBoy ?1:2; if(s!= Constants.SEX){ + TTAdManagerHolder.initOnSexChange(MyApp.applicationContext); Constants.SEX=s; config.setSexOption(s); Fragment current = getSupportFragmentManager().findFragmentById(R.id.realtabcontent); diff --git a/zhuike/src/main/java/com/novelbook/android/MyApp.java b/zhuike/src/main/java/com/novelbook/android/MyApp.java index b87d348..155dccc 100644 --- a/zhuike/src/main/java/com/novelbook/android/MyApp.java +++ b/zhuike/src/main/java/com/novelbook/android/MyApp.java @@ -12,6 +12,7 @@ import com.novelbook.android.AD.toutiao.TTAdManagerHolder; import com.novelbook.android.netutils.HttpMethods; import com.novelbook.android.netutils.NetUtil; import com.novelbook.android.utils.Config; +import com.novelbook.android.utils.Constants; import com.novelbook.android.utils.LogcatHelper; import com.novelbook.android.utils.PageFactory; import com.novelbook.android.AD.SplashAdManager; @@ -34,8 +35,7 @@ public class MyApp extends Application { applicationContext = getApplicationContext(); HttpMethods.USERAGENT = NetUtil.getUserAgent(); HttpMethods.LOCALUSERAGENT = NetUtil.getUserAgent(applicationContext); - - Config.createConfig(this); + initialConstants(); PageFactory.createPageFactory(this); LogcatHelper.getInstance(this).start(); // BlurKit.init(this); @@ -44,7 +44,10 @@ public class MyApp extends Application { initUmengApi(); initAD(); } - + private void initialConstants(){ + Config.createConfig(this); + Constants.SEX = Config.getInstance().getSexOption(); + } private void initUmengApi(){ UMConfigure.init(applicationContext,UMConfigure.DEVICE_TYPE_PHONE,null); MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO); @@ -59,8 +62,8 @@ public class MyApp extends Application { public boolean exit() { - System.exit(-1); removeALLActivity_(); + System.exit(-1); return true; } diff --git a/zhuike/src/main/java/com/novelbook/android/bean/AdSetting.java b/zhuike/src/main/java/com/novelbook/android/bean/AdSetting.java new file mode 100644 index 0000000..886ab30 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/bean/AdSetting.java @@ -0,0 +1,22 @@ +package com.novelbook.android.bean; + +public class AdSetting { + private int splashInterval; + private int splashPageCount; + + public int getSplashInterval() { + return splashInterval; + } + + public void setSplashInterval(int splashInterval) { + this.splashInterval = splashInterval; + } + + public int getSplashPageCount() { + return splashPageCount; + } + + public void setSplashPageCount(int splashPageCount) { + this.splashPageCount = splashPageCount; + } +} diff --git a/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java b/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java index a966aba..4288510 100644 --- a/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java @@ -8,9 +8,13 @@ import android.os.Build; import android.text.TextUtils; import android.util.Log; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.novelbook.android.BookActivity; import com.novelbook.android.Main2Activity; import com.novelbook.android.MyApp; +import com.novelbook.android.bean.AdSetting; +import com.novelbook.android.db.Novel; import com.novelbook.android.netsubscribe.BookSubscribe; import com.novelbook.android.upgrade.UpdateManager; import com.novelbook.android.utils.CommonUtil; @@ -361,6 +365,13 @@ public class NetUtil { Constants.updateUrl =TextUtils.isEmpty(tmp)?Constants.updateUrl:tmp; Constants.minVersion = jsonObject.getInt("minVersion"); + JSONObject ads = jsonObject.getJSONObject("adsenseSetting") ; +// Gson gson = new Gson(); +// AdSetting ads = gson.fromJson(adStr, AdSetting.class); + + Constants.AD_SPLASH_INVTERVAL =(long) 1000 * ads.getInt("splashInterval"); + Constants.AD_SPLASH_PAGES = ads.getInt("splashPageCount"); + Log.d(TAG, String.format("initHostConstants: Constants.AD_SPLASH_INVTERVAL %s,AD_SPLASH_PAGES %s",Constants.AD_SPLASH_INVTERVAL,Constants.AD_SPLASH_PAGES )); // try { Constants.version = CommonUtil.getVersionCode(MyApp.applicationContext); if (lastUpgradCheck == 0 ||Constants.version - - + style="@style/frmBannerContainer" /> + style="@style/frmBannerContainer" /> - + diff --git a/zhuike/src/main/res/layout/fragment_jingxuan.xml b/zhuike/src/main/res/layout/fragment_jingxuan.xml index 1266432..f793b70 100644 --- a/zhuike/src/main/res/layout/fragment_jingxuan.xml +++ b/zhuike/src/main/res/layout/fragment_jingxuan.xml @@ -6,10 +6,7 @@ tools:context=".Fragments.Fragment_jingxuan"> + style="@style/frmBannerContainer"/>