1.laya这边的步骤和打包其他apk的步骤一样
需要特别注意的是:

在游戏隐私协议中附加⼩⽶SDK隐私协议:本游戏接⼊了⼩⽶游戏服务
SDK,提供登录和⽀付以及实名制服务,所收集信息请阅读《⼩⽶游戏服务隐私政策》
https://privacy.mi.com/xiaomigame-sdk/zh_CN/
关于隐私协议,android工程需要做的工作:
隐私协议 ⽤⼾在第⼀次打开游戏时,需要显⽰相关隐私协议,⽤⼾选择之后,调⽤

2.android工程,sdk初始化:

开发环境和版本要求:
1.游戏接⼊SDK,还需要依赖Android Support V4,版本27.1.1以上
2.Andoird Studio建议3.0.0以上,Gradle建议3.6.3以上,JDK建议1.8
3.targetSdkVersion要求必须>=26
4.minSdkVersion建议>=18,compileSdkVersion建议>=28,targetSdkVersion>=26,buildToolsVersion 建议28.0.3

classpath 'com.android.tools.build:gradle:3.6.3'
需要注意的是:这里的Gradle配置是
gradle plugin的配置,需要对应
gradle的版本:

开发环境配置如下:
android {
compileSdkVersion 29
buildToolsVersion "30.0.2"
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId "com.cszs.jgdnc.mi"
minSdkVersion 24
targetSdkVersion 28
versionCode 1
versionName "2.0"
}
sourceSets.main{
jniLibs.srcDir 'libs'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
}
先接入网游的sdk:
(1)引入res和lib文件夹下的文件
* 在小米开发者创建应用并获取 AppId 、AppKey和AppSecret(注意AppSecret是用于服务器端签名,不要在客户端里使用),创建应用时如果是游戏PackageName必须以“.mi”为后缀。
* 将 SDK 包中res目录中的资源,完整添加到游戏Android工程的res目录。如果样式有冲突,可酌情修改。
* 将 SDK 包中libs目录下的文件放在你的项目的libs目录下(图中mio_sdk_base_3.2.0_12748.jar包会根据不同版本,名称会有所变化,以实际名称为准,部分第三方包也可能由于版本不同而有变化,以实际为准),在 buildpath 中引用,然后对 SDK 进行初始化(如不支持x86可不复制x86目录及其下内容,由于armeabi-v7a兼容armeabi,armeabi-v7a或者armeabi下的so文件其实是一样的,请将其放入您的游戏实际支持的armeabi-v7a和/或armeabi架构的目录下)。
库文件路径:

arm64-v8a文件夹中,armeabi-v7a文件中,x86文件夹中都新增的文件:

然后新增文件夹:

可能出现的报错:

解决办法:重新加回依赖
implementation 'com.android.support:appcompat-v7:22.1.1'

(2)引入jar包体:
implementation files('libs/mio_sdk_base_3.2.8_12822.jar')
implementation files('libs/alipaySdk-20180601.jar')
implementation files('libs/eventbus-3.0.0.jar')
implementation files('libs/gaid.jar')
implementation files('libs/onetrack-sdk-1.1.3.jar')
implementation files('libs/org.apache.http.legacy.jar')
implementation files('libs/protobuf-java-2.6.1.jar')
implementation files('libs/zxing-3.1.0.jar')

(3)sdk初始化代码:
在demo包下创建 MMApplication.java ,初始化 小米sdk:
package demo;
import android.support.multidex.MultiDexApplication;
import android.util.Log;
//这些包要等小米的广告sdk包引入后再引入
import com.xiaomi.ad.mediation.internal.config.IMediationConfigInitListener;
import com.xiaomi.ad.mediation.mimonew.MIMOAdSdkConfig;
import com.xiaomi.ad.mediation.mimonew.MiMoNewSdk;
import com.cszs.jgdnc.mi.R; //这里包名要改
import com.xiaomi.gamecenter.sdk.MiCommplatform;
import com.xiaomi.gamecenter.sdk.MiErrorCode;
import com.xiaomi.gamecenter.sdk.OnInitProcessListener;
import com.xiaomi.gamecenter.sdk.OnLoginProcessListener;
import com.xiaomi.gamecenter.sdk.entry.MiAccountInfo;
import com.xiaomi.gamecenter.sdk.entry.MiAppInfo;
import java.util.List;
/**
* Copyright (C) 2013, Xiaomi Inc. All rights reserved.
*/
public class MMApplication extends MultiDexApplication {
private static final String TAG = "MMApplication";
private static MainActivity mActivity;
private static final String APPID = "2882303761520039686";
@Override
public void onCreate() {
super.onCreate();
//网游sdk初始化
MiAppInfo appInfo = new MiAppInfo();
//正式环境下的appid
appInfo.setAppId(APPID);
//测试广告包的appid
// appInfo.setAppId("2882303761517973922");
//正式包体的appKey
appInfo.setAppKey("5852003941686");
// appInfo.setAppKey("");
Log.d("initSDK", "initSDK");
MiCommplatform.Init(this, appInfo, new OnInitProcessListener() {
@Override
public void finishInitProcess(List<String> loginMethod, int gameConfig) {
Log.i("Demo","Init success");
}
@Override
public void onMiSplashEnd() {
//小米闪屏⻚结束回调,小米闪屏可配,无闪屏也会返回此回调,游戏的闪屏应当在收到此回调之后
}
});
}
}
然后在 AndroidManifest.xml中声明这个Application:

