Commit 1d3a7eee authored by 王雪伟's avatar 王雪伟

[提交人]:王雪伟

[提交简述] :1.1.2
[实现方案] :加入开屏广告
parent 03f48870
...@@ -45,7 +45,6 @@ ...@@ -45,7 +45,6 @@
<application <application
android:name=".Appli" android:name=".Appli"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:largeHeap="true" android:largeHeap="true"
......
...@@ -25,7 +25,6 @@ import com.zxhl.cms.net.RxSchedulers; ...@@ -25,7 +25,6 @@ import com.zxhl.cms.net.RxSchedulers;
import com.zxhl.cms.net.SettingPreference; import com.zxhl.cms.net.SettingPreference;
import com.zxhl.cms.net.callback.BaseObserver; import com.zxhl.cms.net.callback.BaseObserver;
import com.zxhl.cms.net.model.uc.UserInfo; import com.zxhl.cms.net.model.uc.UserInfo;
import com.zxhl.cms.utils.AdDataSupport;
import com.zxhl.cms.utils.EventUtils; import com.zxhl.cms.utils.EventUtils;
import com.zxhl.cms.utils.JumpUtils; import com.zxhl.cms.utils.JumpUtils;
import com.zxhl.cms.utils.RxBus; import com.zxhl.cms.utils.RxBus;
...@@ -80,7 +79,6 @@ public class MainActivity extends BaseActivity implements NavigationBottomView.N ...@@ -80,7 +79,6 @@ public class MainActivity extends BaseActivity implements NavigationBottomView.N
); );
navigationView = findViewById(R.id.id_activity_main_fragment_navigation); navigationView = findViewById(R.id.id_activity_main_fragment_navigation);
initListener(); initListener();
AdDataSupport.INSTANCE.init(this);
mRestartLoginObservable = RxBus.get().register(Constant.REFRESH_LOGIN_STATS, String.class); mRestartLoginObservable = RxBus.get().register(Constant.REFRESH_LOGIN_STATS, String.class);
mRestartLoginObservable.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() { mRestartLoginObservable.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
@Override @Override
......
...@@ -80,7 +80,6 @@ dependencies { ...@@ -80,7 +80,6 @@ dependencies {
api 'jp.wasabeef:glide-transformations:2.0.1' api 'jp.wasabeef:glide-transformations:2.0.1'
api(name: 'oaid_sdk_1.0.25', ext: 'aar') api(name: 'oaid_sdk_1.0.25', ext: 'aar')
api(name: 'open_ad_sdk_4.0.0.3', ext: 'aar')
api(name: 'tools_release', ext: 'aar') api(name: 'tools_release', ext: 'aar')
api 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.3.1' api 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
...@@ -93,4 +92,6 @@ dependencies { ...@@ -93,4 +92,6 @@ dependencies {
api 'com.yarolegovich:discrete-scrollview:1.5.1' api 'com.yarolegovich:discrete-scrollview:1.5.1'
//bugly //bugly
api 'com.tencent.bugly:crashreport:4.0.4' api 'com.tencent.bugly:crashreport:4.0.4'
//
api project(':moduleZxAd')
} }
...@@ -3,6 +3,8 @@ package com.zxhl.cms.common ...@@ -3,6 +3,8 @@ package com.zxhl.cms.common
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import com.ayl.ces.jni.CesCore import com.ayl.ces.jni.CesCore
import com.zx.ad.AdManager
import com.zx.ad.modulecommon.AdConstant
import com.zxhl.cms.AppContext import com.zxhl.cms.AppContext
import com.zxhl.cms.utils.LogUtils import com.zxhl.cms.utils.LogUtils
import com.zxhl.cms.utils.PhoneUtils import com.zxhl.cms.utils.PhoneUtils
...@@ -57,6 +59,21 @@ class Config { ...@@ -57,6 +59,21 @@ class Config {
LogUtils.d("Param", "Param.imsi: " + Constant.Param.imsi) LogUtils.d("Param", "Param.imsi: " + Constant.Param.imsi)
LogUtils.d("Param", "Param.miToken: " + Constant.Param.miToken) LogUtils.d("Param", "Param.miToken: " + Constant.Param.miToken)
LogUtils.d("Param", "Param.env: " + Constant.Param.env) LogUtils.d("Param", "Param.env: " + Constant.Param.env)
AdConstant.param.androidId = Constant.Param.androidId
AdConstant.param.carrier = Constant.Param.carrier
AdConstant.param.w = Constant.Param.w
AdConstant.param.h = Constant.Param.h
AdConstant.param.model = Constant.Param.model
AdConstant.param.vc = Constant.Param.vc
AdConstant.param.device = Constant.Param.device
AdConstant.param.imei = Constant.Param.imei
AdConstant.param.mac = Constant.Param.mac
AdConstant.param.ua = Constant.Param.ua
AdConstant.param.ntt = Constant.Param.ntt
AdConstant.param.svn = Constant.Param.svn
AdConstant.param.imsi = Constant.Param.imsi
AdConstant.param.env = Constant.Param.env
AdManager.init(context, Constant.Param.APPLS)
} }
} }
} }
......
...@@ -2,6 +2,7 @@ package com.zxhl.cms.utils ...@@ -2,6 +2,7 @@ package com.zxhl.cms.utils
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.os.Bundle
import com.bytedance.sdk.openadsdk.* import com.bytedance.sdk.openadsdk.*
import com.zxhl.cms.ad.upload.Utils.AdUpload import com.zxhl.cms.ad.upload.Utils.AdUpload
import com.zxhl.cms.ad.upload.model.NewsEntity import com.zxhl.cms.ad.upload.model.NewsEntity
...@@ -72,8 +73,6 @@ object AdDataSupport { ...@@ -72,8 +73,6 @@ object AdDataSupport {
) { ) {
val adSlot = AdSlot.Builder() val adSlot = AdSlot.Builder()
.setCodeId(data.codeId) .setCodeId(data.codeId)
.setRewardName("金币") //奖励的名称 选填
.setRewardAmount(3) //奖励的数量 选填
.setMediaExtra("media_extra") //附加参数 .setMediaExtra("media_extra") //附加参数
.setOrientation(TTAdConstant.VERTICAL) //必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL .setOrientation(TTAdConstant.VERTICAL) //必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL
.build() .build()
...@@ -126,6 +125,10 @@ object AdDataSupport { ...@@ -126,6 +125,10 @@ object AdDataSupport {
) { ) {
} }
override fun onRewardArrived(p0: Boolean, p1: Int, p2: Bundle?) {
}
override fun onSkippedVideo() { override fun onSkippedVideo() {
} }
......
...@@ -6,6 +6,8 @@ import android.util.Log ...@@ -6,6 +6,8 @@ import android.util.Log
import android.view.View import android.view.View
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import com.umeng.analytics.MobclickAgent import com.umeng.analytics.MobclickAgent
import com.zx.ad.AdManager
import com.zx.ad.callback.SplashAdListener
import com.zxbw.modulemain.R import com.zxbw.modulemain.R
import com.zxbw.modulemain.contract.SplashContract import com.zxbw.modulemain.contract.SplashContract
import com.zxbw.modulemain.presenter.SplashPresenter import com.zxbw.modulemain.presenter.SplashPresenter
...@@ -24,6 +26,7 @@ import com.zxhl.cms.utils.EventUtils ...@@ -24,6 +26,7 @@ import com.zxhl.cms.utils.EventUtils
import com.zxhl.cms.utils.JumpUtils import com.zxhl.cms.utils.JumpUtils
import com.zxhl.cms.utils.Utils import com.zxhl.cms.utils.Utils
import com.zxhl.cms.widget.CenterDialog import com.zxhl.cms.widget.CenterDialog
import kotlinx.android.synthetic.main.activity_splash.*
/** /**
* Created by gaoleichao on 2018/12/26 * Created by gaoleichao on 2018/12/26
...@@ -64,30 +67,32 @@ class SplashActivity : BaseActivity(), SplashContract.View { ...@@ -64,30 +67,32 @@ class SplashActivity : BaseActivity(), SplashContract.View {
private fun initListener() { private fun initListener() {
getAppInfo() getAppInfo()
AdManager.loadSplashAd(this,id_splash_view,object :SplashAdListener{
override fun onAdShow() {
}
override fun onAdSkip() {
jumpMainPage()
}
override fun onError(errorMsg: String?) {
jumpMainPage() jumpMainPage()
// id_activity_splash_skip?.setOnClickListener { }
// jumpMainPage() })
// }
} }
override fun jumpMainPage() { override fun jumpMainPage() {
val user = SettingPreference.getUserInfoData() val user = SettingPreference.getUserInfoData()
val token = SettingPreference.getUserToken() val token = SettingPreference.getUserToken()
if (user == null && TextUtils.isEmpty(token)) { if (user == null && TextUtils.isEmpty(token)) {
// if (TextUtils.equals(Utils.getChannel(this), "baichuan")) {
// JumpUtils.loginJump()
// } else {
// mPresenter?.checkLogin()
// }
JumpUtils.loginJump() JumpUtils.loginJump()
} else { } else {
// openApp() openApp()
JumpUtils.activityJump( JumpUtils.activityJump(
RounterBus.getRounter(RounterApi::class.java).getIntentActivityMain() RounterBus.getRounter(RounterApi::class.java).getIntentActivityMain()
) )
} }
finish() finish()
} }
......
...@@ -6,6 +6,8 @@ import android.view.View ...@@ -6,6 +6,8 @@ import android.view.View
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.CircleCrop import com.bumptech.glide.load.resource.bitmap.CircleCrop
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.zx.ad.AdManager
import com.zx.ad.callback.RewardVideoAdListener
import com.zxbw.modulemain.R import com.zxbw.modulemain.R
import com.zxbw.modulemain.view.DialogUtils import com.zxbw.modulemain.view.DialogUtils
import com.zxhl.cms.common.NetConfig import com.zxhl.cms.common.NetConfig
...@@ -67,6 +69,26 @@ class UserCenterFragment : BaseFragment(), AdCallback<String> { ...@@ -67,6 +69,26 @@ class UserCenterFragment : BaseFragment(), AdCallback<String> {
} }
private fun loadRewardAd(){
AdManager.loadRewardAd(activity!!,object :RewardVideoAdListener{
override fun onRewardVideoAdClose() {
Log.d("wxw","onRewardVideoAdClose")
}
override fun onRewardVideoAdReward() {
Log.d("wxw","onRewardVideoAdReward")
}
override fun onRewardVideoAdShow() {
Log.d("wxw","onRewardVideoAdShow")
}
override fun onRewardVideoAdError(errorMsg: String?) {
Log.d("wxw","onRewardVideoAdError${errorMsg}")
}
})
}
override fun data() { override fun data() {
super.data() super.data()
userVisibleHint = true userVisibleHint = true
......
...@@ -35,4 +35,8 @@ ...@@ -35,4 +35,8 @@
android:textColor="#FFD7CDC1"/> android:textColor="#FFD7CDC1"/>
</LinearLayout> </LinearLayout>
<FrameLayout
android:id="@+id/id_splash_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout> </RelativeLayout>
/build
\ No newline at end of file
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
consumerProguardFiles "consumer-rules.pro"
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
repositories {
flatDir {
dirs 'libs' // aar用到
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
packagingOptions {
exclude 'META-INF/ASL2.0'
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
exclude 'META-INF/LGPL2.1'
exclude 'META-INF/AL2.0'
exclude 'META-INF/services/javax.annotation.processing.Processor'
exclude 'META-INF/rxjava.properties'
exclude("META-INF/*.kotlin_module")
}
}
dependencies {
api fileTree(include: ['*.jar'], dir: 'libs')
api fileTree(include: ['*.aar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api 'androidx.appcompat:appcompat:1.2.0-alpha02'
api 'com.android.support:design:28.0.0'
// api 'com.android.support:multidex:1.0.0'
api 'com.squareup.okhttp3:okhttp:3.10.0'
api 'com.squareup.okhttp3:logging-interceptor:3.4.1'
api 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
api 'com.trello.rxlifecycle2:rxlifecycle:2.2.0'
api 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.0'
api 'com.squareup.retrofit2:retrofit:2.3.0'
api 'com.squareup.retrofit2:converter-gson:2.3.0'
api 'com.badoo.mobile:android-weak-handler:1.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.zx.ad
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.zx.ad.test", appContext.packageName)
}
}
\ No newline at end of file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.zx.ad">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true">
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<provider
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<provider
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:exported="false" />
<!-- 声明SDK所需要的组件 -->
<provider
android:name="com.qq.e.comm.GDTFileProvider"
android:authorities="${applicationId}.gdt.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/gdt_file_path" />
</provider>
<service
android:name="com.qq.e.comm.DownloadService"
android:exported="false" />
<!-- 请开发者注意字母的大小写,ADActivity,而不是AdActivity -->
<activity
android:name="com.qq.e.ads.ADActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize" />
<activity
android:name="com.qq.e.ads.PortraitADActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<!-- <activity-->
<!-- android:name="com.qq.e.ads.LandscapeADActivity"-->
<!-- android:configChanges="keyboard|keyboardHidden|orientation|screenSize"-->
<!-- android:screenOrientation="landscape" />-->
</application>
</manifest>
\ No newline at end of file
This diff is collapsed.
package com.zx.ad.callback;
import com.zx.ad.modulecommon.module.NewsEntity;
/**
* @author (wangXuewei)
* @datetime 2022-06-13 19:02 GMT+8
* @detail :
*/
public interface AdLoadCallBack {
void OnAdLoadSuccess(String platform, NewsEntity entity);
void OnAdLoadFail(String errorMsg);
}
package com.zx.ad.callback
interface RewardVideoAdListener {
//激励视频是否完整看完
fun onRewardVideoAdClose()
//奖励
fun onRewardVideoAdReward()
//获取广告展示
fun onRewardVideoAdShow()
//获取广告错误
fun onRewardVideoAdError(errorMsg: String?)
}
\ No newline at end of file
package com.zx.ad.callback
interface SplashAdListener {
//获取开屏广告 展示 广告
fun onAdShow()
//获取开屏广告 跳过 广告
fun onAdSkip()
//获取广告 错误 广告
fun onError(errorMsg: String?)
}
\ No newline at end of file
package com.zx.ad.modulecommon;
import android.os.Build;
import java.util.HashMap;
/**
* Created by gaoleichao on 2018/4/25.
*/
public class AdConstant {
//全局参数配置
public static HashMap<String,String> commParams = new HashMap<String,String>();
/**
* key
*/
public static class Device {
public static final String h = "h";
public static final String w = "w";
public static final String model = "model";
public static final String vendor = "vendor";
public static final String svn = "svn";
public static final String env = "env";
public static final String cv = "cv";
public static final String ntt = "ntt";
public static final String vc = "vc";
public static final String vn = "vn";
public static final String ts = "ts";
public static final String aid = "aid";//android id,用户设备唯一标识
public static final String uid = "uid";
public static final String device = "device";
public static final String carrier = "carrier";
public static final String mac = "mac";//mac
public static final String imei = "imei";//全球唯一标识
public static final String platform = "platform";//平台
public static final String imsi = "imsi";
public static final String oaid = "oaid";
public static final String ssid = "ssid";
public static final String ip = "ip";
public static final String pkg = "pkg";
public static final String token = "token";
public static final String source = "source";
public static final String ua = "ua";
public static final String lat = "lat";
public static final String lon = "lon";
public static final String locationtype = "locationtype";
public static final String city = "city";
public static final String blackBox = "blackBox";
}
/**
* value
*/
public static class param {
//最重要的参数 公共参数
public static String uid = "";
public static String token = "";
public static String appLs = "";
public static String a = "D0EV7FZL45A5DVKD";
public static String b = "E2Y1YREK2BYDAC5B";
public static String mPacketName = "";
public static String svn = Build.VERSION.SDK_INT + "";
public static String androidId = "";
public static String carrier = "";
public static String h = "";
public static String w = "";
public static String model = "";
public static String source = "";
public static String vc = "";
public static String vn = "";
public static String device = "";
public static String mac = "";
public static String imei = "";
public static String ua = "";
public static String ntt = "";
public static String userAgent = "";
public static String imsi = "";
public static String oaid = "";
public static String lat = "";
public static String lon = "";
public static String city = "";
public static String locationType = "";
public static String uuid = "";
public static String env = "";
}
}
\ No newline at end of file
package com.zx.ad.modulecommon;
public class AdNetConfig {
public static enum Environment {
DEV,
TEST,
PRODUCT
}
// 根据调试选项更新环境
public static Environment sEnvironment = Environment.PRODUCT;// 当前环境
public static String BASE_WEB_URL = "";
public static String BASE_URL = "";
public static String BASE_AD_URL = "";
public static String BASE_NEW_URL = "";
public static String BASE_FEED_URL = "";
public static String URL_REPORT_BASE = "http://report.zhangxinhulian.com/";
public static final String HOME_BANNER_BASE_URL = "https://bs.zhangxinhulian.com/";
public static void setBase_Url(Environment s) {
sEnvironment = s;
switch (sEnvironment) {
case PRODUCT:
BASE_URL = "https://api.zhangxinhulian.com/";
BASE_WEB_URL = "https://www.zhangxinhulian.com/";
BASE_NEW_URL = "https://newapi.zhangxinhulian.com/";
BASE_FEED_URL = "https://feedapi.zhangxinhulian.com/";
BASE_AD_URL = "https://bs.zhangxinhulian.com/";
URL_REPORT_BASE = "https://report.zhangxinhulian.com/";
break;
case TEST:
BASE_URL = "https://sandbox.zhangxinhulian.com/";
BASE_WEB_URL = "https://www.zhangxinhulian.com/";
BASE_NEW_URL = "http://newapi.zhangxinhulian.com/";
BASE_FEED_URL = "http://feedapi.zhangxinhulian.com/";
BASE_AD_URL = "https://bs.zhangxinhulian.com/";
URL_REPORT_BASE = "http://report.zhangxinhulian.com/";
break;
default:
BASE_URL = "http://apitest.zhangxinhulian.com/";
BASE_WEB_URL = "http://www.zhangxinhulian.com:8888/";
BASE_NEW_URL = "http://newapitest.zhangxinhulian.com/";
BASE_FEED_URL = "http://feedapitest.zhangxinhulian.com/";
BASE_AD_URL = "http://bstest.zhangxinhulian.com/";
URL_REPORT_BASE = "http://reporttest.zhangxinhulian.com/";
break;
}
}
public static class Ad {
public static final String URL_EVENT = "logCollection/log/v1/userLogCollection";
public static final String URL_GET_ADS_V4 = "v4/ads";
}
}
This diff is collapsed.
package com.zx.ad.modulecommon.module
/**
* Created by erwin on 2020/11/11
*/
class AdIdConfig {
var adPlatform:String? = null
var codeAppId:String? = null
var codeAppKey:String? = null
}
\ No newline at end of file
package com.zx.ad.modulecommon.module;
public class PackageInfoEntity {
private String packageName;
private String installTime;
private String updateTime;
public PackageInfoEntity(String packageName, String installTime, String updateTime) {
this.packageName = packageName;
this.installTime = installTime;
this.updateTime = updateTime;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getInstallTime() {
return installTime;
}
public void setInstallTime(String installTime) {
this.installTime = installTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
}
package com.zx.ad.modulecommon.module
class ReportEntity {
var sessionId: String? = ""
var page: String? = ""
var status: String? = ""
constructor(sessionId: String, page: String, status: String){
this.sessionId = sessionId
this.page = page
this.status = status
}
}
\ No newline at end of file
package com.zx.ad.modulecommon.module
class WithdrawResultEntity {
val buttonStatus: Int? = 0//按钮跳转 0 不跳转 1 福利页 2 首页 3 跳转激励视频 4 大富翁 5 刮刮卡 6 邀请页 7 旅行打卡页
val buttonText: String? = ""
val cash: Int? = 0
val reason: String? = ""//提现失败原因
val status: Int? = 0
val title: String? = ""
val type: Int? = 0
}
\ No newline at end of file
package com.zx.ad.modulecommon.net;
import android.text.TextUtils;
import io.reactivex.Observer;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
public abstract class BaseObserver<T> implements Observer<Response<T>> {
private Disposable disposable;
@Override
public void onNext(@NonNull Response<T> result) {
if (TextUtils.equals(result.status, "200")) {
if (result.result != null) {
onSuccess(result.result.data);
} else {
onSuccess(null);
}
} else if (TextUtils.equals(result.status, "101")) {
} else if (TextUtils.equals(result.status, "160")) {
onFailure(null, "160", "请重试");//该异常可以汇报服务端
} else {
onFailure(new Exception(result.msg), result.status, result.msg);//该异常可以汇报服务端
}
}
@Override
public void onError(@NonNull Throwable e) {
// if(e.getMessage().contains("403")){//
//// NetConfig.setBase_Url(NetConfig.Environment.DEV);
// AdPreference.saveEvnvironment(NetConfig.Environment.DEV.toString());
// NetConfig.setBase_Url(NetConfig.Environment.DEV);
// restartApp();
// }
onFailure(e, "250", e.getMessage());//该异常可以汇报服务端
}
@Override
public void onComplete() {
if (disposable != null && !disposable.isDisposed()) {
disposable.dispose();
}
}
@Override
public void onSubscribe(@NonNull Disposable d) {
disposable = d;
}
public abstract void onSuccess(T result);
public abstract void onFailure(Throwable e, String code, String errorMsg);
}
package com.zx.ad.modulecommon.net;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class DecryptInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
MediaType mediaType = response.body().contentType();
String body = response.body().string();
// LogUtils.d("DecryptInterceptor", "response: " + body);
try {
JSONObject jsonObject = new JSONObject(body);
int status = jsonObject.getInt("status");
if (status == 200) {
if (jsonObject.has("security")) {
String security = jsonObject.getString("security");
if (("SECURITY").equals(security)) {
if (jsonObject.has("sign") && jsonObject.has("enc")) {
String sign = jsonObject.getString("sign");
String enc = jsonObject.getString("enc");
String signResult = DecryptInterface.INSTANCE.DataSignVerify(enc, sign);
// LogUtils.d("DecryptInterceptor", "signResult: " + signResult);
if (("OK").equals(signResult)) {
String decryptResult = DecryptInterface.INSTANCE.DecryptData(enc);
// LogUtils.d("DecryptInterceptor", "decryptResult: " + decryptResult);
return response.newBuilder().body(ResponseBody.create(mediaType, decryptResult)).build();
}
}
}
}
}
return response.newBuilder().body(ResponseBody.create(mediaType, body)).build();
} catch (JSONException e) {
e.printStackTrace();
}
return response.newBuilder().body(ResponseBody.create(mediaType, body)).build();
}
}
package com.zx.ad.modulecommon.net;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface DecryptInterface extends Library {
DecryptInterface INSTANCE = Native.loadLibrary("encrypt", DecryptInterface.class);
String DataSignVerify(String enc, String sign);
String DecryptData(String enc);
}
package com.zx.ad.modulecommon.net;
import com.zx.ad.modulecommon.AdConstant
import com.zx.ad.modulecommon.AdNetConfig
import com.zx.ad.modulecommon.AdPhoneUtil
import com.zx.ad.modulecommon.net.api.IAdApi
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
/**
* Created by gaoleichao on 2018/5/2.
*/
object EventApiClient {
private val logInterceptor = HttpLoggingInterceptor()
private val paramsInterceptor = Interceptor { chain ->
val request = chain.request()
val builder = request.url().newBuilder()
val params = AdPhoneUtil.addCommonParam()
val putkeys = params.keys
for (s in putkeys) {
builder.addQueryParameter(s, params[s])
}
chain.proceed(request.newBuilder().url(builder.build()).build())
}
private val headInterceptor = Interceptor { chain ->
val request = chain.request()
val builder = request.newBuilder()
// PhoneUtils.addHeader(builder)
builder.addHeader(AdConstant.Device.aid, AdConstant.param.androidId)
val headers: Request = builder.build()
chain.proceed(headers)
}
private val httpClient = okhttp3.OkHttpClient.Builder()
.connectTimeout(10000, TimeUnit.MILLISECONDS)
.readTimeout(10000, TimeUnit.MILLISECONDS)
.addInterceptor(logInterceptor.apply {
level = HttpLoggingInterceptor.Level.NONE
})
.hostnameVerifier { hostname, session ->
true
}
.addInterceptor(paramsInterceptor)
.addInterceptor(headInterceptor)
.build()!!
private val retrofit = retrofit2.Retrofit.Builder()
.client(httpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(AdNetConfig.URL_REPORT_BASE)
.build()
val adApi by lazy { retrofit.create(IAdApi::class.java) }
}
\ No newline at end of file
package com.zx.ad.modulecommon.net
import java.util.Comparator
/**
* Created by gaoleichao on 2018/7/13.
*/
class MapKeyComparator : Comparator<String> {
override fun compare(str1: String, str2: String): Int {
return str1.compareTo(str2)
}
}
package com.zx.ad.modulecommon.net;
import java.io.Serializable;
public class Response<T> {
public String status = "";
public String msg = "";
public Result<T> result = null;
class Result<T> implements Serializable {
T data = null;
}
}
package com.zx.ad.modulecommon.net;
import android.content.Context;
import com.trello.rxlifecycle2.android.ActivityEvent;
import com.trello.rxlifecycle2.components.RxActivity;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
import com.trello.rxlifecycle2.components.support.RxFragment;
import com.trello.rxlifecycle2.components.support.RxFragmentActivity;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public class RxSchedulers {
public static <T> ObservableTransformer<T, T> observableIO2Main(final Context context) {
return upstream -> {
Observable<T> observable = upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
return composeContext(context, observable);
};
}
public static <T> ObservableTransformer<T, T> observableIO2Main(RxFragment fragment) {
return upstream -> upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).compose(fragment.<T>bindToLifecycle());
}
public static <T> ObservableTransformer<T, T> observableIO2Main() {
return upstream -> upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private static <T> ObservableSource<T> composeContext(Context context, Observable<T> observable) {
if (context instanceof RxActivity) {
return observable.compose(((RxActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
} else if (context instanceof RxFragmentActivity) {
return observable.compose(((RxFragmentActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
} else if (context instanceof RxAppCompatActivity) {
return observable.compose(((RxAppCompatActivity) context).bindUntilEvent(ActivityEvent.DESTROY));
} else {
return observable;
}
}
}
package com.zx.ad.modulecommon.net
import android.text.TextUtils
import com.zx.ad.modulecommon.AdConstant
import com.zx.ad.modulecommon.AdNetConfig
import com.zx.ad.modulecommon.AdPhoneUtil
import com.zx.ad.modulecommon.net.api.IAdApi
import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
object ZXADClient {
private val logInterceptor = HttpLoggingInterceptor()
private val paramsInterceptor = Interceptor { chain ->
val request = chain.request()
val builder = request.url().newBuilder()
if (request.url().toString().contains("yilan")) {
chain.proceed(request.newBuilder().build())
} else {
AdPhoneUtil.addParam(request, builder)
chain.proceed(request.newBuilder().url(builder.build()).build())
}
}
private val headInterceptor = Interceptor { chain ->
val request = chain.request()
val builder = request.newBuilder()
builder.addHeader(AdConstant.Device.aid, AdConstant.param.androidId)
builder.addHeader(AdConstant.Device.env, AdConstant.param.env)
if (!TextUtils.isEmpty(AdConstant.param.userAgent)) {
builder.addHeader("web-user-agent", AdConstant.param.userAgent)
builder.removeHeader("User-Agent")
builder.addHeader("User-Agent", AdConstant.param.userAgent)
}
chain.proceed(builder.build())
}
private val httpClient = okhttp3.OkHttpClient.Builder()
.connectTimeout(10000, TimeUnit.MILLISECONDS)
.readTimeout(10000, TimeUnit.MILLISECONDS)
.addInterceptor(logInterceptor.apply {
level = HttpLoggingInterceptor.Level.BODY
// level = HttpLoggingInterceptor.Level.NONE
})
.addInterceptor(DecryptInterceptor())
.hostnameVerifier { hostname, session ->
true
}
.addInterceptor(paramsInterceptor)
.addInterceptor(headInterceptor)
.build()!!
private val retrofit = retrofit2.Retrofit.Builder()
.client(httpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(AdNetConfig.BASE_AD_URL)
.build()
val adApi by lazy { retrofit.create(IAdApi::class.java) }
}
\ No newline at end of file
package com.zx.ad.modulecommon.net.api
import com.zx.ad.modulecommon.AdNetConfig
import com.zx.ad.modulecommon.module.AdIdConfig
import com.zx.ad.modulecommon.module.NewsEntity
import com.zx.ad.modulecommon.net.Response
import io.reactivex.Observable
import okhttp3.ResponseBody
import retrofit2.http.*
/**
* Created by gaoleichao on 2020-05-07
*/
interface IAdApi{
@GET(AdNetConfig.Ad.URL_GET_ADS_V4)
fun getAds(@Query("slotName") slotId: String): Observable<Response<List<NewsEntity>?>>
@GET("v1/fetch/adAppIds")
fun getADConfig(@Query("pkg") pkg: String): Observable<Response<List<AdIdConfig>?>>
/**
* 普通上报
*
* @return
*/
@POST(AdNetConfig.Ad.URL_EVENT)
fun requestEvent(
@Query("module") module: String?,
@Body data: Any?
): Observable<Response<Any?>>
/**
* 广告上报
*
* @return
*/
@GET
fun requestEvent(@Url url: String?): Observable<Response<ResponseBody?>>
}
\ No newline at end of file
package com.zx.ad.platform
object ADType {
// start=====================================================================
/**
* 新
* 1001 chuanshanjia 穿山甲 1
1002 kuaishou 快手 1
1003 guangdiantong 广点通 1
1004 youliangbao 优量宝 1
*/
const val PLATFORM_AD_TT = "chuanshanjia" //穿山甲
const val PLATFORM_AD_GDT = "guangdiantong" //广点通
const val PLATFORM_AD_KS = "kuaishou" //快手
const val PLATFORM_SH_YLB = "youliangbao"//优量宝
const val PLATFORM_AD_SIGNMOB = "sigmob" //sign Mob
const val PLATFORM_AD_BD = "baidu" //百度
const val PLATFORM_AD_SH = "shanhu"//珊瑚
const val PLATFORM_AD_RS = "ruishi"//瑞狮
const val PLATFORM_AD_NEWS = "news"//新闻站
const val PLATFORM_AD_FENGXING = "fengxing"//风行
const val AD_SPLASH = "splash" //开屏广告
const val AD_REWARD_VIDEO = "video" //激励视频广告
const val AD_BIG_IMAGE = "bigimage" //大图广告
const val AD_FULL_VIDEO = "fullvideo" //全屏视频广告
// =====================================================================stop
// 广告内容模式
// 大图
const val AD_MODE_BIGIMAGE = 1
// 小图
const val AD_MODE_SMALLIMG = 2
// 多图
const val AD_MODE_MOREIMG = 3
// 图文
const val AD_MODE_WORDSIMG = 4
// 视频
const val AD_MODE_VIDEO = 5
// 渠道类型
const val AD_TYPE_CSJ = 11
const val AD_TYPE_GDT = 12
const val AD_TYPE_BAI = 13
const val AD_TYPE_SEL = 14
const val AD_TYPE_KUS = 15
// 渠道名定义
const val AD_CHANNEL_CSJ = "csj"
const val AD_CHANNEL_GDT = "gdt"
const val AD_CHANNEL_BAI = "bai"
const val AD_CHANNEL_SEL = "sel"
const val AD_CHANNEL_KUS = "kus"
// 渠道ADID
const val AD_ID_CSJ = "1101"
const val AD_ID_GDT = "1102"
const val AD_ID_BAI = "1103"
const val AD_ID_SEL = "1104"
const val AD_ID_KUS = "1105"
}
\ No newline at end of file
package com.zx.ad.platform.csj
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import com.bytedance.sdk.openadsdk.*
import com.zx.ad.callback.AdLoadCallBack
import com.zx.ad.callback.RewardVideoAdListener
import com.zx.ad.callback.SplashAdListener
import com.zx.ad.modulecommon.module.NewsEntity
import com.zx.ad.platform.ADType
import com.zx.ad.utils.AdEventUtils
import com.zx.ad.utils.LogUtils
import com.zx.ad.utils.UIUtils
/**
* @author (wangXuewei)
* @datetime 2022-06-13 19:06 GMT+8
* @detail :穿山甲广告平台
*/
object CSJAdManager {
private var mTTAdNative: TTAdNative? = null
fun adInit(context: Context, appId: String) {
TTAdManagerHolder.init(context, appId)
// TTAdManagerHolder.init(context, "5001121")
}
private var splashAd: TTSplashAd? = null
/**
* 加载开屏广告
*/
fun loadSplashAd(context: Context, entity: NewsEntity, loadCallBack: AdLoadCallBack) {
mTTAdNative = TTAdManagerHolder.get().createAdNative(context)
val splashWidthPx = UIUtils.getScreenWidthInPx(context)
val screenHeightPx = UIUtils.getScreenHeight(context)
val splashWidthDp = UIUtils.getScreenWidthDp(context)
val screenHeightDp = UIUtils.px2dip(context, screenHeightPx.toFloat()).toFloat()
var adSlot = AdSlot.Builder()
.setCodeId(entity.codeId)
.setImageAcceptedSize(splashWidthPx, screenHeightPx)
.setExpressViewAcceptedSize(splashWidthDp, screenHeightDp)
.build()
mTTAdNative?.loadSplashAd(adSlot, object : TTAdNative.SplashAdListener {
override fun onError(p0: Int, p1: String?) {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("CSJ p0:${p0} p1:${p1}")
}
override fun onTimeout() {
loadCallBack.OnAdLoadFail("CSJ onTimeout")
}
override fun onSplashAdLoad(p0: TTSplashAd?) {
AdEventUtils.onEventPullSuccess(entity)
splashAd = p0;
loadCallBack.OnAdLoadSuccess(ADType.PLATFORM_AD_TT,entity)
}
})
}
/**
* 展示开屏广告
*/
fun showSplashAd(
context: Activity,
entity: NewsEntity,
mSplashContainer: FrameLayout?,
listener: SplashAdListener
) {
if (splashAd == null) {
listener.onError("CSJ splashAd is Null")
return
}
//获取SplashView
var view = splashAd?.splashView
if (view != null && mSplashContainer != null && !context.isFinishing) {
mSplashContainer.removeAllViews()
//把SplashView 添加到ViewGroup中,注意开屏广告view:width =屏幕宽;height >=75%屏幕高
mSplashContainer.addView(view)
//设置不开启开屏广告倒计时功能以及不显示跳过按钮,如果这么设置,您需要自定义倒计时逻辑
//ad.setNotAllowSdkCountdown();
} else {
AdEventUtils.onEventShowFail(entity)
listener.onError("CSJ view Exception")
return
}
splashAd?.setSplashInteractionListener(object : TTSplashAd.AdInteractionListener {
override fun onAdClicked(p0: View?, p1: Int) {
}
override fun onAdShow(p0: View?, p1: Int) {
AdEventUtils.onEventShowSuccess(entity)
listener.onAdShow()
}
override fun onAdSkip() {
listener.onAdSkip()
}
override fun onAdTimeOver() {
AdEventUtils.onEventComplete(entity)
listener.onAdSkip()
}
})
}
private var rewardVideoAd: TTRewardVideoAd? = null
/**
* 加载激励视频广告
*/
fun loadRewardVideoAd(context: Context, entity: NewsEntity, loadCallBack: AdLoadCallBack) {
mTTAdNative = TTAdManagerHolder.get().createAdNative(context)
var adSlot = AdSlot.Builder()
.setCodeId(entity.codeId)
// .setCodeId("901121365")
.setExpressViewAcceptedSize(500f, 500f)
.setOrientation(TTAdConstant.VERTICAL) //必填参数,期望视频的播放方向:TTAdConstant.HORIZONTAL 或 TTAdConstant.VERTICAL
.setAdLoadType(TTAdLoadType.UNKNOWN)//推荐使用,用于标注此次的广告请求用途为预加载(当做缓存)还是实时加载,方便后续为开发者优化相关策略
.build();
mTTAdNative?.loadRewardVideoAd(adSlot, object : TTAdNative.RewardVideoAdListener {
override fun onError(p0: Int, p1: String?) {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("CSJ RewardVideoAd error p0:${p0} p1:${p1}")
}
override fun onRewardVideoAdLoad(p0: TTRewardVideoAd?) {
AdEventUtils.onEventPullSuccess(entity)
}
override fun onRewardVideoCached() {
}
override fun onRewardVideoCached(p0: TTRewardVideoAd?) {
rewardVideoAd = p0
loadCallBack.OnAdLoadSuccess(ADType.PLATFORM_AD_TT,entity)
}
})
}
private var isSkipRewardVideoAd = false
/**
* 展示激励视频广告
*/
fun showRewardVideoAd(
context: Activity,
entity: NewsEntity,
listener: RewardVideoAdListener
) {
if (rewardVideoAd == null) {
listener.onRewardVideoAdError("CSJ rewardVideoAd Is Null")
return
}
if (!context.isFinishing) {
isSkipRewardVideoAd = false
rewardVideoAd?.setRewardAdInteractionListener(object :
TTRewardVideoAd.RewardAdInteractionListener {
override fun onAdShow() {
AdEventUtils.onEventShowSuccess(entity)
LogUtils.d("onAdShow")
listener.onRewardVideoAdShow()
}
override fun onAdVideoBarClick() {
LogUtils.d("onAdVideoBarClick")
}
override fun onAdClose() {
LogUtils.d("onAdClose")
listener.onRewardVideoAdClose()
}
override fun onVideoComplete() {
AdEventUtils.onEventComplete(entity)
LogUtils.d("onVideoComplete")
}
override fun onVideoError() {
AdEventUtils.onEventShowFail(entity)
LogUtils.d("onVideoError")
listener.onRewardVideoAdError("Csj RewardVideoAd PlayError")
}
override fun onRewardVerify(
p0: Boolean,
p1: Int,
p2: String?,
p3: Int,
p4: String?
) {
LogUtils.d("onRewardVerify")
listener.onRewardVideoAdReward()
}
override fun onRewardArrived(p0: Boolean, p1: Int, p2: Bundle?) {
LogUtils.d("onRewardArrived")
}
override fun onSkippedVideo() {
LogUtils.d("onSkippedVideo")
isSkipRewardVideoAd = true
}
})
rewardVideoAd?.showRewardVideoAd(context)
}else{
listener.onRewardVideoAdError("context is finish")
}
}
fun onDestroy() {
splashAd = null
rewardVideoAd = null
}
}
\ No newline at end of file
package com.zx.ad.platform.csj;
import android.content.Context;
import android.util.Log;
import com.bytedance.sdk.openadsdk.TTAdConfig;
import com.bytedance.sdk.openadsdk.TTAdConstant;
import com.bytedance.sdk.openadsdk.TTAdManager;
import com.bytedance.sdk.openadsdk.TTAdSdk;
/**
* 可以用一个单例来保存TTAdManager实例,在需要初始化sdk的时候调用
*/
public class TTAdManagerHolder {
private static final String TAG = "TTAdManagerHolder";
private static boolean sInit;
public static TTAdManager get() {
return TTAdSdk.getAdManager();
}
public static void init(final Context context,String appId) {
doInit(context,appId);
}
//step1:接入网盟广告sdk的初始化操作,详情见接入文档和穿山甲平台说明
private static void doInit(Context context,String appId) {
if (!sInit) {
//TTAdSdk.init(context, buildConfig(context));
TTAdSdk.init(context, buildConfig(context,appId), new TTAdSdk.InitCallback() {
@Override
public void success() {
Log.i(TAG, "success: " + TTAdSdk.isInitSuccess());
}
@Override
public void fail(int code, String msg) {
Log.i(TAG, "fail: code = " + code + " msg = " + msg);
}
});
sInit = true;
}
}
private static TTAdConfig buildConfig(Context context,String appId) {
return new TTAdConfig.Builder()
.appId(appId)
.useTextureView(true) //使用TextureView控件播放视频,默认为SurfaceView,当有SurfaceView冲突的场景,可以使用TextureView
.allowShowNotify(true) //是否允许sdk展示通知栏提示
.debug(false) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
.directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI, TTAdConstant.NETWORK_STATE_5G, TTAdConstant.NETWORK_STATE_4G) //允许直接下载的网络状态集合
.supportMultiProcess(false)//是否支持多进程
.needClearTaskReset()
.build();
}
}
package com.zx.ad.platform.gdt
import android.app.Activity
import android.content.Context
import android.widget.FrameLayout
import com.qq.e.ads.rewardvideo.RewardVideoAD
import com.qq.e.ads.rewardvideo.RewardVideoADListener
import com.qq.e.ads.splash.SplashAD
import com.qq.e.ads.splash.SplashADListener
import com.qq.e.comm.managers.GDTAdSdk
import com.qq.e.comm.util.AdError
import com.zx.ad.callback.AdLoadCallBack
import com.zx.ad.callback.RewardVideoAdListener
import com.zx.ad.callback.SplashAdListener
import com.zx.ad.modulecommon.module.NewsEntity
import com.zx.ad.platform.ADType
import com.zx.ad.utils.AdEventUtils
import com.zx.ad.utils.LogUtils
/**
* @author (wangXuewei)
* @datetime 2022-06-14 15:22 GMT+8
* @detail :广点通广告平台
*/
object GdtAdManager {
fun adInit(context: Context, appId: String) {
GDTAdSdk.init(context,appId)
// GDTAdSdk.init(context, "1101152570")
}
private var splashAd: SplashAD? = null
private var mSplashAdListener: SplashAdListener? = null
fun loadSplashAd(context: Context, entity: NewsEntity, loadCallBack: AdLoadCallBack) {
mSplashAdListener = null
splashAd = SplashAD(context, entity.codeId, object : SplashADListener {
override fun onADDismissed() {
if (mSplashAdListener != null) {
mSplashAdListener?.onAdSkip()
}
}
override fun onNoAD(p0: AdError?) {
if (mSplashAdListener != null) {
mSplashAdListener?.onError("GDT SplashShow p0:${p0?.errorCode} msg:${p0?.errorMsg}")
} else {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("GDT Splash p0:${p0?.errorCode} msg:${p0?.errorMsg}")
}
}
override fun onADPresent() {
}
override fun onADClicked() {
}
override fun onADTick(p0: Long) {
}
override fun onADExposure() {
if (mSplashAdListener != null) {
mSplashAdListener?.onAdShow()
}
}
override fun onADLoaded(p0: Long) {
AdEventUtils.onEventPullSuccess(entity)
loadCallBack.OnAdLoadSuccess(ADType.PLATFORM_AD_GDT, entity)
}
})
splashAd?.fetchAdOnly()
}
fun showSplashAd(
context: Activity,
entity: NewsEntity,
mSplashContainer: FrameLayout?,
listener: SplashAdListener
) {
if (splashAd == null) {
listener.onError("GDT splashAd is Null")
return
}
mSplashAdListener = listener
if (mSplashContainer != null && !context.isFinishing) {
mSplashContainer.removeAllViews()
splashAd?.showAd(mSplashContainer)
} else {
listener.onError("GDT view Exception")
return
}
}
private var rewardVideoAd: RewardVideoAD? = null
private var mRewardAdListener: RewardVideoAdListener? = null
/**
* 加载激励视频广告
*/
fun loadRewardVideoAd(context: Context, entity: NewsEntity, loadCallBack: AdLoadCallBack) {
mRewardAdListener = null
rewardVideoAd = RewardVideoAD(context, entity.codeId, object : RewardVideoADListener {
override fun onADLoad() {
AdEventUtils.onEventPullSuccess(entity)
loadCallBack.OnAdLoadSuccess(ADType.PLATFORM_AD_KS, entity)
}
override fun onVideoCached() {
}
override fun onADShow() {
if (mRewardAdListener != null) {
AdEventUtils.onEventShowSuccess(entity)
LogUtils.d("onVideoPlayStart")
mRewardAdListener?.onRewardVideoAdShow()
}
}
override fun onADExpose() {
}
override fun onReward(p0: MutableMap<String, Any>?) {
if (mRewardAdListener != null) {
mRewardAdListener?.onRewardVideoAdReward()
}
}
override fun onADClick() {
}
override fun onVideoComplete() {
AdEventUtils.onEventComplete(entity)
}
override fun onADClose() {
if (mRewardAdListener != null) {
AdEventUtils.onEventComplete(entity)
LogUtils.d("onADClose")
mRewardAdListener?.onRewardVideoAdClose()
}
}
override fun onError(p0: AdError?) {
if (mRewardAdListener != null) {
AdEventUtils.onEventShowFail(entity)
mRewardAdListener?.onRewardVideoAdError("GDT RewardVideoAd PlayError p0:${p0?.errorCode} msg:${p0?.errorMsg}")
} else {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("GDT RewardVideoAd p0:${p0?.errorCode} msg:${p0?.errorMsg}")
}
}
})
rewardVideoAd?.loadAD()
}
/**
* 展示激励视频广告
*/
fun showRewardVideoAd(
context: Activity, entity: NewsEntity,
listener: RewardVideoAdListener
) {
if (rewardVideoAd == null) {
listener.onRewardVideoAdError("KS rewardVideoAd Is Null")
return
}
mRewardAdListener = listener
if (!context.isFinishing) {
rewardVideoAd?.showAD(context)
} else {
listener.onRewardVideoAdError("context is finish")
}
}
}
\ No newline at end of file
package com.zx.ad.platform.ks
import android.app.Activity
import android.content.Context
import android.widget.FrameLayout
import com.kwad.sdk.api.*
import com.zx.ad.callback.AdLoadCallBack
import com.zx.ad.callback.RewardVideoAdListener
import com.zx.ad.callback.SplashAdListener
import com.zx.ad.modulecommon.module.NewsEntity
import com.zx.ad.platform.ADType
import com.zx.ad.utils.AdEventUtils
import com.zx.ad.utils.LogUtils
/**
* @author (wangXuewei)
* @datetime 2022-06-14 15:22 GMT+8
* @detail :快手广告平台
*/
object KsAdManager {
private var splashAd: KsSplashScreenAd? = null
fun adInit(context: Context, appId: String) {
KsAdSDK.init(
context, SdkConfig.Builder()
.appId(appId)
// .appId("90009")
.showNotification(true) // 是否展示下载通知栏
.debug(true) // 是否开启sdk 调试⽇志 可选
.build()
);
}
fun loadSplashAd(context: Context, entity: NewsEntity, loadCallBack: AdLoadCallBack) {
var scene = KsScene.Builder(entity.codeId.toLong()).needShowMiniWindow(false).build()
// var scene = KsScene.Builder(4000000042L).needShowMiniWindow(false).build()
if (KsAdSDK.getLoadManager() == null) {
loadCallBack.OnAdLoadFail("Ks KsAdSDK.getLoadManager Is NUll")
return
}
KsAdSDK.getLoadManager()?.loadSplashScreenAd(scene, object :
KsLoadManager.SplashScreenAdListener {
override fun onError(p0: Int, p1: String?) {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("KS p0:${p0} p1:${p1}")
}
override fun onRequestResult(p0: Int) {
}
override fun onSplashScreenAdLoad(p0: KsSplashScreenAd?) {
AdEventUtils.onEventPullSuccess(entity)
splashAd = p0;
loadCallBack.OnAdLoadSuccess(ADType.PLATFORM_AD_KS, entity)
}
})
}
fun showSplashAd(
context: Activity, entity: NewsEntity,
mSplashContainer: FrameLayout?,
listener: SplashAdListener
) {
if (splashAd == null) {
listener.onError("CSJ splashAd is Null")
return
}
//获取SplashView
var view =
splashAd?.getView(context, object : KsSplashScreenAd.SplashScreenAdInteractionListener {
override fun onAdClicked() {
LogUtils.d("ks onAdClicked")
}
override fun onAdShowError(p0: Int, p1: String?) {
AdEventUtils.onEventShowFail(entity)
LogUtils.d("Ks SplashShow p0${p0} p1${p1}")
listener.onError("Ks SplashShow p0${p0} p1${p1}")
}
override fun onAdShowEnd() {
AdEventUtils.onEventComplete(entity)
LogUtils.d("onAdShowEnd")
listener.onAdSkip()
}
override fun onAdShowStart() {
AdEventUtils.onEventShowSuccess(entity)
}
override fun onSkippedAd() {
listener.onAdSkip()
}
override fun onDownloadTipsDialogShow() {
}
override fun onDownloadTipsDialogDismiss() {
}
override fun onDownloadTipsDialogCancel() {
}
})
if (view != null && mSplashContainer != null && !context.isFinishing) {
mSplashContainer.removeAllViews()
//把SplashView 添加到ViewGroup中,注意开屏广告view:width =屏幕宽;height >=75%屏幕高
mSplashContainer.addView(view)
//设置不开启开屏广告倒计时功能以及不显示跳过按钮,如果这么设置,您需要自定义倒计时逻辑
//ad.setNotAllowSdkCountdown();
} else {
listener.onError("KS view Exception")
return
}
}
private var rewardVideoAd: KsRewardVideoAd? = null
/**
* 加载激励视频广告
*/
fun loadRewardVideoAd(context: Context, entity: NewsEntity, loadCallBack: AdLoadCallBack) {
var scene = KsScene.Builder(entity.codeId.toLong()).build()
// var scene = KsScene.Builder(90009001).build()
if (KsAdSDK.getLoadManager() == null) {
loadCallBack.OnAdLoadFail("Ks KsAdSDK.getLoadManager Is NUll")
return
}
KsAdSDK.getLoadManager()
?.loadRewardVideoAd(scene, object : KsLoadManager.RewardVideoAdListener {
override fun onError(p0: Int, p1: String?) {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("KS RewardVideoAd p0:${p0} p1:${p1}")
}
override fun onRewardVideoResult(p0: MutableList<KsRewardVideoAd>?) {
}
override fun onRewardVideoAdLoad(adList: MutableList<KsRewardVideoAd>?) {
if (adList != null && adList.size > 0) {
AdEventUtils.onEventPullSuccess(entity)
rewardVideoAd = adList[0];
loadCallBack.OnAdLoadSuccess(ADType.PLATFORM_AD_KS, entity)
} else {
AdEventUtils.onEventPullFail(entity)
loadCallBack.OnAdLoadFail("KS RewardVideoAd adSize 0")
}
}
})
}
private var isSkipRewardVideoAd = false
/**
* 展示激励视频广告
*/
fun showRewardVideoAd(
context: Activity, entity: NewsEntity,
listener: RewardVideoAdListener
) {
if (rewardVideoAd == null) {
listener.onRewardVideoAdError("KS rewardVideoAd Is Null")
return
}
if (!context.isFinishing) {
isSkipRewardVideoAd = false
rewardVideoAd?.setRewardAdInteractionListener(object :
KsRewardVideoAd.RewardAdInteractionListener {
override fun onAdClicked() {
LogUtils.d("onAdClicked")
}
override fun onPageDismiss() {
AdEventUtils.onEventComplete(entity)
LogUtils.d("onPageDismiss")
listener.onRewardVideoAdClose()
}
override fun onVideoPlayError(p0: Int, p1: Int) {
AdEventUtils.onEventShowFail(entity)
LogUtils.d("onVideoPlayError p0${p0} p1${p1}")
listener.onRewardVideoAdError("Ks RewardVideoAd PlayError p0:${p0} p1:${p1}")
}
override fun onVideoPlayEnd() {
LogUtils.d("onVideoPlayEnd ")
}
override fun onVideoSkipToEnd(p0: Long) {
LogUtils.d("onVideoSkipToEnd ${p0}")
}
override fun onVideoPlayStart() {
AdEventUtils.onEventShowSuccess(entity)
LogUtils.d("onVideoPlayStart")
listener.onRewardVideoAdShow()
}
override fun onRewardVerify() {
LogUtils.d("onRewardVerify")
listener.onRewardVideoAdReward()
}
override fun onRewardStepVerify(p0: Int, p1: Int) {
LogUtils.d("onRewardStepVerify p0${p0} p1${p1}")
}
override fun onExtraRewardVerify(p0: Int) {
LogUtils.d("onExtraRewardVerify ${p0}")
}
})
//2.设置展示配置
val videoPlayConfig = KsVideoPlayConfig.Builder()
.showLandscape(false) // 横屏播放, 建议和当前屏幕方向保持一致
.build()
rewardVideoAd?.showRewardVideoAd(context, videoPlayConfig)
}else{
listener.onRewardVideoAdError("context is finish")
}
}
}
\ No newline at end of file
package com.zx.ad.utils;
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by gaoleichao on 2018/9/6.
*/
public class AESUtils {
private static String CIPHERMODEPADDING = "AES/CBC/PKCS7Padding";// AES/CBC/PKCS7Padding
private static String ivParameter = "e2e7d664d72f710b";// 密钥默认偏移,可更改
private static String sKey = "c20505927997d952";// key必须为16位,可更改为自己的key
// /** 算法/模式/填充 **/
// /** 创建密钥 **/
private static SecretKeySpec createKey(String key) {
byte[] data = null;
if (key == null) {
key = "";
}
StringBuffer sb = new StringBuffer(16);
sb.append(key);
while (sb.length() < 16) {
sb.append("0");
}
if (sb.length() > 16) {
sb.setLength(16);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(data, "AES");
}
private static IvParameterSpec createIV(String password) {
byte[] data = null;
if (password == null) {
password = "";
}
StringBuffer sb = new StringBuffer(16);
sb.append(password);
while (sb.length() < 16) {
sb.append("0");
}
if (sb.length() > 16) {
sb.setLength(16);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new IvParameterSpec(data);
}
// /** 加密字节数据 **/
public static byte[] encrypt(byte[] content, String password, String iv) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CIPHERMODEPADDING);
cipher.init(Cipher.ENCRYPT_MODE, key, createIV(iv));
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// /** 加密(结果为16进制字符串) **/
public static String encrypt(String content) {
byte[] data = null;
try {
data = content.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
data = encrypt(data, sKey, ivParameter);
String result = Utils.getBase64(data);
return result;
}
public static String decrypt(String sSrc) throws Exception {
try {
byte[] raw = sKey.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.decode(sSrc, Base64.DEFAULT);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "utf-8");
return originalString;
} catch (Exception ex) {
return null;
}
}
public static String decrypt(String sSrc, String key) throws Exception {
try {
byte[] raw = key.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("4kbnwmth98nnjy94".getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.decode(sSrc, Base64.DEFAULT);// 先用base64解密
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "utf-8");
return originalString;
} catch (Exception ex) {
return null;
}
}
}
package com.zx.ad.utils
import android.text.TextUtils
import android.util.Log
import com.zx.ad.modulecommon.module.NewsEntity
import com.zx.ad.modulecommon.net.EventApiClient
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONObject
/**
* Created by gaoleichao on 2019/1/11
*/
object AdEventUtils {
val EVENT = "ad"
val AD_MODEL_SPLAH = "splash"
val AD_MODEL_REWARD = "reward"
val AD_MODEL_FULL_VIDEO = "fullvideo"
val AD_MODEL_BIGIMG = "bigimg"
val AD_MODEL_SCREEN = "fullscreen"
fun getJSON(action: String): JSONObject {
var data = JSONObject()
data.put("event", EVENT)
data.put("action", action)
return data
}
//广告拉取失败上报
fun onEvent(newsEntity: NewsEntity, errorCode: Any?, errorMsg: String?) {
val jsonObj = getJSON("pull_ad_error")
jsonObj.put("codeId", newsEntity?.codeId)
jsonObj.put("reqId", newsEntity.reqId)
jsonObj.put("errorMsg", errorMsg)
jsonObj.put("errorCode", errorCode)
apiClient(jsonObj)
}
//广告成功展示
fun onEventShowSuccess(entity: NewsEntity) {
if (entity?.imp_tracking != null && entity?.imp_tracking.size > 0) {
for (i in 0 until entity.imp_tracking?.size!!) {
var newUrl = entity.imp_tracking!![i]
apiClient(newUrl)
}
}
val json = getJSON("show")
json.put("ad_model",entity?.slotName)
json.put("ad_plantform",entity?.adPlatform?:"")
json.put("code_id",entity?.codeId?:"")
json.put("slot",entity?.actionName?:"")
apiClient(json)
if(!TextUtils.isEmpty(entity?.actionName)){
// MobclickAgent.onEvent(AppliContext.get(), entity?.actionName, json.toString())
}
}
//广告展示失败 渲染失败
fun onEventShowFail(entity: NewsEntity) {
if (entity?.showfail_tracking != null && entity?.showfail_tracking.size > 0) {
for (i in 0 until entity.showfail_tracking?.size!!) {
var newUrl = entity.showfail_tracking!![i]
apiClient(newUrl)
}
}
val json = getJSON("showfail")
json.put("ad_model",entity?.slotName)
json.put("ad_plantform",entity?.adPlatform?:"")
json.put("code_id",entity?.codeId?:"")
json.put("slot",entity?.actionName?:"")
apiClient(json)
if(!TextUtils.isEmpty(entity?.actionName)){
// MobclickAgent.onEvent(AppliContext.get(), entity?.actionName, json.toString())
}
}
//广告拉取成功
fun onEventPullSuccess(entity: NewsEntity) {
if (entity?.pullsucc_tracking != null && entity?.pullsucc_tracking.size > 0) {
for (i in 0 until entity.pullsucc_tracking?.size!!) {
var newUrl = entity.pullsucc_tracking!![i]
apiClient(newUrl)
}
}
val json = getJSON("pull_success")
json.put("ad_model",entity?.slotName)
json.put("ad_plantform",entity?.adPlatform?:"")
json.put("code_id",entity?.codeId?:"")
json.put("slot",entity?.actionName?:"")
apiClient(json)
if(!TextUtils.isEmpty(entity?.actionName)){
// MobclickAgent.onEvent(AppliContext.get(), entity?.actionName, json.toString())
}
}
//广告拉取失败
fun onEventPullFail(entity: NewsEntity) {
if (entity?.pullfail_tracking != null && entity?.pullfail_tracking.size > 0) {
for (i in 0 until entity.pullfail_tracking?.size!!) {
var newUrl = entity.pullfail_tracking!![i]
apiClient(newUrl)
}
}
val json = getJSON("pull_fail")
json.put("ad_model",entity.slotName)
json.put("ad_plantform",entity?.adPlatform?:"")
json.put("code_id",entity?.codeId?:"")
json.put("slot",entity?.actionName?:"")
apiClient(json)
if(!TextUtils.isEmpty(entity?.actionName)){
// MobclickAgent.onEvent(AppliContext.get(), entity?.actionName, json.toString())
}
}
//广告展示完成 播放完成
fun onEventComplete(entity: NewsEntity) {
if (entity?.playcomplete_trackings != null && entity?.playcomplete_trackings.size > 0) {
for (i in 0 until entity.playcomplete_trackings?.size!!) {
var newUrl = entity.playcomplete_trackings!![i]
apiClient(newUrl)
}
}
val json = getJSON("complete")
json.put("ad_model",entity?.slotName)
json.put("ad_plantform",entity?.adPlatform?:"")
json.put("code_id",entity?.codeId?:"")
json.put("slot",entity?.actionName?:"")
apiClient(json)
if(!TextUtils.isEmpty(entity?.actionName)){
// MobclickAgent.onEvent(AppliContext.get(), entity?.actionName, json.toString())
}
}
/**
* {"event": "ad", "action": "click", "ad_model": "splash", "code_id": "58587854"}
*/
fun onEventClick(entity: NewsEntity) {
if (entity?.clk_tracking != null && entity?.clk_tracking.size > 0) {
for (i in 0 until entity.clk_tracking?.size!!) {
var newUrl = entity.clk_tracking!![i]
apiClient(newUrl)
}
}
val json = getJSON("click")
json.put("ad_model",entity?.slotName)
json.put("ad_plantform",entity?.adPlatform?:"")
json.put("code_id",entity?.codeId?:"")
json.put("slot",entity?.actionName?:"")
apiClient(json)
if(!TextUtils.isEmpty(entity?.actionName)){
// MobclickAgent.onEvent(AppliContext.get(), entity?.actionName, json.toString())
}
}
private fun apiClient(url: String?) {
if (url != null && url != "") {
try {
EventApiClient.adApi.requestEvent(url).subscribeOn(Schedulers.io())
.subscribe(object : Observer<Any> {
override fun onComplete() {}
override fun onSubscribe(d: Disposable) {}
override fun onNext(t: Any) {}
override fun onError(e: Throwable) { onEventUM("zxad_report_fail", url) }})
} catch (e: Exception) {
e.printStackTrace()
}
}
}
//事件上报
private fun apiClient(data: JSONObject) {
val str = data.toString()
val key = AESUtils.encrypt(str)
try {
EventApiClient.adApi.requestEvent("behavior", key).subscribeOn(Schedulers.io())
.subscribe(object : Observer<Any> {
override fun onComplete() {}
override fun onSubscribe(d: Disposable) {}
override fun onNext(t: Any) {}
override fun onError(e: Throwable) {}
})
}catch (e:Exception){ }
}
//上报友盟
fun onEventUM(action: String, value: String) {
// MobclickAgent.onEvent(AppliContext.get(), action, value)
}
}
\ No newline at end of file
package com.zx.ad.utils;
import android.app.Dialog;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.badoo.mobile.util.WeakHandler;
import com.zx.ad.R;
public class LoadingDialog extends Dialog {
private Context mContext;
private LayoutInflater inflater;
private WindowManager.LayoutParams lp;
private TextView mTextTv;
private ProgressBar mProgressBar;
private ImageView mSucIv;
private ImageView mFailIv;
private WeakHandler mHandler = new WeakHandler();
public static LoadingDialog getLoadingDialog(Context context, String loadingText) {
return getLoadingDialog(context, loadingText, true, true);
}
public static LoadingDialog getLoadingDialog(Context context, String loadingText, boolean cancelable, boolean outeSiteCanceled) {
LoadingDialog dialog = new LoadingDialog(context);
if (!invalidString(loadingText)) {
dialog.setLoadText(loadingText);
}
dialog.setCanceledOnTouchOutside(outeSiteCanceled);
dialog.setCancelable(cancelable);
return dialog;
}
public LoadingDialog(Context context) {
super(context, R.style.confirm_dialog);
this.mContext = context;
View layout = LayoutInflater.from(context).inflate(R.layout.widget_loadingdialog, null);
mTextTv = (TextView) layout.findViewById(R.id.loading_text);
mProgressBar = (ProgressBar) layout.findViewById(R.id.loading_bar);
mSucIv = (ImageView) layout.findViewById(R.id.img_success);
mFailIv = (ImageView) layout.findViewById(R.id.img_fail);
setContentView(layout);
}
public void setDimAmount(boolean b) {
if (b) {
getWindow().setAttributes(lp);
}
}
public void setLoadText(final String content) {
mTextTv.setVisibility(View.VISIBLE);
if (!TextUtils.isEmpty(content)) {
mTextTv.setText(content);
}
}
public void setLoadText(int resId) {
if (mTextTv.getVisibility() != View.VISIBLE) {
mTextTv.setVisibility(View.VISIBLE);
}
mTextTv.setText(resId);
}
public void setLoading(String text) {
setLoadText(text);
mProgressBar.setVisibility(View.VISIBLE);
mSucIv.setVisibility(View.GONE);
mFailIv.setVisibility(View.GONE);
}
public void setResult(boolean isSucc, String text, int duration) {
setResult(isSucc, text, duration, null);
}
public void setResult(boolean isSucc, String text, int duration, OnDissListener onDismissListener) {
try {
if (duration <= 0 && isShowing()) {
dismiss();
}
mProgressBar.setVisibility(View.GONE);
mSucIv.setVisibility(isSucc ? View.VISIBLE : View.GONE);
mFailIv.setVisibility(isSucc ? View.GONE : View.VISIBLE);
setLoadText(text);
mHandler.postDelayed(() -> {
if (LoadingDialog.this.isShowing())
LoadingDialog.this.dismiss();
if (onDismissListener != null) {
onDismissListener.dissComplete();
}
}, duration);
} catch (Exception e) {
e.printStackTrace();
}
}
public static boolean invalidString(Object obj) {
return obj == null || "".equals(obj.toString())
|| "null".equals(obj.toString());
}
public interface OnDissListener {
void dissComplete();
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacksAndMessages(null);
}
}
package com.zx.ad.utils;
import android.text.TextUtils;
import android.util.Log;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2016/09/21
* desc : Log相关工具类
* </pre>
*/
public final class LogUtils {
public static String tagPrefix = "";
public static boolean showV = true;
public static boolean showD = true;
public static boolean showI = true;
public static boolean showW = true;
public static boolean showE = true;
public static boolean showWTF = true;
/**
* 得到tag(所在类.方法(L:行))
*
* @return
*/
private static String generateTag() {
// StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4];
// String callerClazzName = stackTraceElement.getClassName();
// callerClazzName = callerClazzName.substring(callerClazzName.lastIndexOf(".") + 1);
// String tag = "%s.%s(L:%d)";
// tag = String.format(tag, new Object[]{callerClazzName, stackTraceElement.getMethodName(), Integer.valueOf(stackTraceElement.getLineNumber())});
// //给tag设置前缀
// tag = TextUtils.isEmpty(tagPrefix) ? tag : tagPrefix + ":" + tag;
// return tag;
return "AdManager";
}
public static void isShowLog(boolean isShow) {
showV = isShow;
showD = isShow;
showI = isShow;
showW = isShow;
showE = isShow;
showWTF = isShow;
}
public static void v(String msg) {
if (showV) {
String tag = generateTag();
Log.v(tag, msg);
}
}
public static void v(String msg, Throwable tr) {
if (showV) {
String tag = generateTag();
Log.v(tag, msg, tr);
}
}
public static void d(String msg) {
if (showD) {
String tag = generateTag();
Log.d(tag, msg);
}
}
public static void d(String msg, Throwable tr) {
if (showD) {
String tag = generateTag();
Log.d(tag, msg, tr);
}
}
public static void i(String msg) {
if (showI) {
String tag = generateTag();
Log.i(tag, msg);
}
}
public static void i(String msg, Throwable tr) {
if (showI) {
String tag = generateTag();
Log.i(tag, msg, tr);
}
}
public static void w(String msg) {
if (showW) {
String tag = generateTag();
Log.w(tag, msg);
}
}
public static void w(String msg, Throwable tr) {
if (showW) {
String tag = generateTag();
Log.w(tag, msg, tr);
}
}
public static void e(String msg) {
if (showE) {
String tag = generateTag();
Log.e(tag, msg);
}
}
public static void e(String msg, Throwable tr) {
if (showE) {
String tag = generateTag();
Log.e(tag, msg, tr);
}
}
public static void wtf(String msg) {
if (showWTF) {
String tag = generateTag();
Log.wtf(tag, msg);
}
}
public static void wtf(String msg, Throwable tr) {
if (showWTF) {
String tag = generateTag();
Log.wtf(tag, msg, tr);
}
}
}
package com.zx.ad.utils;
import android.os.Handler;
import android.os.Looper;
/**
* 工具栏,处理子线程需要丢到主线程逻辑使用
*/
public class ThreadUtils
{
private static Handler sUiHander = null;
public static boolean isUIThread()
{
final Looper myLooper = Looper.myLooper();
final Looper mainLooper = Looper.getMainLooper();
return mainLooper.equals(myLooper);
}
static
{
sUiHander = new Handler(Looper.getMainLooper());
}
public static void runOnUIT(Runnable runnable)
{
sUiHander.post(runnable);
}
public static void postOnUIDelayed(Runnable r, long delay)
{
sUiHander.postDelayed(r, delay);
}
}
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/icon_loading"
android:pivotX="50.0%"
android:pivotY="50.0%" />
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 填充的颜色 -->
<solid android:color="#4a000000"/>
<!-- 设置矩形的四个角为弧形 -->
<!-- android:radius 弧形的半径 -->
<corners android:radius="10dip"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_round_loading"
android:gravity="center">
<RelativeLayout
android:id="@+id/rl"
android:layout_width="150dp"
android:layout_height="100dp"
android:gravity="center">
<RelativeLayout
android:id="@+id/layout_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center">
<ProgressBar
android:id="@+id/loading_bar"
style="@style/progressbar_loading"
android:layout_width="29dp"
android:layout_height="29dp" />
<ImageView
android:id="@+id/img_success"
android:layout_width="29dp"
android:layout_height="29dp"
android:src="@drawable/icon_loading_suc"
android:visibility="gone" />
<ImageView
android:id="@+id/img_fail"
android:layout_width="29dp"
android:layout_height="29dp"
android:src="@drawable/icon_loading_fail"
android:visibility="gone" />
</RelativeLayout>
<TextView
android:id="@+id/loading_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/layout_icon"
android:layout_centerHorizontal="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:ellipsize="end"
android:gravity="center"
android:maxLines="3"
android:text="请稍等..."
android:textColor="#ffffffff"
android:textSize="18sp"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>
\ No newline at end of file
<resources>
<style name="confirm_dialog" parent="android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowIsTranslucent">true</item>
</style>
<style name="progressbar_loading">
<item name="android:indeterminateDrawable">@anim/anim_progress_loading</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--为了适配所有路径可以设置 path = "." -->
<external-path name="tt_external_root" path="." />
<external-path name="tt_external_download" path="Download" />
<external-files-path name="tt_external_files_download" path="Download" />
<files-path name="tt_internal_file_download" path="Download" />
<cache-path name="tt_internal_cache_download" path="Download" />
</paths>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates
overridePins="true"
src="system"/>
<certificates
overridePins="true"
src="user"/>
</trust-anchors>
</base-config>
<domain-config>
<domain includeSubdomains="true">i.snssdk.com</domain>
<domain includeSubdomains="true">is.snssdk.com</domain>
<domain includeSubdomains="true">extlog.snssdk.com</domain>
<domain includeSubdomains="true">127.0.0.1</domain>
<trust-anchors>
<certificates src="user"/>//信任用户自己安装的证书
<certificates src="system"/>
</trust-anchors>
</domain-config>
</network-security-config>
package com.zx.ad
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
\ No newline at end of file
include ':moduleZxAd'
include ':moduleMain' include ':moduleMain'
include ':cms' include ':cms'
include ':app' include ':app'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment