├── .gitignore ├── ADSuyiDemo.jks ├── AdapterErrorCode ├── ADSuyiErrorCode.md ├── BaiduAdapterErrorCode.md ├── GdtAdapterErrorCode.md ├── IflyAdapterErrorCode.md ├── KuaiShouAdapterErrorCode.md ├── OneWayAdapterErrorCode.md └── ToutiaoAdapterErrorCode.md ├── Android-SuyiSDK激励视频服务端验证使用说明.md ├── LICENSE ├── README-ADSuyiNetworkRequestInfo.md ├── README.md ├── app ├── build.gradle ├── gromore-proguard-rules.pro ├── libs │ └── oaid_sdk_1.0.25.aar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── supplierconfig.json │ ├── java │ └── cn │ │ └── admobiletop │ │ └── adsuyidemo │ │ ├── ADSuyiApplication.java │ │ ├── activity │ │ ├── MainActivity.java │ │ ├── ad │ │ │ ├── ADSuyiInitAndLoadSplashAdActivity.java │ │ │ ├── BannerAdActivity.java │ │ │ ├── DrawVodActivity.java │ │ │ ├── FullScreenVodAdActivity.java │ │ │ ├── PrivacyActivity.java │ │ │ ├── RewardVodAdActivity.java │ │ │ ├── feed │ │ │ │ ├── NativeExpressActivity.java │ │ │ │ ├── NativeExpressListActivity.java │ │ │ │ ├── NativeSelfRenderActivity.java │ │ │ │ └── NativeSelfRenderListActivity.java │ │ │ ├── interstitial │ │ │ │ └── InterstitialAdActivity.java │ │ │ └── splash │ │ │ │ ├── SplashAdActivity.java │ │ │ │ ├── SplashAdLoadShowSeparationActivity.java │ │ │ │ └── SplashAdSettingActivity.java │ │ ├── base │ │ │ └── BaseAdActivity.java │ │ ├── other │ │ │ └── NormalWebActivity.java │ │ └── setting │ │ │ ├── PositionSettingActivity.java │ │ │ └── SettingActivity.java │ │ ├── adapter │ │ ├── BaseNativeAdAdapter.java │ │ ├── ContentAllianceAdAdapter.java │ │ ├── DrawVodAdAdapter.java │ │ ├── NativeAdAdapter.java │ │ ├── NativeExpressAdAdapter.java │ │ ├── NativeFeedAdAdapter.java │ │ ├── SettingAdapter.java │ │ └── holder │ │ │ ├── NativeExpressAdViewHolder.java │ │ │ ├── NativeFeedAdViewHolder.java │ │ │ └── NormalDataViewHolder.java │ │ ├── constant │ │ └── ADSuyiDemoConstant.java │ │ ├── entity │ │ ├── AdSettingData.java │ │ ├── ContentAllianceAdSampleData.java │ │ └── DrawVodAdSampleData.java │ │ ├── fragment │ │ ├── BannerAdFragment.java │ │ ├── BaseFragment.java │ │ ├── DrawVodAdFragment.java │ │ ├── NativeAdFragment.java │ │ ├── OtherFragment.java │ │ └── TestFragment.java │ │ ├── util │ │ ├── ADSuyiClassFindUtils.java │ │ ├── ADSuyiViewFindUtils.java │ │ ├── LoadAdUtil.java │ │ ├── SPUtil.java │ │ ├── StringUtil.java │ │ └── UIUtils.java │ │ └── widget │ │ ├── AdMobileDlExpressAdDialog.java │ │ ├── AdMobileDlFeedAdDialog.java │ │ ├── MySmartRefreshLayout.java │ │ ├── PrivacyPolicyDialog.java │ │ └── ViewPagerLayoutManager.java │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable-xxhdpi │ ├── icon_close.png │ └── icon_setting.png │ ├── drawable │ ├── ic_chevron_right_black_24dp.xml │ ├── ic_launcher_background.xml │ ├── ic_settings_black_24dp.xml │ ├── shape_background_button_selector.xml │ ├── shape_background_circle.xml │ ├── shape_black_000000_radius15.xml │ ├── shape_color_primary_dark_stroke.xml │ ├── shape_f2f2f2_4dp.xml │ ├── shape_fff2e0_4dp.xml │ ├── shape_splash.xml │ └── shape_white_ffffff_radius50.xml │ ├── layout │ ├── activity_adsuyi_init_and_load_splash_ad.xml │ ├── activity_banner.xml │ ├── activity_content_alliance_ad.xml │ ├── activity_dl_module.xml │ ├── activity_dl_normal.xml │ ├── activity_dl_switch.xml │ ├── activity_draw_vod.xml │ ├── activity_feed_native.xml │ ├── activity_feed_native_express_ad.xml │ ├── activity_feed_native_interstitial_ad.xml │ ├── activity_feed_native_recyclerview_ad.xml │ ├── activity_feed_native_self_render_ad.xml │ ├── activity_feed_native_splash_ad.xml │ ├── activity_fragment.xml │ ├── activity_interstitial_ad.xml │ ├── activity_main.xml │ ├── activity_native_ad.xml │ ├── activity_normal_web.xml │ ├── activity_position_setting.xml │ ├── activity_privacy.xml │ ├── activity_reward_ad_switch.xml │ ├── activity_reward_vod.xml │ ├── activity_setting.xml │ ├── activity_splash_ad.xml │ ├── activity_splash_ad_load_show_separation.xml │ ├── activity_splash_setting.xml │ ├── dialog_admobile_dl_ad.xml │ ├── dialog_admobile_dl_ad2.xml │ ├── dialog_feed_native_adapter_interstitial_ad.xml │ ├── dialog_feed_native_adapter_interstitial_ad2.xml │ ├── dialog_privacy_policy.xml │ ├── fragment_other_page.xml │ ├── fragment_test_page.xml │ ├── item_draw_vod_ad.xml │ ├── item_draw_vod_ad_normal_data.xml │ ├── item_native_ad_express_ad.xml │ ├── item_native_ad_native_ad.xml │ ├── item_native_ad_normal_data.xml │ ├── item_setting_ad.xml │ └── item_setting_title.xml │ ├── menu │ └── menu_toolbar.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── admobile_icon.png │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── admobile_icon.png │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── admobile_icon.png │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── admobile_icon.png │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── admobile_icon.png │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── adsuyi_network_security_config.xml ├── build.gradle ├── gradle.properties └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | /build 6 | /local.properties 7 | /captures 8 | .externalNativeBuild 9 | output.json 10 | *.apk 11 | gradlew 12 | gradlew.bat 13 | gradle-wrapper.jar 14 | gradle-wrapper.properties 15 | app/build -------------------------------------------------------------------------------- /ADSuyiDemo.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ADSuyi/ADSuyiSdkDemo-Android/8200f11ae36b6ec66fcb5f93b3e5571b0dd6ed7b/ADSuyiDemo.jks -------------------------------------------------------------------------------- /AdapterErrorCode/ADSuyiErrorCode.md: -------------------------------------------------------------------------------- 1 | ## ADSuyi错误码 2 | 3 | | 错误码 | 信息描述 | 4 | | ------- | --------------------------------------------------- | 5 | | 10001 | AppId不能为空 | 6 | | 10004 | 没有初始化或者初始化没有成功, 可能没有导入该平台需要的SDK或者混淆配置不正确 | 7 | | 10006 | 初始化接口数据为空 | 8 | | 10007 | 初始化接口KEY为空 | 9 | | 10008 | 初始化接口数据解密失败 | 10 | | 10009 | 初始化接口数据解析失败 | 11 | | 10010 | 平台AdapterSdk支持的ADJgSdk版本为空 | 12 | | 10011 | 平台AdapterSdk不支持当前版本的ADJgSdk | 13 | | 10012 | 没有调用初始化方法 | 14 | | 10013 | 请求的初始化数据为空 | 15 | | 20000 | 必须在主线程获取广告 | 16 | | 20001 | 广告容器不能为空 | 17 | | 20002 | 广告对象已被释放或者传入的Activity或Fragment为空 | 18 | | 20100 | 获取广告超时 | 19 | | 20101 | 所有三方广告位均没有获取到广告,请结合descList排查原因 | 20 | | 20102 | 获取广告时发生未知异常 | 21 | | 20103 | PosId不能为空 | 22 | | 20104 | 初始化数据为空,可能是没有本地缓存的初始化数据并且初始接口请求失败 | 23 | | 20105 | AppId和包名不匹配 | 24 | | 20106 | 没有找到当前PosId的配置信息,主要有以下三种情况 : | 25 | | | 1、初始化失败,本地没有初始化配置信息并且远程拉取初始化配置失败了,请检查网络或AppId是否正确; | 26 | | | 2、传入的PosId有误; | 27 | | | 3、如果前两条均正常,请后台检查该PosId是否配置并开启了三方平台的广告位信息 | | 28 | | 20107 | 平台的广告位信息为空 | 29 | | 20108 | 该PosId对应的广告类型不匹配 30 | | 20109 | 暂不支持当前广告类型 | 31 | | 20110 | 返回的广告数据为空 | 32 | | 20112 | 已达到展示上限 | 33 | | 20113 | 初始化配置信息拉取失败并需要阻止广告加载 | 34 | | 20114 | 打底广告信息不能为空 | 35 | | 20115 | 所有三方竞价广告位均没有获取到广告 | 36 | | 20118 | 竞价广告C2S模式加载器初始化异常 | 37 | | 20121 | 瀑布流预加载模式加载器初始化异常 | 38 | | 20122 | 广告源获取广告超时 | 39 | | 20123 | 广告还未准备好,请在onAdReceive回调后再展示广告 | 40 | | 20124 | 开屏广告出现未知异常 | 41 | | 20125 | 开屏广告出现未知异常 | 42 | | 20126 | 开屏广告出现未知异常 | 43 | | 20130 | 开屏父布局为空或不可见 | 44 | | 20131 | 开屏广告错误信息为空 | 45 | | 20132 | 开屏广告对象为空 | 46 | | 20133 | 开屏广告展示超时 | 47 | | 20134 | 本轮并发请求失败 | 48 | 49 | -------------------------------------------------------------------------------- /AdapterErrorCode/BaiduAdapterErrorCode.md: -------------------------------------------------------------------------------- 1 | ## 百度错误码 2 | 3 | | 错误码 | 信息描述 | 4 | | ------- | --------------------------------------------------- | 5 | | 0 | 无广告返回 | 6 | | 0103011 | 应用 ID 信息错误,MSSP 未收录 | 7 | | 0103060 | 应用包名信息错误,请保证注册包 名和实际请求包名一致 | 8 | | 0107003 | 广告位 ID 与 APPID 不匹配 | 9 | | 1020001 | 网络连接失败 | 10 | | 1040003 | 请求超时 | 11 | | 1040001 | 请求时使用了错误的参数,比如使 用错误的广告位 ID | 12 | | 3030002 | 缓存物料失败 | 13 | | 3040001 | 广告展现标准不达标 | 14 | 15 | -------------------------------------------------------------------------------- /AdapterErrorCode/IflyAdapterErrorCode.md: -------------------------------------------------------------------------------- 1 | ## 讯飞错误码 2 | 3 | | 错 误 码 | 描 述 | 4 | | -------- | ------------------------------ | 5 | | 70200 | 广告请求成功 | 6 | | 70204 | 请求成功,但是无广告内容 | 7 | | 70400 | 无效的广告位ID | 8 | | 70403 | 当日广告请求次数达到上限 | 9 | | 70500 | 服务错误 | 10 | | 71001 | 未知错误 | 11 | | 71002 | 无效的广告请求(请求频率过快) | 12 | | 71003 | 网络错误 | 13 | | 71004 | Permission未设置 | 14 | | 71005 | Appid为空 | 15 | | 71006 | 广告落地页加载超时 | 16 | | 71007 | 广告落地页加载异常 | 17 | | 71008 | 视频缓存异常 | 18 | | 71009 | 广告页面销毁异常 | -------------------------------------------------------------------------------- /AdapterErrorCode/KuaiShouAdapterErrorCode.md: -------------------------------------------------------------------------------- 1 | ## 快手错误码 2 | 3 | | 错误码 | 说明 | 4 | | :----- | :----------------------------------- | 5 | | 40001 | 没有⽹络 | 6 | | 40000 | 数据解析失败 | 7 | | 40003 | ⼴告数据为空 | 8 | | 40004 | 缓存视频资源失 | 9 | | 100001 | 参数有误 | 10 | | 100002 | 服务器错误 | 11 | | 100003 | 不允许的操作 | 12 | | 100004 | 服务不可⽤ | 13 | | 310001 | appId未注册 | 14 | | 310002 | appId⽆效 | 15 | | 310003 | appId已封禁 | 16 | | 310004 | packageName与注册的packageName不⼀致 | 17 | | 310005 | 操作系统与注册的不⼀致 | 18 | | 320002 | appId对应账号⽆效 | 19 | | 320003 | appId对应账号已封禁 | 20 | | 330001 | posId未注册 | 21 | | 330002 | posId⽆效 | 22 | | 330003 | posId已封禁 | 23 | | 330004 | posid与注册的appId信息不⼀致 | -------------------------------------------------------------------------------- /AdapterErrorCode/OneWayAdapterErrorCode.md: -------------------------------------------------------------------------------- 1 | ## 万维错误码 2 | 3 | | Error | Message | 说明 | 4 | | :--------------------- | :--------------------- | :----------------------------------------------------------- | 5 | | NOT_INITIALIZED | SDK 尚未初始化 | 请开发者在调用 SDK 相关接口时务必先进行 SDK 初始化 | 6 | | INITIALIZE_FAILED | 初始化失败 | 请根据文档检查相关配置是否正确 | 7 | | INVALID_ARGUMENT | 参数错误 | 检查调用初始化接口或播放接口时传入的参数以及参数格式是否正确 | 8 | | VIDEO_PLAYER_ERROR | 播放失败 | 请检查 Manifest 配置,请检查 SDK 是否能初始化成功 | 9 | | INIT_SANITY_CHECK_FAIL | 参数错误 | 参数错误 | 10 | | AD_BLOCKER_DETECTED | 广告插件拦截 | 请检查设备是否存在广告拦截插件阻止了 SDK 初始化 | 11 | | FILE_IO_ERROR | SDK 无法读取或写入文件 | 请查看文件读写权限 | 12 | | DEVICE_ID_ERROR | 未知的设备标识符 | 请确定设备是否合法 | 13 | | SHOW_ERROR | 播放广告错误 | 在没有成功请求到广告数据(比如未初始化或初始化失败)时就调用广告播放接口 则会通知此错误信息 | 14 | | INTERNAL_ERROR | SDK 内部发生异常 | 请联系我们 | 15 | | CAMPAIGN_NO_FILL | 请求广告失败 | 当前设备和 APP 所在区域等综合情况未符合我们的广告条件(注:此情况下 SDK 会每隔十分钟重试请求广告) | -------------------------------------------------------------------------------- /AdapterErrorCode/ToutiaoAdapterErrorCode.md: -------------------------------------------------------------------------------- 1 | ## 穿山甲错误码 2 | 3 | | 错误码 | 说明 | 4 | | :------ | :----------------------------------------------------------- | 5 | | 20000 | 成功 | 6 | | 40000 | http content type错误 | 7 | | 40001 | http request pb错误 | 8 | | 40002 | source_type=‘app’, 请求app不能为空 | 9 | | 40003 | source_type=‘wap’, 请求wap不能为空 | 10 | | 40004 | 广告位不能为空 | 11 | | 40005 | 广告位尺寸不能为空 | 12 | | 40006 | 广告位ID不合法 | 13 | | 40007 | 广告数量错误 | 14 | | 40008 | 图片尺寸错误 | 15 | | 40009 | 媒体ID不合法 | 16 | | 40010 | 媒体类型不合法 | 17 | | 40011 | 广告类型不合法 | 18 | | 40013 | 代码位id小于9亿,但是adType不是开屏 | 19 | | 40014 | redirect参数不正确 | 20 | | 40015 | 媒体整改超过期限,请求非法 | 21 | | 40016 | slot_id 与 app_id对应关系不合法 | 22 | | 40017 | 媒体接入类型不合法 API/SDK | 23 | | 40018 | 媒体包名与录入不一致 | 24 | | 40019 | 媒体配置adtype和请求不一致 | 25 | | 40020 | 开发注册新上线广告位超出日请求量限制 | 26 | | 40021 | apk签名sha1值与媒体平台录入不一致 | 27 | | 40022 | 媒体请求素材是否原生与媒体平台录入不一致 | 28 | | 40023 | os字段填的不对 | 29 | | 40024 | sdk 版本过低不返回广告 | 30 | | 40025 | 渲染异常,分为两种情况: 1.Android版本,媒体使用了非该应用所属账号下的SDK版本导致,请媒体到该代码位所属账号下工具-文档下载展示的SDK版本去进行接入。或者so库冲突,请对照文档进行调整。 2.iOS版本,媒体使用2100之前的版本可能渲染异常,请媒体更新到最新版本接入即可解决该问题。 | 31 | | 50001 | 服务器错误 | 32 | | 60001 | show event处理错误 | 33 | | 60002 | click event处理错误 | 34 | | 60007 | 激励视频验证服务器异常或处理失败 | 35 | | isValid | 校验结果 | 36 | | -1 | 数据解析失败 | 37 | | -2 | 网络错误 | 38 | | -3 | 解析数据没有ad | 39 | | -4 | 返回数据缺少必要字段 | 40 | | -5 | bannerAd加载图片失败 | 41 | | -6 | 插屏广告图片加载失败 | 42 | | -7 | 开屏广告图片加载失败 | 43 | | -8 | 频繁请求 | 44 | | -9 | 请求实体为空 | 45 | | -10 | 缓存解析失败 | 46 | | -11 | 缓存过期 | 47 | | -12 | 缓存中没有开屏广告 | 48 | | 101 | 渲染结果数据解析失败 | 49 | | 102 | 主模板无效 | 50 | | 103 | 模板差量无效 | 51 | | 104 | 物料数据异常 | 52 | | 105 | 模板数据解析异常 | 53 | | 106 | 渲染异常 | 54 | | 107 | 渲染超时未回调 | 55 | | 108 | 模板广告加载超时无返回 | 56 | | 109 | 模板加载失败 | 57 | | 113 | 原生动态化1.0 JS 解析出错 | 58 | | 117 | 原生动态化1.0 JS 解析超时 | 59 | | 118 | 原生动态化1.0 JS 渲染错误 | 60 | | 123 | 原生动态化2.0 SDK解析出错 | 61 | | 127 | 原生动态化2.0 SDK解析超时 | 62 | | 128 | 原生动态化2.0 SDK渲染出错 | 63 | | 601 | 链接建立失败 | 64 | | 602 | 链接建立超时 | 65 | | 603 | 广告返回异常 | 66 | | 604 | 广告解析失败 | 67 | | 605 | 广告解析失败 | 68 | | 606 | 广告解析异常 | 69 | | 607 | 广告读写失败 | 70 | | 608 | 广告读写失败 | 71 | | 609 | 广告下载失败 | 72 | | 610 | 广告下载异常 | 73 | | 611 | 广告请求被取消 | 74 | | 612 | 图片加载异常 | 75 | | 40026 | 使用海外ip请求国内服务器导致,请确认使用的是国内ip请求广告。 | 76 | | 40028 | ios老设备(涉及设备 iPad 4G/iPad 3G/iPhone 5/iPhone 5C/iPad Mini 1G/iPad 2G/iPhone 4S)被屏蔽,会不返回广告。在2310版本后放开了限制,媒体可以更新到2310或者之后的版本。 | 77 | | 40029 | 两种情况: 1. SDK版本低:您使用的sdk版本不得低于2.5.0.0,麻烦升级到平台最新版本sdk。 2. 接口使用错误:创建的代码位类型是模板渲染/非模板渲染,但是请求方法是非模板渲染/模板渲染的方法。解决办法:使用模板渲染的方法去请求模板渲染类型或者使用非模板渲染的方法去请求非模板类型的广告,如果代码位在平台上是模板渲染,可以参考文档中个性化模板XX广告的部分,demo中参考带有express部分的代码。如果代码位不是模板渲染,则不要调用含有express字样的接口。 参考文档:https://partner.oceanengine.com/doc?id=5de4cc6d78c8690012a90aa5 | -------------------------------------------------------------------------------- /README-ADSuyiNetworkRequestInfo.md: -------------------------------------------------------------------------------- 1 | #### 开屏打底对象 API 2 | 3 | /** 4 | * 加载开屏保底广告,可选的 5 | * 功能说明:App在首次启动时,需要先请求获取广告位配置文件后,然后再去请求开屏广告,也就是首次加载开屏广告时需要两次串行网络请求,因此很容易因超时导致开屏广告展示失败。 6 | * 解决方案:为避免开屏超时问题,开放此设置给开发者,开发者可以根据实际需求选择一家广告平台,通过API接口将必需参数传递给Suyi聚合SDK。(该设置只能指定一家广告平台,并且首次启动时只会请求该平台的广告,但App首次开屏广告将不受ADmobile后台控制,包括下载提示,广告位关闭。) 7 | * 该设置仅会在首次加载开屏广告时,SDK会使用开发者传入的参数进行广告请求,同时获取后台配置文件的广告配置信息缓存到本地(首次请求广告平台广告和获取配置信息时并发进行),后续的开屏广告将按照缓存缓存的后台广告位配置顺序进行开屏广告请求。 8 | * 支持穿山甲、优量汇、快手、百度 9 | */ 10 | 11 | **GdtSplashAdRequestInfo** 12 | 13 | cn.admobiletop.adsuyi.ad.api.GdtSplashAdRequestInfo 14 | 15 | | 方法名 | 介绍 | 16 | | ------------ | ---- | 17 | | GdtSplashAdRequestInfo(String appId, String networkSlotId, String networkAdPosListID, @DownloadTipParam int downloadTip) | 优量汇打底构造方法。参数说明:appId(渠道AppId)、networkSlotId(开屏广告源ID)、networkAdPosListID(Suyi开屏广告源AdPosList ID)、downloadTip(下载提示模式))。| 18 | 19 | **TTSplashAdRequestInfo** 20 | 21 | cn.admobiletop.adsuyi.ad.api.TTSplashAdRequestInfo 22 | 23 | | 方法名 | 介绍 | 24 | | ------------ | ---- | 25 | | TTSplashAdRequestInfo(String appId, String networkSlotId, String networkAdPosListID, @DownloadTipParam int downloadTip, @RenderTypeParam int renderType) | 优量汇打底构造方法。参数说明:appId(渠道AppId)、networkSlotId(开屏广告源ID)、networkAdPosListID(Suyi开屏广告源AdPosList ID)、downloadTip(下载提示模式))renderType(渲染方式)。| 26 | 27 | **BaiduSplashAdRequestInfo** 28 | 29 | cn.admobiletop.adsuyi.ad.api.BaiduSplashAdRequestInfo 30 | 31 | | 方法名 | 介绍 | 32 | | ------------ | ---- | 33 | | BaiduSplashAdRequestInfo(String appId, String networkSlotId, String networkAdPosListID, @DownloadTipParam int downloadTip) | 优量汇打底构造方法。参数说明:appId(渠道AppId)、networkSlotId(开屏广告源ID)、networkAdPosListID(Suyi开屏广告源AdPosList ID)、downloadTip(下载提示模式))。| 34 | 35 | **KsSplashAdRequestInfo** 36 | 37 | cn.admobiletop.adsuyi.ad.api.KsSplashAdRequestInfo 38 | 39 | | 方法名 | 介绍 | 40 | | ------------ | ---- | 41 | | KsSplashAdRequestInfo(String appId, String networkSlotId, String networkAdPosListID, @DownloadTipParam int downloadTip) | 优量汇打底构造方法。参数说明:appId(渠道AppId)、networkSlotId(开屏广告源ID)、networkAdPosListID(Suyi开屏广告源AdPosList ID)、downloadTip(下载提示模式))。| -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 31 5 | defaultConfig { 6 | applicationId "cn.admobiletop.adsuyidemo" 7 | minSdkVersion 21 8 | targetSdkVersion 31 9 | versionCode 202505131 10 | versionName "202505131" 11 | multiDexEnabled true 12 | ndk { 13 | // 设置支持的SO库架构,暂不支持x86 14 | abiFilters 'armeabi-v7a', 'arm64-v8a'// 'armeabi' 15 | } 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled true 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | debug { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | 33 | signingConfigs { 34 | release { 35 | keyAlias 'adsuyidemo' 36 | keyPassword '123123' 37 | storeFile file('..//ADSuyiDemo.jks') 38 | storePassword '123123' 39 | } 40 | debug { 41 | keyAlias 'adsuyidemo' 42 | keyPassword '123123' 43 | storeFile file('..//ADSuyiDemo.jks') 44 | storePassword '123123' 45 | } 46 | } 47 | 48 | repositories { 49 | 50 | flatDir { 51 | dirs 'libs' 52 | } 53 | } 54 | 55 | android.applicationVariants.all { 56 | variant -> 57 | variant.outputs.all { 58 | //这里修改apk文件名 59 | outputFileName = "ADSuyiSdkDemo-V${variant.versionName}.apk" 60 | } 61 | } 62 | } 63 | 64 | dependencies { 65 | implementation fileTree(dir: 'libs', include: ['*.jar']) 66 | implementation 'androidx.multidex:multidex:2.0.0' 67 | 68 | // 以下都是用于demo演示加入的三方依赖 69 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 70 | implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.2' 71 | implementation 'com.github.bumptech.glide:glide:4.9.0' 72 | // 以上都是用于demo演示加入的三方依赖 73 | 74 | // support支持库,如果是AndroidX请使用对应的支持库 75 | implementation 'androidx.appcompat:appcompat:1.0.0' 76 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 77 | implementation 'com.google.android.material:material:1.0.0' 78 | 79 | // ADSuyiSdk核心库必须导入 80 | implementation 'cn.admobiletop.adsuyi.ad:core:4.0.0.05061' 81 | 82 | // 天目适配器,必选 83 | implementation 'cn.admobiletop.adsuyi.ad.adapter:tianmu:3.0.0.05151' 84 | 85 | // 优量汇(广点通)适配器,可选 86 | implementation 'cn.admobiletop.adsuyi.ad.adapter:gdt:4.640.1510.05133' 87 | 88 | // // 穿山甲(头条)适配器,可选 89 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:toutiao:6.8.1.7.05132' 90 | // 91 | // // 百度适配器,可选。仅支持AndroidX版本 92 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:baidu-androidx:9.391.05141' 93 | // 94 | // // 快手适配器,可选 95 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:ksadbase:3.3.76.5.05141' 96 | // 97 | // // 华为适配器,可选 98 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:hwpps:13.4.76.300.01031' 99 | // 100 | // // 京媒适配器,可选。仅支持AndroidX版本 101 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:jadyun-androidx:2.6.28.05141' 102 | // 103 | // // 爱奇艺适配器,可选 104 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:iqy:1.15.100.53.05141' 105 | // 106 | // // gromoreAdapterSdk,可选的。如使用gromore的其他渠道,请联系开发者。 107 | // // gromore已与穿山甲合并,此处无需重复导入穿山甲。 108 | // implementation 'cn.admobiletop.adsuyi.ad.adapter:gromore-without:6.6.0.7.01084' 109 | // implementation "com.pangle.cn:mediation-gdt-adapter:4.575.1445.1" //广点通 adapter 110 | // // 有gromore其他渠道需求,请联系开发者。 111 | 112 | } 113 | -------------------------------------------------------------------------------- /app/gromore-proguard-rules.pro: -------------------------------------------------------------------------------- 1 | ## pangle 穿山甲原有的 2 | -keepclassmembers class * { 3 | *** getContext(...); 4 | *** getActivity(...); 5 | *** getResources(...); 6 | *** startActivity(...); 7 | *** startActivityForResult(...); 8 | *** registerReceiver(...); 9 | *** unregisterReceiver(...); 10 | *** query(...); 11 | *** getType(...); 12 | *** insert(...); 13 | *** delete(...); 14 | *** update(...); 15 | *** call(...); 16 | *** setResult(...); 17 | *** startService(...); 18 | *** stopService(...); 19 | *** bindService(...); 20 | *** unbindService(...); 21 | *** requestPermissions(...); 22 | *** getIdentifier(...); 23 | } 24 | 25 | -keep class com.bytedance.pangle.** {*;} 26 | -keep class com.bytedance.sdk.openadsdk.** { *; } 27 | -keep class com.bytedance.frameworks.** { *; } 28 | 29 | -keep class ms.bd.c.Pgl.**{*;} 30 | -keep class com.bytedance.mobsec.metasec.ml.**{*;} 31 | 32 | -keep class com.ss.android.**{*;} 33 | 34 | -keep class com.bytedance.embedapplog.** {*;} 35 | -keep class com.bytedance.embed_dr.** {*;} 36 | 37 | -keep class com.bykv.vk.** {*;} 38 | 39 | 40 | //聚合混淆 41 | -keep class bykvm*.** 42 | -keep class com.bytedance.msdk.adapter.**{ public *; } 43 | -keep class com.bytedance.msdk.api.** { 44 | public *; 45 | } 46 | -keep class com.bytedance.msdk.base.TTBaseAd{*;} 47 | -keep class com.bytedance.msdk.adapter.TTAbsAdLoaderAdapter{ 48 | public *; 49 | protected ; 50 | } 51 | 52 | # baidu sdk 不接入baidu sdk可以不引入 53 | -ignorewarnings 54 | -dontwarn com.baidu.mobads.sdk.api.** 55 | -keepclassmembers class * extends android.app.Activity { 56 | public void *(android.view.View); 57 | } 58 | 59 | -keepclassmembers enum * { 60 | public static **[] values(); 61 | public static ** valueOf(java.lang.String); 62 | } 63 | 64 | -keep class com.baidu.mobads.** { *; } 65 | -keep class com.style.widget.** {*;} 66 | -keep class com.component.** {*;} 67 | -keep class com.baidu.ad.magic.flute.** {*;} 68 | -keep class com.baidu.mobstat.forbes.** {*;} 69 | 70 | 71 | # Admob 不接入admob sdk可以不引入 72 | -keep class com.google.android.gms.ads.MobileAds { 73 | public *; 74 | } 75 | 76 | #sigmob 不接入sigmob sdk可以不引入 77 | -dontwarn android.support.v4.** 78 | -keep class android.support.v4.** { *; } 79 | -keep interface android.support.v4.** { *; } 80 | -keep public class * extends android.support.v4.** 81 | 82 | -keep class sun.misc.Unsafe { *; } 83 | -dontwarn com.sigmob.** 84 | -keep class com.sigmob.**.**{*;} 85 | 86 | #oaid 不同的版本混淆代码不太一致,你注意你接入的oaid版本 ,不接入oaid可以不添加 87 | -dontwarn com.bun.** 88 | -keep class com.bun.** {*;} 89 | -keep class a.**{*;} 90 | -keep class XI.CA.XI.**{*;} 91 | -keep class XI.K0.XI.**{*;} 92 | -keep class XI.XI.K0.**{*;} 93 | -keep class XI.vs.K0.**{*;} 94 | -keep class XI.xo.XI.XI.**{*;} 95 | -keep class com.asus.msa.SupplementaryDID.**{*;} 96 | -keep class com.asus.msa.sdid.**{*;} 97 | -keep class com.huawei.hms.ads.identifier.**{*;} 98 | -keep class com.samsung.android.deviceidservice.**{*;} 99 | -keep class com.zui.opendeviceidlibrary.**{*;} 100 | -keep class org.json.**{*;} 101 | -keep public class com.netease.nis.sdkwrapper.Utils {public ;} 102 | 103 | 104 | #klevin 游可赢 105 | -keep class com.tencent.tgpa.**{*;} 106 | -keep class com.tencent.klevin.**{*;} 107 | 108 | 109 | #Mintegral 不接入Mintegral sdk,可以不引入 110 | -keepattributes Signature 111 | -keepattributes *Annotation* 112 | -keep class com.mbridge.** {*; } 113 | -keep interface com.mbridge.** {*; } 114 | -keep class android.support.v4.** { *; } 115 | -dontwarn com.mbridge.** 116 | -keep class **.R$* { public static final int mbridge*; } -------------------------------------------------------------------------------- /app/libs/oaid_sdk_1.0.25.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ADSuyi/ADSuyiSdkDemo-Android/8200f11ae36b6ec66fcb5f93b3e5571b0dd6ed7b/app/libs/oaid_sdk_1.0.25.aar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -ignorewarnings 2 | # v4、v7(如果是Support支持库需添加) 3 | -keep class android.support.v4.**{public *;} 4 | -keep class android.support.v7.**{public *;} 5 | 6 | # AndroidX (如果是AndroidX支持库需添加) 7 | -keep class com.google.android.material.** {*;} 8 | -keep class androidx.** {*;} 9 | -keep class * extends androidx.** 10 | 11 | # 资源文件混淆配置 12 | -keep class **.R$* { *; } 13 | -keep public class **.R$*{ 14 | public static final int *; 15 | } 16 | -keepclassmembers class **.R$* { 17 | public static ; 18 | } 19 | 20 | # ADSuyiSdk混淆 21 | -dontwarn cn.admobiletop.adsuyi.** 22 | -keep class adsuyi.com.** { *; } 23 | -keep interface adsuyi.com.** { *; } 24 | -dontwarn org.apache.commons.** 25 | -keep class cn.admobiletop.adsuyi.**{public *;} 26 | -keep class cn.admobiletop.materialutil.**{public *;} 27 | -keep class com.android.**{*;} 28 | -keep class com.ciba.**{ *; } 29 | -keep class org.apache.**{*;} 30 | 31 | # okhttp 32 | -dontwarn okhttp3.** 33 | -keep class okhttp3.**{*;} 34 | 35 | # OAID混淆 36 | -keep class com.bun.miitmdid.core.** {*;} 37 | -keep class XI.CA.XI.**{*;} 38 | -keep class XI.K0.XI.**{*;} 39 | -keep class XI.XI.K0.**{*;} 40 | -keep class XI.vs.K0.**{*;} 41 | -keep class XI.xo.XI.XI.**{*;} 42 | -keep class com.asus.msa.SupplementaryDID.**{*;} 43 | -keep class com.asus.msa.sdid.**{*;} 44 | -keep class com.bun.lib.**{*;} 45 | -keep class com.bun.miitmdid.**{*;} 46 | -keep class com.huawei.hms.ads.identifier.**{*;} 47 | -keep class com.samsung.android.deviceidservice.**{*;} 48 | -keep class com.zui.opendeviceidlibrary.**{*;} 49 | -keep class org.json.**{*;} 50 | -keep public class com.netease.nis.sdkwrapper.Utils {public ;} 51 | 52 | # admobile广告平台混淆 53 | -keep class admsdk.library.**{*;} 54 | 55 | # 优量汇广告平台混淆 56 | -keep class com.qq.e.** {public protected *;} 57 | -keep class MTT.ThirdAppInfoNew {*;} 58 | -keep class com.tencent.** {*;} 59 | 60 | # 如果使用了tbs版本的sdk需要进行以下配置 61 | -keep class com.tencent.smtt.** { *; } 62 | -dontwarn dalvik.** 63 | -dontwarn com.tencent.smtt.** 64 | 65 | # 百度广告SDK混淆 66 | -keepclassmembers class * extends android.app.Activity { public void *(android.view.View);} 67 | -keepclassmembers enum * { 68 | public static **[] values(); 69 | public static ** valueOf(java.lang.String); 70 | } 71 | -keep class com.baidu.mobads.** { *; } 72 | -keep class com.baidu.mobad.** { *; } 73 | 74 | # 穿山甲(头条)广告平台混淆 75 | -keep class com.bytedance.sdk.openadsdk.** { *; } 76 | -keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;} 77 | -keep class com.pgl.sys.ces.* {*;} 78 | -keep class com.bytedance.embed_dr.** {*;} 79 | -keep class com.bytedance.embedapplog.** {*;} 80 | -keep class com.bytedance.frameworks.** { *; } 81 | -keep class ms.bd.c.Pgl.**{*;} 82 | -keep class com.bytedance.mobsec.metasec.ml.**{*;} 83 | -keep class com.ss.android.**{*;} 84 | -keep class com.bykv.vk.** {*;} 85 | 86 | # imobi广告平台混淆 87 | -dontwarn com.inmobi.** 88 | -dontwarn com.squareup.picasso.** 89 | -dontwarn com.squareup.okhttp.** 90 | -dontwarn com.bun.** 91 | -dontwarn com.iab.** 92 | -keepattributes SourceFile,LineNumberTable 93 | -keep class com.inmobi.** { *; } 94 | -keep class com.squareup.picasso.** {*;} 95 | -keep class com.integralads.avid.library.** {*;} 96 | -keep class com.iab.** {*;} 97 | 98 | # 快手广告平台混淆 99 | -keep class org.chromium.** { *; } 100 | -keep class aegon.chrome.** { *; } 101 | -keep class com.kwai.**{ *; } 102 | -keep class com.kwad.**{ *; } 103 | -dontwarn com.kwai.** 104 | -dontwarn com.kwad.** 105 | -dontwarn com.ksad.** 106 | -dontwarn aegon.chrome.** 107 | -keep class com.kwad.sdk.** { *;} 108 | -keep class com.ksad.download.** { *;} 109 | -keep class com.kwai.filedownloader.** { *;} 110 | 111 | # 快手广告平台混淆 112 | -keep class org.chromium.** { *; } 113 | -keep class aegon.chrome.** { *; } 114 | -keep class com.kwai.**{ *; } 115 | -keep class com.kwad.**{ *; } 116 | -dontwarn com.kwai.** 117 | -dontwarn com.kwad.** 118 | -dontwarn com.ksad.** 119 | -dontwarn aegon.chrome.** 120 | -keepclasseswithmembernames class * { native ;} 121 | 122 | # 华为广告联盟混淆 123 | -keep class com.huawei.openalliance.ad.** { *; } 124 | -dontwarn com.huawei.openalliance.ad.activity.PPSActivity 125 | -keep public class * implements com.bumptech.glide.module.GlideModule 126 | -keep public class * extends com.bumptech.glide.module.AppGlideModule 127 | -keep public enum com.bumptech.glide.load.ImageHeaderParser$** { **[] $VALUES; public *; } 128 | -dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder 129 | 130 | #京媒 混淆 131 | -keep class com.jd.ad.sdk.** { *; } 132 | 133 | # gromore 134 | # 请参考gromore-proguard-rules.pro文件 135 | 136 | # 天目 137 | -keep class com.tianmu.**{ *; } 138 | -keep class tianmu.com.** { *; } 139 | -keep interface tianmu.com.** { *; } 140 | 141 | #京媒 混淆 142 | -keep class com.jd.ad.sdk.** { *; } 143 | 144 | # 爱奇艺混淆 145 | -keep class com.mcto.sspsdk.** { *; } -------------------------------------------------------------------------------- /app/src/main/assets/supplierconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "supplier":{ 3 | "vivo":{ 4 | "appid":"替换成自己vivo市场的appid,目前暂时可以只配置vivo平台的appid,没有可不设置" 5 | }, 6 | "xiaomi":{ 7 | }, 8 | "huawei":{ 9 | }, 10 | "oppo":{ 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/ad/BannerAdActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.ad; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import android.util.Log; 6 | import android.widget.FrameLayout; 7 | 8 | import cn.admobiletop.adsuyi.ad.ADSuyiBannerAd; 9 | import cn.admobiletop.adsuyi.ad.data.ADSuyiAdInfo; 10 | import cn.admobiletop.adsuyi.ad.entity.ADSuyiExtraParams; 11 | import cn.admobiletop.adsuyi.ad.error.ADSuyiError; 12 | import cn.admobiletop.adsuyi.ad.listener.ADSuyiBannerAdListener; 13 | import cn.admobiletop.adsuyidemo.R; 14 | import cn.admobiletop.adsuyidemo.activity.base.BaseAdActivity; 15 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 16 | import cn.admobiletop.adsuyidemo.util.SPUtil; 17 | 18 | /** 19 | * @author ciba 20 | * @description Banner广告示例 21 | * @date 2020/3/26 22 | */ 23 | public class BannerAdActivity extends BaseAdActivity { 24 | 25 | private FrameLayout flContainer; 26 | private ADSuyiBannerAd suyiBannerAd; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_banner); 32 | flContainer = findViewById(R.id.flContainer); 33 | loadBannerAd(); 34 | } 35 | 36 | private void loadBannerAd() { 37 | boolean issensor = SPUtil.getBoolean(this, "sensor"); 38 | ADSuyiExtraParams extraParams = new ADSuyiExtraParams.Builder() 39 | .setAdShakeDisable(issensor) 40 | .build(); 41 | 42 | // 创建Banner广告实例,第一个参数可以是Activity或Fragment,第二个参数是广告容器(请保证容器不会拦截点击、触摸等事件) 43 | suyiBannerAd = new ADSuyiBannerAd(this, flContainer); 44 | // 设置自刷新时间范围为30~120秒,⚠️注意!!!如果设置了自刷新,初始化ADSuyiSDK时传入的content一定为Application的Content 45 | suyiBannerAd.setAutoRefreshInterval(ADSuyiDemoConstant.BANNER_AD_AUTO_REFRESH_INTERVAL); 46 | // 设置仅支持的广告平台,设置了这个值,获取广告时只会去获取该平台的广告,null或空字符串为不限制,默认为null,方便调试使用,上线时建议不设置 47 | // 注:仅debug模式为true时生效。 48 | suyiBannerAd.setOnlySupportPlatform(ADSuyiDemoConstant.BANNER_AD_ONLY_SUPPORT_PLATFORM); 49 | // 如果横幅容器不是全屏可以设置额外参数 50 | suyiBannerAd.setLocalExtraParams(extraParams); 51 | // 设置Banner广告监听 52 | suyiBannerAd.setListener(new ADSuyiBannerAdListener() { 53 | @Override 54 | public void onAdReceive(ADSuyiAdInfo adSuyiAdInfo) { 55 | Log.d(ADSuyiDemoConstant.TAG, "onAdReceive..."); 56 | } 57 | 58 | @Override 59 | public void onAdExpose(ADSuyiAdInfo adSuyiAdInfo) { 60 | Log.d(ADSuyiDemoConstant.TAG, "onAdExpose..."); 61 | } 62 | 63 | @Override 64 | public void onAdClick(ADSuyiAdInfo adSuyiAdInfo) { 65 | Log.d(ADSuyiDemoConstant.TAG, "onAdClick..."); 66 | } 67 | 68 | @Override 69 | public void onAdClose(ADSuyiAdInfo adSuyiAdInfo) { 70 | Log.d(ADSuyiDemoConstant.TAG, "onAdClose..."); 71 | if (flContainer != null) { 72 | flContainer.removeAllViews(); 73 | // flContainer.setVisibility(View.GONE); 74 | } 75 | 76 | if (suyiBannerAd != null) { 77 | suyiBannerAd.release(); 78 | } 79 | if (adSuyiAdInfo != null) { 80 | adSuyiAdInfo.release(); 81 | } 82 | } 83 | 84 | @Override 85 | public void onAdFailed(ADSuyiError adSuyiError) { 86 | // ADSuyiToastUtil.show(getApplicationContext(), "广告获取失败"); 87 | if (adSuyiError != null) { 88 | String failedJson = adSuyiError.toString(); 89 | Log.d(ADSuyiDemoConstant.TAG, "onAdFailed..." + failedJson); 90 | } 91 | } 92 | }); 93 | // banner广告场景id(场景id非必选字段,如果需要可到开发者后台创建) 94 | suyiBannerAd.setSceneId(ADSuyiDemoConstant.BANNER_AD_SCENE_ID); 95 | // 加载Banner广告,参数为广告位ID,同一个ADSuyiBannerAd只有一次loadAd有效 96 | suyiBannerAd.loadAd(ADSuyiDemoConstant.BANNER_AD_POS_ID); 97 | } 98 | 99 | @Override 100 | protected void onDestroy() { 101 | super.onDestroy(); 102 | if (suyiBannerAd != null) { 103 | suyiBannerAd.release(); 104 | suyiBannerAd = null; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/ad/FullScreenVodAdActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.ad; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.Toast; 9 | 10 | import cn.admobiletop.adsuyi.ad.ADSuyiFullScreenVodAd; 11 | import cn.admobiletop.adsuyi.ad.data.ADSuyiFullScreenVodAdInfo; 12 | import cn.admobiletop.adsuyi.ad.error.ADSuyiError; 13 | import cn.admobiletop.adsuyi.ad.listener.ADSuyiFullScreenVodAdListener; 14 | import cn.admobiletop.adsuyi.util.ADSuyiToastUtil; 15 | import cn.admobiletop.adsuyidemo.R; 16 | import cn.admobiletop.adsuyidemo.activity.base.BaseAdActivity; 17 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 18 | 19 | /** 20 | * @author ciba 21 | * @description 全屏视频广告示例 22 | * @date 2020/3/27 23 | */ 24 | public class FullScreenVodAdActivity extends BaseAdActivity implements View.OnClickListener { 25 | private ADSuyiFullScreenVodAd fullScreenVodAd; 26 | private ADSuyiFullScreenVodAdInfo fullScreenVodAdInfo; 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_reward_vod); 32 | 33 | initListener(); 34 | initAd(); 35 | } 36 | 37 | private void initListener() { 38 | Button btnLoadAd = findViewById(R.id.btnLoadAd); 39 | Button btnShowAd = findViewById(R.id.btnShowAd); 40 | 41 | btnLoadAd.setText("获取全屏视频广告"); 42 | btnShowAd.setText("展示全屏视频广告"); 43 | 44 | btnLoadAd.setOnClickListener(this); 45 | btnShowAd.setOnClickListener(this); 46 | } 47 | 48 | private void initAd() { 49 | fullScreenVodAd = new ADSuyiFullScreenVodAd(this); 50 | // 设置仅支持的广告平台,设置了这个值,获取广告时只会去获取该平台的广告,null或空字符串为不限制,默认为null,方便调试使用,上线时建议不设置 51 | // 注:仅debug模式为true时生效。 52 | fullScreenVodAd.setOnlySupportPlatform(ADSuyiDemoConstant.FULL_SCREEN_VOD_AD_ONLY_SUPPORT_PLATFORM); 53 | // 设置全屏视频监听 54 | fullScreenVodAd.setListener(new ADSuyiFullScreenVodAdListener() { 55 | 56 | @Override 57 | public void onAdReceive(ADSuyiFullScreenVodAdInfo fullScreenVodAdInfo) { 58 | // TODO 全屏视频广告对象一次成功拉取的广告数据只允许展示一次 59 | FullScreenVodAdActivity.this.fullScreenVodAdInfo = fullScreenVodAdInfo; 60 | ADSuyiToastUtil.show(getApplicationContext(), "全屏视频广告获取成功"); 61 | Log.d(ADSuyiDemoConstant.TAG, "onAdReceive..."); 62 | } 63 | 64 | @Override 65 | public void onVideoCache(ADSuyiFullScreenVodAdInfo adSuyiFullScreenVodAdInfo) { 66 | // 部分渠道不会回调该方法,请在onAdReceive做广告展示处理 67 | Log.d(ADSuyiDemoConstant.TAG, "onVideoCache..."); 68 | } 69 | 70 | @Override 71 | public void onVideoComplete(ADSuyiFullScreenVodAdInfo adSuyiFullScreenVodAdInfo) { 72 | Log.d(ADSuyiDemoConstant.TAG, "onVideoComplete..."); 73 | } 74 | 75 | @Override 76 | public void onVideoError(ADSuyiFullScreenVodAdInfo adSuyiFullScreenVodAdInfo, ADSuyiError adSuyiError) { 77 | Log.d(ADSuyiDemoConstant.TAG, "onVideoError..." + adSuyiError.toString()); 78 | } 79 | 80 | @Override 81 | public void onAdExpose(ADSuyiFullScreenVodAdInfo adSuyiFullScreenVodAdInfo) { 82 | Log.d(ADSuyiDemoConstant.TAG, "onAdExpose..."); 83 | } 84 | 85 | @Override 86 | public void onAdClick(ADSuyiFullScreenVodAdInfo adSuyiFullScreenVodAdInfo) { 87 | Log.d(ADSuyiDemoConstant.TAG, "onAdClick..."); 88 | } 89 | 90 | @Override 91 | public void onAdClose(ADSuyiFullScreenVodAdInfo adSuyiFullScreenVodAdInfo) { 92 | Log.d(ADSuyiDemoConstant.TAG, "onAdClose..."); 93 | } 94 | 95 | @Override 96 | public void onAdFailed(ADSuyiError adSuyiError) { 97 | // ADSuyiToastUtil.show(getApplicationContext(), "广告获取失败"); 98 | if (adSuyiError != null) { 99 | String failedJson = adSuyiError.toString(); 100 | Log.d(ADSuyiDemoConstant.TAG, "onAdFailed..." + failedJson); 101 | } 102 | } 103 | }); 104 | } 105 | 106 | @Override 107 | public void onClick(View v) { 108 | switch (v.getId()) { 109 | case R.id.btnLoadAd: 110 | loadAd(); 111 | break; 112 | case R.id.btnShowAd: 113 | if (fullScreenVodAdInfo == null) { 114 | Toast.makeText(this, "无可用广告", Toast.LENGTH_SHORT).show(); 115 | return; 116 | } 117 | if (!fullScreenVodAdInfo.isReady()) { 118 | Toast.makeText(this, "广告未准备好", Toast.LENGTH_SHORT).show(); 119 | return; 120 | } 121 | if (fullScreenVodAdInfo.hasExpired()) { 122 | Toast.makeText(this, "广告已失效", Toast.LENGTH_SHORT).show(); 123 | return; 124 | } 125 | fullScreenVodAdInfo.showFullScreenVod(this); 126 | break; 127 | default: 128 | break; 129 | } 130 | } 131 | 132 | /** 133 | * 加载广告 134 | */ 135 | private void loadAd() { 136 | if (fullScreenVodAdInfo != null) { 137 | fullScreenVodAdInfo.release(); 138 | fullScreenVodAdInfo = null; 139 | } 140 | fullScreenVodAd.loadAd(ADSuyiDemoConstant.FULL_SCREEN_VOD_AD_POS_ID); 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/ad/PrivacyActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.ad; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.TextView; 9 | 10 | import cn.admobiletop.adsuyidemo.ADSuyiApplication; 11 | import cn.admobiletop.adsuyidemo.R; 12 | import cn.admobiletop.adsuyidemo.activity.MainActivity; 13 | import cn.admobiletop.adsuyidemo.activity.other.NormalWebActivity; 14 | import cn.admobiletop.adsuyidemo.util.SPUtil; 15 | import cn.admobiletop.adsuyidemo.util.StringUtil; 16 | 17 | public class PrivacyActivity extends AppCompatActivity { 18 | 19 | private TextView tv_content; 20 | private TextView tv_disagree; 21 | private TextView tv_agree; 22 | 23 | @Override 24 | protected void onCreate(@Nullable Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | 27 | setContentView(R.layout.activity_privacy); 28 | 29 | initView(); 30 | initListener(); 31 | initData(); 32 | 33 | // 获取是否已经同意过隐私政策 34 | boolean agreePrivacyPolicy = SPUtil.getBoolean(this, ADSuyiApplication.AGREE_PRIVACY_POLICY); 35 | if (agreePrivacyPolicy) { 36 | ADSuyiApplication.initAd(); 37 | jumpMain(); 38 | } 39 | } 40 | 41 | private void initView() { 42 | tv_content = findViewById(R.id.tv_content); 43 | tv_disagree = findViewById(R.id.tv_disagree); 44 | tv_agree = findViewById(R.id.tv_agree); 45 | } 46 | 47 | private void initListener() { 48 | tv_disagree.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | jumpMain(); 52 | } 53 | }); 54 | 55 | tv_agree.setOnClickListener(new View.OnClickListener() { 56 | @Override 57 | public void onClick(View v) { 58 | // 用户同意之后SP进行记录 59 | SPUtil.putBoolean(getApplicationContext(), ADSuyiApplication.AGREE_PRIVACY_POLICY, true); 60 | ADSuyiApplication.initAd(); 61 | jumpMain(); 62 | } 63 | }); 64 | } 65 | 66 | private void initData() { 67 | StringUtil.KeyWordClick privacyPolicySpan = new StringUtil.KeyWordClick("《隐私政策》", 0xff1b78c8, new View.OnClickListener() { 68 | @Override 69 | public void onClick(View v) { 70 | // TODO: 2020/9/10 跳转隐私政策详情界面(仅为示例,请结合自己的业务需求) 71 | NormalWebActivity.jump(PrivacyActivity.this, "https://www.admobile.top/privacyPolicy.html"); 72 | } 73 | }); 74 | StringUtil.KeyWordClick privacyPolicySpan2 = new StringUtil.KeyWordClick("《用户协议》", 0xff1b78c8, new View.OnClickListener() { 75 | @Override 76 | public void onClick(View v) { 77 | // TODO: 2020/9/10 跳转隐私政策详情界面(仅为示例,请结合自己的业务需求) 78 | NormalWebActivity.jump(PrivacyActivity.this, "https://doc.admobile.top/ssp/pages/contract/"); 79 | } 80 | }); 81 | StringUtil.KeyWordClick privacyPolicySpan3 = new StringUtil.KeyWordClick("《第三方SDK使用列表》", 0xff1b78c8, new View.OnClickListener() { 82 | @Override 83 | public void onClick(View v) { 84 | // TODO: 2020/9/10 跳转隐私政策详情界面(仅为示例,请结合自己的业务需求) 85 | NormalWebActivity.jump(PrivacyActivity.this, "https://doc.admobile.top/ssp/pages/sfsdkth/"); 86 | } 87 | }); 88 | StringUtil.setCustomKeyWordClickSpan(tv_content, tv_content.getText().toString(), privacyPolicySpan, privacyPolicySpan2, privacyPolicySpan3); 89 | } 90 | 91 | /** 92 | * 跳转到主界面 93 | */ 94 | private void jumpMain() { 95 | startActivity(new Intent(this, MainActivity.class)); 96 | finish(); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/ad/interstitial/InterstitialAdActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.ad.interstitial; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.Toast; 9 | 10 | import cn.admobiletop.adsuyi.ad.ADSuyiInterstitialAd; 11 | import cn.admobiletop.adsuyi.ad.data.ADSuyiInterstitialAdInfo; 12 | import cn.admobiletop.adsuyi.ad.entity.ADSuyiExtraParams; 13 | import cn.admobiletop.adsuyi.ad.error.ADSuyiError; 14 | import cn.admobiletop.adsuyi.ad.listener.ADSuyiInterstitialAdListener; 15 | import cn.admobiletop.adsuyi.util.ADSuyiToastUtil; 16 | import cn.admobiletop.adsuyidemo.R; 17 | import cn.admobiletop.adsuyidemo.activity.base.BaseAdActivity; 18 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 19 | 20 | /** 21 | * @author ciba 22 | * @description 插屏广告示例 23 | * @date 2020/3/27 24 | */ 25 | public class InterstitialAdActivity extends BaseAdActivity implements View.OnClickListener { 26 | private ADSuyiInterstitialAd interstitialAd; 27 | private ADSuyiInterstitialAdInfo interstitialAdInfo; 28 | 29 | @Override 30 | protected void onCreate(@Nullable Bundle savedInstanceState) { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_reward_vod); 33 | 34 | initListener(); 35 | initAd(); 36 | } 37 | 38 | private void initListener() { 39 | Button btnLoadAd = findViewById(R.id.btnLoadAd); 40 | Button btnShowAd = findViewById(R.id.btnShowAd); 41 | 42 | btnLoadAd.setText("获取插屏广告"); 43 | btnShowAd.setText("展示插屏广告"); 44 | 45 | btnLoadAd.setOnClickListener(this); 46 | btnShowAd.setOnClickListener(this); 47 | 48 | } 49 | 50 | private void initAd() { 51 | interstitialAd = new ADSuyiInterstitialAd(this); 52 | // 设置仅支持的广告平台,设置了这个值,获取广告时只会去获取该平台的广告,null或空字符串为不限制,默认为null,方便调试使用,上线时建议不设置 53 | // 注:仅debug模式为true时生效。 54 | interstitialAd.setOnlySupportPlatform(ADSuyiDemoConstant.INTERSTITIAL_AD_ONLY_SUPPORT_PLATFORM); 55 | // 创建额外参数实例 56 | ADSuyiExtraParams extraParams = new ADSuyiExtraParams.Builder() 57 | // 设置视频类广告是否静音 58 | .setVideoWithMute(ADSuyiDemoConstant.INTERSTITIAL_AD_PLAY_WITH_MUTE) 59 | .build(); 60 | interstitialAd.setLocalExtraParams(extraParams); 61 | // 设置插屏广告监听 62 | interstitialAd.setListener(new ADSuyiInterstitialAdListener() { 63 | 64 | @Override 65 | public void onAdReceive(ADSuyiInterstitialAdInfo interstitialAdInfo) { 66 | // TODO 插屏广告对象一次成功拉取的广告数据只允许展示一次 67 | InterstitialAdActivity.this.interstitialAdInfo = interstitialAdInfo; 68 | ADSuyiToastUtil.show(getApplicationContext(), "插屏广告获取成功"); 69 | Log.d(ADSuyiDemoConstant.TAG, "onAdReceive..."); 70 | } 71 | 72 | @Override 73 | public void onAdReady(ADSuyiInterstitialAdInfo interstitialAdInfo) { 74 | // 部分渠道不会回调该方法,请在onAdReceive做广告展示处理 75 | Log.d(ADSuyiDemoConstant.TAG, "onAdReady..."); 76 | } 77 | 78 | @Override 79 | public void onAdExpose(ADSuyiInterstitialAdInfo interstitialAdInfo) { 80 | Log.d(ADSuyiDemoConstant.TAG, "onAdExpose..."); 81 | } 82 | 83 | @Override 84 | public void onAdClick(ADSuyiInterstitialAdInfo interstitialAdInfo) { 85 | Log.d(ADSuyiDemoConstant.TAG, "onAdClick..."); 86 | } 87 | 88 | @Override 89 | public void onAdClose(ADSuyiInterstitialAdInfo interstitialAdInfo) { 90 | Log.d(ADSuyiDemoConstant.TAG, "onAdClose..."); 91 | } 92 | 93 | @Override 94 | public void onAdFailed(ADSuyiError adSuyiError) { 95 | // ADSuyiToastUtil.show(getApplicationContext(), "广告获取失败"); 96 | if (adSuyiError != null) { 97 | String failedJson = adSuyiError.toString(); 98 | Log.d(ADSuyiDemoConstant.TAG, "onAdFailed..." + failedJson); 99 | } 100 | } 101 | }); 102 | } 103 | 104 | @Override 105 | public void onClick(View v) { 106 | switch (v.getId()) { 107 | case R.id.btnLoadAd: 108 | loadAd(); 109 | break; 110 | case R.id.btnShowAd: 111 | if (interstitialAdInfo == null) { 112 | Toast.makeText(this, "无可用广告", Toast.LENGTH_SHORT).show(); 113 | return; 114 | } 115 | if (!interstitialAdInfo.isReady()) { 116 | Toast.makeText(this, "广告未准备好", Toast.LENGTH_SHORT).show(); 117 | return; 118 | } 119 | if (interstitialAdInfo.hasExpired()) { 120 | Toast.makeText(this, "广告已失效", Toast.LENGTH_SHORT).show(); 121 | return; 122 | } 123 | interstitialAdInfo.showInterstitial(this); 124 | break; 125 | default: 126 | break; 127 | } 128 | } 129 | 130 | /** 131 | * 加载广告 132 | */ 133 | private void loadAd() { 134 | if (interstitialAdInfo != null) { 135 | interstitialAdInfo.release(); 136 | interstitialAdInfo = null; 137 | } 138 | // 插屏广告场景id(场景id非必选字段,如果需要可到开发者后台创建) 139 | interstitialAd.setSceneId(ADSuyiDemoConstant.INTERSTITIAL_AD_SCENE_ID); 140 | // 加载插屏广告,参数为广告位ID 141 | interstitialAd.loadAd(ADSuyiDemoConstant.INTERSTITIAL_AD_POS_ID); 142 | } 143 | 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/ad/splash/SplashAdSettingActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.ad.splash; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import androidx.annotation.Nullable; 6 | import androidx.appcompat.app.AppCompatActivity; 7 | import android.text.TextUtils; 8 | import android.view.View; 9 | import android.widget.EditText; 10 | import android.widget.LinearLayout; 11 | import android.widget.RadioGroup; 12 | 13 | import cn.admobiletop.adsuyidemo.R; 14 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 15 | 16 | /** 17 | * @Description: 18 | * @Author: 草莓 19 | * @CreateDate: 7/15/22 10:39 AM 20 | */ 21 | public class SplashAdSettingActivity extends AppCompatActivity { 22 | 23 | private RadioGroup rgDisplayStyle; 24 | private RadioGroup rgLoadType; 25 | private LinearLayout llHalfEnterLogoHeightSize; 26 | private EditText etLogoHeight; 27 | 28 | private int splashType = ADSuyiDemoConstant.HALF_SCREEN; 29 | 30 | private int loadType = ADSuyiDemoConstant.LOAD_AND_SHOW; 31 | 32 | @Override 33 | protected void onCreate(@Nullable Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_splash_setting); 36 | 37 | rgDisplayStyle = findViewById(R.id.rgDisplayStyle); 38 | rgLoadType = findViewById(R.id.rgLoadType); 39 | llHalfEnterLogoHeightSize = findViewById(R.id.llHalfEnterLogoHeightSize); 40 | etLogoHeight = findViewById(R.id.etLogoHeight); 41 | 42 | rgDisplayStyle.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 43 | @Override 44 | public void onCheckedChanged(RadioGroup group, int checkedId) { 45 | if (checkedId == R.id.rbHalf) { 46 | splashType = ADSuyiDemoConstant.HALF_SCREEN; 47 | llHalfEnterLogoHeightSize.setVisibility(View.VISIBLE); 48 | } else if (checkedId == R.id.rbFullScreen) { 49 | splashType = ADSuyiDemoConstant.FULL_SCREEN; 50 | llHalfEnterLogoHeightSize.setVisibility(View.GONE); 51 | } else if (checkedId == R.id.rbImmersiveAndFullScreen) { 52 | splashType = ADSuyiDemoConstant.IMMERSIVE_AND_FULLSCREEN; 53 | llHalfEnterLogoHeightSize.setVisibility(View.GONE); 54 | } 55 | } 56 | }); 57 | 58 | rgLoadType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 59 | @Override 60 | public void onCheckedChanged(RadioGroup group, int checkedId) { 61 | if (checkedId == R.id.loadAndShow) { 62 | loadType = ADSuyiDemoConstant.LOAD_AND_SHOW; 63 | } else if (checkedId == R.id.loadOnly) { 64 | loadType = ADSuyiDemoConstant.LOAD_ONLY; 65 | } 66 | } 67 | }); 68 | 69 | findViewById(R.id.btnLoadSplashAd).setOnClickListener(new View.OnClickListener() { 70 | @Override 71 | public void onClick(View v) { 72 | Intent intent = new Intent(SplashAdSettingActivity.this, SplashAdActivity.class); 73 | String etLogoHeightString = etLogoHeight.getText().toString().trim(); 74 | intent.putExtra("splashType", splashType); 75 | intent.putExtra("logoHeightPx", TextUtils.isEmpty(etLogoHeightString) ? 0 : Integer.valueOf(etLogoHeightString)); 76 | intent.putExtra("loadType", loadType); 77 | startActivity(intent); 78 | } 79 | }); 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/base/BaseAdActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.base; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.Nullable; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import android.view.MenuItem; 7 | 8 | /** 9 | * @author ciba 10 | * @description Banner广告示例 11 | * @date 2020/3/26 12 | */ 13 | public class BaseAdActivity extends AppCompatActivity { 14 | @Override 15 | protected void onCreate(@Nullable Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 18 | } 19 | 20 | @Override 21 | public boolean onOptionsItemSelected(MenuItem item) { 22 | switch (item.getItemId()) { 23 | case android.R.id.home: 24 | finish(); 25 | break; 26 | 27 | default: 28 | break; 29 | } 30 | return super.onOptionsItemSelected(item); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/other/NormalWebActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.other; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.http.SslError; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | import androidx.appcompat.app.AppCompatActivity; 11 | import android.webkit.SslErrorHandler; 12 | import android.webkit.WebSettings; 13 | import android.webkit.WebView; 14 | import android.webkit.WebViewClient; 15 | 16 | import cn.admobiletop.adsuyidemo.R; 17 | 18 | /** 19 | * @author 草莓 20 | * @description 描述 21 | * @date 2020/9/21 22 | */ 23 | public class NormalWebActivity extends AppCompatActivity { 24 | private static final String WEB_URL = "WEB_URL"; 25 | private WebView webView; 26 | 27 | public static void jump(@NonNull Context context, @NonNull String webUrl) { 28 | Intent intent = new Intent(context, NormalWebActivity.class); 29 | intent.putExtra(WEB_URL, webUrl); 30 | context.startActivity(intent); 31 | } 32 | 33 | @Override 34 | protected void onCreate(@Nullable Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | setContentView(R.layout.activity_normal_web); 37 | 38 | webView = findViewById(R.id.webView); 39 | WebSettings settings = webView.getSettings(); 40 | settings.setJavaScriptEnabled(true); 41 | //设置 缓存模式 42 | settings.setCacheMode(WebSettings.LOAD_NO_CACHE); 43 | 44 | // 是否支持viewport属性,默认值 false 45 | // 页面通过``自适应手机屏幕 46 | settings.setUseWideViewPort(true); 47 | // 是否自动加载图片 48 | settings.setLoadsImagesAutomatically(true); 49 | // 开启 DOM storage API 功能 50 | settings.setDomStorageEnabled(true); 51 | settings.setDefaultTextEncodingName("UTF-8"); 52 | //启用数据库 53 | settings.setDatabaseEnabled(true); 54 | settings.setGeolocationEnabled(true); 55 | webView.clearHistory(); 56 | webView.clearFormData(); 57 | webView.clearCache(true); 58 | 59 | webView.getSettings().setDisplayZoomControls(false); 60 | webView.getSettings().setSupportMultipleWindows(true); 61 | 62 | // android 5.0以上默认不支持Mixed Content 63 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 64 | webView.getSettings().setMixedContentMode( 65 | WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); 66 | } 67 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 68 | // 是否在离开屏幕时光栅化(会增加内存消耗),默认值 false 69 | settings.setOffscreenPreRaster(false); 70 | } 71 | webView.setWebViewClient(new WebViewClient() { 72 | @Override 73 | public void onPageFinished(WebView view, String url) { 74 | super.onPageFinished(view, url); 75 | } 76 | 77 | @Override 78 | public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { 79 | } 80 | 81 | @Override 82 | public boolean shouldOverrideUrlLoading(WebView view, String url) { 83 | view.loadUrl(url); 84 | return true; 85 | } 86 | 87 | @Override 88 | public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { 89 | handler.proceed(); 90 | } 91 | }); 92 | 93 | webView.loadUrl(getIntent().getStringExtra(WEB_URL)); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/activity/setting/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.activity.setting; 2 | 3 | import android.os.Bundle; 4 | import androidx.recyclerview.widget.LinearLayoutManager; 5 | import androidx.recyclerview.widget.RecyclerView; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | import cn.admobiletop.adsuyidemo.R; 12 | import cn.admobiletop.adsuyidemo.activity.base.BaseAdActivity; 13 | import cn.admobiletop.adsuyidemo.adapter.SettingAdapter; 14 | import cn.admobiletop.adsuyidemo.entity.AdSettingData; 15 | 16 | public class SettingActivity extends BaseAdActivity { 17 | public static final String KEY_ONLY_SUPPORT_PLATFORM = "KEY_ONLY_SUPPORT_PLATFORM"; 18 | public static final String KEY_OPEN_FLOATING_AD = "KEY_OPEN_FLOATING_AD"; 19 | 20 | private RecyclerView mRv; 21 | private SettingAdapter mAdapter; 22 | private List mData = new ArrayList<>(); 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | setContentView(R.layout.activity_setting); 28 | initView(); 29 | initData(); 30 | } 31 | 32 | 33 | 34 | private void initView() { 35 | mRv = findViewById(R.id.recycler); 36 | mRv.setLayoutManager(new LinearLayoutManager(this)); 37 | mAdapter = new SettingAdapter(this); 38 | mRv.setAdapter(mAdapter); 39 | } 40 | 41 | private void initData() { 42 | AdSettingData titlePlatData = new AdSettingData(SettingAdapter.ITEM_VIEW_TYPE_TITLE_DATA,"广告平台设置-所有广告位都生效"); 43 | mData.add(titlePlatData); 44 | AdSettingData platformData = new AdSettingData(SettingAdapter.ITEM_VIEW_TYPE_PLATFORM_DATA,"选择广告平台"); 45 | mData.add(platformData); 46 | AdSettingData titleAdData = new AdSettingData(SettingAdapter.ITEM_VIEW_TYPE_TITLE_DATA,"广告位设置"); 47 | mData.add(titleAdData); 48 | 49 | String[] adTypeItems = getResources().getStringArray(R.array.ad_type_items); 50 | List TypeItems = Arrays.asList(adTypeItems); 51 | for (String typeItem : TypeItems) { 52 | AdSettingData TypeData = new AdSettingData(SettingAdapter.ITEM_VIEW_TYPE_AD_DATA, typeItem); 53 | mData.add(TypeData); 54 | } 55 | mAdapter.setDataList(mData); 56 | mAdapter.notifyDataSetChanged(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/BaseNativeAdAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter; 2 | 3 | import androidx.recyclerview.widget.RecyclerView; 4 | 5 | import java.util.List; 6 | 7 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 8 | 9 | public abstract class BaseNativeAdAdapter extends RecyclerView.Adapter { 10 | public abstract void removeData(ADSuyiNativeAdInfo adSuyiNativeAdInfo); 11 | 12 | public abstract void clearData(); 13 | 14 | public abstract void addData(List datas); 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/ContentAllianceAdAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter; 2 | 3 | import android.content.Context; 4 | import androidx.annotation.NonNull; 5 | import androidx.recyclerview.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | import cn.admobiletop.adsuyi.ad.data.ADSuyiContentAllianceAdInfo; 15 | import cn.admobiletop.adsuyi.util.ADSuyiAdUtil; 16 | import cn.admobiletop.adsuyi.util.ADSuyiViewUtil; 17 | import cn.admobiletop.adsuyidemo.R; 18 | import cn.admobiletop.adsuyidemo.entity.ContentAllianceAdSampleData; 19 | 20 | /** 21 | * @author 草莓 22 | * @description 内容联盟广告Adapter 23 | * @date 2021/01/06 24 | */ 25 | public class ContentAllianceAdAdapter extends RecyclerView.Adapter { 26 | /** 27 | * 普通数据类型 28 | */ 29 | private static final int ITEM_VIEW_TYPE_NORMAL_DATA = 0; 30 | /** 31 | * 内容联盟数据 32 | */ 33 | private static final int ITEM_VIEW_TYPE_CONTENT_ALLIANCE_AD = 1; 34 | private final Context context; 35 | 36 | private List dataList = new ArrayList<>(); 37 | 38 | public ContentAllianceAdAdapter(Context context) { 39 | this.context = context; 40 | } 41 | 42 | @NonNull 43 | @Override 44 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int itemViewType) { 45 | switch (itemViewType) { 46 | case ITEM_VIEW_TYPE_CONTENT_ALLIANCE_AD: 47 | return new ContentAllianceAdViewHolder(viewGroup); 48 | default: 49 | return new NormalDataViewHolder(viewGroup); 50 | } 51 | } 52 | 53 | @Override 54 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { 55 | ContentAllianceAdSampleData sampleData = dataList.get(position); 56 | if (viewHolder instanceof NormalDataViewHolder) { 57 | ((NormalDataViewHolder) viewHolder).setData(sampleData.getNormalData()); 58 | } else if (viewHolder instanceof ContentAllianceAdViewHolder) { 59 | ((ContentAllianceAdViewHolder) viewHolder).setData(sampleData.getContentAllianceAdInfo()); 60 | } 61 | } 62 | 63 | @Override 64 | public int getItemCount() { 65 | return dataList.size(); 66 | } 67 | 68 | @Override 69 | public int getItemViewType(int position) { 70 | ADSuyiContentAllianceAdInfo nativeAdInfo = dataList.get(position).getContentAllianceAdInfo(); 71 | if (nativeAdInfo == null) { 72 | return ITEM_VIEW_TYPE_NORMAL_DATA; 73 | } else { 74 | return ITEM_VIEW_TYPE_CONTENT_ALLIANCE_AD; 75 | } 76 | } 77 | 78 | /** 79 | * 刷新数据 80 | */ 81 | public void clearData() { 82 | dataList.clear(); 83 | notifyDataSetChanged(); 84 | } 85 | 86 | /** 87 | * 添加数据 88 | */ 89 | public void addData(List nativeAdSampleDataList) { 90 | int startPosition = dataList.size(); 91 | dataList.addAll(nativeAdSampleDataList); 92 | if (startPosition <= 0) { 93 | notifyDataSetChanged(); 94 | } else { 95 | notifyItemRangeInserted(startPosition + 1, dataList.size() - startPosition); 96 | } 97 | } 98 | 99 | /** 100 | * 普通数据ViewHolder 101 | */ 102 | private static class NormalDataViewHolder extends RecyclerView.ViewHolder { 103 | 104 | private final TextView tvNormalData; 105 | 106 | NormalDataViewHolder(@NonNull ViewGroup viewGroup) { 107 | super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_native_ad_normal_data, viewGroup, false)); 108 | tvNormalData = itemView.findViewById(R.id.tvNormalData); 109 | } 110 | 111 | public void setData(String normalData) { 112 | tvNormalData.setText(normalData); 113 | } 114 | } 115 | 116 | /** 117 | * 信息流模板广告ViewHolder 118 | */ 119 | private static class ContentAllianceAdViewHolder extends RecyclerView.ViewHolder { 120 | 121 | ContentAllianceAdViewHolder(@NonNull ViewGroup viewGroup) { 122 | super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_native_ad_express_ad, viewGroup, false)); 123 | } 124 | 125 | public void setData(ADSuyiContentAllianceAdInfo adSuyiContentAllianceAdInfo) { 126 | // 判断广告Info对象是否被释放(调用过ADSuyiNativeAd的release()或ADSuyiNativeAdInfo的release()会释放广告Info对象) 127 | // 释放后的广告Info对象不能再次使用 128 | if (!ADSuyiAdUtil.adInfoIsRelease(adSuyiContentAllianceAdInfo)) { 129 | // 当前是信息流模板广告,getNativeExpressAdView获取的是整个模板广告视图 130 | View nativeExpressAdView = adSuyiContentAllianceAdInfo.getContentAllianceAdView((ViewGroup) itemView); 131 | // 将广告视图添加到容器中的便捷方法 132 | ADSuyiViewUtil.addAdViewToAdContainer((ViewGroup) itemView, nativeExpressAdView); 133 | 134 | // 渲染广告视图, 必须调用, 因为是模板广告, 所以传入ViewGroup和响应点击的控件可能并没有用 135 | // 务必在最后调用 136 | adSuyiContentAllianceAdInfo.render((ViewGroup) itemView); 137 | } 138 | } 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/NativeAdAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.view.ViewGroup; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 11 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeExpressAdInfo; 12 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeFeedAdInfo; 13 | import cn.admobiletop.adsuyidemo.adapter.holder.NativeFeedAdViewHolder; 14 | import cn.admobiletop.adsuyidemo.adapter.holder.NativeExpressAdViewHolder; 15 | import cn.admobiletop.adsuyidemo.adapter.holder.NormalDataViewHolder; 16 | 17 | /** 18 | * @author ciba 19 | * @description 信息流广告Adapter 20 | * @date 2020/4/1 21 | */ 22 | public class NativeAdAdapter extends BaseNativeAdAdapter { 23 | /** 24 | * 普通数据类型(模拟数据) 25 | */ 26 | private static final int ITEM_VIEW_TYPE_NORMAL_DATA = 0; 27 | 28 | // 以下为三种信息流广告适配类型,模板一种,自渲染两种(没有MediaView)和(包含MediaView)。 29 | /** 30 | * 信息流原生广告类型(没有MediaView) 31 | */ 32 | private static final int ITEM_VIEW_TYPE_NATIVE_AD = 1; 33 | /** 34 | * 信息流模板广告类型 35 | */ 36 | private static final int ITEM_VIEW_TYPE_EXPRESS_AD = 3; 37 | 38 | private List dataList = new ArrayList<>(); 39 | 40 | @NonNull 41 | @Override 42 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int itemViewType) { 43 | switch (itemViewType) { 44 | case ITEM_VIEW_TYPE_NATIVE_AD: 45 | return new NativeFeedAdViewHolder(viewGroup); 46 | case ITEM_VIEW_TYPE_EXPRESS_AD: 47 | return new NativeExpressAdViewHolder(viewGroup); 48 | default: 49 | return new NormalDataViewHolder(viewGroup); 50 | } 51 | } 52 | 53 | @Override 54 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { 55 | Object item = dataList.get(position); 56 | if (viewHolder instanceof NormalDataViewHolder) { 57 | // 普通数据类型的 58 | ((NormalDataViewHolder) viewHolder).setData((String) item); 59 | } else if (viewHolder instanceof NativeFeedAdViewHolder) { 60 | // 信息流原生广告类型 61 | ((NativeFeedAdViewHolder) viewHolder).setData((ADSuyiNativeFeedAdInfo) item); 62 | } else if (viewHolder instanceof NativeExpressAdViewHolder) { 63 | // 信息流模板广告类型 64 | ((NativeExpressAdViewHolder) viewHolder).setData((ADSuyiNativeExpressAdInfo) item); 65 | } 66 | } 67 | 68 | @Override 69 | public int getItemCount() { 70 | return dataList.size(); 71 | } 72 | 73 | @Override 74 | public int getItemViewType(int position) { 75 | Object item = dataList.get(position); 76 | if (item instanceof String) { 77 | return ITEM_VIEW_TYPE_NORMAL_DATA; 78 | } else if (item instanceof ADSuyiNativeExpressAdInfo) { 79 | // isNativeExpress() true 信息流模版广告 80 | return ITEM_VIEW_TYPE_EXPRESS_AD; 81 | } else { 82 | // isNativeExpress() false 信息流原生广告 83 | return ITEM_VIEW_TYPE_NATIVE_AD; 84 | } 85 | } 86 | 87 | /** 88 | * 移除广告所在的对象,一般模板广告有可能会渲染失败 89 | */ 90 | @Override 91 | public void removeData(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 92 | if (dataList.contains(adSuyiNativeAdInfo)) { 93 | // 释放广告Info对象 94 | adSuyiNativeAdInfo.release(); 95 | // 从数据源中移除 96 | dataList.remove(adSuyiNativeAdInfo); 97 | // 通知刷新Adapter 98 | notifyDataSetChanged(); 99 | } 100 | } 101 | 102 | /** 103 | * 刷新数据 104 | */ 105 | @Override 106 | public void clearData() { 107 | dataList.clear(); 108 | notifyDataSetChanged(); 109 | } 110 | 111 | /** 112 | * 添加数据 113 | */ 114 | @Override 115 | public void addData(List datas) { 116 | int startPosition = dataList.size(); 117 | dataList.addAll(datas); 118 | if (startPosition <= 0) { 119 | notifyDataSetChanged(); 120 | } else { 121 | notifyItemRangeInserted(startPosition + 1, dataList.size() - startPosition); 122 | } 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/NativeExpressAdAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.view.ViewGroup; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 11 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeExpressAdInfo; 12 | import cn.admobiletop.adsuyidemo.adapter.holder.NativeExpressAdViewHolder; 13 | import cn.admobiletop.adsuyidemo.adapter.holder.NormalDataViewHolder; 14 | 15 | /** 16 | * @author ciba 17 | * @description 信息流模板广告Adapter 18 | * @date 2020/4/1 19 | */ 20 | public class NativeExpressAdAdapter extends BaseNativeAdAdapter { 21 | /** 22 | * 普通数据类型(模拟数据) 23 | */ 24 | private static final int ITEM_VIEW_TYPE_NORMAL_DATA = 0; 25 | /** 26 | * 信息流模板广告类型 27 | */ 28 | private static final int ITEM_VIEW_TYPE_EXPRESS_AD = 3; 29 | 30 | private List dataList = new ArrayList<>(); 31 | 32 | @NonNull 33 | @Override 34 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int itemViewType) { 35 | switch (itemViewType) { 36 | case ITEM_VIEW_TYPE_EXPRESS_AD: 37 | return new NativeExpressAdViewHolder(viewGroup); 38 | default: 39 | return new NormalDataViewHolder(viewGroup); 40 | } 41 | } 42 | 43 | @Override 44 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { 45 | Object item = dataList.get(position); 46 | if (viewHolder instanceof NativeExpressAdViewHolder) { 47 | // 信息流模板广告类型 48 | ((NativeExpressAdViewHolder) viewHolder).setData((ADSuyiNativeExpressAdInfo) item); 49 | } else { 50 | // 普通数据类型的 51 | try { 52 | ((NormalDataViewHolder) viewHolder).setData((String) item); 53 | } catch (Exception e) { 54 | ((NormalDataViewHolder) viewHolder).setData("广告类型异常"); 55 | } 56 | } 57 | } 58 | 59 | @Override 60 | public int getItemCount() { 61 | return dataList.size(); 62 | } 63 | 64 | @Override 65 | public int getItemViewType(int position) { 66 | Object item = dataList.get(position); 67 | if (item instanceof ADSuyiNativeExpressAdInfo) { 68 | // item 为信息流模板广告数据 69 | return ITEM_VIEW_TYPE_EXPRESS_AD; 70 | } else { 71 | // item 为模拟数据 72 | return ITEM_VIEW_TYPE_NORMAL_DATA; 73 | } 74 | } 75 | 76 | /** 77 | * 移除广告所在的对象,一般模板广告有可能会渲染失败 78 | */ 79 | @Override 80 | public void removeData(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 81 | if (dataList.contains(adSuyiNativeAdInfo)) { 82 | // 释放广告Info对象 83 | adSuyiNativeAdInfo.release(); 84 | // 从数据源中移除 85 | dataList.remove(adSuyiNativeAdInfo); 86 | // 通知刷新Adapter 87 | notifyDataSetChanged(); 88 | } 89 | } 90 | 91 | /** 92 | * 刷新数据 93 | */ 94 | @Override 95 | public void clearData() { 96 | dataList.clear(); 97 | notifyDataSetChanged(); 98 | } 99 | 100 | /** 101 | * 添加数据 102 | */ 103 | @Override 104 | public void addData(List datas) { 105 | int startPosition = dataList.size(); 106 | dataList.addAll(datas); 107 | if (startPosition <= 0) { 108 | notifyDataSetChanged(); 109 | } else { 110 | notifyItemRangeInserted(startPosition + 1, dataList.size() - startPosition); 111 | } 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/NativeFeedAdAdapter.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.view.ViewGroup; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 11 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeFeedAdInfo; 12 | import cn.admobiletop.adsuyidemo.adapter.holder.NativeFeedAdViewHolder; 13 | import cn.admobiletop.adsuyidemo.adapter.holder.NormalDataViewHolder; 14 | 15 | /** 16 | * @author ciba 17 | * @description 信息流广告Adapter 18 | * @date 2020/4/1 19 | */ 20 | public class NativeFeedAdAdapter extends BaseNativeAdAdapter { 21 | /** 22 | * 普通数据类型(模拟数据) 23 | */ 24 | private static final int ITEM_VIEW_TYPE_NORMAL_DATA = 0; 25 | /** 26 | * 信息流原生广告类型 27 | */ 28 | private static final int ITEM_VIEW_TYPE_NATIVE_AD = 1; 29 | 30 | private List dataList = new ArrayList<>(); 31 | 32 | @NonNull 33 | @Override 34 | public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int itemViewType) { 35 | switch (itemViewType) { 36 | case ITEM_VIEW_TYPE_NATIVE_AD: 37 | return new NativeFeedAdViewHolder(viewGroup); 38 | default: 39 | return new NormalDataViewHolder(viewGroup); 40 | } 41 | } 42 | 43 | @Override 44 | public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { 45 | Object item = dataList.get(position); 46 | if (viewHolder instanceof NativeFeedAdViewHolder) { 47 | // 信息流原生广告类型 NativeAdViewHolder or NativeAdMediaViewHolder 48 | ((NativeFeedAdViewHolder) viewHolder).setData((ADSuyiNativeFeedAdInfo) item); 49 | } else { 50 | // 普通数据类型的 51 | try { 52 | ((NormalDataViewHolder) viewHolder).setData((String) item); 53 | } catch (Exception e) { 54 | ((NormalDataViewHolder) viewHolder).setData("广告类型异常"); 55 | } 56 | } 57 | } 58 | 59 | @Override 60 | public int getItemCount() { 61 | return dataList.size(); 62 | } 63 | 64 | @Override 65 | public int getItemViewType(int position) { 66 | Object item = dataList.get(position); 67 | if (item instanceof ADSuyiNativeFeedAdInfo) { 68 | return ITEM_VIEW_TYPE_NATIVE_AD; 69 | } else { 70 | return ITEM_VIEW_TYPE_NORMAL_DATA; 71 | } 72 | } 73 | 74 | /** 75 | * 移除广告所在的对象,一般模板广告有可能会渲染失败 76 | */ 77 | @Override 78 | public void removeData(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 79 | if (dataList.contains(adSuyiNativeAdInfo)) { 80 | // 释放广告Info对象 81 | adSuyiNativeAdInfo.release(); 82 | // 从数据源中移除 83 | dataList.remove(adSuyiNativeAdInfo); 84 | // 通知刷新Adapter 85 | notifyDataSetChanged(); 86 | } 87 | } 88 | 89 | /** 90 | * 刷新数据 91 | */ 92 | @Override 93 | public void clearData() { 94 | dataList.clear(); 95 | notifyDataSetChanged(); 96 | } 97 | 98 | /** 99 | * 添加数据 100 | */ 101 | @Override 102 | public void addData(List datas) { 103 | int startPosition = dataList.size(); 104 | dataList.addAll(datas); 105 | if (startPosition <= 0) { 106 | notifyDataSetChanged(); 107 | } else { 108 | notifyItemRangeInserted(startPosition + 1, dataList.size() - startPosition); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/holder/NativeExpressAdViewHolder.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter.holder; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.util.Log; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.RelativeLayout; 10 | 11 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 12 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeExpressAdInfo; 13 | import cn.admobiletop.adsuyi.ad.error.ADSuyiError; 14 | import cn.admobiletop.adsuyi.ad.listener.ADSuyiNativeVideoListener; 15 | import cn.admobiletop.adsuyi.util.ADSuyiAdUtil; 16 | import cn.admobiletop.adsuyi.util.ADSuyiViewUtil; 17 | import cn.admobiletop.adsuyidemo.R; 18 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 19 | 20 | /** 21 | * 信息流模板广告ViewHolder 22 | */ 23 | public class NativeExpressAdViewHolder extends RecyclerView.ViewHolder { 24 | 25 | public NativeExpressAdViewHolder(@NonNull ViewGroup viewGroup) { 26 | super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_native_ad_express_ad, viewGroup, false)); 27 | } 28 | 29 | public void setData(ADSuyiNativeExpressAdInfo nativeExpressAdInfo) { 30 | // 判断广告Info对象是否被释放(调用过ADSuyiNativeAd的release()或ADSuyiNativeAdInfo的release()会释放广告Info对象) 31 | // 释放后的广告Info对象不能再次使用 32 | if (!ADSuyiAdUtil.adInfoIsRelease(nativeExpressAdInfo)) { 33 | setVideoListener(nativeExpressAdInfo); 34 | // 当前是信息流模板广告,getNativeExpressAdView获取的是整个模板广告视图 35 | View nativeExpressAdView = nativeExpressAdInfo.getNativeExpressAdView((ViewGroup) itemView); 36 | // 将广告视图添加到容器中的便捷方法 37 | ADSuyiViewUtil.addAdViewToAdContainer( 38 | (ViewGroup) itemView, 39 | nativeExpressAdView, 40 | new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) 41 | ); 42 | 43 | // 渲染广告视图, 必须调用, 因为是模板广告, 所以传入ViewGroup和响应点击的控件可能并没有用 44 | // 务必在最后调用 45 | nativeExpressAdInfo.render((ViewGroup) itemView); 46 | } 47 | } 48 | 49 | /** 50 | * 设置视频监听,无需求可不设置,视频监听回调因平台差异会有所不一,如:某些平台可能没有完成回调等 51 | */ 52 | private static void setVideoListener(ADSuyiNativeAdInfo nativeAdInfo) { 53 | if (nativeAdInfo.isVideo()) { 54 | // 设置视频监听,监听回调因三方平台SDK差异有所差异,无需要可不设置 55 | nativeAdInfo.setVideoListener(new ADSuyiNativeVideoListener() { 56 | @Override 57 | public void onVideoLoad(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 58 | Log.d(ADSuyiDemoConstant.TAG, "onVideoLoad.... "); 59 | } 60 | 61 | @Override 62 | public void onVideoStart(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 63 | Log.d(ADSuyiDemoConstant.TAG, "onVideoStart.... "); 64 | } 65 | 66 | @Override 67 | public void onVideoPause(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 68 | Log.d(ADSuyiDemoConstant.TAG, "onVideoPause.... "); 69 | } 70 | 71 | @Override 72 | public void onVideoComplete(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 73 | Log.d(ADSuyiDemoConstant.TAG, "onVideoComplete.... "); 74 | } 75 | 76 | @Override 77 | public void onVideoError(ADSuyiNativeAdInfo adSuyiNativeAdInfo, ADSuyiError adSuyiError) { 78 | Log.d(ADSuyiDemoConstant.TAG, "onVideoError.... " + adSuyiError.toString()); 79 | } 80 | }); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/adapter/holder/NormalDataViewHolder.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.adapter.holder; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import cn.admobiletop.adsuyidemo.R; 10 | 11 | /** 12 | * 普通数据ViewHolder 13 | */ 14 | public class NormalDataViewHolder extends RecyclerView.ViewHolder { 15 | 16 | private final TextView tvNormalData; 17 | 18 | public NormalDataViewHolder(@NonNull ViewGroup viewGroup) { 19 | super(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_native_ad_normal_data, viewGroup, false)); 20 | tvNormalData = itemView.findViewById(R.id.tvNormalData); 21 | } 22 | 23 | public void setData(String normalData) { 24 | tvNormalData.setText(normalData); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/constant/ADSuyiDemoConstant.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.constant; 2 | 3 | /** 4 | * @author ciba 5 | * @description 描述 6 | * @date 2020/4/7 7 | */ 8 | public class ADSuyiDemoConstant { 9 | public static final String APP_ID = "3801556"; 10 | public static final String TAG = "ADSuyiDemoLog"; 11 | /** 12 | * 开屏广告位ID 13 | */ 14 | public static final String SPLASH_AD_POS_ID1 = "63a981ded04aa89442"; 15 | public static String SPLASH_AD_POS_ID = SPLASH_AD_POS_ID1; 16 | /** 17 | * 开屏广告位仅支持的平台 18 | */ 19 | public static String SPLASH_AD_ONLY_SUPPORT_PLATFORM = null; 20 | /** 21 | * 开屏自定义跳过按钮 22 | */ 23 | public static boolean SPLASH_AD_CUSTOM_SKIP_VIEW = false; 24 | 25 | /** 26 | * Banner广告位ID, 640*100 27 | */ 28 | public final static String BANNER_AD_POS_ID1 = "467b6588a2a28bff5b"; 29 | /** 30 | * Banner广告位ID, 600*300 31 | */ 32 | public final static String BANNER_AD_POS_ID2 = "8ca4d2887cdc6c37de"; 33 | /** 34 | * Banner广告位ID, 600*150 35 | */ 36 | public final static String BANNER_AD_POS_ID3 = "098c34f804fd2591e9"; 37 | public static String BANNER_AD_POS_ID = BANNER_AD_POS_ID1; 38 | 39 | /** 40 | * Banner广告自刷新间隔时长,单位秒 41 | */ 42 | public static int BANNER_AD_AUTO_REFRESH_INTERVAL = 30; 43 | /** 44 | * BANNER广告位仅支持的平台 45 | */ 46 | public static String BANNER_AD_ONLY_SUPPORT_PLATFORM = null; 47 | /** 48 | * BANNER广告场景id 49 | */ 50 | public static String BANNER_AD_SCENE_ID = ""; 51 | 52 | /** 53 | * 信息流广告位ID,自渲染 54 | */ 55 | public static final String NATIVE_AD_POS_ID1 = "c078638e143ac16f46"; 56 | /** 57 | * 信息流广告位ID,模板自渲染混合 58 | */ 59 | public static final String NATIVE_AD_POS_ID2 = "9f273c39a30ab43655"; 60 | /** 61 | * 信息流广告位ID,只建了优量汇模板2.0 62 | */ 63 | public static final String NATIVE_AD_POS_ID3 = "6552acfed554d68c78"; 64 | /** 65 | * 信息流广告位ID,模板 66 | */ 67 | public static final String NATIVE_AD_POS_ID4 = "fd3b78d0c93e75330a"; 68 | public static String NATIVE_AD_POS_ID = NATIVE_AD_POS_ID1; 69 | /** 70 | * 信息流广告一次拉取广告数量 71 | */ 72 | public static int NATIVE_AD_COUNT = 2; 73 | /** 74 | * 信息流广告位仅支持的平台 75 | */ 76 | public static String NATIVE_AD_ONLY_SUPPORT_PLATFORM = null; 77 | public static boolean NATIVE_AD_PLAY_WITH_MUTE = true; 78 | /** 79 | * 信息流广告位场景id 80 | */ 81 | public static String NATIVE_AD_SCENE_ID = ""; 82 | 83 | /** 84 | * 激励视频广告位ID,竖版 85 | */ 86 | public static final String REWARD_VOD_AD_POS_ID1 = "9ec7704ebcad7364ce"; 87 | /** 88 | * 激励视频广告位ID,横版 89 | */ 90 | public static final String REWARD_VOD_AD_POS_ID2 = "31167c54f5edc926f4"; 91 | public static String REWARD_VOD_AD_POS_ID = REWARD_VOD_AD_POS_ID1; 92 | /** 93 | * 激励视频广告位仅支持的平台 94 | */ 95 | public static String REWARD_VOD_AD_ONLY_SUPPORT_PLATFORM = null; 96 | public static boolean REWARD_AD_PLAY_WITH_MUTE = false; 97 | 98 | /** 99 | * 全屏视频广告位ID 100 | */ 101 | public static final String FULL_SCREEN_VOD_AD_POS_ID1 = "6620c9299df9013cf5"; 102 | public static String FULL_SCREEN_VOD_AD_POS_ID = FULL_SCREEN_VOD_AD_POS_ID1; 103 | /** 104 | * 全屏视频广告位仅支持的平台 105 | */ 106 | public static String FULL_SCREEN_VOD_AD_ONLY_SUPPORT_PLATFORM = null; 107 | /** 108 | * 激励视频广告位场景id 109 | */ 110 | public static String REWARD_VOD_AD_SCENE_ID = ""; 111 | 112 | /** 113 | * 插屏广告位ID 114 | */ 115 | public static final String INTERSTITIAL_AD_POS_ID1 = "7b4e3d4697e1c00908"; 116 | public static String INTERSTITIAL_AD_POS_ID = INTERSTITIAL_AD_POS_ID1; 117 | /** 118 | * 插屏广告位仅支持的平台 119 | */ 120 | public static String INTERSTITIAL_AD_ONLY_SUPPORT_PLATFORM = null; 121 | public static boolean INTERSTITIAL_AD_PLAY_WITH_MUTE = false; 122 | public static boolean INTERSTITIAL_AD_AUTO_CLOSE = false; 123 | 124 | /** 125 | * 插屏广告位场景id 126 | */ 127 | public static String INTERSTITIAL_AD_SCENE_ID = ""; 128 | 129 | /** 130 | * Draw视频信息流广告位ID 131 | */ 132 | public static final String DRAW_VOD_AD_POS_ID1 = "4d6bee2ec7217adf86"; 133 | public static String DRAW_VOD_AD_POS_ID = DRAW_VOD_AD_POS_ID1; 134 | /** 135 | * Draw视频信息流广告一次拉取广告数量 136 | */ 137 | public static int DRAW_VOD_AD_COUNT = 1; 138 | /** 139 | * Draw视频信息流广告位仅支持的平台 140 | */ 141 | public static String DRAW_VOD_AD_ONLY_SUPPORT_PLATFORM = null; 142 | 143 | /** 144 | * Dl激励广告位ID 145 | */ 146 | public static String ADMOBILE_DL_AD_POS_ID = "ac966d36094a167687"; 147 | 148 | /** 149 | * 内容联盟广告位场景id 150 | */ 151 | public static String CONTENT_ALLIANCE_AD_SCENE_ID = ""; 152 | /** 153 | * 内容联盟广告位ID 154 | */ 155 | public static final String CONTENT_ALLIANCE_AD_POS_ID1 = "724469db49ff19761e"; 156 | public static String CONTENT_ALLIANCE_AD_POS_ID = CONTENT_ALLIANCE_AD_POS_ID1; 157 | 158 | 159 | /** 160 | * 开屏广告全屏并去除状态了 161 | */ 162 | public static int IMMERSIVE_AND_FULLSCREEN = 0; 163 | /** 164 | * 开屏广告全屏不去除状态栏 165 | */ 166 | public static int FULL_SCREEN = 1; 167 | /** 168 | * 开屏广告半屏 169 | */ 170 | public static int HALF_SCREEN = 2; 171 | /** 172 | * 加载并展示 173 | */ 174 | public static int LOAD_AND_SHOW = 0; 175 | /** 176 | * 仅加载 177 | */ 178 | public static int LOAD_ONLY = 1; 179 | 180 | } 181 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/entity/AdSettingData.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.entity; 2 | 3 | /** 4 | * @author songzi 5 | * @date 2021/4/29 6 | */ 7 | public class AdSettingData { 8 | 9 | 10 | private int type; 11 | private String title; 12 | 13 | public AdSettingData(int type, String title) { 14 | this.type = type; 15 | this.title = title; 16 | } 17 | 18 | public int getType() { 19 | return type; 20 | } 21 | 22 | public String getTitle() { 23 | return title; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/entity/ContentAllianceAdSampleData.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.entity; 2 | 3 | import cn.admobiletop.adsuyi.ad.data.ADSuyiContentAllianceAdInfo; 4 | 5 | /** 6 | * @author 草莓 7 | * @description 信息流广告示例数据 8 | * @date 2020/4/1 9 | */ 10 | public class ContentAllianceAdSampleData { 11 | /** 12 | * 普通数据 13 | */ 14 | private String normalData; 15 | /** 16 | * 信息流广告对象 17 | */ 18 | private ADSuyiContentAllianceAdInfo contentAllianceAdInfo; 19 | 20 | public ContentAllianceAdSampleData(String normalData) { 21 | this.normalData = normalData; 22 | } 23 | 24 | public ContentAllianceAdSampleData(ADSuyiContentAllianceAdInfo contentAllianceAdInfo) { 25 | this.contentAllianceAdInfo = contentAllianceAdInfo; 26 | } 27 | 28 | public String getNormalData() { 29 | return normalData; 30 | } 31 | 32 | public ADSuyiContentAllianceAdInfo getContentAllianceAdInfo() { 33 | return contentAllianceAdInfo; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/entity/DrawVodAdSampleData.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.entity; 2 | 3 | import cn.admobiletop.adsuyi.ad.data.ADSuyiDrawVodAdInfo; 4 | 5 | /** 6 | * @author ciba 7 | * @description Draw视频信息流广告示例数据 8 | * @date 2020/4/1 9 | */ 10 | public class DrawVodAdSampleData { 11 | /** 12 | * 普通数据 13 | */ 14 | private String normalData; 15 | /** 16 | * Draw视频信息流广告对象 17 | */ 18 | private ADSuyiDrawVodAdInfo drawVodAdInfo; 19 | 20 | public DrawVodAdSampleData(String normalData) { 21 | this.normalData = normalData; 22 | } 23 | 24 | public DrawVodAdSampleData(ADSuyiDrawVodAdInfo drawVodAdInfo) { 25 | this.drawVodAdInfo = drawVodAdInfo; 26 | } 27 | 28 | public String getNormalData() { 29 | return normalData; 30 | } 31 | 32 | public ADSuyiDrawVodAdInfo getDrawVodAdInfo() { 33 | return drawVodAdInfo; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/fragment/BannerAdFragment.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.fragment; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import android.util.Log; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.FrameLayout; 11 | 12 | import cn.admobiletop.adsuyi.ad.ADSuyiBannerAd; 13 | import cn.admobiletop.adsuyi.ad.data.ADSuyiAdInfo; 14 | import cn.admobiletop.adsuyi.ad.error.ADSuyiError; 15 | import cn.admobiletop.adsuyi.ad.listener.ADSuyiBannerAdListener; 16 | import cn.admobiletop.adsuyidemo.R; 17 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 18 | 19 | /** 20 | * @author ciba 21 | * @description Banner广告Fragment示例 22 | * @date 2020/4/20 23 | */ 24 | public class BannerAdFragment extends BaseFragment { 25 | private FrameLayout flContainer; 26 | 27 | @Nullable 28 | @Override 29 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 30 | View inflate = inflater.inflate(R.layout.activity_banner, null); 31 | flContainer = inflate.findViewById(R.id.flContainer); 32 | 33 | initBannerAd(); 34 | return inflate; 35 | } 36 | 37 | private void initBannerAd() { 38 | // 创建Banner广告实例,第一个参数可以是Activity或Fragment,第二个参数是广告容器(请保证容器不会拦截点击、触摸等事件) 39 | ADSuyiBannerAd suyiBannerAd = new ADSuyiBannerAd(this, flContainer); 40 | // 设置自刷新时间间隔,0为不自动刷新,其他取值范围为[30,120],单位秒 41 | suyiBannerAd.setAutoRefreshInterval(ADSuyiDemoConstant.BANNER_AD_AUTO_REFRESH_INTERVAL); 42 | // 设置仅支持的广告平台,设置了这个值,获取广告时只会去获取该平台的广告,null或空字符串为不限制,默认为null,方便调试使用,上线时建议不设置 43 | // 注:仅debug模式为true时生效。 44 | suyiBannerAd.setOnlySupportPlatform(ADSuyiDemoConstant.BANNER_AD_ONLY_SUPPORT_PLATFORM); 45 | // 设置Banner广告监听 46 | suyiBannerAd.setListener(new ADSuyiBannerAdListener() { 47 | @Override 48 | public void onAdReceive(ADSuyiAdInfo adSuyiAdInfo) { 49 | Log.d(ADSuyiDemoConstant.TAG, "onAdReceive..."); 50 | } 51 | 52 | @Override 53 | public void onAdExpose(ADSuyiAdInfo adSuyiAdInfo) { 54 | Log.d(ADSuyiDemoConstant.TAG, "onAdExpose..."); 55 | } 56 | 57 | @Override 58 | public void onAdClick(ADSuyiAdInfo adSuyiAdInfo) { 59 | Log.d(ADSuyiDemoConstant.TAG, "onAdClick..."); 60 | } 61 | 62 | @Override 63 | public void onAdClose(ADSuyiAdInfo adSuyiAdInfo) { 64 | Log.d(ADSuyiDemoConstant.TAG, "onAdClose..."); 65 | } 66 | 67 | @Override 68 | public void onAdFailed(ADSuyiError adSuyiError) { 69 | if (adSuyiError != null) { 70 | String failedJson = adSuyiError.toString(); 71 | Log.d(ADSuyiDemoConstant.TAG, "onAdFailed..." + failedJson); 72 | } 73 | } 74 | }); 75 | // 加载Banner广告,参数为广告位ID,同一个ADSuyiBannerAd只有一次loadAd有效 76 | suyiBannerAd.loadAd(ADSuyiDemoConstant.BANNER_AD_POS_ID); 77 | } 78 | 79 | @Override 80 | public String getTitle() { 81 | return "Banner"; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/fragment/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.fragment; 2 | 3 | import androidx.fragment.app.Fragment; 4 | 5 | /** 6 | * @author ciba 7 | * @description 描述 8 | * @date 2020/4/20 9 | */ 10 | public abstract class BaseFragment extends Fragment { 11 | public abstract String getTitle(); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/fragment/OtherFragment.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.fragment; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | 11 | import cn.admobiletop.adsuyidemo.R; 12 | 13 | /** 14 | * @author ciba 15 | * @description 信息流广告Fragment示例 16 | * @date 2020/4/20 17 | */ 18 | public class OtherFragment extends BaseFragment { 19 | 20 | @Nullable 21 | @Override 22 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 23 | View inflate = inflater.inflate(R.layout.fragment_other_page, null); 24 | initView(inflate); 25 | return inflate; 26 | } 27 | 28 | @Override 29 | public String getTitle() { 30 | return "其他页面"; 31 | } 32 | 33 | private void initView(View inflate) { 34 | Button btnFinish = inflate.findViewById(R.id.btnFinish); 35 | btnFinish.setOnClickListener(new View.OnClickListener() { 36 | @Override 37 | public void onClick(View v) { 38 | getActivity().finish(); 39 | } 40 | }); 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/fragment/TestFragment.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.fragment; 2 | 3 | import android.os.Bundle; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.Button; 10 | 11 | import cn.admobiletop.adsuyidemo.R; 12 | 13 | /** 14 | * @author ciba 15 | * @description 信息流广告Fragment示例 16 | * @date 2020/4/20 17 | */ 18 | public class TestFragment extends BaseFragment { 19 | 20 | @Nullable 21 | @Override 22 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 23 | View inflate = inflater.inflate(R.layout.fragment_test_page, null); 24 | initView(inflate); 25 | return inflate; 26 | } 27 | 28 | @Override 29 | public String getTitle() { 30 | return "测试页面"; 31 | } 32 | 33 | private void initView(View inflate) { 34 | Button btnFinish = inflate.findViewById(R.id.btnFinish); 35 | btnFinish.setOnClickListener(new View.OnClickListener() { 36 | @Override 37 | public void onClick(View v) { 38 | getActivity().finish(); 39 | } 40 | }); 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/util/ADSuyiClassFindUtils.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.util; 2 | 3 | import android.os.Build; 4 | 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Method; 7 | 8 | /** 9 | * Created by linjiang on 2019/3/5. 10 | */ 11 | 12 | public class ADSuyiClassFindUtils { 13 | 14 | static { 15 | if (Build.VERSION.SDK_INT >= 28) { 16 | try { 17 | Class classClazz = Class.class; 18 | // light greyList 19 | Field classLoaderField = classClazz.getDeclaredField("classLoader"); 20 | classLoaderField.setAccessible(true); 21 | classLoaderField.set(ADSuyiClassFindUtils.class, null); 22 | } catch (Exception e) { 23 | e.printStackTrace(); 24 | } 25 | } 26 | } 27 | 28 | public static Class forName(String className) throws ClassNotFoundException { 29 | return Class.forName(className); 30 | } 31 | 32 | /** 33 | * 根据完整路径类名反射获取对象 34 | * 35 | * @param className :完整路径类名 36 | * @param :对象类型 37 | * @return :反射对象 38 | */ 39 | public static T reflexClass(String className) { 40 | try { 41 | Class clz = Class.forName(className); 42 | return (T) clz.newInstance(); 43 | } catch (Exception e) { 44 | } 45 | return null; 46 | } 47 | 48 | public static Field getDeclaredField(Class clz, String name) throws NoSuchFieldException { 49 | return clz.getDeclaredField(name); 50 | } 51 | 52 | public static Method getDeclaredMethod(Class clz, String name, Class... parameterType) 53 | throws NoSuchMethodException { 54 | return clz.getDeclaredMethod(name, parameterType); 55 | } 56 | 57 | 58 | 59 | 60 | } -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/util/ADSuyiViewFindUtils.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.util; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.ContextWrapper; 6 | import android.os.Build; 7 | import android.view.View; 8 | import android.view.WindowManager; 9 | 10 | import java.lang.reflect.Field; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | /** 15 | * @author songzi 16 | * @date 2022/2/21 17 | */ 18 | public class ADSuyiViewFindUtils { 19 | 20 | 21 | public static View tryGetTheFrontView(Activity targetActivity) { 22 | try { 23 | WindowManager windowManager = targetActivity.getWindowManager(); 24 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { 25 | Field mWindowManagerField = Class.forName("android.view.WindowManagerImpl$CompatModeWrapper").getDeclaredField("mWindowManager"); 26 | mWindowManagerField.setAccessible(true); 27 | Field mViewsField = Class.forName("android.view.WindowManagerImpl").getDeclaredField("mViews"); 28 | mViewsField.setAccessible(true); 29 | List views = Arrays.asList((View[]) mViewsField.get(mWindowManagerField.get(windowManager))); 30 | for (int i = views.size() - 1; i >= 0; i--) { 31 | View targetView = getTargetDecorView(targetActivity, views.get(i)); 32 | if (targetView != null) { 33 | return targetView; 34 | } 35 | } 36 | } 37 | Field mGlobalField = ADSuyiClassFindUtils.getDeclaredField(ADSuyiClassFindUtils.forName("android.view.WindowManagerImpl"), "mGlobal"); 38 | mGlobalField.setAccessible(true); 39 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { 40 | Field mViewsField = Class.forName("android.view.WindowManagerGlobal").getDeclaredField("mViews"); 41 | mViewsField.setAccessible(true); 42 | List views = (List) mViewsField.get(mGlobalField.get(windowManager)); 43 | for (int i = views.size() - 1; i >= 0; i--) { 44 | View targetView = getTargetDecorView(targetActivity, views.get(i)); 45 | if (targetView != null) { 46 | return targetView; 47 | } 48 | } 49 | } else { 50 | Field mRootsField = ADSuyiClassFindUtils.getDeclaredField(ADSuyiClassFindUtils.forName("android.view.WindowManagerGlobal"), "mRoots"); 51 | mRootsField.setAccessible(true); 52 | List viewRootImpls; 53 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 54 | viewRootImpls = (List) mRootsField.get(mGlobalField.get(windowManager)); 55 | } else { 56 | viewRootImpls = Arrays.asList((Object[]) mRootsField.get(mGlobalField.get(windowManager))); 57 | } 58 | for (int i = viewRootImpls.size() - 1; i >= 0; i--) { 59 | Class clazz = ADSuyiClassFindUtils.forName("android.view.ViewRootImpl"); 60 | Object object = viewRootImpls.get(i); 61 | Field mWindowAttributesField = ADSuyiClassFindUtils.getDeclaredField(clazz, "mWindowAttributes"); 62 | mWindowAttributesField.setAccessible(true); 63 | Field mViewField = ADSuyiClassFindUtils.getDeclaredField(clazz, "mView"); 64 | mViewField.setAccessible(true); 65 | View decorView = (View) mViewField.get(object); 66 | WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) mWindowAttributesField.get(object); 67 | if (layoutParams.getTitle().toString().contains(targetActivity.getClass().getName()) 68 | || getTargetDecorView(targetActivity, decorView) != null) { 69 | return decorView; 70 | } 71 | } 72 | } 73 | } catch (Throwable e) { 74 | e.printStackTrace(); 75 | //Accessing hidden field Landroid/view/WindowManagerImpl;->mGlobal:Landroid/view/WindowManagerGlobal; (light greylist, reflection) 76 | //Accessing hidden field Landroid/view/WindowManagerGlobal;->mRoots:Ljava/util/ArrayList; (light greylist, reflection) 77 | //Accessing hidden field Landroid/view/ViewRootImpl;->mWindowAttributes:Landroid/view/WindowManager$LayoutParams; (dark greylist, reflection) 78 | //Accessing hidden field Landroid/view/ViewRootImpl;->mView:Landroid/view/View; (light greylist, reflection) 79 | } 80 | return targetActivity.getWindow().peekDecorView(); 81 | } 82 | 83 | private static View getTargetDecorView(Activity targetActivity, View decorView) { 84 | View targetView = null; 85 | Context context = decorView.getContext(); 86 | if (context == targetActivity) { 87 | targetView = decorView; 88 | } else { 89 | while (context instanceof ContextWrapper && !(context instanceof Activity)) { 90 | Context baseContext = ((ContextWrapper) context).getBaseContext(); 91 | if (baseContext == null) { 92 | break; 93 | } 94 | if (baseContext == targetActivity) { 95 | targetView = decorView; 96 | break; 97 | } 98 | context = baseContext; 99 | } 100 | } 101 | return targetView; 102 | } 103 | 104 | 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/util/LoadAdUtil.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.util; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.FrameLayout; 8 | 9 | import cn.admobiletop.adsuyi.ad.ADSuyiSplashAd; 10 | import cn.admobiletop.adsuyi.ad.data.ADSuyiAdInfo; 11 | import cn.admobiletop.adsuyi.ad.entity.ADSuyiAdSize; 12 | import cn.admobiletop.adsuyi.ad.entity.ADSuyiExtraParams; 13 | import cn.admobiletop.adsuyi.ad.error.ADSuyiError; 14 | import cn.admobiletop.adsuyi.ad.listener.ADSuyiSplashAdListener; 15 | import cn.admobiletop.adsuyidemo.constant.ADSuyiDemoConstant; 16 | 17 | public class LoadAdUtil { 18 | public static void loadSplashVPlusAd(Activity activity, FrameLayout flContainer) { 19 | flContainer.removeAllViews(); 20 | // 请在先展示布局 21 | flContainer.setVisibility(View.VISIBLE); 22 | // 创建开屏广告实例,第一个参数可以是Activity或Fragment,第二个参数是广告容器(请保证容器不会拦截点击、触摸等事件,高度不小于真实屏幕高度的75%,并且处于可见状态) 23 | ADSuyiSplashAd adSuyiSplashAd = new ADSuyiSplashAd(activity, flContainer); 24 | adSuyiSplashAd.setOnlySupportPlatform(ADSuyiDemoConstant.SPLASH_AD_ONLY_SUPPORT_PLATFORM); 25 | // 设置开屏广告监听 26 | adSuyiSplashAd.setListener(new ADSuyiSplashAdListener() { 27 | 28 | @Override 29 | public void onADTick(long countdownSeconds) { 30 | } 31 | 32 | @Override 33 | public void onReward(ADSuyiAdInfo adSuyiAdInfo) { 34 | // 目前仅仅优量汇渠道会被使用 35 | Log.d(ADSuyiDemoConstant.TAG, "广告奖励回调... "); 36 | } 37 | 38 | @Override 39 | public void onAdSkip(ADSuyiAdInfo adSuyiAdInfo) { 40 | Log.d(ADSuyiDemoConstant.TAG, "广告跳过回调,不一定准确,埋点数据仅供参考... "); 41 | } 42 | 43 | @Override 44 | public void onAdReceive(ADSuyiAdInfo adSuyiAdInfo) { 45 | Log.d(ADSuyiDemoConstant.TAG, "广告获取成功回调... "); 46 | } 47 | 48 | @Override 49 | public void onAdExpose(ADSuyiAdInfo adSuyiAdInfo) { 50 | Log.d(ADSuyiDemoConstant.TAG, "广告展示回调,有展示回调不一定是有效曝光,如网络等情况导致上报失败"); 51 | } 52 | 53 | @Override 54 | public void onAdClick(ADSuyiAdInfo adSuyiAdInfo) { 55 | Log.d(ADSuyiDemoConstant.TAG, "广告点击回调,有点击回调不一定是有效点击,如网络等情况导致上报失败"); 56 | } 57 | 58 | @Override 59 | public void onAdClose(ADSuyiAdInfo adSuyiAdInfo) { 60 | Log.d(ADSuyiDemoConstant.TAG, "广告关闭回调,需要在此进行页面跳转"); 61 | flContainer.removeAllViews(); 62 | flContainer.setVisibility(View.GONE); 63 | if (adSuyiSplashAd != null) { 64 | adSuyiSplashAd.release(); 65 | } 66 | } 67 | 68 | @Override 69 | public void onAdFailed(ADSuyiError adSuyiError) { 70 | if (adSuyiError != null) { 71 | String failedJson = adSuyiError.toString(); 72 | Log.d(ADSuyiDemoConstant.TAG, "onAdFailed----->" + failedJson); 73 | // ADSuyiToastUtil.show(getApplicationContext(), "广告获取失败 : " + failedJson); 74 | } 75 | flContainer.removeAllViews(); 76 | flContainer.setVisibility(View.GONE); 77 | if (adSuyiSplashAd != null) { 78 | adSuyiSplashAd.release(); 79 | } 80 | } 81 | }); 82 | 83 | adSuyiSplashAd.loadAd("5380eccc543592625d"); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/util/SPUtil.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.util; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import androidx.annotation.NonNull; 6 | 7 | public class SPUtil { 8 | 9 | private static SharedPreferences getSP(@NonNull Context context) { 10 | return context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); 11 | } 12 | 13 | public static void putBoolean(Context context, String key, boolean value) { 14 | getSP(context).edit().putBoolean(key, value).apply(); 15 | } 16 | 17 | public static boolean getBoolean(Context context, String key) { 18 | return getBoolean(context, key, false); 19 | } 20 | 21 | public static boolean getBoolean(Context context, String key, boolean defaultValue) { 22 | return getSP(context).getBoolean(key, defaultValue); 23 | } 24 | 25 | public static void putString(Context context, String key, String value) { 26 | getSP(context).edit().putString(key, value).apply(); 27 | } 28 | 29 | public static String getString(Context context, String key, String defaultValue) { 30 | return getSP(context).getString(key, defaultValue); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.util; 2 | 3 | import androidx.annotation.ColorInt; 4 | import androidx.annotation.NonNull; 5 | import android.text.SpannableString; 6 | import android.text.Spanned; 7 | import android.text.TextPaint; 8 | import android.text.method.LinkMovementMethod; 9 | import android.text.style.ClickableSpan; 10 | import android.view.View; 11 | import android.widget.TextView; 12 | 13 | import java.util.regex.Matcher; 14 | import java.util.regex.Pattern; 15 | 16 | /** 17 | * @author ciba 18 | * @description 描述 19 | * @date 2018/10/29 20 | */ 21 | public class StringUtil { 22 | public static void setCustomKeyWordClickSpan(TextView tvContent, String text, KeyWordClick...keyWordClicks) { 23 | if (text == null || keyWordClicks == null || tvContent == null) { 24 | return; 25 | } 26 | SpannableString spannableString = new SpannableString(text); 27 | for (KeyWordClick keyWordClick : keyWordClicks) { 28 | if (keyWordClick.getKeyWord() == null) { 29 | continue; 30 | } 31 | Pattern p = Pattern.compile(keyWordClick.getKeyWord()); 32 | Matcher m = p.matcher(spannableString); 33 | while (m.find()) { 34 | int start = m.start(); 35 | int end = m.end(); 36 | spannableString.setSpan(new CustomKeyWordClickSpan(keyWordClick.getHighLightColor(), keyWordClick.getClickListener()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 37 | } 38 | } 39 | tvContent.setClickable(true); 40 | tvContent.setMovementMethod(LinkMovementMethod.getInstance()); 41 | tvContent.setText(spannableString); 42 | } 43 | 44 | public static class KeyWordClick{ 45 | private final String mKeyWord; 46 | private final int mHighLightColor; 47 | private final View.OnClickListener mClickListener; 48 | 49 | public KeyWordClick(String mKeyWord, int mHighLightColor, View.OnClickListener mClickListener) { 50 | this.mKeyWord = mKeyWord; 51 | this.mHighLightColor = mHighLightColor; 52 | this.mClickListener = mClickListener; 53 | } 54 | 55 | String getKeyWord() { 56 | return mKeyWord; 57 | } 58 | 59 | int getHighLightColor() { 60 | return mHighLightColor; 61 | } 62 | 63 | View.OnClickListener getClickListener() { 64 | return mClickListener; 65 | } 66 | } 67 | 68 | private static class CustomKeyWordClickSpan extends ClickableSpan { 69 | private final int mHighLightColor; 70 | private boolean mUnderLine = false; 71 | private View.OnClickListener mClickListener; 72 | 73 | CustomKeyWordClickSpan(@ColorInt int highLightColor 74 | , @NonNull View.OnClickListener listener) { 75 | this.mHighLightColor = highLightColor; 76 | this.mClickListener = listener; 77 | } 78 | 79 | @Override 80 | public void onClick(@NonNull View widget) { 81 | if (mClickListener != null) { 82 | mClickListener.onClick(widget); 83 | } 84 | } 85 | 86 | @Override 87 | public void updateDrawState(@NonNull TextPaint ds) { 88 | ds.setColor(mHighLightColor); 89 | ds.setUnderlineText(mUnderLine); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/widget/AdMobileDlExpressAdDialog.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.widget; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import androidx.annotation.NonNull; 6 | import android.util.Log; 7 | import android.view.View; 8 | import android.view.Window; 9 | import android.view.WindowManager; 10 | import android.widget.RelativeLayout; 11 | 12 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 13 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeExpressAdInfo; 14 | import cn.admobiletop.adsuyi.util.ADSuyiAdUtil; 15 | import cn.admobiletop.adsuyi.util.ADSuyiViewUtil; 16 | import cn.admobiletop.adsuyidemo.R; 17 | 18 | /** 19 | * @author 草莓 20 | * @description admobileDl 模板广告弹出框 21 | * @date 2020/10/21 22 | */ 23 | public class AdMobileDlExpressAdDialog extends Dialog { 24 | 25 | public AdMobileDlExpressAdDialog(@NonNull Context context) { 26 | super(context); 27 | setContentView(R.layout.dialog_admobile_dl_ad); 28 | // 设置点击外部不关闭dialog 29 | setCanceledOnTouchOutside(false); 30 | Window dialogWindow = getWindow(); 31 | WindowManager.LayoutParams lp = dialogWindow.getAttributes(); 32 | lp.width = WindowManager.LayoutParams.MATCH_PARENT; 33 | dialogWindow.setAttributes(lp); 34 | } 35 | 36 | public void render(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 37 | if(adSuyiNativeAdInfo instanceof ADSuyiNativeExpressAdInfo) { 38 | ADSuyiNativeExpressAdInfo nativeExpressAdInfo = (ADSuyiNativeExpressAdInfo) adSuyiNativeAdInfo; 39 | if (nativeExpressAdInfo == null) { 40 | Log.d("AdMobileDlAdDialog", "ADSuyiNativeExpressAdInfo is null"); 41 | return; 42 | } 43 | // 判断广告Info对象是否被释放(调用过ADSuyiNativeAd的release()或ADSuyiNativeAdInfo的release()会释放广告Info对象) 44 | // 释放后的广告Info对象不能再次使用 45 | if (ADSuyiAdUtil.adInfoIsRelease(nativeExpressAdInfo)) { 46 | Log.d("AdMobileDlAdDialog", "dl广告对象已被释放"); 47 | return; 48 | } 49 | RelativeLayout relativeLayout = findViewById(R.id.rlAdContainer); 50 | // 当前是信息流模板广告,getNativeExpressAdView获取的是整个模板广告视图 51 | View nativeExpressAdView = nativeExpressAdInfo.getNativeExpressAdView(relativeLayout); 52 | // 将广告视图添加到容器中的便捷方法 53 | ADSuyiViewUtil.addAdViewToAdContainer(relativeLayout, nativeExpressAdView); 54 | 55 | // 渲染广告视图, 必须调用, 因为是模板广告, 所以传入ViewGroup和响应点击的控件可能并没有用 56 | // 务必在最后调用 57 | nativeExpressAdInfo.render(relativeLayout); 58 | show(); 59 | } else { 60 | Log.d("AdMobileDlAdDialog", "dl广告对象类型异常"); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/widget/AdMobileDlFeedAdDialog.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.widget; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import androidx.annotation.NonNull; 6 | import android.util.Log; 7 | import android.view.Window; 8 | import android.view.WindowManager; 9 | import android.widget.ImageView; 10 | import android.widget.RelativeLayout; 11 | 12 | import com.bumptech.glide.Glide; 13 | 14 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeAdInfo; 15 | import cn.admobiletop.adsuyi.ad.data.ADSuyiNativeFeedAdInfo; 16 | import cn.admobiletop.adsuyi.util.ADSuyiAdUtil; 17 | import cn.admobiletop.adsuyidemo.R; 18 | 19 | /** 20 | * @author 草莓 21 | * @description admobileDl自渲染广告弹出框 22 | * @date 2020/10/21 23 | */ 24 | public class AdMobileDlFeedAdDialog extends Dialog { 25 | 26 | private RelativeLayout rlAdContainer; 27 | private ImageView ivImage; 28 | private ImageView ivClose; 29 | private ImageView ivAdTarget; 30 | 31 | public AdMobileDlFeedAdDialog(@NonNull Context context) { 32 | super(context); 33 | setContentView(R.layout.dialog_admobile_dl_ad2); 34 | rlAdContainer = findViewById(R.id.rlAdContainer); 35 | ivImage = findViewById(R.id.ivImage); 36 | ivClose = findViewById(R.id.ivClose); 37 | ivAdTarget = findViewById(R.id.ivAdTarget); 38 | // 设置点击外部不关闭dialog 39 | setCanceledOnTouchOutside(false); 40 | Window dialogWindow = getWindow(); 41 | WindowManager.LayoutParams lp = dialogWindow.getAttributes(); 42 | lp.width = WindowManager.LayoutParams.MATCH_PARENT; 43 | dialogWindow.setAttributes(lp); 44 | } 45 | 46 | public void render(ADSuyiNativeAdInfo adSuyiNativeAdInfo) { 47 | if(adSuyiNativeAdInfo instanceof ADSuyiNativeFeedAdInfo) { 48 | ADSuyiNativeFeedAdInfo nativeFeedAdInfo = (ADSuyiNativeFeedAdInfo) adSuyiNativeAdInfo; 49 | if (nativeFeedAdInfo == null) { 50 | Log.d("AdMobileDlAdDialog", "ADSuyiNativeFeedAdInfo is null"); 51 | return; 52 | } 53 | if (nativeFeedAdInfo.hasMediaView()) { 54 | Log.d("AdMobileDlAdDialog", "dl广告没有MediaView"); 55 | return; 56 | } 57 | // 判断广告Info对象是否被释放(调用过ADSuyiNativeAd的release()或ADSuyiNativeAdInfo的release()会释放广告Info对象) 58 | // 释放后的广告Info对象不能再次使用 59 | if (ADSuyiAdUtil.adInfoIsRelease(nativeFeedAdInfo)) { 60 | Log.d("AdMobileDlAdDialog", "dl广告对象已被释放"); 61 | return; 62 | } 63 | Glide.with(ivImage).load(nativeFeedAdInfo.getImageUrl()).into(ivImage); 64 | ivAdTarget.setImageResource(nativeFeedAdInfo.getPlatformIcon()); 65 | // 注册关闭按钮,将关闭按钮点击事件交于SDK托管,以便于回调onAdClose 66 | nativeFeedAdInfo.registerCloseView(ivClose); 67 | // 注册广告交互, 必须调用 68 | // 务必最后调用 69 | nativeFeedAdInfo.registerViewForInteraction(rlAdContainer, rlAdContainer); 70 | show(); 71 | } else { 72 | Log.d("AdMobileDlAdDialog", "dl广告对象类型异常"); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/widget/MySmartRefreshLayout.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.widget; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.scwang.smartrefresh.layout.SmartRefreshLayout; 7 | import com.scwang.smartrefresh.layout.footer.ClassicsFooter; 8 | import com.scwang.smartrefresh.layout.header.ClassicsHeader; 9 | 10 | /** 11 | * @author ciba 12 | * @date 2020/4/01 13 | * @description 14 | */ 15 | 16 | public class MySmartRefreshLayout extends SmartRefreshLayout { 17 | public static final int TYPE_FRESH = 0; 18 | public static final int TYPE_LOAD_MORE = 1; 19 | 20 | public MySmartRefreshLayout(Context context) { 21 | this(context, null); 22 | } 23 | 24 | public MySmartRefreshLayout(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | init(); 27 | } 28 | 29 | private void init() { 30 | //显示下拉高度/手指真实下拉高度=阻尼效果 31 | setDragRate(0.5f); 32 | //是否启用越界回弹 33 | setEnableOverScrollBounce(true); 34 | //回弹动画时长(毫秒) 35 | setReboundDuration(300); 36 | //是否启用越界拖动(仿苹果效果) 37 | setEnableOverScrollDrag(true); 38 | // 设置默认的刷新布局 39 | setRefreshHeader(new ClassicsHeader(getContext())); 40 | // 设置默认的加载更多布局 41 | setRefreshFooter(new ClassicsFooter(getContext())); 42 | //是否在刷新的时候禁止列表的操作 43 | setDisableContentWhenRefresh(false); 44 | //是否在加载的时候禁止列表的操作 45 | setDisableContentWhenLoading(false); 46 | } 47 | 48 | /** 49 | * 结束刷新或加载更多 50 | * 51 | * @param type :当前获取数据的类型 0 - 刷新 1 - 加载更多 52 | * @param success :获取数据是否成功 53 | */ 54 | public void finish(int type, boolean success, boolean noMoreData) { 55 | if (TYPE_FRESH == type) { 56 | finishRefresh(success); 57 | } else if (TYPE_LOAD_MORE == type) { 58 | finishLoadMore(0, success, noMoreData); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/widget/PrivacyPolicyDialog.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.widget; 2 | 3 | import android.app.Activity; 4 | import android.app.Dialog; 5 | import androidx.annotation.NonNull; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.TextView; 9 | 10 | import cn.admobiletop.adsuyidemo.R; 11 | import cn.admobiletop.adsuyidemo.activity.other.NormalWebActivity; 12 | import cn.admobiletop.adsuyidemo.util.StringUtil; 13 | 14 | /** 15 | * @author parting_soul 16 | * @date 2018/11/1 17 | */ 18 | public class PrivacyPolicyDialog extends Dialog { 19 | 20 | private OnResultCallback mCallback; 21 | 22 | 23 | public PrivacyPolicyDialog(@NonNull Activity activity) { 24 | super(activity); 25 | setContentView(R.layout.dialog_privacy_policy); 26 | TextView tvContent = findViewById(R.id.tvContent); 27 | StringUtil.KeyWordClick privacyPolicySpan = new StringUtil.KeyWordClick("《隐私政策》", 0xffFEB34D, new View.OnClickListener() { 28 | @Override 29 | public void onClick(View v) { 30 | // TODO: 2020/9/10 跳转隐私政策详情界面(仅为示例,请结合自己的业务需求) 31 | NormalWebActivity.jump(getContext(), "https://www.admobile.top/privacyPolicy.html"); 32 | } 33 | }); 34 | StringUtil.setCustomKeyWordClickSpan(tvContent, tvContent.getText().toString(), privacyPolicySpan); 35 | Button btnDisagree = findViewById(R.id.btnDisagree); 36 | Button btnAgree = findViewById(R.id.btnAgree); 37 | 38 | btnAgree.setOnClickListener(new View.OnClickListener() { 39 | @Override 40 | public void onClick(View v) { 41 | dismiss(); 42 | if (mCallback != null) { 43 | mCallback.onConfirm(); 44 | } 45 | } 46 | }); 47 | 48 | btnDisagree.setOnClickListener(new View.OnClickListener() { 49 | @Override 50 | public void onClick(View v) { 51 | dismiss(); 52 | if (mCallback != null) { 53 | mCallback.onCancel(); 54 | } 55 | } 56 | }); 57 | } 58 | 59 | public void setOnResultCallback(OnResultCallback callback) { 60 | this.mCallback = callback; 61 | } 62 | 63 | public interface OnResultCallback { 64 | void onConfirm(); 65 | 66 | void onCancel(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/main/java/cn/admobiletop/adsuyidemo/widget/ViewPagerLayoutManager.java: -------------------------------------------------------------------------------- 1 | package cn.admobiletop.adsuyidemo.widget; 2 | 3 | import android.content.Context; 4 | import androidx.recyclerview.widget.LinearLayoutManager; 5 | import androidx.recyclerview.widget.PagerSnapHelper; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | public class ViewPagerLayoutManager extends LinearLayoutManager { 9 | private PagerSnapHelper mPagerSnapHelper; 10 | 11 | public ViewPagerLayoutManager(Context context, int orientation) { 12 | super(context, orientation, false); 13 | init(); 14 | } 15 | 16 | public ViewPagerLayoutManager(Context context, int orientation, boolean reverseLayout) { 17 | super(context, orientation, reverseLayout); 18 | init(); 19 | } 20 | 21 | private void init() { 22 | mPagerSnapHelper = new PagerSnapHelper(); 23 | } 24 | 25 | @Override 26 | public void onAttachedToWindow(RecyclerView recyclerView) { 27 | super.onAttachedToWindow(recyclerView); 28 | mPagerSnapHelper.attachToRecyclerView(recyclerView); 29 | } 30 | 31 | @Override 32 | public void onScrollStateChanged(int state) { 33 | switch (state) { 34 | case RecyclerView.SCROLL_STATE_IDLE: 35 | mPagerSnapHelper.findSnapView(this); 36 | break; 37 | default: 38 | break; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/icon_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ADSuyi/ADSuyiSdkDemo-Android/8200f11ae36b6ec66fcb5f93b3e5571b0dd6ed7b/app/src/main/res/drawable-xxhdpi/icon_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/icon_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ADSuyi/ADSuyiSdkDemo-Android/8200f11ae36b6ec66fcb5f93b3e5571b0dd6ed7b/app/src/main/res/drawable-xxhdpi/icon_setting.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chevron_right_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_background_button_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_background_circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_black_000000_radius15.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_color_primary_dark_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_f2f2f2_4dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_fff2e0_4dp.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_white_ffffff_radius50.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_adsuyi_init_and_load_splash_ad.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_banner.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 15 | 16 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | 38 | 39 | 40 | 41 | 42 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_content_alliance_ad.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 17 | 18 | 19 | 20 |