这两行代码非常重要不能少!!!
android:extractNativeLibs="true"
android:name="demo.MMApplication"
这里可能会出现一个问题:

解决办法:原来引入包还不够,还
需要引入依赖
build.gradle 文件中:
:
/**sdk**/
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.android.support:multidex:1.0.3'
(4)AndroidManifest.xml中需要新增权限:
<uses-permission android:name="com.xiaomi.permission.AUTH_SERVICE"/>
<uses-permission android:name="com.xiaomi.sdk.permission.PAYMENT" />
(5)这个时候直接运行会报错报错,因为
缺少运行所需的 activity配置以及对于的资源文件:请确保在AndroidManifest.xml声明了以下Activity:[com.xiaomi.gamecenter.sdk.ui.MiActivity, com.xiaomi.gamecenter.sdk.ui.PayListActivity, com.xiaomi.hy.dj.HyDjActivity, com.alipay.sdk.app.H5PayActivity, com.xiaomi.gamecenter.sdk.ui.notice.NoticeActivity, com.xiaomi.gamecenter.sdk.ui.fault.ViewFaultNoticeActivity, com.xiaomi.gamecenter.sdk.anti.ui.MiAntiAlertActivity, com.xiaomi.gamecenter.sdk.ui.MiPayAntiActivity, ]

解决办法:
SDK所需要的AndroidManifest清单配置,
在AndroidManifest.xml中配置:
<!-- Xiaomi SDK Need -->
<meta-data
android:name="notch.config"
android:value="portrait|landscape" />
<activity
android:name="com.xiaomi.gamecenter.sdk.ui.MiActivity"
android:configChanges="orientation|screenSize"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">
</activity>
<activity
android:name="com.xiaomi.gamecenter.sdk.ui.PayListActivity"
android:configChanges="orientation|screenSize"
android:exported="true"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" />
<activity
android:name="com.xiaomi.hy.dj.HyDjActivity"
android:configChanges="orientation|screenSize"
android:exported="true"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" />
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden" />
<!--不支持${applicationId}的请替换为包名-->
<provider
android:name="com.xiaomi.gamecenter.sdk.utils.MiFileProvider"
android:authorities="${applicationId}.mi_fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/mio_file_paths" />
</provider>
<activity
android:name="com.xiaomi.gamecenter.sdk.ui.fault.ViewFaultNoticeActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" />
<activity
android:name="com.xiaomi.gamecenter.sdk.ui.notice.NoticeActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" />
<activity
android:name="com.xiaomi.gamecenter.sdk.anti.ui.MiAntiAlertActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">
<intent-filter>
<data
android:host="open_anti_alert"
android:scheme="mioauthsdk" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<activity
android:name="com.xiaomi.gamecenter.sdk.ui.MiPayAntiActivity"
android:configChanges="orientation|screenSize"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" />
<activity android:name="com.xiaomi.gamecenter.sdk.ui.MiVerifyActivity"
android:configChanges="orientation|screenSize"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"
android:screenOrientation="behind"/>
<!-- Xiaomi SDK Need End-->
配置好AndroidManifest.xml后,由于这些 Activity依赖很多 xml文件来布局,所以必须把所有依赖的 xml文件全部拷贝到对应的文件夹里,文件很多,一个都不能少,都是互相有依赖的,很麻烦:

此外,
引入这个xml布局文件之后还不够,需要引入这些xml布局文件的依赖 build.gradle 文件中:
/**引入一些xml布局需要的依赖**/
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31"
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'android.arch.navigation:navigation-fragment:1.0.0'
implementation 'android.arch.navigation:navigation-ui:1.0.0'
implementation 'android.arch.lifecycle:extensions:1.1.1'
(6) 这个时候直接运行,也是会报错,因为
缺少 jsBridge-mix.js文件:
Caused by: java.lang.IllegalStateException: 请确保在Assets目录下存在文件: jsBridge-mix.js

