package com.novelbook.android; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.androidquery.callback.AQuery2; import com.androidquery.callback.ImageOptions; import com.bytedance.sdk.openadsdk.AdSlot; import com.bytedance.sdk.openadsdk.TTAdConstant; import com.bytedance.sdk.openadsdk.TTAdDislike; import com.bytedance.sdk.openadsdk.TTAdNative; import com.bytedance.sdk.openadsdk.TTAppDownloadListener; import com.bytedance.sdk.openadsdk.TTBannerAd; import com.bytedance.sdk.openadsdk.TTFeedAd; import com.bytedance.sdk.openadsdk.TTImage; import com.bytedance.sdk.openadsdk.TTInteractionAd; import com.bytedance.sdk.openadsdk.TTNativeAd; import com.google.gson.Gson; import com.novelbook.android.AD.toutiao.TTAdManagerHolder; import com.novelbook.android.db.Novel; import com.novelbook.android.netutils.NetUtil; import com.novelbook.android.upgrade.UpdateManager; import com.novelbook.android.utils.CommonUtil; import com.novelbook.android.utils.Constants; import com.novelbook.android.utils.ImageUtil; import com.novelbook.android.utils.OnItemClickListener; import com.novelbook.android.adapter.BookListAdapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import butterknife.BindView; import butterknife.ButterKnife; public abstract class Activity_base extends AppCompatActivity { private static String TAG ="Activity_base"; private ProgressDialog mProgressDialog; private MyApp application; private Activity_base oContext; protected Gson gson = new Gson(); @Nullable @BindView(R.id.toolbar) Toolbar toolbar; @Nullable @BindView(R.id.banner_container) FrameLayout mBannerContainer; /* @Nullable @BindView(R.id.banner_native_container) FrameLayout mNativeBannerContainer;*/ @Nullable @BindView(R.id.recycleViewBookList) RecyclerView rvshudan; void showBook(String bookName) { //show paihangbang activity Intent intent = new Intent(this, BookActivity.class); intent.putExtra("BOOKNAME",bookName); startActivity(intent); } // protected MyImageLoader imgloader = new MyImageLoader(); /** * 初始化布局 */ public abstract int getLayoutRes(); protected abstract void initViews(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (application == null) { // 得到Application对象 application = (MyApp) getApplication(); } oContext = this;// 把当前的上下文对象赋值给BaseActivity addActivity();// 调用添加方法 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(getLayoutRes()); ButterKnife.bind(this); setupToolbar(); // 初始化View注入 initAD_TouTiao(); setTitle(); initData(); initViews(); } protected void setupToolbar(){ // Toolbar toolbar = findViewById(R.id.toolbar); // setSupportActionBar(toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); } protected abstract void setTitle(); protected abstract void initData() ; @Override protected void onResume() { super.onResume(); // MobclickAgent.onResume(this); } @Override protected void onPause(){ super.onPause(); hideProgress(); // MobclickAgent.onPause(this); } protected void closeCurrentActitivty(){ if( this instanceof BookActivity ) { // return; } finish(); } protected BookListAdapter getBookListAdapter(List mDatas,int itemResourceId){ BookListAdapter mAdapter = new BookListAdapter(this ,mDatas,itemResourceId,new OnItemClickListener() { @Override public void onItemClick(View view, int position) { // showBook("射雕" +position); showBookDetail(mDatas.get(position)); closeCurrentActitivty(); } @Override public void onItemLongClick(View view, int position) { // initDialog(position); // mAdapter.removeData(position); } @Override public void onLinearOutClick(View view, int bookId,int llId) { // Toast.makeText(activity, "book "+ bookId + " clicked", Toast.LENGTH_SHORT).show(); // showBookDetail( mData.get(bookId)); } }); return mAdapter; } void showBookDetail(Novel book) { List acts = application.getActivityList(); for(Activity activity :acts){ if(activity instanceof BookActivity){ activity.finish(); break; } } Intent intent = new Intent(this, BookActivity.class); intent.putExtra(BookActivity.EXTRA_BOOK,book); startActivity(intent); } @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId()==android.R.id.home){ //拦截toolbar 返回事件 finish(); return true; } return super.onOptionsItemSelected(item); } protected List getFakeData(int max ){ List mDatas = new ArrayList(); for (int i = 0; i 390){ width =(int)(height*1.78); if(width > Constants.SCREEN_WIDTH_PIX-50 ){ width= Constants.SCREEN_WIDTH_PIX-50; height =(int)(width/1.78); } }else if(height >150){ width =(int)(height*1.78); }*/ // width =690; //height=150; // height=height > 500 ? 500: height; Log.d(TAG, String.format("loadBannerAd:finial width %s, height %s ",width,height)); AdSlot adSlot = new AdSlot.Builder() .setCodeId(codeId) //广告位id .setSupportDeepLink(true) .setImageAcceptedSize(width, height) .build(); //step5:请求广告,对请求回调的广告作渲染处理 getTTAdNative().loadBannerAd(adSlot, new TTAdNative.BannerAdListener() { @Override public void onError(int code, String message) { // TToast.show(oContext, "load error : " + code + ", " + message); Log.e(TAG, String.format("loadBannerAd:code %s, message %s ", code,message)); bannerContainer.removeAllViews(); // bannerContainer.setVisibility(View.GONE); } @Override public void onBannerAdLoad(final TTBannerAd ad) { if (ad == null ) { return; } View bannerView = ad.getBannerView(); if (bannerView == null) { return; } //设置轮播的时间间隔 间隔在30s到120秒之间的值,不设置默认不轮播 ad.setSlideIntervalTime(30 * 1000); bannerContainer.removeAllViews(); bannerContainer.addView(bannerView); // bannerContainer.setVisibility(View.VISIBLE); // Log.d(TAG, "loadBannerAd: set banner VISIBLE"); // mTTAdNative.loadBannerAd(adSlot,null); //设置广告互动监听回调 ad.setBannerInteractionListener(new TTBannerAd.AdInteractionListener() { @Override public void onAdClicked(View view, int type) { // TToast.show(oContext, "广告被点击"); } @Override public void onAdShow(View view, int type) { // TToast.show(oContext, "广告展示"); } }); //(可选)设置下载类广告的下载监听 bindDownloadListener(ad); //在banner中显示网盟提供的dislike icon,有助于广告投放精准度提升 ad.setShowDislikeIcon(new TTAdDislike.DislikeInteractionCallback() { @Override public void onSelected(int position, String value) { // TToast.show(oContext, "点击 " + value); //用户选择不喜欢原因后,移除广告展示 bannerContainer.removeAllViews(); } @Override public void onCancel() { // TToast.show(oContext, "点击取消 "); } }); //获取网盟dislike dialog,您可以在您应用中本身自定义的dislike icon 按钮中设置 mTTAdDislike.showDislikeDialog(); /*mTTAdDislike = ad.getDislikeDialog(new TTAdDislike.DislikeInteractionCallback() { @Override public void onSelected(int position, String value) { TToast.show(mContext, "点击 " + value); } @Override public void onCancel() { TToast.show(mContext, "点击取消 "); } }); if (mTTAdDislike != null) { XXX.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mTTAdDislike.showDislikeDialog(); } }); } */ } }); } private boolean mHasShowDownloadActive = false; private void bindDownloadListener(TTBannerAd ad) { ad.setDownloadListener(new TTAppDownloadListener() { @Override public void onIdle() { // TToast.show(oContext, "点击图片开始下载", Toast.LENGTH_LONG); } @Override public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) { if (!mHasShowDownloadActive) { mHasShowDownloadActive = true; // TToast.show(oContext, "下载中,点击图片暂停", Toast.LENGTH_LONG); } } @Override public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) { // TToast.show(oContext, "下载暂停,点击图片继续", Toast.LENGTH_LONG); } @Override public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) { // TToast.show(oContext, "下载失败,点击图片重新下载", Toast.LENGTH_LONG); } @Override public void onInstalled(String fileName, String appName) { // TToast.show(oContext, "安装完成,点击图片打开", Toast.LENGTH_LONG); } @Override public void onDownloadFinished(long totalBytes, String fileName, String appName) { // TToast.show(oContext, "点击图片安装", Toast.LENGTH_LONG); } }); } //-------------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) { //step4:创建广告请求参数AdSlot,注意其中的setNativeAdtype方法,具体参数含义参考文档 if (!Constants.SHOWAD || getTTAdNative() == null) { return; } final String key =width+"_"+height; List adCache =null; if( toutiaoNati_Banner_AdCache.containsKey(key)){ adCache = toutiaoNati_Banner_AdCache.get(key); } final boolean isfillAd = adCache!=null &&adCache.size()>1; // final boolean isfillAd =!toutiaoNati_Banner_AdCache.containsKey(key); if(adCache!=null && isfillAd){ Log.d(TAG, "loadNativeBannerAd: set ad from cache, cache Size " + adCache.size()); setNativeBanner(bannerContainer, key); if(adCache.size()>0){ return; } } final AdSlot adSlot = new AdSlot.Builder() .setCodeId(codeId) .setSupportDeepLink(true) .setImageAcceptedSize(width, height) .setNativeAdType(AdSlot.TYPE_BANNER) //请求原生广告时候,请务必调用该方法,设置参数为TYPE_BANNER或TYPE_INTERACTION_AD .setAdCount(3) .build(); //step5:请求广告,对请求回调的广告作渲染处理 getTTAdNative().loadNativeAd(adSlot, new TTAdNative.NativeAdListener() { @Override public void onError(int code, String message) { // TToast.show(oContext, "load error : " + code + ", " + message); Log.e(TAG, "loadBannerAd: " + code + ", " + message); // bannerContainer.setBackgroundResource(R.color.transparent); } @Override public void onNativeAdLoad(List ads) { // bannerContainer.setBackgroundResource(R.color.transparent); List tmp = new ArrayList(); for (TTNativeAd ad : ads) { if (ad != null) { tmp.add(ad); } } if (!toutiaoNati_Banner_AdCache.containsKey(key)) { toutiaoNati_Banner_AdCache.put(key, tmp); } else { toutiaoNati_Banner_AdCache.get(key).addAll(tmp); } boolean isfillAd1 =toutiaoNati_Banner_AdCache.get(key).size()>1; Log.d(TAG, String.format("loadNativeBannerAd: ads count %s ,not null count %s,key %s,will fill ad %s", ads.size(), tmp.size(), key, isfillAd1)); if (isfillAd1) { setNativeBanner(bannerContainer, key); }else{ loadNativeBannerAd(bannerContainer, codeId, 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 )); } /* if (!toutiaoNati_Banner_AdCache.containsKey(key)){ loadNativeBannerAd(bannerContainer, codeId, 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 )); }*/ /* if (ads.get(0) == null || !mShowAd) { return; } View bannerView = LayoutInflater.from(oContext).inflate(R.layout.ad_toutiao_native_ad, bannerContainer, false); if (bannerView == null) { return; } if (mCreativeButton != null) { //防止内存泄漏 mCreativeButton = null; } bannerContainer.removeAllViews(); bannerContainer.addView(bannerView); bannerContainer.setVisibility(View.VISIBLE); if (!Constants.AD_BACKGROUND_TRANSPARENT) bannerContainer.setBackgroundResource(R.color.mintcream); // @color/mintcream Log.d(TAG, "loadBannerAd: set banner VISIBLE,mShowAd " + mShowAd); //绑定原生广告的数据 setAdData(bannerContainer, bannerView, ads.get(0));*/ // mTTAdNative.loadNativeAd(adSlot,null); } }); } void setNativeBanner(FrameLayout bannerContainer,String key ){ if(!toutiaoNati_Banner_AdCache.containsKey(key)){ return; } List adCache = toutiaoNati_Banner_AdCache.get(key); TTNativeAd nativeAd =null ; int i=0; for (TTNativeAd ad :adCache){ if(ad!=null){ nativeAd =ad; break; } i++; } if (nativeAd == null ) { return; } adCache.remove(i); if(adCache.size()>0) { toutiaoNati_Banner_AdCache.put(key, adCache); }else{ toutiaoNati_Banner_AdCache.remove(key); } View bannerView = LayoutInflater.from(oContext).inflate(R.layout.ad_toutiao_native_ad, bannerContainer, false); if (bannerView == null) { return; } if (mCreativeButton != null) { //防止内存泄漏 mCreativeButton = null; } bannerContainer.removeAllViews(); bannerContainer.addView(bannerView); //bannerContainer.setVisibility(View.VISIBLE); if (!Constants.AD_BACKGROUND_TRANSPARENT) bannerContainer.setBackgroundResource(R.color.mintcream); // @color/mintcream // Log.d(TAG, "loadBannerAd: set banner VISIBLE,mShowAd " + mShowAd); //绑定原生广告的数据 setAdData(bannerContainer, bannerView, nativeAd); // mTTAdNative.loadNativeAd(adSlot,null); } @SuppressWarnings("RedundantCast") private void setAdData(FrameLayout bannerContainer,View nativeView, TTNativeAd nativeAd) { ((TextView) nativeView.findViewById(R.id.tv_native_ad_title)).setText(nativeAd.getTitle()); ((TextView) nativeView.findViewById(R.id.tv_native_ad_desc)).setText(nativeAd.getDescription()); ImageView imgDislike = nativeView.findViewById(R.id.img_native_dislike); bindDislikeAction( bannerContainer,nativeAd, imgDislike); if (nativeAd.getImageList() != null && !nativeAd.getImageList().isEmpty()) { TTImage image = nativeAd.getImageList().get(0); if (image != null && image.isValid()) { mAQuery.id(nativeView.findViewById(R.id.iv_native_image)).image(image.getImageUrl()); } } TTImage icon = nativeAd.getIcon(); if (icon != null && icon.isValid()) { ImageOptions options = new ImageOptions(); mAQuery.id((nativeView.findViewById(R.id.iv_native_icon))).image(icon.getImageUrl(), options); } mCreativeButton = (Button) nativeView.findViewById(R.id.btn_native_creative); //可根据广告类型,为交互区域设置不同提示信息 switch (nativeAd.getInteractionType()) { case TTAdConstant.INTERACTION_TYPE_DOWNLOAD: //如果初始化ttAdManager.createAdNative(getApplicationContext())没有传入activity 则需要在此传activity,否则影响使用Dislike逻辑 nativeAd.setActivityForDownloadApp(this); mCreativeButton.setVisibility(View.VISIBLE); nativeAd.setDownloadListener(mDownloadListener); // 注册下载监听器 break; case TTAdConstant.INTERACTION_TYPE_DIAL: mCreativeButton.setVisibility(View.VISIBLE); mCreativeButton.setText("立即拨打"); break; case TTAdConstant.INTERACTION_TYPE_LANDING_PAGE: case TTAdConstant.INTERACTION_TYPE_BROWSER: mCreativeButton.setVisibility(View.VISIBLE); mCreativeButton.setText("查看详情"); break; default: mCreativeButton.setVisibility(View.GONE); // TToast.show(oContext, "交互类型异常"); } //可以被点击的view, 也可以把nativeView放进来意味整个广告区域可被点击 List clickViewList = new ArrayList<>(); clickViewList.add(nativeView); //触发创意广告的view(点击下载或拨打电话) List creativeViewList = new ArrayList<>(); //如果需要点击图文区域也能进行下载或者拨打电话动作,请将图文区域的view传入 //creativeViewList.add(nativeView); creativeViewList.add(mCreativeButton); //重要! 这个涉及到广告计费,必须正确调用。convertView必须使用ViewGroup。 nativeAd.registerViewForInteraction((ViewGroup) nativeView, clickViewList, creativeViewList, imgDislike, new TTNativeAd.AdInteractionListener() { @Override public void onAdClicked(View view, TTNativeAd ad) { if (ad != null) { // TToast.show(oContext, "广告" + ad.getTitle() + "被点击"); } } @Override public void onAdCreativeClick(View view, TTNativeAd ad) { if (ad != null) { // TToast.show(oContext, "广告" + ad.getTitle() + "被创意按钮被点击"); } } @Override public void onAdShow(TTNativeAd ad) { if (ad != null) { // TToast.show(oContext, "广告" + ad.getTitle() + "展示"); } } }); } //接入网盟的dislike 逻辑,有助于提示广告精准投放度 private void bindDislikeAction(FrameLayout bannerContainer,TTNativeAd ad, View dislikeView) { final TTAdDislike ttAdDislike = ad.getDislikeDialog(this); if (ttAdDislike != null) { ttAdDislike.setDislikeInteractionCallback(new TTAdDislike.DislikeInteractionCallback() { @Override public void onSelected(int position, String value) { bannerContainer.removeAllViews(); } @Override public void onCancel() { } }); } dislikeView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ttAdDislike != null) ttAdDislike.showDislikeDialog(); } }); } private final TTAppDownloadListener mDownloadListener = new TTAppDownloadListener() { @Override public void onIdle() { if (mCreativeButton != null) { mCreativeButton.setText("开始下载"); } } @Override public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) { if (mCreativeButton != null) { if (totalBytes <= 0L) { mCreativeButton.setText("下载中 percent: 0"); } else { mCreativeButton.setText("下载中 percent: " + (currBytes * 100 / totalBytes)); } } } @Override public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) { if (mCreativeButton != null) { mCreativeButton.setText("下载暂停 percent: " + (currBytes * 100 / totalBytes)); } } @Override public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) { if (mCreativeButton != null) { mCreativeButton.setText("重新下载"); } } @Override public void onInstalled(String fileName, String appName) { if (mCreativeButton != null) { mCreativeButton.setText("点击打开"); } } @Override public void onDownloadFinished(long totalBytes, String fileName, String appName) { if (mCreativeButton != null) { mCreativeButton.setText("点击安装"); } } }; public TTAdNative getAdNative(){ return mTTAdNative; } void loadInteractionAd(String codeId) { //step4:创建插屏广告请求参数AdSlot,具体参数含义参考文档 if(getAdNative()==null){ return; } AdSlot adSlot = new AdSlot.Builder() .setCodeId(codeId) .setSupportDeepLink(true) .setImageAcceptedSize(600, 600) //根据广告平台选择的尺寸,传入同比例尺寸 .build(); //step5:请求广告,调用插屏广告异步请求接口 getAdNative().loadInteractionAd(adSlot, new TTAdNative.InteractionAdListener() { @Override public void onError(int code, String message) { Log.e(TAG, String.format("loadInteractionAd onError: code %s ,message %s",code,message) ); } @Override public void onInteractionAdLoad(TTInteractionAd ttInteractionAd) { // TToast.show(getApplicationContext(), "type: " + ttInteractionAd.getInteractionType()); ttInteractionAd.setAdInteractionListener(new TTInteractionAd.AdInteractionListener() { @Override public void onAdClicked() { Log.d(TAG, "被点击"); // TToast.show(mContext, "广告被点击"); } @Override public void onAdShow() { Log.d(TAG, "被展示"); // TToast.show(mContext, "广告被展示"); } @Override public void onAdDismiss() { Log.d(TAG, "插屏广告消失"); // TToast.show(mContext, "广告消失"); } }); //如果是下载类型的广告,可以注册下载状态回调监听 if (ttInteractionAd.getInteractionType() == TTAdConstant.INTERACTION_TYPE_DOWNLOAD) { ttInteractionAd.setDownloadListener(new TTAppDownloadListener() { @Override public void onIdle() { Log.d(TAG, "点击开始下载"); // TToast.show(mContext, "点击开始下载"); } @Override public void onDownloadActive(long totalBytes, long currBytes, String fileName, String appName) { Log.d(TAG, "下载中"); // TToast.show(mContext, "下载中"); } @Override public void onDownloadPaused(long totalBytes, long currBytes, String fileName, String appName) { Log.d(TAG, "下载暂停"); // TToast.show(mContext, "下载暂停"); } @Override public void onDownloadFailed(long totalBytes, long currBytes, String fileName, String appName) { Log.d(TAG, "下载失败"); // TToast.show(mContext, "下载失败"); } @Override public void onDownloadFinished(long totalBytes, String fileName, String appName) { Log.d(TAG, "下载完成"); // TToast.show(mContext, "下载完成"); } @Override public void onInstalled(String fileName, String appName) { Log.d(TAG, "安装完成"); // TToast.show(mContext, "安装完成"); } }); } //弹出插屏广告 ttInteractionAd.showInteractionAd(oContext); } }); } /** * 加载 toutiao feed广告 */ public void loadListAd(BookListAdapter adapter, int adCnt, boolean addFooter) { //feed广告请求类型参数 AdSlot adSlot = new AdSlot.Builder() .setCodeId(BuildConfig.AD_SLOT_TOUTIAO_FEEDAD_ID) .setSupportDeepLink(true) .setImageAcceptedSize(228, 150) .setAdCount(adCnt) .build(); //调用feed广告异步请求接口 getAdNative().loadFeedAd(adSlot, new TTAdNative.FeedAdListener() { @Override public void onError(int code, String message) { Log.e(TAG, String.format("loadListAd onError: code %s,msg %s",code,message) ); } @Override public void onFeedAdLoad(List ads) { // myAdapter.changeMoreStatus(2); if (ads == null || ads.isEmpty()) { Log.e(TAG, "on FeedAdLoaded: ad is null!" ); return; } if(addFooter) { adapter.AddFooterItem(ads); }else{ adapter.AddHeaderItem(ads); } } }); } }