小米游戏APK接入

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);
            }
        });
  • 28
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小春熙子

你一毛我一毛,先富带后富

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值