解决办法:

添加到这里:

(7)我尝试打包,打包的过程中,还是报错了:
解决办法:在 gradle.properties文件中,添加:
android.enableBuildCache=false


(8)调用小米sdk登录接口:
每次登录游戏都要调用登录接口:在 MMApplication.java中定义登录接口:
public void initSDK(MainActivity _mActivity){
mActivity =_mActivity;
MiCommplatform.getInstance().miLogin(mActivity,
new OnLoginProcessListener()
{
@Override
public void finishLoginProcess(int code , MiAccountInfo arg1)
{
switch( code )
{
case MiErrorCode.MI_XIAOMI_PAYMENT_SUCCESS:// 登陆成功
Log.i(TAG,"小米登录成功");
//获取用户的登陆后的UID(即用户唯一标识)
String uid = arg1.getUid();
//以下为获取session并校验流程,如果是网络游戏必须校验,(12小时过期)
//获取用户的登陆的Session(请参考5.3.3流程校验Session有效性)
String session = arg1.getSessionId();
//请开发者完成将uid和session提交给开发者自己服务器进行session验证
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_LOGIN_FAIL:
Log.i(TAG,"登录失败");
// 登陆失败
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_CANCEL:
Log.i(TAG,"取消登录");
// 取消登录
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_ACTION_EXECUTED:
//登录操作正在进行中
Log.i(TAG,"登录操作正在进行中");
break;
default:
// 登录失败
Log.i(TAG,"登录失败");
break;
}
}
} );
}
(9)必接接口,游戏退出接口 在MainActivity.java中定义:
public void exitGame(){
MiCommplatform.getInstance().miAppExit( this, new OnExitListner()
{
@Override
public void onExit( int code )
{
Log.i("Demo","小米游戏退出");
if ( code == MiErrorCode.MI_XIAOMI_EXIT )
{
android.os.Process.killProcess( android.os.Process.myPid() );
}
}
} );
}
3.广告sdk接入:
(1)引入广告sdk的aar包:
正确的引入aar包方式如下
implementation files('libs/mimo_sdk.aar')

当用了错误的引用方式,可能会出现报错:Could not resolve all files for configuration ':app:debugCompileClasspath'.

解决办法:google()放在jcenter()前边
buildscript {
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/google'}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
maven {url 'https://dl.bintray.com/jetbrains/anko'}
maven {url 'https://maven.aliyun.com/repository/google'}
}
}

这样还是不行,换一种引用方法:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:22.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation files('libs/mio_sdk_base_3.2.8_12822.jar')
implementation files('libs/alipaySdk-20180601.jar')
implementation files('libs/eventbus-3.0.0.jar')
implementation files('libs/gaid.jar')
implementation files('libs/onetrack-sdk-1.1.3.jar')
implementation files('libs/org.apache.http.legacy.jar')
implementation files('libs/protobuf-java-2.6.1.jar')
implementation files('libs/zxing-3.1.0.jar')
implementation files('libs/mimo_sdk.aar')
}
(2)广告sdk初始化:
在MMapplication.java中初始化:这里广告sdk初始化和调用登录接口都放在 initSDK函数里了:
因为SDK初始化接口必须在用户选择是否统一隐私协议后调用,若用户拒绝隐私协议,不可调用该广告SDK初始化接口,所以
必须在调用android的隐私政策弹窗,点击同意后,才调用这里的initSDK函数
这里的appid,在测试的过程中是测试id,并且需要设置广告sdk为测试模式:

否则会出现加载广告的报错:-400

public void initSDK(MainActivity _mActivity){
mActivity =_mActivity;
//广告sdk初始化
Log.i(TAG,"广告sdk初始化");
MiMoNewSdk.init(this, APPID, getString(R.string.app_name),
new MIMOAdSdkConfig.Builder()
.setDebug(false)
.setStaging(false).build(), new IMediationConfigInitListener() {
@Override
public void onSuccess() {
Log.i(TAG,"广告sdk初始化成功");
}
@Override
public void onFailed(int errorCode) {
Log.i(TAG,"广告sdk初始化失败"+errorCode);
}
});
MiCommplatform.getInstance().miLogin(mActivity,
new OnLoginProcessListener()
{
@Override
public void finishLoginProcess(int code , MiAccountInfo arg1)
{
switch( code )
{
case MiErrorCode.MI_XIAOMI_PAYMENT_SUCCESS:// 登陆成功
Log.i(TAG,"小米登录成功");
//获取用户的登陆后的UID(即用户唯一标识)
String uid = arg1.getUid();
//以下为获取session并校验流程,如果是网络游戏必须校验,(12小时过期)
//获取用户的登陆的Session(请参考5.3.3流程校验Session有效性)
String session = arg1.getSessionId();
//请开发者完成将uid和session提交给开发者自己服务器进行session验证
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_LOGIN_FAIL:
Log.i(TAG,"登录失败");
// 登陆失败
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_CANCEL:
Log.i(TAG,"取消登录");
// 取消登录
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_ACTION_EXECUTED:
//登录操作正在进行中
Log.i(TAG,"登录操作正在进行中");
break;
default:
// 登录失败
Log.i(TAG,"登录失败");
break;
}
}
} );
}

