From 7d2a6467dba49f74c79c718a48b30499afdf570d Mon Sep 17 00:00:00 2001 From: mwang <8205347@qq.com> Date: Wed, 12 Jun 2019 00:14:19 +0800 Subject: [PATCH] add qq ad --- zhuike/build.gradle | 2 +- zhuike/src/main/AndroidManifest.xml | 24 +- .../novelbook/android/AD/SplashAdManager.java | 17 +- .../novelbook/android/AD/qq/Constants.java | 25 ++ .../android/AD/qq/SplashActivity.java | 290 +++++++++++++ .../android/AD/toutiao/SplashActivity.java | 4 +- .../novelbook/android/Activity_Search.java | 2 +- .../com/novelbook/android/Activity_base.java | 388 +++++++++++++++++- .../android/Activity_cate_books.java | 4 + .../com/novelbook/android/BookActivity.java | 4 +- .../android/Fragments/BasicFragment.java | 56 ++- .../java/com/novelbook/android/MyApp.java | 10 + .../com/novelbook/android/ReadActivity.java | 92 +++-- .../novelbook/android/netutils/NetUtil.java | 63 +-- .../com/novelbook/android/utils/Config.java | 49 ++- .../novelbook/android/utils/Constants.java | 8 + .../novelbook/android/utils/PageFactory.java | 20 +- .../res/drawable-v21/background_circle.xml | 19 + .../main/res/layout/ad_qq_activity_splash.xml | 59 +++ zhuike/src/main/res/layout/zactivity_read.xml | 175 ++++---- zhuike/src/main/res/values/strings.xml | 4 +- zhuike/zhuike.iml | 97 ++--- 22 files changed, 1171 insertions(+), 241 deletions(-) create mode 100644 zhuike/src/main/java/com/novelbook/android/AD/qq/Constants.java create mode 100644 zhuike/src/main/java/com/novelbook/android/AD/qq/SplashActivity.java create mode 100644 zhuike/src/main/res/drawable-v21/background_circle.xml create mode 100644 zhuike/src/main/res/layout/ad_qq_activity_splash.xml diff --git a/zhuike/build.gradle b/zhuike/build.gradle index 8ac0bdd..859ca45 100644 --- a/zhuike/build.gradle +++ b/zhuike/build.gradle @@ -13,7 +13,7 @@ android { compileSdkVersion 28 buildToolsVersion "28.0.3" defaultConfig { - applicationId "com.novelbook.android" + applicationId "com.qq.e.union.demo" minSdkVersion 19 //target 19 Android 4.4 以下版本仅占比4.1% targetSdkVersion 28 versionCode 5 diff --git a/zhuike/src/main/AndroidManifest.xml b/zhuike/src/main/AndroidManifest.xml index bebfd2a..ef84f6f 100644 --- a/zhuike/src/main/AndroidManifest.xml +++ b/zhuike/src/main/AndroidManifest.xml @@ -66,7 +66,10 @@ android:launchMode="singleTop" android:screenOrientation="portrait" android:theme="@style/ToolBarTheme.NoActionBar"> - + + + + - + + + + + + @@ -121,7 +134,7 @@ --> + android:required="false" /> - - - - + interVal)); return in >interVal; diff --git a/zhuike/src/main/java/com/novelbook/android/AD/qq/Constants.java b/zhuike/src/main/java/com/novelbook/android/AD/qq/Constants.java new file mode 100644 index 0000000..71c2e9b --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/AD/qq/Constants.java @@ -0,0 +1,25 @@ +package com.novelbook.android.AD.qq; + +public class Constants { + public static final String APPID = "1101152570"; + public static final String BannerPosID = "9079537218417626401"; + public static final String InterteristalPosID = "8575134060152130849"; + public static final String SplashPosID = "8863364436303842593"; + public static final String NativePosID = "5010320697302671"; + public static final String NativeVideoPosID = "5090421627704602"; + public static final String NativeExpressPosID = "7030020348049331"; //如果选择支持视频的模版样式,请使用NativeExpressSupportVideoPosID测试广告位拉取 + public static final String NativeUnifiedPosID = "6040749702835933"; + public static final String NativeExpressSupportVideoPosID = "2000629911207832"; //支持视频模版样式的广告位 + public static final String ContentADPosID = "5060323935699523"; + public static final String RewardVideoADPosIDSupportH = "2090845242931421";//支持竖版出横版视频 + public static final String RewardVideoADPosIDUnsupportH = "5040942242835423";//不支持竖版出横版视频 + public static final String IEGRewardVideoADPosID = "6000625736289442";//内广激励视频广告位id + public static final String UNIFIED_BANNER_POS_ID = "4080052898050840"; + public static final String UNIFIED_INTERSTITIAL_ID_LARGE_SMALL = "3040652898151811";// 大小规格 + public static final String UNIFIED_INTERSTITIAL_ID_ONLY_SMALL = "8020259898964453";// 只小规格 + + public static final String POS_ID = "pos_id"; + public static final String MAX_VIDEO_DURATION = "maxVideoDuration"; + public static final int VIDEO_DURATION_SETTING_MIN = 5; + public static final int VIDEO_DURATION_SETTING_MAX = 60; +} diff --git a/zhuike/src/main/java/com/novelbook/android/AD/qq/SplashActivity.java b/zhuike/src/main/java/com/novelbook/android/AD/qq/SplashActivity.java new file mode 100644 index 0000000..527a402 --- /dev/null +++ b/zhuike/src/main/java/com/novelbook/android/AD/qq/SplashActivity.java @@ -0,0 +1,290 @@ +package com.novelbook.android.AD.qq; + +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.provider.Settings; +import android.text.TextUtils; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.novelbook.android.Main2Activity; +import com.novelbook.android.R; +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; + +/** + * 这是demo工程的入口Activity,在这里会首次调用广点通的SDK。 + * + * 在调用SDK之前,如果您的App的targetSDKVersion >= 23,那么一定要把"READ_PHONE_STATE"、"WRITE_EXTERNAL_STORAGE"、"ACCESS_FINE_LOCATION"这几个权限申请到,否则SDK将不会工作。 + */ +public class SplashActivity extends Activity implements SplashADListener { + + private SplashAD splashAD; + private ViewGroup container; + private TextView skipView; + //private ImageView splashHolder; + private TextView splashHolder; + private TextView tvTitle; + private static final String SKIP_TEXT = "点击跳过 %d"; + + public boolean canJump = false; + private boolean needStartDemoList = true; + + /** + * 为防止无广告时造成视觉上类似于"闪退"的情况,设定无广告时页面跳转根据需要延迟一定时间,demo + * 给出的延时逻辑是从拉取广告开始算开屏最少持续多久,仅供参考,开发者可自定义延时逻辑,如果开发者采用demo + * 中给出的延时逻辑,也建议开发者考虑自定义minSplashTimeWhenNoAD的值(单位ms) + **/ + private int minSplashTimeWhenNoAD = 2000; + /** + * 记录拉取广告的时间 + */ + private long fetchSplashADTime = 0; + private Handler handler = new Handler(Looper.getMainLooper()); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.ad_qq_activity_splash ); + container = (ViewGroup) this.findViewById(R.id.splash_container); + skipView = (TextView) findViewById(R.id.skip_view); + tvTitle = (TextView) findViewById(R.id.textTile); + splashHolder = (TextView) findViewById(R.id.splash_holder); + + tvTitle.setText(R.string.app_name); + 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 + ); + + /* boolean needLogo = getIntent().getBooleanExtra("need_logo", true); + needStartDemoList = getIntent().getBooleanExtra("need_start_demo_list", true); + if (!needLogo) { + findViewById(R.id.app_logo).setVisibility(View.GONE); + }*/ + // 如果targetSDKVersion >= 23,就要申请好权限。如果您的App没有适配到Android6.0(即targetSDKVersion < 23),那么只需要在这里直接调用fetchSplashAD接口。 + if (Build.VERSION.SDK_INT >= 23) { + checkAndRequestPermission(); + } else { + // 如果是Android6.0以下的机器,默认在安装时获得了所有权限,可以直接调用SDK + fetchSplashAD(this, container, skipView, Constants.APPID, getPosId(), this, 0); + } + } + + private String getPosId() { + String posId = getIntent().getStringExtra("pos_id"); + return TextUtils.isEmpty(posId) ? Constants.SplashPosID : posId; + } + + /** + * + * ----------非常重要---------- + * + * 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.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) { + lackedPermission.add(Manifest.permission.ACCESS_FINE_LOCATION); + } + + // 权限都已经有了,那么直接调用SDK + if (lackedPermission.size() == 0) { + fetchSplashAD(this, container, skipView, Constants.APPID, 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, container, skipView, Constants.APPID, 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(); + } + } + + /** + * 拉取开屏广告,开屏广告的构造方法有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"); + 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(); + } + }, shouldDelayMills); + } + + /** + * 设置一个变量来控制当前开屏页面是否可以跳转,当开屏广告为普链类广告时,点击会打开一个广告落地页,此时开发者还不能打开自己的App主页。当从广告落地页返回以后, + * 才可以跳转到开发者自己的App主页;当开屏广告是App类广告时只会下载App。 + */ + private void next() { + if (canJump) { + + this.finish(); + } else { + canJump = true; + } + } + + @Override + protected void onPause() { + super.onPause(); + canJump = false; + } + + @Override + protected void onResume() { + super.onResume(); + if (canJump) { + next(); + } + canJump = true; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + handler.removeCallbacksAndMessages(null); + } + + /** 开屏页一定要禁止用户对返回按钮的控制,否则将可能导致用户手动退出了App而广告无法正常曝光和计费 */ + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) { + return true; + } + return super.onKeyDown(keyCode, event); + } + +} 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 index 7960121..956479d 100644 --- a/zhuike/src/main/java/com/novelbook/android/AD/toutiao/SplashActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/AD/toutiao/SplashActivity.java @@ -183,8 +183,8 @@ public class SplashActivity extends Activity implements WeakHandler.IHandler { */ private void goToMainActivity() { - Intent intent = new Intent(SplashActivity.this, Main2Activity.class); - startActivity(intent); + /* Intent intent = new Intent(SplashActivity.this, Main2Activity.class); + startActivity(intent);*/ if(mSplashContainer!=null) { mSplashContainer.removeAllViews(); } diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_Search.java b/zhuike/src/main/java/com/novelbook/android/Activity_Search.java index 577a2af..9a806f6 100644 --- a/zhuike/src/main/java/com/novelbook/android/Activity_Search.java +++ b/zhuike/src/main/java/com/novelbook/android/Activity_Search.java @@ -44,7 +44,7 @@ public class Activity_Search extends Activity_base { @Override protected void initViews() { - loadNativeBannerAd(mBannerContainer,BuildConfig.AD_SLOT_TOUTIAO_BANNER_NATIVE_ID); + loadNativeBannerAd(mBannerContainer); } diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_base.java b/zhuike/src/main/java/com/novelbook/android/Activity_base.java index 42d3db2..81c081c 100644 --- a/zhuike/src/main/java/com/novelbook/android/Activity_base.java +++ b/zhuike/src/main/java/com/novelbook/android/Activity_base.java @@ -1,9 +1,13 @@ package com.novelbook.android; +import android.Manifest; +import android.annotation.TargetApi; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -23,6 +27,7 @@ import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; +import com.androidquery.AQuery; import com.androidquery.callback.AQuery2; import com.androidquery.callback.ImageOptions; import com.bytedance.sdk.openadsdk.AdSlot; @@ -59,15 +64,40 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import com.qq.e.ads.banner.AbstractBannerADListener; +import com.qq.e.ads.banner.BannerView; +import com.qq.e.ads.cfg.VideoOption; +import com.qq.e.ads.nativ.ADSize; +import com.qq.e.ads.nativ.NativeADUnifiedListener; +import com.qq.e.ads.nativ.NativeExpressAD; +import com.qq.e.ads.nativ.NativeExpressADView; +import com.qq.e.ads.nativ.NativeExpressMediaListener; +import com.qq.e.ads.nativ.NativeUnifiedAD; +import com.qq.e.ads.nativ.NativeUnifiedADData; +import com.qq.e.comm.constants.AdPatternType; +import com.qq.e.comm.pi.AdData; +import com.qq.e.comm.util.AdError; + +import org.litepal.util.Const; + import butterknife.BindView; import butterknife.ButterKnife; -public abstract class Activity_base extends AppCompatActivity { +import static com.novelbook.android.utils.Constants.AD_TENCENT_QQ; +import static com.novelbook.android.utils.Constants.AD_TOUTIAO; + +public abstract class Activity_base extends AppCompatActivity implements NativeExpressAD.NativeExpressADListener { + private static String TAG ="Activity_base"; private ProgressDialog mProgressDialog; private MyApp application; private Activity_base oContext; protected Gson gson = new Gson(); + + //---qq ad----> + private NativeExpressAD nativeExpressAD; + private NativeExpressADView nativeExpressADView; + //---qq ad end---- @Nullable @BindView(R.id.toolbar) Toolbar toolbar; @@ -77,9 +107,6 @@ public abstract class Activity_base extends AppCompatActivity { /* @Nullable @BindView(R.id.banner_native_container) FrameLayout mNativeBannerContainer;*/ - - - @Nullable @BindView(R.id.recycleViewBookList) RecyclerView rvshudan; @@ -111,19 +138,47 @@ public abstract class Activity_base extends AppCompatActivity { ButterKnife.bind(this); setupToolbar(); // 初始化View注入 - + this.mAQuery = new AQuery2(this); initAD_TouTiao(); setTitle(); initData(); initViews(); initNaviBanner(); + if (Build.VERSION.SDK_INT >= 23) { + checkAndRequestPermission(); + } + } + @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.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) { + lackedPermission.add(Manifest.permission.ACCESS_FINE_LOCATION); + } + + + + // 请求所缺少的权限,在onRequestPermissionsResult中再看是否获得权限,如果获得权限就可以调用SDK,否则不要调用SDK。 + String[] requestPermissions = new String[lackedPermission.size()]; + if(requestPermissions.length>0) { + lackedPermission.toArray(requestPermissions); + requestPermissions(requestPermissions, 1024); + } + } void initNaviBanner(){ if(mBannerContainer==null){ return; } if(Constants.SHOWAD){ - loadNativeBannerAd(mBannerContainer,BuildConfig.AD_SLOT_TOUTIAO_BANNER_NATIVE_ID); + loadNativeBannerAd(); mBannerContainer.setVisibility(View.VISIBLE); }else{ mBannerContainer.setVisibility(View.GONE); @@ -258,6 +313,8 @@ public abstract class Activity_base extends AppCompatActivity { }; + + class MyViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.title) TextView tvTitle; @@ -343,6 +400,45 @@ public abstract class Activity_base extends AppCompatActivity { super.finish(); } + public void loadNativeBannerAd(FrameLayout bannerContainer ) { + mBannerContainer =bannerContainer; + loadNativeBannerAd( ) ; + } + + private void loadNativeBannerAd() { + /* if (mBannerContainer .getVisibility() != View.VISIBLE) { + mBannerContainer.setVisibility(View.VISIBLE); + } + */ + if (mBannerContainer.getChildCount() > 0) { + mBannerContainer.removeAllViews(); + } + + if(!Constants.SHOWAD ){return;} + if(Constants.AD_NATIVE_BANNER_SOURCE == AD_TENCENT_QQ) { + loadNativeBanner_qq(-1, 388); + }else if(Constants.AD_NATIVE_BANNER_SOURCE == AD_TOUTIAO) { + loadNativeBanner_toutiao(mBannerContainer ,690,388); + } + } + + public void loadBanner(FrameLayout bannerContainer, int width, int height) { + mBannerContainer =bannerContainer; + loadBanner( width, height); + } + + private void loadBanner( int width, int height){ + if(Constants.AD_BANNER_SOURCE == AD_TENCENT_QQ) { + getBanner_qq(); + // loadNativeBanner_qq(-1, 388); + }else if(Constants.AD_BANNER_SOURCE == AD_TOUTIAO) { + loadBanner_toutiao(mBannerContainer, width,height); + + } + } + + + //------ 头条 ad ----- AQuery2 mAQuery; Button mCreativeButton; @@ -353,7 +449,7 @@ public abstract class Activity_base extends AppCompatActivity { mTTAdNative = TTAdManagerHolder.get().createAdNative(this); //step3:(可选,强烈建议在合适的时机调用):申请部分权限,如read_phone_state,防止获取不了imei时候,下载类广告没有填充的问题。 TTAdManagerHolder.get().requestPermissionIfNecessary(this); - this.mAQuery = new AQuery2(this); + //this.mAQuery = new AQuery2(this); }catch (Exception er){ Log.e(TAG, "initAD_TouTiao: ", er); } @@ -369,12 +465,16 @@ public abstract class Activity_base extends AppCompatActivity { return mTTAdNative; } -//----toutiao ad ---- + + + + + //----toutiao ad ---- // boolean mShowAd =false; - public void loadBannerAd(FrameLayout bannerContainer, String codeId, int width, int height) { + void loadBanner_toutiao(FrameLayout bannerContainer,int width, int height) { //step4:创建广告请求参数AdSlot,具体参数含义参考文档 if(!Constants.SHOWAD || getTTAdNative()==null ){return;} - + String codeId =BuildConfig.AD_SLOT_TOUTIAO_BANNER_ID; /* if(height >390){ width =(int)(height*1.78); if(width > Constants.SCREEN_WIDTH_PIX-50 ){ @@ -511,21 +611,19 @@ public abstract class Activity_base extends AppCompatActivity { }); } //-------------native toutiao ad - void loadNativeBannerAd(FrameLayout bannerContainer,String codeId) { - loadNativeBannerAd(bannerContainer,codeId,690,388); - } // List toutiaoNati_Banner_AdCache = new ArrayList(); Map > toutiaoNati_Banner_AdCache = new ConcurrentHashMap>(); - void loadNativeBannerAd(FrameLayout bannerContainer,String codeId,int width,int height) { + void loadNativeBanner_toutiao(FrameLayout bannerContainer,int width,int height) { //step4:创建广告请求参数AdSlot,注意其中的setNativeAdtype方法,具体参数含义参考文档 if (!Constants.SHOWAD || getTTAdNative() == null) { return; } + String codeId =BuildConfig.AD_SLOT_TOUTIAO_BANNER_NATIVE_ID; final String key =width+"_"+height; List adCache =null; @@ -585,7 +683,7 @@ public abstract class Activity_base extends AppCompatActivity { if (isfillAd1) { setNativeBanner(bannerContainer, key); }else{ - loadNativeBannerAd(bannerContainer, codeId, width, height); + loadNativeBanner_toutiao(mBannerContainer, width, height); Log.d(TAG, String.format("loadNativeBannerAd: load again ... containsKey(key) ? %s,ads size %s",toutiaoNati_Banner_AdCache.containsKey(key), toutiaoNati_Banner_AdCache.containsKey(key)?toutiaoNati_Banner_AdCache.get(key).size() :0 )); @@ -909,7 +1007,7 @@ public abstract class Activity_base extends AppCompatActivity { /** * 加载 toutiao feed广告 */ - public void loadListAd(BookListAdapter adapter, int adCnt, boolean addFooter) { + public void loadListAd_toutiao(BookListAdapter adapter, int adCnt, boolean addFooter) { //feed广告请求类型参数 AdSlot adSlot = new AdSlot.Builder() .setCodeId(BuildConfig.AD_SLOT_TOUTIAO_FEEDAD_ID) @@ -942,4 +1040,262 @@ public abstract class Activity_base extends AppCompatActivity { } }); } + + + // qq ad ------------------------------begin + //private AQuery mAQuery; + + + + BannerView bv; + private void getBanner_qq() { + + if(this.bv != null){ + mBannerContainer.removeView(bv); + bv.destroy(); + } + + this.bv = new BannerView(this, com.qq.e.ads.banner.ADSize.BANNER,com.novelbook.android.AD.qq.Constants. APPID,com.novelbook.android.AD.qq.Constants.BannerPosID); + // 注意:如果开发者的banner不是始终展示在屏幕中的话,请关闭自动刷新,否则将导致曝光率过低。 + // 并且应该自行处理:当banner广告区域出现在屏幕后,再手动loadAD。 + // bv.setRefresh(0); + bv.setADListener(new AbstractBannerADListener() { + + @Override + public void onNoAD(AdError error) { + Log.i( + "AD_DEMO", + String.format("Banner onNoAD,eCode = %d, eMsg = %s", error.getErrorCode(), + error.getErrorMsg())); + } + + @Override + public void onADReceiv() { + Log.i("AD_DEMO", "ONBannerReceive"); + } + }); + mBannerContainer.addView(bv); + this.bv.loadAD(); + } + + + private void loadNativeBanner_qq(int adWidth,int adHeight) { + try { + + /* if(mAdList!=null && mAdList.size()>1){ + nativeExpressADView = mAdList.get(0); + // bindAD(); + Log.d(TAG, "loadNativeBanner_qq: mAdList.size()" +mAdList.size()); + if(mAdList.size()>1){ + return; + } + }*/ + + + nativeExpressAD = new NativeExpressAD(this, getMyADSize(adWidth, adHeight), com.novelbook.android.AD.qq.Constants.APPID, com.novelbook.android.AD.qq.Constants.NativeExpressPosID, this); // 这里的Context必须为Activity + /* nativeExpressAD.setVideoOption(new VideoOption.Builder() + .setAutoPlayPolicy(VideoOption.AutoPlayPolicy.WIFI) // 设置什么网络环境下可以自动播放视频 + .setAutoPlayMuted(true) // 设置自动播放视频时,是否静音 + .build()); // setVideoOption是可选的,开发者可根据需要选择是否配置 + nativeExpressAD.setMaxVideoDuration(com.novelbook.android.AD.qq.Constants.VIDEO_DURATION_SETTING_MAX);*/ + nativeExpressAD.loadAD(1); + + } catch (NumberFormatException e) { + Log.w(TAG, "ad size invalid."); + Toast.makeText(this, "请输入合法的宽高数值", Toast.LENGTH_SHORT).show(); + } + } + + private ADSize getMyADSize(int adWidth,int adHeight) { + + return new ADSize(adWidth, adHeight); + } + + /** + * 获取广告数据 + * + * @param nativeExpressADView + * @return + */ + private String getAdInfo(NativeExpressADView nativeExpressADView) { + AdData adData = nativeExpressADView.getBoundData(); + if (adData != null) { + StringBuilder infoBuilder = new StringBuilder(); + infoBuilder.append("title:").append(adData.getTitle()).append(",") + .append("desc:").append(adData.getDesc()).append(",") + .append("patternType:").append(adData.getAdPatternType()); + if (adData.getAdPatternType() == AdPatternType.NATIVE_VIDEO) { + infoBuilder.append(", video info: ").append(getVideoInfo(adData.getProperty(AdData.VideoPlayer.class))); + } + return infoBuilder.toString(); + } + return null; + } + /** + * 获取播放器实例 + * + * 仅当视频回调{@link NativeExpressMediaListener#onVideoInit(NativeExpressADView)}调用后才会有返回值 + * + * @param videoPlayer + * @return + */ + private String getVideoInfo(AdData.VideoPlayer videoPlayer) { + if (videoPlayer != null) { + StringBuilder videoBuilder = new StringBuilder(); + videoBuilder.append("{state:").append(videoPlayer.getVideoState()).append(",") + .append("duration:").append(videoPlayer.getDuration()).append(",") + .append("position:").append(videoPlayer.getCurrentPosition()).append("}"); + return videoBuilder.toString(); + } + return null; + } + + FrameLayout getNativeContainer(){ + return mBannerContainer; + } + List mAdList; + @Override + public void onADLoaded(List adList){ + // 释放前一个展示的NativeExpressADView的资源 + + if(mAdList==null){ + mAdList = new ArrayList(); + } + boolean toBind = mAdList.size()==0; + mAdList.addAll(0,adList); + for(NativeExpressADView ad :mAdList){ + Log.d(TAG, "onADLoaded: ad is " +ad); + } + /* if(toBind ){ + bindAD(adList); + }*/ + bindAD(adList); + + } + void bindAD(List adList){ + if (nativeExpressADView != null) { + nativeExpressADView.destroy(); + } + FrameLayout bannerContainer = getNativeContainer(); + + if (bannerContainer .getVisibility() != View.VISIBLE) { + return; + // bannerContainer.setVisibility(View.VISIBLE); + } + + if (bannerContainer.getChildCount() > 0) { + bannerContainer.removeAllViews(); + } + + nativeExpressADView = adList.get(0); + + /* Log.i(TAG, "onADLoaded, video info: " + getAdInfo(nativeExpressADView)); + if (nativeExpressADView.getBoundData().getAdPatternType() == AdPatternType.NATIVE_VIDEO) { + nativeExpressADView.setMediaListener(mediaListener); + }*/ + // 广告可见才会产生曝光,否则将无法产生收益。 + bannerContainer.addView(nativeExpressADView); + nativeExpressADView.render(); + // mAdList.remove(0); + } + @Override + public void onNoAD(AdError adError) { + Log.i( + TAG, + String.format("onNoAD, error code: %d, error msg: %s", adError.getErrorCode(), + adError.getErrorMsg())); + } + + @Override + public void onRenderFail(NativeExpressADView adView) { + Log.i(TAG, "onRenderFail"); + } + + @Override + public void onRenderSuccess(NativeExpressADView adView) { + Log.i(TAG, "onRenderSuccess"); + } + + @Override + public void onADExposure(NativeExpressADView adView) { + Log.i(TAG, "onADExposure"); + } + + @Override + public void onADClicked(NativeExpressADView var1){ + + } + + @Override + public void onADClosed(NativeExpressADView var1) { + FrameLayout bannerContainer = getNativeContainer(); + if (bannerContainer != null && bannerContainer.getChildCount() > 0) { + bannerContainer.removeAllViews(); + // bannerContainer.setVisibility(View.GONE); + } + } + @Override + public void onADLeftApplication(NativeExpressADView var1){ + + } + + @Override + public void onADOpenOverlay(NativeExpressADView var1){ + + } + + @Override + public void onADCloseOverlay(NativeExpressADView var1){ + + } + private NativeExpressMediaListener mediaListener = new NativeExpressMediaListener() { + @Override + public void onVideoInit(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoInit: " + + getVideoInfo(nativeExpressADView.getBoundData().getProperty(AdData.VideoPlayer.class))); + } + + @Override + public void onVideoLoading(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoLoading"); + } + + @Override + public void onVideoReady(NativeExpressADView nativeExpressADView, long l) { + Log.i(TAG, "onVideoReady"); + } + + @Override + public void onVideoStart(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoStart: " + + getVideoInfo(nativeExpressADView.getBoundData().getProperty(AdData.VideoPlayer.class))); + } + + @Override + public void onVideoPause(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoPause: " + + getVideoInfo(nativeExpressADView.getBoundData().getProperty(AdData.VideoPlayer.class))); + } + + @Override + public void onVideoComplete(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoComplete: " + + getVideoInfo(nativeExpressADView.getBoundData().getProperty(AdData.VideoPlayer.class))); + } + + @Override + public void onVideoError(NativeExpressADView nativeExpressADView, AdError adError) { + Log.i(TAG, "onVideoError"); + } + + @Override + public void onVideoPageOpen(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoPageOpen"); + } + + @Override + public void onVideoPageClose(NativeExpressADView nativeExpressADView) { + Log.i(TAG, "onVideoPageClose"); + } + }; } diff --git a/zhuike/src/main/java/com/novelbook/android/Activity_cate_books.java b/zhuike/src/main/java/com/novelbook/android/Activity_cate_books.java index d233109..664314d 100644 --- a/zhuike/src/main/java/com/novelbook/android/Activity_cate_books.java +++ b/zhuike/src/main/java/com/novelbook/android/Activity_cate_books.java @@ -94,6 +94,10 @@ public class Activity_cate_books extends Activity_base { } void initTabs2() { + if(Constants.lstProgressType==null){ + return; + } + if (mFragments == null ) { diff --git a/zhuike/src/main/java/com/novelbook/android/BookActivity.java b/zhuike/src/main/java/com/novelbook/android/BookActivity.java index 2557bc2..b03d9c6 100644 --- a/zhuike/src/main/java/com/novelbook/android/BookActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/BookActivity.java @@ -251,7 +251,7 @@ public class BookActivity extends Activity_base { rvBooklistAuthor.setLayoutManager(new LinearLayoutManager(this)); rvBooklistAuthor.setAdapter(mAdapterAuthor); - loadListAd(mAdapterAuthor, 1 ,false); + loadListAd_toutiao(mAdapterAuthor, 1 ,false); } private void setNovelsRelated(){ @@ -270,7 +270,7 @@ public class BookActivity extends Activity_base { rvBooklistRelated.setLayoutManager(new LinearLayoutManager(this)); rvBooklistRelated.setAdapter(mAdapterRelated); - loadListAd(mAdapterRelated, 1 ,false); + loadListAd_toutiao(mAdapterRelated, 1 ,false); } /** diff --git a/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java b/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java index 232f22d..9570151 100644 --- a/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java +++ b/zhuike/src/main/java/com/novelbook/android/Fragments/BasicFragment.java @@ -65,6 +65,11 @@ import com.novelbook.android.utils.ImageUtil; import com.novelbook.android.utils.MyImageLoader; import com.novelbook.android.utils.OnItemClickListener; import com.novelbook.android.utils.PageFactory; +import com.qq.e.ads.nativ.NativeADUnifiedListener; +import com.qq.e.ads.nativ.NativeExpressAD; +import com.qq.e.ads.nativ.NativeUnifiedAD; +import com.qq.e.ads.nativ.NativeUnifiedADData; +import com.qq.e.comm.util.AdError; import com.umeng.analytics.MobclickAgent; import com.youth.banner.loader.ImageLoader; @@ -84,7 +89,7 @@ import butterknife.ButterKnife; /** * A simple {@link Fragment} subclass. */ -public abstract class BasicFragment extends Fragment { +public abstract class BasicFragment extends Fragment implements NativeADUnifiedListener { private static String TAG = BasicFragment.class.getSimpleName(); protected View rootView; @@ -157,6 +162,7 @@ public abstract class BasicFragment extends Fragment { mBannerContainer.setVisibility(View.GONE); } } + return view; // Inflate the layout for this fragment @@ -474,15 +480,59 @@ void initTabs(){ return; } - activity .loadBannerAd(bannerContainer, BuildConfig.AD_SLOT_TOUTIAO_BANNER_ID,(int)(adHeight*5.9), adHeight); + activity .loadBanner(bannerContainer, (int)(adHeight*5.9), adHeight); if( mBannerContainer.getVisibility() !=View.VISIBLE) mBannerContainer.setVisibility(View.VISIBLE); } + // qq ad ------------------------------begin + private NativeUnifiedAD mAdManager; + private List mAds = new ArrayList<>(); + public void loadListAd_qq(BookListAdapter adapter, int adCnt, boolean addFooter) { + if(mAdManager==null) { + mAdManager = new NativeUnifiedAD(activity, com.novelbook.android.AD.qq.Constants.APPID, + com.novelbook.android.AD.qq.Constants.UNIFIED_INTERSTITIAL_ID_ONLY_SMALL, this); + } + mAdManager.loadData(adCnt); + qqAdapter =adapter; + qqAddFooter=addFooter; + + } + + private boolean qqAddFooter; + private BookListAdapter qqAdapter; + @Override + public void onADLoaded(List ads) { + // mIsLoading = false; + // 防止在onDestory后网络回包 + if(qqAdapter==null){ + return; + } + if(qqAddFooter) { + qqAdapter.AddFooterItem(ads); + }else{ + qqAdapter.AddHeaderItem(ads); + } + } + @Override + public void onNoAD(AdError adError) { + Log.i( + TAG, + String.format("onNoAD, error code: %d, error msg: %s", adError.getErrorCode(), + adError.getErrorMsg())); + } + + //qq ad end<------------- + /** * 加载 toutiao feed广告 */ void loadListAd( BookListAdapter adapter, int adCnt, boolean addFooter) { - activity.loadListAd(adapter, adCnt ,addFooter); + if(Constants.AD_UNIFIED_RECYCLE_SOURCE==1) { + loadListAd_qq(adapter, adCnt, addFooter); + }else if(Constants.AD_UNIFIED_RECYCLE_SOURCE==2){ + activity.loadListAd_toutiao(adapter, adCnt, addFooter); + } + } } diff --git a/zhuike/src/main/java/com/novelbook/android/MyApp.java b/zhuike/src/main/java/com/novelbook/android/MyApp.java index 8f77ab2..9cc01e4 100644 --- a/zhuike/src/main/java/com/novelbook/android/MyApp.java +++ b/zhuike/src/main/java/com/novelbook/android/MyApp.java @@ -54,6 +54,16 @@ public class MyApp extends Application { Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT = config.getAdTopBannerRate(); Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT= config.getAdNativeBannerInLinesRate() ; + Constants.AD_SPLASH_SOURCE=config.getAdSplashSource(); + Constants.AD_UNIFIED_RECYCLE_SOURCE=config.getAdUnifiedRecycleSource(); + Constants.AD_NATIVE_BANNER_SOURCE=config.getAdNativeBannerSource(); + Constants.AD_BANNER_SOURCE=config.getAdBannerSource(); + + + + + + Constants.ONE_DP_SIZE = (int)applicationContext.getResources().getDimension(R.dimen.one_dp); } diff --git a/zhuike/src/main/java/com/novelbook/android/ReadActivity.java b/zhuike/src/main/java/com/novelbook/android/ReadActivity.java index b8252ce..56b7971 100644 --- a/zhuike/src/main/java/com/novelbook/android/ReadActivity.java +++ b/zhuike/src/main/java/com/novelbook/android/ReadActivity.java @@ -137,11 +137,10 @@ public class ReadActivity extends Activity_base implements AdInterface { @BindView(R.id.frmAD) FrameLayout frmAD; - @BindView(R.id.native_banner_container ) + @BindView(R.id.native_banner_container ) FrameLayout mNative_status_banner_container; - - @BindView(R.id.native_banner_container_in_lines ) - FrameLayout mNative_banner_container_in_lines; + @BindView(R.id.banner_container ) + FrameLayout mBannerContainer; @BindView(R.id.llShelfBottom) LinearLayout llShelf; private Config config; @@ -482,8 +481,8 @@ public class ReadActivity extends Activity_base implements AdInterface { public void showAdAfterIni() { // if(frmAD.getVisibility()== View.INVISIBLE) // frmAD.setVisibility(View.VISIBLE); - /* if(mNative_banner_container_in_lines.getVisibility()== View.GONE) - mNative_banner_container_in_lines.setVisibility(View.VISIBLE);*/ + /* if(mBannerContainer.getVisibility()== View.GONE) + mBannerContainer.setVisibility(View.VISIBLE);*/ // Log.d(TAG, "pageAnimation showAdAfterIni: "); pageFactory.showAd(); } @@ -492,9 +491,9 @@ public class ReadActivity extends Activity_base implements AdInterface { public void hideAdBeforeIni() { // if(frmAD.getVisibility()== View.VISIBLE) // frmAD.setVisibility(View.INVISIBLE); - /* if(mNative_banner_container_in_lines.getVisibility()== View.VISIBLE) - mNative_banner_container_in_lines.setVisibility(View.GONE);*/ - // mNative_banner_container_in_lines.removeAllViews(); + /* if(mBannerContainer.getVisibility()== View.VISIBLE) + mBannerContainer.setVisibility(View.GONE);*/ + // mBannerContainer.removeAllViews(); // Log.d(TAG, "pageAnimation hideAdBeforeIni: "); @@ -1079,31 +1078,43 @@ public class ReadActivity extends Activity_base implements AdInterface { } */ + FrameLayout tmpFrame =mBannerContainer; + @Override + FrameLayout getNativeContainer(){ + return tmpFrame; + } + public void hideStatusAds(){ - Log.d(TAG, "loadBannerAd: hideAds()"); + /* try{ throw new Exception(""); }catch (Exception e){ Log.e(TAG, "loadBannerAd: ", e); }*/ if(mNative_status_banner_container.getVisibility() ==View.VISIBLE) { - mNative_status_banner_container.setVisibility(View.GONE); + Log.d(TAG, "loadBannerAd: hideStatusAds()"); + mNative_status_banner_container.setVisibility(View.GONE); } -// mNative_banner_container_in_lines.removeAllViews(); -// mNative_banner_container_in_lines.setBackgroundResource(R.color.transparent); + // mBannerContainer.removeAllViews(); +// mBannerContainer.setBackgroundResource(R.color.transparent); } private void hideAdSlot(ViewGroup view){ - mNative_banner_container_in_lines.removeAllViews(); - if(view.getVisibility() ==View.VISIBLE) { + + if(view.getChildCount()>0) { + view.removeAllViews(); + Log.d(TAG, "loadBannerAd: hideAdSlot()"); + } + + /* if(view.getVisibility() ==View.VISIBLE) { view.setVisibility(View.GONE); - } + }*/ /* FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); params.width =0; view.setLayoutParams(params);*/ // view.setBackgroundResource(R.color.transparent); - //mNative_banner_container_in_lines.removeAllViews(); - // mNative_banner_container_in_lines.setBackgroundResource(R.color.transparent); + //mBannerContainer.removeAllViews(); + // mBannerContainer.setBackgroundResource(R.color.transparent); } private void showAdSlot(ViewGroup view){ @@ -1120,11 +1131,11 @@ public class ReadActivity extends Activity_base implements AdInterface { public void showNativeBannerInLines(int height,int adY){ // hideSystemUI(); // hideAdSlot(mNative_banner_container); - // hideAdSlot(mNative_banner_container_in_lines); - // mNative_banner_container_in_lines.removeAllViews(); - // mNative_banner_container_in_lines.removeAllViews(); - // mNative_banner_container_in_lines.setBackgroundResource(R.color.transparent); - hideAdSlot(mNative_banner_container_in_lines); + // hideAdSlot(mBannerContainer); + // mBannerContainer.removeAllViews(); + // mBannerContainer.removeAllViews(); + // mBannerContainer.setBackgroundResource(R.color.transparent); + hideAdSlot(mBannerContainer); if(height<=0){ return; } @@ -1132,14 +1143,16 @@ public class ReadActivity extends Activity_base implements AdInterface { if( adY >390*Constants.ONE_DP_SIZE){ return; } + tmpFrame =mBannerContainer; + Log.d(TAG, String.format("loadBannerAd:showNativeBannerInLines width %s, height %s ,adY %s ",Constants.SCREEN_WIDTH_PIX-50,height,adY)); - loadNativeBannerAd(mNative_banner_container_in_lines,BuildConfig.AD_SLOT_TOUTIAO_BANNER_NATIVE_ID); - FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mNative_banner_container_in_lines.getLayoutParams(); + loadNativeBannerAd(mBannerContainer); + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mBannerContainer.getLayoutParams(); params.setMargins(10*Constants.ONE_DP_SIZE, adY+5*Constants.ONE_DP_SIZE, 10*Constants.ONE_DP_SIZE, 0*Constants.ONE_DP_SIZE); params.width =-1; params.height = (int) getResources().getDimension(R.dimen.nativeBannerHeight); - mNative_banner_container_in_lines.setLayoutParams(params); - showAdSlot(mNative_banner_container_in_lines); + mBannerContainer.setLayoutParams(params); + showAdSlot(mBannerContainer); @@ -1150,19 +1163,20 @@ public class ReadActivity extends Activity_base implements AdInterface { // mTopBannerContainer.setVisibility(View.INVISIBLE);//翻页引起抖动 //mTopBannerContainer.removeAllViews(); Log.d(TAG, String.format("loadBannerAd:showTopBanner width %s, height %s ,adY %s ",Constants.SCREEN_WIDTH_PIX-50,adHeight,adY)); - hideAdSlot(mNative_banner_container_in_lines); + tmpFrame =mBannerContainer; + hideAdSlot(mBannerContainer); if(adHeight<=0){ return; } Log.d(TAG, String.format("loadBannerAd:showTopBanner width %s, height %s ,adY %s ",Constants.SCREEN_WIDTH_PIX-50,adHeight,adY)); - FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mNative_banner_container_in_lines.getLayoutParams(); - loadBannerAd(mNative_banner_container_in_lines,BuildConfig.AD_SLOT_TOUTIAO_BANNER_ID, Constants.SCREEN_WIDTH_PIX-50,adHeight); + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mBannerContainer.getLayoutParams(); + loadBanner(mBannerContainer, Constants.SCREEN_WIDTH_PIX-50,adHeight); // loadNativeBannerAd(mTopBannerContainer,BuildConfig.AD_SLOT_TOUTIAO_BANNER_NATIVE_ID, 304,200); params.setMargins(10*Constants.ONE_DP_SIZE, adY -5*Constants.ONE_DP_SIZE, 10*Constants.ONE_DP_SIZE, 0); params.width =-1; params.height = (int) getResources().getDimension(R.dimen.topBannerHeight); - mNative_banner_container_in_lines.setLayoutParams(params); - showAdSlot(mNative_banner_container_in_lines); + mBannerContainer.setLayoutParams(params); + showAdSlot(mBannerContainer); } @@ -1192,19 +1206,19 @@ public class ReadActivity extends Activity_base implements AdInterface { // Log.d(TAG, String.format("loadBannerAd:width %s, height %s ,adY %s",Constants.SCREEN_WIDTH_PIX-50,adHeight,adY)); if(adHeight>150*Constants.ONE_DP_SIZE && adY <400*Constants.ONE_DP_SIZE){ - Log.d(TAG, String.format("loadBannerAd:width %s, height %s ,adY %s ",Constants.SCREEN_WIDTH_PIX-50,adHeight/Constants.ONE_DP_SIZE,adY/Constants.ONE_DP_SIZE )); - hideAdSlot(mNative_banner_container_in_lines); + Log.d(TAG, String.format("loadBannerAd: showStatusAd width %s, height %s ,adY %s ",Constants.SCREEN_WIDTH_PIX-50,adHeight/Constants.ONE_DP_SIZE,adY/Constants.ONE_DP_SIZE )); + hideAdSlot(mBannerContainer); // hideAdSlot(mTopBannerContainer); - + tmpFrame =mNative_status_banner_container; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mNative_status_banner_container.getLayoutParams(); hideAdSlot(mNative_status_banner_container); - // mNative_banner_container_in_lines.removeAllViews(); - // mNative_banner_container_in_lines.setBackgroundResource(R.color.transparent); + // mBannerContainer.removeAllViews(); + // mBannerContainer.setBackgroundResource(R.color.transparent); - loadNativeBannerAd(mNative_status_banner_container,BuildConfig.AD_SLOT_TOUTIAO_BANNER_NATIVE_ID); + loadNativeBannerAd(mNative_status_banner_container); params.setMargins(10*Constants.ONE_DP_SIZE, adY-20*Constants.ONE_DP_SIZE, 10*Constants.ONE_DP_SIZE, 50*Constants.ONE_DP_SIZE); - params.height=-1; + // params.height=-1; mNative_status_banner_container.setLayoutParams(params); showAdSlot(mNative_status_banner_container); // mNative_banner_container.setVisibility(View.VISIBLE); 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 5a9072c..2ab0f65 100644 --- a/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java +++ b/zhuike/src/main/java/com/novelbook/android/netutils/NetUtil.java @@ -360,55 +360,66 @@ public class NetUtil { static long lastUpgradCheck =0; static void initHostConstants( JSONObject jsonObject ) throws JSONException { - Constants.announcement =jsonObject.getString("declare"); - Constants.email =jsonObject.getString("email"); - String tmp =jsonObject.getString("upgradeUrl"); - Constants.updateUrl =TextUtils.isEmpty(tmp)?Constants.updateUrl:tmp; - Constants.minVersion = jsonObject.getInt("minVersion"); + Constants.announcement = jsonObject.getString("declare"); + Constants.email = jsonObject.getString("email"); + String tmp = jsonObject.getString("upgradeUrl"); + Constants.updateUrl = TextUtils.isEmpty(tmp) ? Constants.updateUrl : tmp; + Constants.minVersion = jsonObject.getInt("minVersion"); - JSONObject ads = jsonObject.getJSONObject("adsenseSetting") ; + 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"); - Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT = ads.getInt("times4ChapterTopBanner"); - Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT = ads.getInt("times4ChapterContentBanner"); + Constants.AD_SPLASH_INVTERVAL = (long) 1000 * ads.getInt("splashInterval"); + Constants.AD_SPLASH_PAGES = ads.getInt("splashPageCount"); + Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT = ads.getInt("times4ChapterTopBanner"); + Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT = ads.getInt("times4ChapterContentBanner"); - if(Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT >1 && Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT == Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT ){ - Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT--; //顶部广告和页内广告要错开 - } + /* Constants.AD_SPLASH_SOURCE = ads.getInt("splashSource"); + Constants.AD_UNIFIED_RECYCLE_SOURCE = ads.getInt("unifiedReceycleSource"); + Constants.AD_NATIVE_BANNER_SOURCE = ads.getInt("nativeBannerSource"); + Constants.AD_BANNER_SOURCE = ads.getInt("bannerSource");*/ - 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 1 && Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT == Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT) { + Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT--; //顶部广告和页内广告要错开 + } - } + 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 < Constants.minVersion) { + lastUpgradCheck = new Date().getTime(); + checkUpdate(true); + + } // }catch (Exception er){ // Log.e(TAG, "initHostConstants: update error ",er ); // } - if( ads.getBoolean("showAdsense")){ - if(!Constants.SHOWAD ){ + if (ads.getBoolean("showAdsense")) { + if (!Constants.SHOWAD) { Constants.SHOWAD = ads.getBoolean("showAdsense"); TTAdManagerHolder.init(MyApp.applicationContext); } } Config config = Config.getInstance(); Constants.SHOWAD = ads.getBoolean("showAdsense"); - Constants.PRE_LOAD_CHAPT= jsonObject.getBoolean("preLoadChapter"); + Constants.PRE_LOAD_CHAPT = jsonObject.getBoolean("preLoadChapter"); config.setShowAd(Constants.SHOWAD); config.setPreLoadChapter(Constants.PRE_LOAD_CHAPT); - config.setAdTopBannerRate( Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT); + config.setAdTopBannerRate(Constants.AD_CHAPT_TOP_BANNER_PER_PAGE_COUNT); config.setAdNativeBannerInLinesRate(Constants.AD_CHAPT_NATIVE_BANNER_PER_PAGE_COUNT); + + config.setAdSplashSource(Constants.AD_SPLASH_SOURCE); + config.setAdUnifiedRecycleSource(Constants.AD_UNIFIED_RECYCLE_SOURCE); + config.setAdNativeBannerSource(Constants.AD_NATIVE_BANNER_SOURCE); + config.setAdBannerSource(Constants.AD_BANNER_SOURCE); + Log.d(TAG, String.format("initHostConstants: Constants.AD_SPLASH_INVTERVAL %s,AD_SPLASH_PAGES %s, Constants.SHOWAD %s,Constants.AD_PRE_LOAD_CHAPT %s " - ,Constants.AD_SPLASH_INVTERVAL,Constants.AD_SPLASH_PAGES, Constants.SHOWAD, Constants.PRE_LOAD_CHAPT )); + , Constants.AD_SPLASH_INVTERVAL, Constants.AD_SPLASH_PAGES, Constants.SHOWAD, Constants.PRE_LOAD_CHAPT)); - } + } public static void checkUpdate(boolean isSilence){ UpdateManager manager = new UpdateManager(Main2Activity.activityContext); diff --git a/zhuike/src/main/java/com/novelbook/android/utils/Config.java b/zhuike/src/main/java/com/novelbook/android/utils/Config.java index 9907b8d..6c46232 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/Config.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/Config.java @@ -41,10 +41,14 @@ public class Config { public final static int PAGE_MODE_SLIDE = 2; public final static int PAGE_MODE_NONE = 3; public final static boolean SHOW_AD = false; - public final static String SHOW_AD_KEY = "showAd"; + private final static String SHOW_AD_KEY = "showAd"; private static final String PRE_LOAD_CHAPT_KEY ="preloadchapt" ; private static final String AD_TOP_BANNER_SEEDS_KEY ="topbannerseeds" ; private static final String AD_NATVIE_BANNER_IN_LINES_SEEDS_KEY ="nativebannerinlinesseeds" ; + + + + private Context mContext; private static Config config; private SharedPreferences sp; @@ -234,6 +238,48 @@ public class Config { sp.edit().putInt(AD_TOP_BANNER_SEEDS_KEY,pageCnt).commit(); } + + + + private final static String AD_NATIVE_BANNER_SOURCE_KEY = "AD_NATIVE_BANNER_SOURCE_KEY"; + private final static String AD_BANNER_SOURCE_KEY = "AD_BANNER_SOURCE_KEY"; + private final static String AD_UNIFIED_RECYCLE_SOURCE_KEY = "AD_UNIFIED_RECYCLE_SOURCE_KEY"; + private final static String AD_SPLASH_SOURCE_KEY = "AD_SPLASH_SOURCE_KEY"; + + + public int getAdNativeBannerSource(){ + return sp.getInt(AD_NATIVE_BANNER_SOURCE_KEY,Constants.AD_TENCENT_QQ); + } + + public void setAdNativeBannerSource(int source){ + sp.edit().putInt(AD_NATIVE_BANNER_SOURCE_KEY,source).commit(); + } + + public int getAdBannerSource(){ + return sp.getInt(AD_BANNER_SOURCE_KEY,Constants.AD_TENCENT_QQ); + } + + public void setAdBannerSource(int source){ + sp.edit().putInt(AD_BANNER_SOURCE_KEY,source).commit(); + } + + public int getAdUnifiedRecycleSource(){ + return sp.getInt(AD_UNIFIED_RECYCLE_SOURCE_KEY,Constants.AD_TENCENT_QQ); + } + + public void setAdUnifiedRecycleSource(int source){ + sp.edit().putInt(AD_UNIFIED_RECYCLE_SOURCE_KEY,source).commit(); + } + + public int getAdSplashSource(){ + return sp.getInt(AD_SPLASH_SOURCE_KEY,Constants.AD_TENCENT_QQ); + } + + public void setAdSplashSource(int source){ + sp.edit().putInt(AD_SPLASH_SOURCE_KEY,source).commit(); + } + + public int getAdNativeBannerInLinesRate(){ return sp.getInt(AD_NATVIE_BANNER_IN_LINES_SEEDS_KEY,0); } @@ -241,4 +287,5 @@ public class Config { public void setAdNativeBannerInLinesRate(int pageCnt){ sp.edit().putInt(AD_NATVIE_BANNER_IN_LINES_SEEDS_KEY,pageCnt).commit(); } + } diff --git a/zhuike/src/main/java/com/novelbook/android/utils/Constants.java b/zhuike/src/main/java/com/novelbook/android/utils/Constants.java index 64b6910..4e52998 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/Constants.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/Constants.java @@ -14,8 +14,16 @@ public class Constants { public static final int MAXAGE_MAX =60*60*24*28; //28 天 ; public static final int MAXAGE_MULU = 60*60*24*7*2; //2周;; public static final String VERSION_ADDRESS ="version.xml"; + + public static final int AD_TENCENT_QQ =1; + public static final int AD_TOUTIAO =2; public static boolean AD_BACKGROUND_TRANSPARENT =true ; public static boolean SHOWAD =false ; + public static int AD_NATIVE_BANNER_SOURCE = 2 ; //1:tencent,2:toutiao + public static int AD_BANNER_SOURCE = 1 ; //1:tencent,2:toutiao + public static int AD_UNIFIED_RECYCLE_SOURCE = 2 ; //1:tencent,2:toutiao + public static int AD_SPLASH_SOURCE = 1 ; //1:tencent,2:toutiao + public static int AD_SOURCE =1 ; //1:tencent,2:toutiao public static boolean PRE_LOAD_CHAPT = false; public static long AD_SPLASH_INVTERVAL = 5*60*1000;//间隔5分钟 public static int AD_SPLASH_PAGES = 15; diff --git a/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java b/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java index 993ebec..58b6607 100644 --- a/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java +++ b/zhuike/src/main/java/com/novelbook/android/utils/PageFactory.java @@ -473,9 +473,10 @@ public class PageFactory implements ChangeSource{ int pageNo =0; long starttime = new Date().getTime(); while(length =chars.length){ if(page.getLines().size()< mLineCount/2) page.setTopBannerHeight(0); } + + chaptPages.add(page); // Log.d(TAG, String.format("prepare book build page %s ready for chapter %s,cost %s",pageNo, chaptId,new Date().getTime()-starttime1)); } // Log.d(TAG, String.format(" prepare book build pages ready for chapter %s,cost %s", chaptId,new Date().getTime()-starttime)); @@ -1089,7 +1096,11 @@ private void hideSysUI(){ } y+=trPage.getNativeBannerHeight() +m_fontSize +lineSpace ; Log.d(TAG, String.format("onDraw showNativeBannerInLines : lineno %s,strline %s ",lineNo,strLine)); - + space = m_fontSize + lineSpace; + // y-=lineSpace; + if (strLine.length() > 0 && (strLine.charAt(strLine.length() - 1) + "").equals("\n")) { + space = m_fontSize + paragraphSpace; + } }else { if (strLine.length() > 0 && (strLine.charAt(strLine.length() - 1) + "").equals("\n")) { @@ -1105,6 +1116,7 @@ private void hideSysUI(){ // Log.d(TAG,String.format("prepare book %s,y plus is %s" ,strLine, m_fontSize + lineSpace)); } + } c.drawText(strLine, measureMarginWidth, y, mPaint); diff --git a/zhuike/src/main/res/drawable-v21/background_circle.xml b/zhuike/src/main/res/drawable-v21/background_circle.xml new file mode 100644 index 0000000..1ae1939 --- /dev/null +++ b/zhuike/src/main/res/drawable-v21/background_circle.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/zhuike/src/main/res/layout/ad_qq_activity_splash.xml b/zhuike/src/main/res/layout/ad_qq_activity_splash.xml new file mode 100644 index 0000000..e2e90ab --- /dev/null +++ b/zhuike/src/main/res/layout/ad_qq_activity_splash.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zhuike/src/main/res/layout/zactivity_read.xml b/zhuike/src/main/res/layout/zactivity_read.xml index 4185d15..11fe705 100644 --- a/zhuike/src/main/res/layout/zactivity_read.xml +++ b/zhuike/src/main/res/layout/zactivity_read.xml @@ -12,8 +12,8 @@ --> + android:layout_height="match_parent"> + - + app:popupTheme="@style/AppTheme.PopupOverlay"> + + android:id="@+id/tvUrl" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:background="@color/read_dialog_bg" + android:ellipsize="end" + android:gravity="bottom" + android:lines="1" + android:paddingLeft="10dp" + android:text="http://abc.om..fd" + android:textColor="@color/whitesmoke" + android:textSize="11sp" /> - + + + android:contentDescription="TODO" + android:scaleType="centerCrop" + android:src="@mipmap/loading" + android:visibility="gone" />