米盟广告模块已测试完成
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Tue Nov 18 07:00:12 GMT 2025
|
||||
#Tue Nov 18 08:35:57 GMT 2025
|
||||
stageCount=1
|
||||
libraryProject=libaes
|
||||
baseVersion=15.11
|
||||
publishVersion=15.11.0
|
||||
buildCount=10
|
||||
buildCount=26
|
||||
baseBetaVersion=15.11.1
|
||||
|
||||
@@ -8,8 +8,7 @@ package cc.winboll.studio.aes;
|
||||
import android.view.Gravity;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import com.hjq.toast.style.WhiteToastStyle;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
|
||||
|
||||
public class App extends GlobalApplication {
|
||||
@@ -19,15 +18,16 @@ public class App extends GlobalApplication {
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
setIsDebugging(BuildConfig.DEBUG);
|
||||
WinBoLLActivityManager.init(this);
|
||||
|
||||
// 初始化 Toast 框架
|
||||
ToastUtils.init(this);
|
||||
// 设置 Toast 布局样式
|
||||
//ToastUtils.setView(R.layout.view_toast);
|
||||
ToastUtils.setStyle(new WhiteToastStyle());
|
||||
ToastUtils.setGravity(Gravity.BOTTOM, 0, 200);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
super.onTerminate();
|
||||
ToastUtils.release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// 吐司类库
|
||||
api 'com.github.getActivity:ToastUtils:10.5'
|
||||
|
||||
// 权限请求框架:https://github.com/getActivity/XXPermissions
|
||||
api 'com.github.getActivity:XXPermissions:18.63'
|
||||
// 下拉控件
|
||||
@@ -53,6 +50,15 @@ dependencies {
|
||||
//api 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
|
||||
//api 'androidx.fragment:fragment:1.1.0'
|
||||
|
||||
// 米盟
|
||||
implementation 'com.miui.zeus:mimo-ad-sdk:5.3.+'//请使用最新版sdk
|
||||
//注意:以下5个库必须要引入
|
||||
//implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.0.0'
|
||||
implementation 'com.google.code.gson:gson:2.8.5'
|
||||
implementation 'com.github.bumptech.glide:glide:4.9.0'
|
||||
//annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
|
||||
|
||||
api 'cc.winboll.studio:libappbase:15.11.0'
|
||||
|
||||
api fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Tue Nov 18 07:00:12 GMT 2025
|
||||
#Tue Nov 18 08:35:57 GMT 2025
|
||||
stageCount=1
|
||||
libraryProject=libaes
|
||||
baseVersion=15.11
|
||||
publishVersion=15.11.0
|
||||
buildCount=10
|
||||
buildCount=26
|
||||
baseBetaVersion=15.11.1
|
||||
|
||||
@@ -31,6 +31,9 @@ import cc.winboll.studio.libappbase.LogUtils;
|
||||
import com.baoyz.widget.PullRefreshLayout;
|
||||
import java.util.ArrayList;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libaes.views.ADsBannerView;
|
||||
import cc.winboll.studio.libappbase.LogActivity;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
|
||||
public abstract class DrawerFragmentActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
|
||||
|
||||
@@ -71,17 +74,22 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
// 修复:释放广告资源,避免内存泄漏
|
||||
ADsBannerView adsBannerView = findViewById(R.id.adsbanner);
|
||||
if (adsBannerView != null) {
|
||||
adsBannerView.releaseAdResources();
|
||||
}
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public Intent getIntent() {
|
||||
// TODO: Implement this method
|
||||
return super.getIntent();
|
||||
}
|
||||
public Intent getIntent() {
|
||||
// TODO: Implement this method
|
||||
return super.getIntent();
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return this.mContext;
|
||||
}*/
|
||||
public Context getContext() {
|
||||
return this.mContext;
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public MenuInflater getMenuInflater() {
|
||||
@@ -90,9 +98,9 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
||||
}
|
||||
|
||||
/*public void setSubtitle(CharSequence context) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setSubtitle(context);
|
||||
}*/
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setSubtitle(context);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void recreate() {
|
||||
@@ -100,9 +108,9 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public boolean moveTaskToBack(boolean nonRoot) {
|
||||
return super.moveTaskToBack(nonRoot);
|
||||
}*/
|
||||
public boolean moveTaskToBack(boolean nonRoot) {
|
||||
return super.moveTaskToBack(nonRoot);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public void startActivity(Intent intent) {
|
||||
@@ -115,24 +123,24 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
||||
}
|
||||
|
||||
/*@Override
|
||||
public FragmentManager getSupportFragmentManager() {
|
||||
return super.getSupportFragmentManager();
|
||||
}
|
||||
public FragmentManager getSupportFragmentManager() {
|
||||
return super.getSupportFragmentManager();
|
||||
}
|
||||
|
||||
public void setSubtitle(int resId) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setSubtitle(resId);
|
||||
}
|
||||
public void setSubtitle(int resId) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setSubtitle(resId);
|
||||
}
|
||||
|
||||
public void setTitle(CharSequence context) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setTitle(context);
|
||||
}
|
||||
public void setTitle(CharSequence context) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setTitle(context);
|
||||
}
|
||||
|
||||
public void setTitle(int resId) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setTitle(resId);
|
||||
}*/
|
||||
public void setTitle(int resId) {
|
||||
// TODO: Implement this method
|
||||
getSupportActionBar().setTitle(resId);
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public SharedPreferences getSharedPreferences(String name, int mode) {
|
||||
@@ -175,6 +183,9 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
||||
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
|
||||
getString(i);
|
||||
}
|
||||
} else if (R.id.item_log == item.getItemId()) {
|
||||
ToastUtils.show("Test");
|
||||
LogActivity.startLogActivity(this);
|
||||
} else if (R.id.item_about == item.getItemId()) {
|
||||
LogUtils.d(TAG, "onAbout");
|
||||
} else if (android.R.id.home == item.getItemId()) {
|
||||
@@ -189,6 +200,11 @@ public abstract class DrawerFragmentActivity extends AppCompatActivity implement
|
||||
if (checkThemeStyleChange()) {
|
||||
recreate();
|
||||
}
|
||||
|
||||
ADsBannerView adsBannerView = findViewById(R.id.adsbanner);
|
||||
if (adsBannerView != null) {
|
||||
adsBannerView.resumeADs();
|
||||
}
|
||||
}
|
||||
|
||||
void initRootView() {
|
||||
|
||||
@@ -13,7 +13,7 @@ import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.libaes.R;
|
||||
import cc.winboll.studio.libaes.views.AButton;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
|
||||
public class TestAButtonFragment extends Fragment {
|
||||
|
||||
|
||||
@@ -12,14 +12,13 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import cc.winboll.studio.libaes.ImagePagerAdapter;
|
||||
import cc.winboll.studio.libaes.R;
|
||||
import cc.winboll.studio.libaes.views.AOHPCTCSeekBar;
|
||||
import cc.winboll.studio.libappbase.LogView;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package cc.winboll.studio.libaes.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/18 15:23
|
||||
* @Describe 米盟 MimoUtils
|
||||
*/
|
||||
public final class MimoUtils {
|
||||
public static final String TAG = "Utils";
|
||||
|
||||
public static int dpToPx(Context context, float dp) {
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
return (int) (dp * displayMetrics.density + 0.5f);
|
||||
}
|
||||
|
||||
public static int pxToDp(Context context, float px) {
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
return (int) (px / displayMetrics.density + 0.5f);
|
||||
}
|
||||
|
||||
public static int pxToSp(Context context, float pxValue) {
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
return (int) (pxValue / displayMetrics.scaledDensity + 0.5f);
|
||||
}
|
||||
|
||||
public static int spToPx(Context context, float spValue) {
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
return (int) (spValue * displayMetrics.scaledDensity + 0.5f);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,36 @@
|
||||
package cc.winboll.studio.libaes.views;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import cc.winboll.studio.libaes.R;
|
||||
import cc.winboll.studio.libaes.utils.MimoUtils;
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import com.miui.zeus.mimo.sdk.ADParams;
|
||||
import com.miui.zeus.mimo.sdk.BannerAd;
|
||||
import com.miui.zeus.mimo.sdk.MimoCustomController;
|
||||
import com.miui.zeus.mimo.sdk.MimoLocation;
|
||||
import com.miui.zeus.mimo.sdk.MimoSdk;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
@@ -15,8 +41,27 @@ public class ADsBannerView extends LinearLayout {
|
||||
|
||||
public static final String TAG = "ADsBannerView";
|
||||
|
||||
private static final String PRIVACY_FILE = "privacy_pfs";
|
||||
private static final String PRIVACY_VALUE = "privacy_value";//0: 拒绝,1:赞同
|
||||
|
||||
private String BANNER_POS_ID = "802e356f1726f9ff39c69308bfd6f06a";
|
||||
private String BANNER_POS_ID_WINBOLL_BETA = "d129ee5a263911f981a6dc7a9802e3e7";
|
||||
private String BANNER_POS_ID_WINBOLL = "4ec30efdb32271765b9a4efac902828b";
|
||||
|
||||
/*
|
||||
private String BANNER_POS_ID = "802e356f1726f9ff39c69308bfd6f06a";
|
||||
private String BANNER_POS_ID_WINBOLL_BETA = "802e356f1726f9ff39c69308bfd6f06a";
|
||||
private String BANNER_POS_ID_WINBOLL = "802e356f1726f9ff39c69308bfd6f06a";
|
||||
*/
|
||||
|
||||
Context mContext;
|
||||
View mMianView;
|
||||
SharedPreferences mSharedPreferences;
|
||||
ViewGroup mContainer;
|
||||
BannerAd mBannerAd;
|
||||
List<BannerAd> mAllBanners = new ArrayList<>();
|
||||
// 新增:主线程Handler,确保广告操作在主线程执行
|
||||
private Handler mMainHandler;
|
||||
|
||||
public ADsBannerView(Context context) {
|
||||
super(context);
|
||||
@@ -43,7 +88,393 @@ public class ADsBannerView extends LinearLayout {
|
||||
}
|
||||
|
||||
void initView() {
|
||||
|
||||
// 初始化主线程Handler(关键:确保广告操作在主线程执行)
|
||||
mMainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
// 米盟模块:隐私协议弹窗
|
||||
showPrivacy();
|
||||
|
||||
this.mMianView = inflate(this.mContext, R.layout.view_adsbanner, null);
|
||||
mContainer = this.mMianView.findViewById(R.id.ads_container);
|
||||
addView(this.mMianView);
|
||||
}
|
||||
|
||||
Activity getActivity() {
|
||||
try {
|
||||
Activity activity = (Activity)this.mContext;
|
||||
return activity;
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void resumeADs() {
|
||||
//ToastUtils.show("resumeADs()");
|
||||
// 修复:优化广告请求逻辑(添加生命周期判断 + 主线程执行)
|
||||
if (getActivity() != null && !getActivity().isFinishing() && !getActivity().isDestroyed()) {
|
||||
String privacyAgreeValue = getSharedPreferences().getString(PRIVACY_VALUE, null);
|
||||
if (TextUtils.equals(privacyAgreeValue, String.valueOf(1))) {
|
||||
LogUtils.i(TAG, "已同意隐私协议,开始播放米盟广告...");
|
||||
mMainHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//ToastUtils.show("ADs run");
|
||||
// 再次校验生命周期,避免延迟执行时Activity已销毁
|
||||
if (getActivity() != null && !getActivity().isFinishing() && !getActivity().isDestroyed()) {
|
||||
fetchAd();
|
||||
}
|
||||
}
|
||||
}, 1000); // 延迟1秒请求广告,提升页面加载体验
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放广告资源(关键:避免内存泄漏和空Context调用)
|
||||
*/
|
||||
public void releaseAdResources() {
|
||||
LogUtils.d(TAG, "releaseAdResources()");
|
||||
|
||||
// 移除Handler回调
|
||||
if (mMainHandler != null) {
|
||||
mMainHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
// 销毁所有广告实例
|
||||
if (mAllBanners != null && !mAllBanners.isEmpty()) {
|
||||
for (BannerAd ad : mAllBanners) {
|
||||
if (ad != null) {
|
||||
ad.destroy();
|
||||
}
|
||||
}
|
||||
mAllBanners.clear();
|
||||
}
|
||||
// 置空当前广告引用
|
||||
mBannerAd = null;
|
||||
// 移除广告容器中的视图
|
||||
if (mContainer != null) {
|
||||
mContainer.removeAllViews();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示广告(核心修复:传递安全的Context + 生命周期校验)
|
||||
*/
|
||||
private void showAd() {
|
||||
LogUtils.d(TAG, "showAd()");
|
||||
// 1. 生命周期校验:避免Activity已销毁时操作UI
|
||||
if (getActivity() == null || getActivity().isFinishing() || getActivity().isDestroyed()) {
|
||||
LogUtils.e(TAG, "showAd: Activity is finishing or destroyed");
|
||||
return;
|
||||
}
|
||||
// 2. 非空校验:广告实例和容器
|
||||
if (mBannerAd == null || mContainer == null) {
|
||||
LogUtils.e(TAG, "showAd: BannerAd or Container is null");
|
||||
return;
|
||||
}
|
||||
// 3. 创建广告容器(使用ApplicationContext避免内存泄漏)
|
||||
final FrameLayout container = new FrameLayout(getActivity().getApplicationContext());
|
||||
container.setPadding(0, 0, 0, MimoUtils.dpToPx(getActivity(), 10));
|
||||
mContainer.addView(container, new FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
));
|
||||
|
||||
// if (mIsBiddingWin) {
|
||||
// mBannerAd.setPrice(getPrice());
|
||||
// }
|
||||
// 4. 显示广告:传递ApplicationContext,避免Activity Context失效
|
||||
mBannerAd.showAd(getActivity(), container, new BannerAd.BannerInteractionListener() {
|
||||
@Override
|
||||
public void onAdClick() {
|
||||
LogUtils.d(TAG, "onAdClick");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdShow() {
|
||||
LogUtils.d(TAG, "onAdShow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdDismiss() {
|
||||
LogUtils.d(TAG, "onAdDismiss");
|
||||
// 修复:移除容器时校验Activity状态
|
||||
if (getActivity() != null && !getActivity().isFinishing() && !getActivity().isDestroyed() && mContainer != null) {
|
||||
mContainer.removeView(container);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderSuccess() {
|
||||
LogUtils.d(TAG, "onRenderSuccess");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderFail(int code, String msg) {
|
||||
LogUtils.e(TAG, "onRenderFail errorCode " + code + " errorMsg " + msg);
|
||||
// 修复:渲染失败时移除容器
|
||||
if (getActivity() != null && !getActivity().isFinishing() && !getActivity().isDestroyed() && mContainer != null) {
|
||||
mContainer.removeView(container);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求广告(核心修复:Context安全校验 + 异常捕获 + 资源管理)
|
||||
*/
|
||||
private void fetchAd() {
|
||||
LogUtils.d(TAG, "fetchAd()");
|
||||
// 1. 双重校验:Activity未销毁 + Context非空
|
||||
if (getActivity() == null || getActivity().isFinishing() || getActivity().isDestroyed() || getActivity().getApplicationContext() == null) {
|
||||
LogUtils.e(TAG, "fetchAd: Invalid Context or Activity state");
|
||||
return;
|
||||
}
|
||||
// 2. 释放之前的广告资源,避免内存泄漏
|
||||
if (mBannerAd != null) {
|
||||
mBannerAd.destroy();
|
||||
}
|
||||
// 3. 初始化广告(使用ApplicationContext,避免Activity Context失效)
|
||||
try {
|
||||
mBannerAd = new BannerAd();
|
||||
mAllBanners.add(mBannerAd);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "fetchAd: Init BannerAd failed", e);
|
||||
return;
|
||||
}
|
||||
// 4. 设置下载监听
|
||||
mBannerAd.setDownLoadListener(new BannerAd.BannerDownloadListener() {
|
||||
@Override
|
||||
public void onDownloadStarted() {
|
||||
LogUtils.d(TAG, "onDownloadStarted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadPaused() {
|
||||
LogUtils.d(TAG, "onDownloadPaused");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFailed(int errorCode) {
|
||||
LogUtils.d(TAG, "onDownloadFailed, errorCode = " + errorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFinished() {
|
||||
LogUtils.d(TAG, "onDownloadFinished");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadProgressUpdated(int progress) {
|
||||
LogUtils.d(TAG, "onDownloadProgressUpdated " + progress + "%");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallFailed(int errorCode) {
|
||||
LogUtils.d(TAG, "onInstallFailed, errorCode = " + errorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallStart() {
|
||||
LogUtils.d(TAG, "onInstallStart");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallSuccess() {
|
||||
LogUtils.d(TAG, "onInstallSuccess");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadCancel() {
|
||||
LogUtils.d(TAG, "onDownloadCancel");
|
||||
}
|
||||
});
|
||||
|
||||
// 5. 构建广告参数并请求
|
||||
String currentAD_ID = getAD_ID();
|
||||
LogUtils.d(TAG, String.format("currentAD_ID = %s", currentAD_ID));
|
||||
ADParams params = new ADParams.Builder().setUpId(currentAD_ID).build();
|
||||
mBannerAd.loadAd(params, new BannerAd.BannerLoadListener() {
|
||||
@Override
|
||||
public void onBannerAdLoadSuccess() {
|
||||
LogUtils.d(TAG, "onBannerAdLoadSuccess()");
|
||||
// 修复:广告加载成功后校验Activity状态
|
||||
if (getActivity() != null && !getActivity().isFinishing() && !getActivity().isDestroyed()) {
|
||||
showAd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdLoadFailed(int errorCode, String errorMsg) {
|
||||
LogUtils.e(TAG, "onAdLoadFailed: errorCode = " + errorCode + ", errorMsg = " + errorMsg);
|
||||
// 修复:加载失败时移除当前广告实例
|
||||
if (mAllBanners.contains(mBannerAd)) {
|
||||
mAllBanners.remove(mBannerAd);
|
||||
}
|
||||
mBannerAd.destroy();
|
||||
mBannerAd = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前秒数获取广告ID(原逻辑保留)
|
||||
*/
|
||||
private String getAD_ID() {
|
||||
long currentSecond = System.currentTimeMillis() / 1000;
|
||||
return (currentSecond % 2 == 0) ? BANNER_POS_ID :
|
||||
(GlobalApplication.isDebugging() ? BANNER_POS_ID_WINBOLL_BETA : BANNER_POS_ID_WINBOLL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取广告价格(原逻辑保留,添加空指针校验)
|
||||
*/
|
||||
private long getPrice() {
|
||||
if (mBannerAd == null) {
|
||||
return 0;
|
||||
}
|
||||
Map<String, Object> map = mBannerAd.getMediaExtraInfo();
|
||||
if (map == null || map.isEmpty() || !map.containsKey("price")) {
|
||||
LogUtils.w(TAG, "getPrice: media extra info is null or no price key");
|
||||
return 0;
|
||||
}
|
||||
Object priceObj = map.get("price");
|
||||
if (priceObj instanceof Long) {
|
||||
return (Long) priceObj;
|
||||
} else if (priceObj instanceof Integer) {
|
||||
return ((Integer) priceObj).longValue();
|
||||
} else {
|
||||
LogUtils.e(TAG, "getPrice: price type is invalid");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示隐私协议弹窗(原逻辑保留,优化Context使用)
|
||||
*/
|
||||
private void showPrivacy() {
|
||||
// 校验Activity状态,避免弹窗泄露
|
||||
if (getActivity() == null || getActivity().isFinishing() || getActivity().isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
String privacyAgreeValue = getSharedPreferences().getString(PRIVACY_VALUE, null);
|
||||
if (TextUtils.equals(privacyAgreeValue, String.valueOf(0))) {
|
||||
LogUtils.i(TAG, "已拒绝隐私协议,广告已处于不可用状态...");
|
||||
Toast.makeText(getActivity().getApplicationContext(), "已拒绝隐私协议,广告已处于不可用状态", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (TextUtils.equals(privacyAgreeValue, String.valueOf(1))) {
|
||||
LogUtils.i(TAG, "已同意隐私协议,开始初始化米盟SDK...");
|
||||
initMimoSdk();
|
||||
return;
|
||||
}
|
||||
LogUtils.i(TAG, "开始弹出隐私协议...");
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle("用户须知");
|
||||
builder.setMessage("小米广告SDK隐私政策: https://dev.mi.com/distribute/doc/details?pId=1688, 请复制到浏览器查看");
|
||||
builder.setIcon(R.drawable.ic_launcher);
|
||||
builder.setCancelable(false); // 点击对话框以外的区域不消失
|
||||
builder.setPositiveButton("同意", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getSharedPreferences().edit()
|
||||
.putString(PRIVACY_VALUE, String.valueOf(1))
|
||||
.apply();
|
||||
initMimoSdk();
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getSharedPreferences().edit()
|
||||
.putString(PRIVACY_VALUE, String.valueOf(0))
|
||||
.apply();
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
// 配置弹窗位置(底部全屏)
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setGravity(Gravity.BOTTOM);
|
||||
WindowManager m = getActivity().getWindowManager();
|
||||
Display d = m.getDefaultDisplay();
|
||||
WindowManager.LayoutParams p = window.getAttributes();
|
||||
p.width = d.getWidth();
|
||||
window.setAttributes(p);
|
||||
}
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化米盟SDK(核心修复:传递ApplicationContext + 异常捕获)
|
||||
*/
|
||||
private void initMimoSdk() {
|
||||
// 1. 安全获取ApplicationContext,避免Activity Context失效
|
||||
Context appContext = getActivity().getApplicationContext();
|
||||
if (appContext == null) {
|
||||
LogUtils.e(TAG, "initMimoSdk: ApplicationContext is null");
|
||||
return;
|
||||
}
|
||||
// 2. 初始化SDK,捕获异常避免崩溃
|
||||
try {
|
||||
MimoSdk.init(appContext, new MimoCustomController() {
|
||||
@Override
|
||||
public boolean isCanUseLocation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MimoLocation getMimoLocation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCanUseWifiState() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alist() {
|
||||
return true;
|
||||
}
|
||||
}, new MimoSdk.InitCallback() {
|
||||
@Override
|
||||
public void success() {
|
||||
LogUtils.d(TAG, "MimoSdk init success");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(int code, String msg) {
|
||||
LogUtils.e(TAG, "MimoSdk init fail, code=" + code + ",msg=" + msg);
|
||||
}
|
||||
});
|
||||
MimoSdk.setDebugOn(true);
|
||||
} catch (Exception e) {
|
||||
LogUtils.e(TAG, "initMimoSdk: init failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取SharedPreferences实例(原逻辑保留,添加空指针校验)
|
||||
*/
|
||||
SharedPreferences getSharedPreferences() {
|
||||
if (mSharedPreferences == null) {
|
||||
// 修复:使用ApplicationContext获取SharedPreferences,避免Activity Context泄露
|
||||
Context appContext = getActivity().getApplicationContext();
|
||||
if (appContext != null) {
|
||||
mSharedPreferences = appContext.getSharedPreferences(PRIVACY_FILE, Context.MODE_PRIVATE);
|
||||
} else {
|
||||
LogUtils.e(TAG, "getSharedPreferences: ApplicationContext is null");
|
||||
// 降级方案:若ApplicationContext为空,使用Activity Context(仅作兼容)
|
||||
mSharedPreferences = getActivity().getSharedPreferences(PRIVACY_FILE, Context.MODE_PRIVATE);
|
||||
}
|
||||
}
|
||||
return mSharedPreferences;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import cc.winboll.studio.libaes.utils.PrefUtils;
|
||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
||||
import cc.winboll.studio.libappbase.GlobalApplication;
|
||||
import cc.winboll.studio.libappbase.LogUtils;
|
||||
import com.hjq.toast.ToastUtils;
|
||||
import cc.winboll.studio.libappbase.ToastUtils;
|
||||
import java.io.IOException;
|
||||
import mehdi.sakout.aboutpage.AboutPage;
|
||||
import mehdi.sakout.aboutpage.Element;
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:id="@+id/ads_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="WinBoLL ADs"/>
|
||||
android:orientation="vertical"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
Reference in New Issue
Block a user