开发者接入SDK时,应用包可能还未上架应用商店,在接入的时候,建议使用demo中的测试广告位进行调试,保证接入方式无问题后再切换到正式环境并更换为正式环境广告位id。 测试使用的APP_ID为:2882303761517973922
广告类型
|
测试广告位ID
|
横幅
|
28e12557924f47bcde1fb4122527a6bc
|
横版插屏广告
|
dc7cc080d643693f4f835b1a7718283d
|
竖版插屏广告
|
a61183c0f3899bc138a320925df3d862
|
横版全屏插屏广告
|
756c0d2cdb935266522249c90ca04dbe
|
竖版全屏插屏广告
|
b539ee9934e2e869c6aced477a02fa0e
|
横版激励视频广告
|
feff23d4d67802626433de32bd1b327d
|
竖版激励视频广告
|
95297e164e1dfb6c0ce4a2eaf61cc791
|
横版开屏
|
f22820b630d6d453f956cbe31235d11a
|
原生模板 - 上文下图(带标题)
|
bfa05071958648861ef32be94c4ac200
|
原生模板 - 左文右图(带标题)
|
77c1a503091c597f8a03d57010637d7c
|
原生模板 - 左图右文(带标题A版)
|
8db571afaf731ec727d42db9894d688d
|
原生模板 - 左图右文(带标题B版)
|
5d1bab599fc4443c17021ea75dfa729d
|
原生模板 - 上图下文(大图)
|
671f83d6d6c1f2356c1a14de9f7ec9cf
|
原生模板 - 上图下文(组图)
|
b72a783f1f1952c09e429f777cf2426e
|
自渲染 - 信息流大图
|
c09e2a394366b0819fd3ac2bc142ed20
|
自渲染 - 信息流小图
|
11cc7b67acfc800ac6228af78f122acf
|
自渲染 - 信息流组图
|
949f4411ceceb8d14042dffb1112af6b
|
(3)修改
SDK需要的provider声明:

在 res/xml/下添加文件 file_paths.xml 参考demo
内容:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="tt_internal_file_download" path="Download" />
<cache-path name="tt_internal_cache_download" path="Download" />
</paths>
**/
/**
在 res/xml/下添加文件 mimo_file_paths.xml 参考demo
内容:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="mimoDownload" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
**/
AndroidMainfest.xml新增provider声明:
<!-- 广告sdk需要的-->
<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" />
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/mimo_file_paths" />
</provider>
4.Banner接入:
小米的banner广告,需要android工程中创建 ViewGround然后在里边渲染,具体步骤:
(1)
新建一个activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="HardcodedText"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- BannerView的Container -->
<FrameLayout
android:id="@+id/game_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#D5D5D5" />
<FrameLayout
android:id="@+id/banner_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#D5D5D5"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
(2)
在MainActivity的initEngin中重新设置ContentView:
//声明变量先:
private ViewGroup gameContainer;
public ViewGroup banner_container;
public void initEngine()
{
mProxy = new RuntimeProxy(this);
mPlugin = new GameEngine(this);
mPlugin.game_plugin_set_runtime_proxy(mProxy);
mPlugin.game_plugin_set_option("localize","false");
mPlugin.game_plugin_set_option("gameUrl", App_Startup_Entry);
mPlugin.game_plugin_init(3);
View gameView = mPlugin.game_plugin_get_view();
this.setContentView(R.layout.activity_main);
this.gameContainer = findViewById(R.id.game_container);
this.banner_container = findViewById(R.id.banner_container);
this.gameContainer.addView(gameView);
mProxy.InitAD();
isLoad=true;
}
(3)创建banner需要用到的,接口getApplication(),需要调用之前创建的MMApplication.java:
5.审核驳回: 自动化测试驳回,针对安卓9、10的机器,原因:Failed to install /tmp/.omni/apks/0915153229_null_0255928c3835f474ea0a7fffe9f5b9b4b83f8ac40.apk: Failure [INSTALL_FAILED_INVALID_APK: Failed to extract native libraries, res=-2]

