Compare commits

...

14 Commits

Author SHA1 Message Date
1414c902d0 <aes>APK 15.11.4 release Publish. 2025-11-19 09:04:27 +08:00
ZhanGSKen
f7b30bebc0 关闭不必要的吐司提示 2025-11-19 09:03:51 +08:00
564289a114 <libaes>Library Release 15.11.3 2025-11-19 08:54:09 +08:00
a08daf142b <aes>APK 15.11.3 release Publish. 2025-11-19 08:54:02 +08:00
ZhanGSKen
bb1f3fba30 调整应用存储配置 2025-11-19 08:53:23 +08:00
66549aea4d <libaes>Library Release 15.11.2 2025-11-19 08:36:28 +08:00
7c6b215d89 <aes>APK 15.11.2 release Publish. 2025-11-19 08:36:14 +08:00
ZhanGSKen
042e25a3dc 精简源码 2025-11-19 08:34:58 +08:00
ZhanGSKen
e2410531ab 更新米盟 SDK 广告显示方案 2025-11-19 08:34:24 +08:00
1fb91e9bfa <libaes>Library Release 15.11.1 2025-11-18 16:40:28 +08:00
7e50147d0b <aes>APK 15.11.1 release Publish. 2025-11-18 16:40:13 +08:00
ZhanGSKen
6e469b2c18 米盟广告模块已测试完成 2025-11-18 16:38:14 +08:00
ZhanGSKen
23ba2bdf0c 添加横幅广告框架 2025-11-18 15:01:38 +08:00
fb7a372f29 <libaes>Library Release 15.11.0 2025-11-13 07:24:25 +08:00
16 changed files with 676 additions and 54 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Thu Nov 13 07:24:09 HKT 2025
stageCount=1
#Wed Nov 19 09:04:27 HKT 2025
stageCount=5
libraryProject=libaes
baseVersion=15.11
publishVersion=15.11.0
publishVersion=15.11.4
buildCount=0
baseBetaVersion=15.11.1
baseBetaVersion=15.11.5

View File

@@ -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();
}
}

View File

@@ -5,6 +5,16 @@ buildscript {
// 设置本地Maven仓库路径
url 'file:///sdcard/.m2/repository/'
}
//米盟通过maven接入时要做如下配置
maven {
url "https://repos.xiaomi.com/maven"
credentials {
username 'mimo-developer'
password 'AKCp8ih1PFG9tV8qaLyws67dLGZi8udFM39SfsHgihN15cgsiRvHuxj8JzFmuZjaViVeNawaA'
}
}
// Nexus Maven 库地址
// "WinBoLL Release"
maven { url "https://nexus.winboll.cc/repository/maven-public/" }
@@ -40,6 +50,15 @@ allprojects {
// 设置本地Maven仓库路径
url 'file:///sdcard/.m2/repository/'
}
//米盟通过maven接入时要做如下配置
maven {
url "https://repos.xiaomi.com/maven"
credentials {
username 'mimo-developer'
password 'AKCp8ih1PFG9tV8qaLyws67dLGZi8udFM39SfsHgihN15cgsiRvHuxj8JzFmuZjaViVeNawaA'
}
}
// Nexus Maven 库地址
// "WinBoLL Release"

View File

@@ -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'])

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Thu Nov 13 07:24:09 HKT 2025
stageCount=1
#Wed Nov 19 09:04:27 HKT 2025
stageCount=5
libraryProject=libaes
baseVersion=15.11
publishVersion=15.11.0
publishVersion=15.11.4
buildCount=0
baseBetaVersion=15.11.1
baseBetaVersion=15.11.5

View File

@@ -1,9 +1,25 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="cc.winboll.studio.libaes">
<application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<!-- 通过GPS得到精确位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 通过网络得到粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="cc.winboll.studio.libaes.unittests.SecondaryLibraryActivity"
@@ -33,6 +49,18 @@
android:name="cc.winboll.studio.libaes.winboll.WinBoLLMail"
android:exported="true"/>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider" />
</provider>
</application>
</manifest>
</manifest>

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -0,0 +1,485 @@
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 cc.winboll.studio.libappbase.ToastUtils;
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;
/**
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
* @Date 2025/11/18 14:41
* @Describe WinBoLL 横幅广告类
*/
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);
this.mContext = context;
initView();
}
public ADsBannerView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
initView();
}
public ADsBannerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
initView();
}
public ADsBannerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.mContext = context;
initView();
}
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() {
// 修复:优化广告请求逻辑(添加生命周期判断 + 主线程执行)
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) {
String msg = "onDownloadFailed, errorCode = " + errorCode;
LogUtils.d(TAG, msg);
//ToastUtils.show(msg);
}
@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) {
String msg = "onAdLoadFailed: errorCode = " + errorCode + ", errorMsg = " + errorMsg;
LogUtils.d(TAG, msg);
removeAllBanners();
}
});
}
void removeAllBanners() {
// 修复:加载失败时移除当前广告实例
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;
}
}

View File

@@ -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;

View File

@@ -10,7 +10,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/activitydrawerfragmentASupportToolbar1"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
@@ -19,7 +19,8 @@
<androidx.drawerlayout.widget.DrawerLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
android:id="@+id/activitydrawerfragmentDrawerLayout1">
<FrameLayout
@@ -52,7 +53,13 @@
</androidx.drawerlayout.widget.DrawerLayout>
</LinearLayout>
<cc.winboll.studio.libaes.views.ADsBannerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/adsbanner"/>
</LinearLayout>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ads_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/ads_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="mimoDownload" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>

View File

@@ -4,4 +4,13 @@
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">winboll.cc</domain>
</domain-config>
<!-- 米盟 SDK 配置 -->
<base-config cleartextTrafficPermitted="true" />
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>