• Android 接入穿山甲广告


    目录

    下载SDK

    集成SDK

    AndroidManifest配置

    provider配置

    运行环境配置

    白名单配置

    工具类


    下载SDK

    首先去穿山甲官网注册账号以及创建应用点此进入官网

    点击进入平台 (我的是创建完账号并且登录之后是这个样子)

    进来之后是如下界面

    然后依次点击流量--->应用会进入到以下界面

     

    然后点击创建应用根据提示走即可

    创建完毕之后去依次点击流量-->代码位创建广告位 根据自己的需求去创建即可

    最后点击接入选择SDK下载与文档选择Android平台SDK

    下载完成之后开始集成

    集成SDK

    集成方式一

            导入aar及SDK依赖的jar包

    将本SDK压缩包内的open_ad_sdk.aar复制到Application Module/libs文件夹(没有的话须手动创建), 并将以下代码添加到您app的build.gradle中:

    1. repositories {
    2. flatDir {
    3. dirs 'libs'
    4. }
    5. }
    6. depedencies {
    7. compile(name: 'open_ad_sdk', ext: 'aar')
    8. }

    方式二:从穿山甲3.5.0.6版本开始,开发者也可以使用Gradle依赖导入穿山甲SDK

    步骤一:添加仓库

    project级别的build.gradle文件中添加Maven的引用,url 'https://artifact.bytedance.com/repository/pangle'

    示例:

    1. allprojects {
    2. repositories {
    3. maven {
    4. url 'https://artifact.bytedance.com/repository/pangle'
    5. }
    6. }
    7. }

    步骤二:添加依赖

    在主modulebuild.gradle文件添加SDK依赖

    1. dependencies {
    2. implementation 'com.pangle.cn:ads-sdk-pro:4.4.0.9'
    3. }

    Gradle版本要求:

    自3400版本开始,穿山甲支持了Android R,引入了Android R的 <queries> 标签,需要对gradle版本进行限制,限制范围为:3.3.3、 3.4.3、 3.5.4、3.6.4、4.0.1 ,开发者根据自身情况酌情升级

    AndroidManifest配置

    添加权限

    1. <!--必要权限-->
    2. <uses-permission android:name="android.permission.INTERNET" />
    3. <!--必要权限,解决安全风险漏洞,发送和注册广播事件需要调用带有传递权限的接口-->
    4. <permission android:name="${applicationId}.openadsdk.permission.TT_PANGOLIN"
    5. android:protectionLevel="signature" />
    6. <uses-permission android:name="${applicationId}.openadsdk.permission.TT_PANGOLIN" />
    7. <!--可选权限-->
    8. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    9. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    10. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    11. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    12. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    13. <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    14. <uses-permission android:name="android.permission.GET_TASKS"/>
    15. <!--可选,穿山甲提供“获取地理位置权限”和“不给予地理位置权限,开发者传入地理位置参数”两种方式上报用户位置,两种方式均可不选,添加位置权限或参数将帮助投放定位广告-->
    16. <!--请注意:无论通过何种方式提供给穿山甲用户地理位置,均需向用户声明地理位置权限将应用于穿山甲广告投放,穿山甲不强制获取地理位置信息-->
    17. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    18. <!-- 如果视频广告使用textureView播放,请务必添加,否则黑屏 -->
    19. <uses-permission android:name="android.permission.WAKE_LOCK" />
    20. <!--demo场景用到的权限,不是必须的-->
    21. <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    22. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    23. <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
    24. <!-- 穿山甲3400版本新增:建议添加“query_all_package”权限,穿山甲将通过此权限在Android R系统上判定广告对应的应用是否在用户的app上安装,避免投放错误的广告,以此提高用户的广告体验。若添加此权限,需要在您的用户隐私文档中声明! -->
    25. <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

    注意: 穿山甲SDK不强制获取以上权限,即使没有获取可选权限SDK也能正常运行;获取以上权限将帮助穿山甲优化投放广告精准度和用户的交互体验,提高eCPM。

    建议在广告请求前,合适的时机调用SDK提供的方法,在用户可以授权的情况下获取到声明中的权限,提高广告变现效率

    1. //TTAdManager接口中的方法,context可以是Activity或Application
    2. void requestPermissionIfNecessary(Context context);

    provider配置

    注意:(1)为不影响下载类型广告使用 无论APP处于任何阶段provider都需要在清单文件中正常配置(2)为不影响到广告的转化及收益 请务必在清单文件中配置xxx.TTMultiProvider(3)${applicationId} 必须与开发者包名保持一致,否则会引发崩溃问题

    适配Anroid7.0及以上如果您的应用需要在Anroid7.0及以上环境运行,请在AndroidManifest中添加如下代码:

    1. <provider
    2. android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
    3. android:authorities="${applicationId}.TTFileProvider"
    4. android:exported="false"
    5. android:grantUriPermissions="true">
    6. <meta-data
    7. android:name="android.support.FILE_PROVIDER_PATHS"
    8. android:resource="@xml/file_paths" />
    9. </provider>

    在res/xml目录下,新建一个xml文件file_paths,在该文件中添加如下代码:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <paths xmlns:android="http://schemas.android.com/apk/res/android">
    3. <!--为了适配所有路径可以设置 path = "." -->
    4. <external-path name="tt_external_root" path="." />
    5. <external-path name="tt_external_download" path="Download" />
    6. <external-files-path name="tt_external_files_download" path="Download" />
    7. <files-path name="tt_internal_file_download" path="Download" />
    8. <cache-path name="tt_internal_cache_download" path="Download" />
    9. </paths>

    为了适配下载和安装相关功能,在工程中引用的包 com.android.support:support-v4:24.2.0使用24.2.0以及以上版本

    注意:单进程或多进程都必须配置

    1. <provider
    2. android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider" android:authorities="${applicationId}.TTMultiProvider" android:exported="false" />

    运行环境配置

    本SDK可运行于Android4.0 (API Level 14) 及以上版本。<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="24" />

    如果开发者声明targetSdkVersion到API 23以上,请确保调用本SDK的任何接口前,已经申请到了SDK要求的所有权限,否则SDK部分特性可能受限

    代码混淆

    如果您需要使用proguard混淆代码,需确保不要混淆SDK的代码。 请在proguard.cfg文件(或其他混淆文件)尾部添加如下配置:35xx以及以下版本混淆规则如下:

    1. -keep class com.bytedance.sdk.openadsdk.** { *; }
    2. -keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
    3. -keep class com.pgl.sys.ces.* {*;}
    4. -keep class com.bytedance.embed_dr.** {*;}
    5. -keep class com.bytedance.embedapplog.** {*;}

    36xx版本-38xx版本混淆规则如下

    1. -keep class com.bytedance.sdk.openadsdk.** { *; }
    2. -keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
    3. -keep class ms.bd.c.**{*;}
    4. -keep class com.bytedance.mobsec.**{*;}
    5. -keep class com.bytedance.embed_dr.** {*;}
    6. -keep class com.bytedance.embedapplog.** {*;}
    7. -keep interface com.bytedance.frameworks.baselib.network.http.cronet.I* {*;}
    8. -keepnames class com.bytedance.framwork.core.sdkmonitor.SDKMonitorUtils

    3900版本及以上版本混淆规则如下

    1. -keep class com.bytedance.sdk.openadsdk.** { *; }
    2. -keep class com.bytedance.frameworks.** { *; }
    3. -keep class ms.bd.c.Pgl.**{*;}
    4. -keep class com.bytedance.mobsec.metasec.ml.**{*;}
    5. -keep class com.ss.android.**{*;}
    6. -keep class com.bytedance.embedapplog.** {*;}
    7. -keep class com.bytedance.embed_dr.** {*;}
    8. -keep class com.bykv.vk.** {*;}

    4000版本混淆规则:以aar包里的混淆文件为准

    注意: SDK代码被混淆后会导致广告无法展现或者其它异常

    支持架构

    注意: 3900以及以上版本SDK默认支持armeabi-v7a,arm64-v8a两种架构,如果有其他架构需求,请联系技术支持同学; 3900以下版本SDK中使用的so文件支持五种架构:x86,x86_64,armeabi,armeabi-v7a,arm64-v8a如果您应用中支持的架构超出这 五种,请在build.gradle中使用abiFilters选择支持的架构。如下所示:

    1. ndk { // 设置支持的 SO 库构架,注意这里要根据你的实际情况来设置
    2. abiFilters armeabi-v7a , arm64-v8a , x86 , x86_64 , armeabi
    3. }

    说明:1、36xx-38xx版本中穿山甲增加了libmetasec_ml.so 库。2、36xx-38xx版本若开发者使用armeabi架构,那么需要把armeabi-v7a下的 libmetasec_ml.so 拷贝到armeabi目录下使用。

    白名单配置

    注意:平台SDK包中whiteList.txt 白名单上的资源不支持混淆

    配置完成之后创建一个SDK初始化脚本内容如下  初始化调用是在开屏界面调用 调用初始化成功之后会自动调用开屏代码

    1. package com.unity3d.player.chuanshanjia;
    2. import android.content.Context;
    3. import android.util.Log;
    4. import com.bytedance.sdk.openadsdk.TTAdConfig;
    5. import com.bytedance.sdk.openadsdk.TTAdConstant;
    6. import com.bytedance.sdk.openadsdk.TTAdManager;
    7. import com.bytedance.sdk.openadsdk.TTAdSdk;
    8. /**
    9. * 可以用一个单例来保存TTAdManager实例,在需要初始化sdk的时候调用
    10. */
    11. public class TTAdManagerHolder {
    12. private static final String TAG = "TTAdManagerHolder";
    13. private static boolean sInit;
    14. private static String appid;
    15. private static String appName;
    16. private static TTAdManagerHolder _Instance;
    17. public static TTAdManager get() {
    18. return TTAdSdk.getAdManager();
    19. }
    20. public static TTAdManagerHolder Inst(){
    21. if (_Instance == null){
    22. _Instance = new TTAdManagerHolder();
    23. }
    24. return _Instance;
    25. }
    26. public void init(final Context context,String aid,String aname) {
    27. appid = aid;
    28. appName = aname;
    29. Log.d(TAG, "TTAdManagerHolderinit aid:"+aid+" aname:"+aname);
    30. doInit(context);
    31. }
    32. //step1:接入网盟广告sdk的初始化操作,详情见接入文档和穿山甲平台说明
    33. private void doInit(Context context) {
    34. if (!sInit) {
    35. TTAdSdk.init(context, buildConfig(context), new TTAdSdk.InitCallback() {
    36. @Override
    37. public void success() {
    38. Log.i(TAG, "success: " );
    39. CsjSplashActivity.Inst().loadSplashAd();
    40. }
    41. @Override
    42. public void fail(int code, String msg) {
    43. Log.i(TAG, "fail: code = " + code + " msg = " + msg);
    44. }
    45. });
    46. sInit = true;
    47. }
    48. }
    49. private TTAdConfig buildConfig(Context context) {
    50. //强烈建议在应用对应的Application#onCreate()方法中调用,避免出现content为null的异常
    51. return new TTAdConfig.Builder()
    52. .appId(appid)
    53. .useTextureView(true) //默认使用SurfaceView播放视频广告,当有SurfaceView冲突的场景,可以使用TextureView
    54. .appName(appName)
    55. .titleBarTheme(TTAdConstant.TITLE_BAR_THEME_DARK)//落地页主题
    56. .allowShowNotify(true) //是否允许sdk展示通知栏提示,若设置为false则会导致通知栏不显示下载进度
    57. .debug(true) //测试阶段打开,可以通过日志排查问题,上线时去除该调用
    58. .directDownloadNetworkType(TTAdConstant.NETWORK_STATE_WIFI) //允许直接下载的网络状态集合,没有设置的网络下点击下载apk会有二次确认弹窗,弹窗中会披露应用信息
    59. .supportMultiProcess(false) //是否支持多进程,true支持
    60. .asyncInit(true) //是否异步初始化sdk,设置为true可以减少SDK初始化耗时。3450版本开始废弃~~
    61. //.httpStack(new MyOkStack3())//自定义网络库,demo中给出了okhttp3版本的样例,其余请自行开发或者咨询工作人员。
    62. .build();
    63. }
    64. }

    SDK集成完成之后开始接入SDK

    工具类

    ChuanShanJiaUtil

    1. package com.unity3d.player.tools;
    2. import android.app.Activity;
    3. import android.content.Context;
    4. import android.os.Build;
    5. import android.text.TextUtils;
    6. import android.util.DisplayMetrics;
    7. import android.view.Display;
    8. import android.view.DisplayCutout;
    9. import android.view.View;
    10. import android.view.ViewGroup;
    11. import android.view.ViewParent;
    12. import android.view.WindowInsets;
    13. import android.view.WindowManager;
    14. import android.widget.FrameLayout;
    15. import android.widget.LinearLayout;
    16. import android.widget.RelativeLayout;
    17. import java.lang.reflect.InvocationTargetException;
    18. import java.lang.reflect.Method;
    19. public class ChuanShanJiaUtil {
    20. public static float getScreenWidthDp(Context context){
    21. final float scale = context.getResources().getDisplayMetrics().density;
    22. float width = context.getResources().getDisplayMetrics().widthPixels;
    23. return width / (scale <= 0 ? 1 : scale) + 0.5f;
    24. }
    25. //全面屏、刘海屏适配
    26. public static float getHeight(Activity activity) {
    27. hideBottomUIMenu(activity);
    28. float height;
    29. int realHeight = getRealHeight(activity);
    30. if (ChuanShanJiaUtil.hasNotchScreen(activity)) {
    31. height = px2dip(activity, realHeight - getStatusBarHeight(activity));
    32. }else {
    33. height = px2dip(activity, realHeight);
    34. }
    35. return height;
    36. }
    37. public static void hideBottomUIMenu(Activity activity) {
    38. if (activity == null) {
    39. return;
    40. }
    41. try {
    42. //隐藏虚拟按键,并且全屏
    43. if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
    44. View v = activity.getWindow().getDecorView();
    45. v.setSystemUiVisibility(View.GONE);
    46. } else if (Build.VERSION.SDK_INT >= 19) {
    47. //for new api versions.
    48. View decorView = activity.getWindow().getDecorView();
    49. int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    50. | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
    51. | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    52. | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
    53. // | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
    54. | View.SYSTEM_UI_FLAG_IMMERSIVE;
    55. decorView.setSystemUiVisibility(uiOptions);
    56. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    57. }
    58. } catch (Exception e) {
    59. e.printStackTrace();
    60. }
    61. }
    62. //获取屏幕真实高度,不包含下方虚拟导航栏
    63. public static int getRealHeight(Context context) {
    64. WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    65. Display display = windowManager.getDefaultDisplay();
    66. DisplayMetrics dm = new DisplayMetrics();
    67. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    68. display.getRealMetrics(dm);
    69. } else {
    70. display.getMetrics(dm);
    71. }
    72. int realHeight = dm.heightPixels;
    73. return realHeight;
    74. }
    75. //获取状态栏高度
    76. public static float getStatusBarHeight(Context context) {
    77. float height = 0;
    78. int resourceId = context.getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
    79. if (resourceId > 0) {
    80. height = context.getApplicationContext().getResources().getDimensionPixelSize(resourceId);
    81. }
    82. return height;
    83. }
    84. public static int px2dip(Context context, float pxValue) {
    85. final float scale = context.getResources().getDisplayMetrics().density;
    86. return (int) (pxValue / (scale <= 0 ? 1 : scale) + 0.5f);
    87. }
    88. public static int dp2px(Context context, float dp) {
    89. final float scale = context.getResources().getDisplayMetrics().density;
    90. return (int) (dp * scale + 0.5f);
    91. }
    92. /**
    93. * 判断是否是刘海屏
    94. * @return
    95. */
    96. public static boolean hasNotchScreen(Activity activity){
    97. return isAndroidPHasNotch(activity)
    98. || getInt("ro.miui.notch", activity) == 1
    99. || hasNotchAtHuawei(activity)
    100. || hasNotchAtOPPO(activity)
    101. || hasNotchAtVivo(activity);
    102. }
    103. /**
    104. * Android P 刘海屏判断
    105. * @param activity
    106. * @return
    107. */
    108. public static boolean isAndroidPHasNotch(Activity activity){
    109. boolean result = false;
    110. if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    111. DisplayCutout displayCutout = null;
    112. try {
    113. WindowInsets windowInsets = activity.getWindow().getDecorView().getRootWindowInsets();
    114. if (windowInsets != null) {
    115. displayCutout = windowInsets.getDisplayCutout();
    116. }
    117. if (displayCutout != null) {
    118. result = true;
    119. }
    120. } catch (Exception e) {
    121. e.printStackTrace();
    122. }
    123. }
    124. return result;
    125. }
    126. /**
    127. * 小米刘海屏判断.
    128. * @return 0 if it is not notch ; return 1 means notch
    129. * @throws IllegalArgumentException if the key exceeds 32 characters
    130. */
    131. public static int getInt(String key,Activity activity) {
    132. int result = 0;
    133. if (isMiui()){
    134. try {
    135. ClassLoader classLoader = activity.getClassLoader();
    136. @SuppressWarnings("rawtypes")
    137. Class SystemProperties = classLoader.loadClass("android.os.SystemProperties");
    138. //参数类型
    139. @SuppressWarnings("rawtypes")
    140. Class[] paramTypes = new Class[2];
    141. paramTypes[0] = String.class;
    142. paramTypes[1] = int.class;
    143. Method getInt = SystemProperties.getMethod("getInt", paramTypes);
    144. //参数
    145. Object[] params = new Object[2];
    146. params[0] = new String(key);
    147. params[1] = new Integer(0);
    148. result = (Integer) getInt.invoke(SystemProperties, params);
    149. } catch (ClassNotFoundException e) {
    150. e.printStackTrace();
    151. } catch (NoSuchMethodException e) {
    152. e.printStackTrace();
    153. } catch (IllegalAccessException e) {
    154. e.printStackTrace();
    155. } catch (IllegalArgumentException e) {
    156. e.printStackTrace();
    157. } catch (InvocationTargetException e) {
    158. e.printStackTrace();
    159. }
    160. }
    161. return result;
    162. }
    163. /**
    164. * 华为刘海屏判断
    165. * @return
    166. */
    167. public static boolean hasNotchAtHuawei(Context context) {
    168. boolean ret = false;
    169. try {
    170. ClassLoader classLoader = context.getClassLoader();
    171. Class HwNotchSizeUtil = classLoader.loadClass("com.huawei.android.util.HwNotchSizeUtil");
    172. Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
    173. ret = (boolean) get.invoke(HwNotchSizeUtil);
    174. } catch (ClassNotFoundException e) {
    175. } catch (NoSuchMethodException e) {
    176. } catch (Exception e) {
    177. } finally {
    178. return ret;
    179. }
    180. }
    181. public static final int VIVO_NOTCH = 0x00000020;//是否有刘海
    182. public static final int VIVO_FILLET = 0x00000008;//是否有圆角
    183. /**
    184. * VIVO刘海屏判断
    185. * @return
    186. */
    187. public static boolean hasNotchAtVivo(Context context) {
    188. boolean ret = false;
    189. try {
    190. ClassLoader classLoader = context.getClassLoader();
    191. Class FtFeature = classLoader.loadClass("android.util.FtFeature");
    192. Method method = FtFeature.getMethod("isFeatureSupport", int.class);
    193. ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH);
    194. } catch (ClassNotFoundException e) {
    195. } catch (NoSuchMethodException e) {
    196. } catch (Exception e) {
    197. } finally {
    198. return ret;
    199. }
    200. }
    201. /**
    202. * O-P-P-O刘海屏判断
    203. * @return
    204. */
    205. public static boolean hasNotchAtOPPO(Context context) {
    206. String temp = "com.kllk.feature.screen.heteromorphism";
    207. String name = getKllkDecryptString(temp);
    208. return context.getPackageManager().hasSystemFeature(name);
    209. }
    210. public static boolean isMiui() {
    211. boolean sIsMiui = false;
    212. try {
    213. Class<?> clz = Class.forName("miui.os.Build");
    214. if (clz != null) {
    215. sIsMiui = true;
    216. //noinspection ConstantConditions
    217. return sIsMiui;
    218. }
    219. } catch (Exception e) {
    220. // ignore
    221. }
    222. return sIsMiui;
    223. }
    224. /**
    225. *用于o-p-p-o 版本隐私协议
    226. */
    227. public static String getKllkDecryptString(String encryptionString) {
    228. if (TextUtils.isEmpty(encryptionString)) {
    229. return "";
    230. }
    231. String decryptTag = "";
    232. String decryptCapitalized = "O" + "P" + "P" + "O";
    233. String decrypt = "o" + "p" + "p" + "o";
    234. if (encryptionString.contains("KLLK")) {
    235. decryptTag = encryptionString.replace("KLLK", decryptCapitalized);
    236. } else if (encryptionString.contains("kllk")) {
    237. decryptTag = encryptionString.replace("kllk", decrypt);
    238. }
    239. return decryptTag;
    240. }
    241. public static void setViewSize(View view, int width, int height) {
    242. if (view.getParent() instanceof FrameLayout) {
    243. FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) view.getLayoutParams();
    244. lp.width = width;
    245. lp.height = height;
    246. view.setLayoutParams(lp);
    247. view.requestLayout();
    248. } else if (view.getParent() instanceof RelativeLayout) {
    249. RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
    250. lp.width = width;
    251. lp.height = height;
    252. view.setLayoutParams(lp);
    253. view.requestLayout();
    254. } else if (view.getParent() instanceof LinearLayout) {
    255. LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams();
    256. lp.width = width;
    257. lp.height = height;
    258. view.setLayoutParams(lp);
    259. view.requestLayout();
    260. }
    261. }
    262. public static int getScreenWidthInPx(Context context) {
    263. DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
    264. return dm.widthPixels;
    265. }
    266. public static int getScreenHeightInPx(Context context) {
    267. DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics();
    268. return dm.heightPixels;
    269. }
    270. public static int getScreenHeight(Context context) {
    271. return (int) (getScreenHeightInPx(context) + getStatusBarHeight(context));
    272. }
    273. public static void removeFromParent(View view) {
    274. if (view != null) {
    275. ViewParent vp = view.getParent();
    276. if (vp instanceof ViewGroup) {
    277. ((ViewGroup) vp).removeView(view);
    278. }
    279. }
    280. }
    281. /**
    282. * 获取全面屏宽高
    283. * @param context
    284. * @return
    285. */
    286. public static int[] getScreenSize(Context context) {
    287. int[] size = new int[]{0,0};
    288. if (context == null){
    289. return size;
    290. }
    291. WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    292. Display display = windowManager.getDefaultDisplay();
    293. DisplayMetrics dm = new DisplayMetrics();
    294. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    295. display.getRealMetrics(dm);
    296. } else {
    297. display.getMetrics(dm);
    298. }
    299. size[0] = dm.widthPixels;
    300. size[1] = dm.heightPixels;
    301. return size;
    302. }
    303. }

    ShowSeqUtils

    1. package com.unity3d.player.tools;
    2. import android.os.Environment;
    3. import java.io.BufferedReader;
    4. import java.io.BufferedWriter;
    5. import java.io.File;
    6. import java.io.FileReader;
    7. import java.io.FileWriter;
    8. import java.text.SimpleDateFormat;
    9. import java.util.Date;
    10. public class ShowSeqUtils {
    11. private FileReader fr;
    12. private BufferedReader br;
    13. private FileWriter fw;
    14. private BufferedWriter bw;
    15. public int loadShowSeq(){
    16. int show_seq = 1;
    17. //获取当前日期字符串
    18. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    19. String data = sdf.format(new Date());
    20. //读取本地缓存show_seq的文件
    21. try {
    22. String rootPath = Environment.getExternalStorageDirectory().getPath();
    23. File file = new File(rootPath + "/Android/data/com.snssdk.api/cache/adloadSeqTemp.txt");
    24. if (!file.exists()) {
    25. file.createNewFile();
    26. return show_seq;
    27. }
    28. fr = new FileReader(file);
    29. br = new BufferedReader(fr);
    30. String line = "";
    31. while ((line = br.readLine()) != null) {
    32. String[] temp = line.split(",");
    33. if (temp[0].equals(data)){
    34. //日期相同返回字段
    35. show_seq = Integer.parseInt(temp[1]);
    36. }
    37. }
    38. return show_seq;
    39. } catch (Exception e) {
    40. e.printStackTrace();
    41. } finally {
    42. try {
    43. if(fr!=null){
    44. fr.close();
    45. }
    46. if(br!=null){
    47. br.close();
    48. }
    49. } catch (Exception e) {
    50. e.printStackTrace();
    51. }
    52. }
    53. return show_seq;
    54. }
    55. public void writeToFile(int show_seq){
    56. //获取当前日期字符串
    57. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    58. String data = sdf.format(new Date());
    59. String content = data+","+show_seq;
    60. //读取本地缓存show_seq的文件
    61. try {
    62. String rootPath = Environment.getExternalStorageDirectory().getPath();
    63. File file = new File(rootPath + "/Android/data/com.snssdk.api/cache/");
    64. if (!file.exists()) {
    65. file.mkdir();
    66. }
    67. String filename = file.getAbsolutePath()+"/adloadSeqTemp.txt";
    68. file = new File(filename);
    69. if(!file.exists()){
    70. file.createNewFile();
    71. }
    72. fw = new FileWriter(file, false);
    73. fw.write(content);
    74. } catch (Exception e) {
    75. e.printStackTrace();
    76. } finally {
    77. try {
    78. if(fw!=null){
    79. fw.flush();
    80. fw.close();
    81. }
    82. } catch (Exception e) {
    83. e.printStackTrace();
    84. }
    85. }
    86. }
    87. }

    TToast

    1. package com.unity3d.player.tools;
    2. import android.annotation.SuppressLint;
    3. import android.content.Context;
    4. import android.util.Log;
    5. import android.widget.Toast;
    6. public final class TToast {
    7. private static Toast sToast;
    8. public static void show(Context context, String msg) {
    9. show(context, msg, Toast.LENGTH_SHORT);
    10. }
    11. public static void show(Context context, String msg, int duration) {
    12. Toast toast = getToast(context);
    13. if (toast != null) {
    14. toast.setDuration(duration);
    15. toast.setText(String.valueOf(msg));
    16. toast.show();
    17. } else {
    18. Log.i("TToast", "toast msg: " + String.valueOf(msg));
    19. }
    20. }
    21. @SuppressLint("ShowToast")
    22. private static Toast getToast(Context context) {
    23. if (context == null) {
    24. return sToast;
    25. }
    26. // if (sToast == null) {
    27. // synchronized (TToast.class) {
    28. // if (sToast == null) {
    29. sToast = Toast.makeText(context.getApplicationContext(), "", Toast.LENGTH_SHORT);
    30. // }
    31. // }
    32. // }
    33. return sToast;
    34. }
    35. public static void reset() {
    36. sToast = null;
    37. }
    38. }

    下一篇 接入开屏广告 传送门

  • 相关阅读:
    web前端框架
    C# 解析xml格式接口数据
    Shopee买家通系统之如何注册虾皮账号
    golang[ssa & callgraph] 获取调用图实战
    docker+nginx 安装部署修改资源目录配置文件和容器端口信息
    【对比学习】Understanding the Behaviour of Contrastive Loss (CVPR‘21)
    Maven的安装与配置(详细版)
    嵌入式BI的精解与探索
    多媒体技术1-颜色在计算机中的表示
    计算机设计大赛心得总结-软件开发组
  • 原文地址:https://blog.csdn.net/qq_41973169/article/details/125427149