解决办法:
打开AndroidManifest.xml
在application 节点添加:
android:extractNativeLibs="true"
6.审核驳回:

解决问题:
(1)隐藏状态栏和虚拟键:
【腾讯文档】如何隐藏状态栏和虚拟键
如何隐藏状态栏和虚拟键。测试机型:MI11 MIUI12.5 稳定版
View decorView = getWindow().getDecorView();
int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN //隐藏状态栏
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION //隐藏虚拟键
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(visibility);
//在大于等于android P的版本上,需要设置flag:LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,保证应用可以显示都notch区域。
//如果设置了该flag,在notch屏手机上,要注意应用内部控件的位置,应该和屏幕边缘保持一定的距离,防止遮挡。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
(2)设置app全屏:

<style name="Theme.AppCompat.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
7.审核驳回问题:

8.关闭按钮 xml文件中定义后,不显示问题:解决办法:
(1)
RelativeLayout
或者FrameLayout 布局的话,你不设置位置而又有后面的填充整个布局view的话,会被遮住的,你自己检查下!
(2)修改 ImageView 中的 xml 属性:
<ImageView
android:id="@+id/view_ad_close"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="40dp"
android:layout_marginBottom="16dp"
android:contentDescription="关闭按钮"
android:src="@drawable/float_hide_tip_sel"
app:layout_constraintBottom_toTopOf="@+id/view_desc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/view_title"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />

(3)和图片是jpg格式还是png格式的没有半毛钱关系!!
9.审核失败问题:实名认证弹窗关闭

解决办法:
(1)在隐私协议的同意的调用中,传入回调:JSBridge.java
//用户同意隐私协议后调用
public static void onUserAgreed(String json) {
Log.e("1111111", "用户同意隐私政策");
try {
JSONObject jsonObj = new JSONObject(json);
((MainActivity) JSBridge.mMainActivity).onUserAgreed(jsonObj, new ValueCallback<JSONObject>() {
@Override
public void onReceiveValue(JSONObject value) {
ExportJavaFunction.CallBackToJS(JSBridge.class, "onUserAgreed", value.toString());
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
MainActivity.java中调用:只有登录成功才会回调 js层一个result=1的结果,否则退出游戏;
public void onUserAgreed(JSONObject jsonObj, final ValueCallback<JSONObject> callback){
Log.d("UserAgreed", "Login info = " + jsonObj.toString());
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
/**
* 如果你的targetSDKVersion >= 23,就要主动申请好权限。如果您的App没有适配到Android6.0(即targetSDKVersion < 23),那么只需要在这里直接调用fetchSplashAd方法。
*
*/
checkAndRequestPermissions();
} else {
/**
* 如果是Android6.0以下的机器,默认在安装时获得了所有权限,可以直接调用SDK。
*/
}
MiCommplatform.getInstance().onUserAgreed(this);
MiCommplatform.getInstance().miLogin(this,
new OnLoginProcessListener()
{
@Override
public void finishLoginProcess(int code , MiAccountInfo arg1)
{
switch( code )
{
case MiErrorCode.MI_XIAOMI_PAYMENT_SUCCESS:// 登陆成功
Log.i("Demo","小米登录成功");
//获取用户的登陆后的UID(即用户唯一标识)
String uid = arg1.getUid();
//以下为获取session并校验流程,如果是网络游戏必须校验,(12小时过期)
//获取用户的登陆的Session(请参考5.3.3流程校验Session有效性)
String session = arg1.getSessionId();
//请开发者完成将uid和session提交给开发者自己服务器进行session验证
Log.e("UserAgreed", "登陆成功");
JSONObject result3 = new JSONObject();
try {
result3.put("result", 1);
} catch (JSONException e) {
e.printStackTrace();
}
callback.onReceiveValue(result3);
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_LOGIN_FAIL:
loginFail(callback);
// 登陆失败
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_CANCEL:
loginFail(callback);
// 取消登录
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_ACTION_EXECUTED:
//登录操作正在进行中
break;
default:
// 登录失败
loginFail(callback);
break;
}
}
} );
}
登录失败的回调:
public void loginFail(final ValueCallback<JSONObject> callback){
Log.e("UserAgreed", "登陆失败");
JSONObject result = new JSONObject();
try {
result.put("result", 0);
} catch (JSONException e) {
e.printStackTrace();
}
callback.onReceiveValue(result);
}
(2)退出游戏:
MainActivity.java:
public void exitGame(){
MiCommplatform.getInstance().miAppExit( this, new OnExitListner()
{
@Override
public void onExit( int code )
{
Log.i("Demo","小米游戏退出");
if ( code == MiErrorCode.MI_XIAOMI_EXIT )
{
android.os.Process.killProcess( android.os.Process.myPid() );
}
}
} );
}
JSBridge.java:
//退出游戏
public static void ExitGame(){
((MainActivity) JSBridge.mMainActivity).exitGame();
}
js层级的函数如下:
static onUserAgreed(thisAry, callback) {
if (!this.isReady) {
callback({ result: 1 });
return;
}
let obj = {};
this.bridge.callWithBack((value) => {
console.log("JS层的登录回调", value)
console.log(value)
if (callback) {
let jsonObj = JSON.parse(value);
callback.call(thisAry, jsonObj);
}
}, 'onUserAgreed', JSON.stringify(obj));
}
static ExitGame() {
console.log("退出游戏");
if (!this.isReady)
return;
this.bridge.callWithBack(null, 'ExitGame');
}
10.广告加载报错:该错误是 后台选择的广告类型与实际请求到的广告类型不匹配,被过滤了
模板广告加载报错{errorCode=-300, externalErrorCode='301007', errorMessage=''}
11.权限问题:在用于同意隐私政策条款之前,不应该初始化广告sdk

解决办法:同意隐私政策之后才调用登录和广告sdk初始化:
MainActivity.java中:
public void onUserAgreed(JSONObject jsonObj, final ValueCallback<JSONObject> callback){
Log.d("UserAgreed", "Login info = " + jsonObj.toString());
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
/**
* 如果你的targetSDKVersion >= 23,就要主动申请好权限。如果您的App没有适配到Android6.0(即targetSDKVersion < 23),那么只需要在这里直接调用fetchSplashAd方法。
*
*/
checkAndRequestPermissions();
} else {
/**
* 如果是Android6.0以下的机器,默认在安装时获得了所有权限,可以直接调用SDK。
*/
}
MiCommplatform.getInstance().onUserAgreed(this);
MMApplication mApplication = (MMApplication) getApplication();
mApplication.initSDK(callback,this);
}
MMApplication.java中,但是联运SDK的初始化,还是应该在onCreate函数中调用才行,不然会无法运行apk
public void initSDK(final ValueCallback<JSONObject> callback, MainActivity _mActivity){
mActivity =_mActivity;
MiCommplatform.getInstance().miLogin(mActivity,
new OnLoginProcessListener()
{
@Override
public void finishLoginProcess(int code , MiAccountInfo arg1)
{
switch( code )
{
case MiErrorCode.MI_XIAOMI_PAYMENT_SUCCESS:// 登陆成功
Log.i("Demo","小米登录成功");
//获取用户的登陆后的UID(即用户唯一标识)
String uid = arg1.getUid();
//以下为获取session并校验流程,如果是网络游戏必须校验,(12小时过期)
//获取用户的登陆的Session(请参考5.3.3流程校验Session有效性)
String session = arg1.getSessionId();
//请开发者完成将uid和session提交给开发者自己服务器进行session验证
Log.e("UserAgreed", "登陆成功");
JSONObject result3 = new JSONObject();
try {
result3.put("result", 1);
} catch (JSONException e) {
e.printStackTrace();
}
callback.onReceiveValue(result3);
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_LOGIN_FAIL:
mActivity.loginFail(callback);
// 登陆失败
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_CANCEL:
mActivity.loginFail(callback);
// 取消登录
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_ACTION_EXECUTED:
//登录操作正在进行中
break;
default:
// 登录失败
mActivity.loginFail(callback);
break;
}
}
} );
//广告sdk初始化
MiMoNewSdk.init(this, APPID, getString(R.string.app_name),
new MIMOAdSdkConfig.Builder()
.setDebug(false)
.setStaging(false).build(), new IMediationConfigInitListener() {
@Override
public void onSuccess() {
MLog.d(TAG, "mediation config init success");
mActivity.mProxy.InitAD();
}
@Override
public void onFailed(int errorCode) {
MLog.d(TAG, "mediation config init failed");
}
});
}
12.小米apk中暂定游戏时间线,可以能用:
if(Laya.timer.scale == 1)Laya.timer.pause();
if(Laya.timer.scale == 0)Laya.timer.resume()
13.小米apk中接入打开网页:
(1)xml中定义VIEW:
<FrameLayout
android:id="@+id/view_url_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_marginRight="0dp"
android:layout_marginBottom="0dp"
android:background="#FFFFFF">
<WebView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/wv"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<ImageView
android:id="@+id/view_url_close"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="9dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="400dp"
android:contentDescription="关闭按钮"
android:src="@drawable/float_hide_tip_sel"
app:layout_constraintBottom_toTopOf="@+id/view_feedBox_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.78"
app:layout_constraintStart_toEndOf="@+id/view_feedBox_image"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
(2)定义打开View的类:
public class SecretUrlView {
private MainActivity mActivity;
private static String TAG = "SecretUrlView";
private View mView;
private WebView wv;
public SecretUrlView(MainActivity mActivity) {
this.mActivity = mActivity;
this.init();
}
public void init(){
mView = (ViewGroup) mActivity.urlView_container;
wv=(WebView)mView.findViewById(R.id.wv);
WebSettings ws=wv.getSettings();
ws.setJavaScriptEnabled(true);
wv.loadUrl("https://res.wqop2018.com//app/common/privacy.html");
wv.setWebViewClient(new WebViewClient());
mView.findViewById(R.id.view_url_close).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mView.setVisibility(View.GONE);
}
});
mView.setVisibility(View.GONE);
}
public void showUrlView(){
mView.setVisibility(View.VISIBLE);
}
public void hideUrlView(){
mView.setVisibility(View.GONE);
}
}
14.隐私问题解决办法:
(1)打开游戏>弹出隐私协议(初始化小米sdk)>同意隐私协议>获取手机信息授权>初始化小米广告sdk(小米登录)>登录成功>游戏加载开始
登录失败需要继续调用登录接口
(2)td初始化 需要放到 用户同意隐私协议并同意授予权限后
(3)隐私协议地址:
隐私政策
"https://res.wqop2018.com/app/web/privacy/v3/privacy.html?app_name=" + Constant.APP_NAME + "&company="+Constant.COMPANY+"&package_name="+Constant.PACKAGE_NAME
15.这样未解决问题:发现获取手机信息是在Laya引擎初始化的时候做的,所以需要用Android做一个隐私界面,同意隐私之后在初始化Laya引擎:

读取IMEI
发生时间 2021-11-23 10:07:42 md5=5743438D7E55887D2CFA5AFEE84D9F6B,pkg=com.cszs.aycsmnq.mi,action=android.permission.READ_PHONE_STATE_IMEI,content=,callstack:android.telephony.TelephonyManager.getDeviceId:1247;layaair.game.device.DevID.GetIMEI:14;layaair.game.browser.ExportJavaFunction.GetDeviceInfo:28;java.lang.reflect.Method.invoke:-2;layaair.game.browser.ExportJavaFunction.callMethod:43;layaair.game.browser.ConchJNI.OnGLReady:-2;layaair.game.browser.c.a:125;layaair.game.browser.x.i:384;layaair.game.browser.x.run:22;
读取IMSI
发生时间 2021-11-23 10:07:42 md5=5743438D7E55887D2CFA5AFEE84D9F6B,pkg=com.cszs.aycsmnq.mi,action=android.permission.READ_PHONE_STATE_IMSI,content=,callstack:android.telephony.TelephonyManager.getSubscriberId:3030;android.telephony.TelephonyManager.getSubscriberId:3011;layaair.game.device.DevID.GetIMSI:13;layaair.game.browser.ExportJavaFunction.GetDeviceInfo:40;java.lang.reflect.Method.invoke:-2;layaair.game.browser.ExportJavaFunction.callMethod:43;layaair.game.browser.ConchJNI.OnGLReady:-2;layaair.game.browser.c.a:125;layaair.game.browser.x.i:384;layaair.game.browser.x.run:22;
获取MAC地址
发生时间 2021-11-23 10:07:42 md5=5743438D7E55887D2CFA5AFEE84D9F6B,pkg=com.cszs.aycsmnq.mi,action=android.permission.GET_MAC,content=wlan0:64:A2:F9:9C:72:1E,callstack:java.net.NetworkInterface.getHardwareAddress:574;layaair.game.device.DevID.getMac:61;layaair.game.device.DevID.GetWifiMac:0;layaair.game.browser.ExportJavaFunction.GetDeviceInfo:95;java.lang.reflect.Method.invoke:-2;layaair.game.browser.ExportJavaFunction.callMethod:43;layaair.game.browser.ConchJNI.OnGLReady:-2;layaair.game.browser.c.a:125;layaair.game.browser.x.i:384;layaair.game.browser.x.run:22;
未经许可读取个人信息: 读取IMEI 读取IMSI 获取MAC地址
16.偶现的插屏广告报错,貌似是因为时机不对,显示插屏广告在初始化广告sdk之前了:
java.lang.NullPointerException: Attempt to invoke virtual method 'void demo.ui.fullscreenInterstitialad.InterstitialView.showFullScreenAd(android.webkit.ValueCallback)' on a null object reference
17.小米必须登录才能加载进入游戏:
(1)流程: 在安卓里同意隐私政策以后,就initEngine ,
然后在laya的loading页去登录,登录成功就回调laya,然后进入游戏主页
JS层:
//小米必须先登录
if (window.zs && zs.Native && zs.Native.Login) zs.Native.Login(this, this.apkLoginBack$.bind(this));
/**
* 小米登录回调
*/
apkLoginBack$(data) {
console.log(data);
if (data.result == 1) {
this.loadingComplete$();
}
}
apk.mi.js:
static Login(thisAry, callback) {
if (!this.isReady)
return;
let obj = {};
obj['uid'] = "uid";
this.bridge.callWithBack((value) => {
if (callback) {
let jsonObj = JSON.parse(value);
callback.call(thisAry, jsonObj);
}
}, 'Login', JSON.stringify(obj));
}
(2)安卓项目工程中:
******JSBridge.java
public static void Login(String json){
try {
JSONObject jsonObj = new JSONObject(json);
MainActivity.mProxy.loginMi(jsonObj, new ValueCallback<JSONObject>() {
@Override
public void onReceiveValue(JSONObject value) {
ExportJavaFunction.CallBackToJS(JSBridge.class, "Login", value.toString());
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
******RuntimeProxy.java:
@Override
public void loginMi(JSONObject jsonObj, final ValueCallback<JSONObject> callback) {
Log.d(TAG, "loginMi " + jsonObj.toString());
if (hasNecessaryPMSGranted()) {
new Thread(new Runnable() {
@Override
public void run() {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mActivity.loginMi(callback);
}
});
}
}).start();
} else {
Toast.makeText(mActivity, "没有 READ_PHONE_STATE 或 WRITE_EXTERNAL_STORAGE 权限,SDK无法正常运行!!!", Toast.LENGTH_SHORT).show();
}
}
******MainActivity.java:
public void loginMi(ValueCallback<JSONObject> callback_){
MMApplication mApplication = (MMApplication) getApplication();
mApplication.loginMI(callback_);
}
******MMApplication.java:
public void loginMI(ValueCallback<JSONObject> callback_){
if(loginSuccess)return;
callback = callback_;
Log.i(TAG,"小米登录.......");
MiCommplatform.getInstance().miLogin(mActivity,
new OnLoginProcessListener()
{
@Override
public void finishLoginProcess(int code , MiAccountInfo arg1)
{
switch( code )
{
case MiErrorCode.MI_XIAOMI_PAYMENT_SUCCESS:// 登陆成功
Log.i(TAG,"小米登录成功");
//获取用户的登陆后的UID(即用户唯一标识)
String uid = arg1.getUid();
//以下为获取session并校验流程,如果是网络游戏必须校验,(12小时过期)
//获取用户的登陆的Session(请参考5.3.3流程校验Session有效性)
String session = arg1.getSessionId();
//请开发者完成将uid和session提交给开发者自己服务器进行session验证
loginSuccess = true;
JSONObject result = new JSONObject();
try {
result.put("result", 1);
} catch (JSONException e) {
e.printStackTrace();
}
callback.onReceiveValue(result);
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_LOGIN_FAIL:
Log.i(TAG,"登录失败22");
loginMI(callback_);
// 登陆失败
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_CANCEL:
Log.i(TAG,"取消登录");
loginMI(callback_);
// 取消登录
break;
case MiErrorCode.MI_XIAOMI_PAYMENT_ERROR_ACTION_EXECUTED:
//登录操作正在进行中
Log.i(TAG,"登录操作正在进行中333");
break;
default:
// 登录失败
Log.i(TAG,"登录失败");
break;
}
}
} );
}
18.广告加载报错的情况:
自渲染广告加载报错{errorCode=-400, externalErrorCode='', errorMessage='adPositionInfo is null'}
通常是需要开启调试的:

MiMoNewSdk.init(this, "2882303761517973922", getString(R.string.app_name),
new MIMOAdSdkConfig.Builder()
.setDebug(true) // true 打开调试,输出调试日志;false 关闭调试
.setStaging(true).build(), new IMediationConfigInitListener() { // true 打开测试请求开关,请求测试广告;false关闭测试请求开关
@Override
public void onSuccess() {
Log.i(TAG,"广告sdk初始化成功");
}
@Override
public void onFailed(int errorCode) {
Log.i(TAG,"广告sdk初始化失败"+errorCode);
}
});