Skip to content

LCM Android SDK 接入指南

RC9.8.0更新内容:

1、新增个人信息收集清单接口  
2、新增第三方信息共享清单功能接口    
3、D商店新增初始化、登录打点    
4、移除IMEI、IMSI、MAC采集   
5、安卓广告更新:AppsFlyer6.7.0, Firebase30.2.0  
6、阿里云打点 新增Web加载失败打点(实名、适龄、隐私、客服)以及其他打点   
7、D商店修复串号问题  
8、安卓OAID优化  
9、安卓12适配  
10、Google Billing 升级  
11、其它优化 

一、接入前准备

开发环境和前提步骤详见在L服务器上注册APP

二、SDK版本选择

三、Android Studio接入步骤

注:由于Android 11引入的一些新特性,建议将Android Studio升级到4.x以上(最好4.2.0以上),SDK使用Gradle Plugin 4.2.1,Gradle Wrapper 6.7.1

  1. 将zip解压后目录如下:

    folder

  2. 此次更新为了区别sample和sdk,将目录分为library和sample两个目录 游戏接入时应引入library中的几个工程。sample中为演示功能,方便测试。sample中包含library 中的几个工程,其中xxx-v4的三个包,这三个基础包必须要游戏接入方手动引入。此目的为了解决R文件问题,不可合并

  3. 接入时如果需要测试登录和支付功能,请将根据接入的商店引用相应的工程。引入规则如下:

    • full : 是除纯google以外其他的商店(测试时也需要引入facebook-sdk)
    • sdk : 不含任何商店纯sdk
    • xxx-v4系列 : 位于support目录下,三个v4工程必须引入,注意,media-v4和support-v4下的build.gradle都需要手动编辑:

      • media-v4 的build.gradle

        //cn选用media-compat.jar,ap选用media-compat-mod.jar
        api files('libs/media-compat.jar')
        //api files('libs/media-compat-mod.jar')
        
      • support-v4 的build.gradle

        //cn选用support-v4-compat-28.jar,ap选用support-v4-compat-28-mod.jar
        api files('libs/support-v4-compat-28.jar')
        //api files('libs/support-v4-compat-28-mod.jar')
        
    • facebok-sdk : 位于facebook目录下,用到facebook相关功能(包含登录,广告等)时需要引入

    • 谷歌推送类库 : 即 firebase-messaging 和 firebase-analytics,以url的方式引入,主要针对需要谷歌推送的ap地区的包,此外 firebase-analytics 也用于 firebase 广告。如果用的老版本gradle,可能会出现编译报错的情况,这时请使用 firebase-analytics:17.2.1 和 firebase-messaging:20.0.0 代替

      // 需要谷歌推送时,请引入以下3项(反之注释掉)
      implementation platform('com.google.firebase:firebase-bom:27.1.0')
      implementation 'com.google.firebase:firebase-analytics'
      implementation 'com.google.firebase:firebase-messaging'
      
    • 谷歌登录类库 :即 play-services-auth、play-services-ads 和 play-services-games,以url的方式引入,主要针对需要谷歌登录的ap地区的包

      // 需要谷歌登录时,请引入以下3项(反之注释掉)
      implementation 'com.google.android.gms:play-services-ads:19.8.0'
      implementation 'com.google.android.gms:play-services-auth:19.0.0'
      implementation 'com.google.android.gms:play-services-games:21.0.0'
      
    • 需要TapTap登录时,请引入这三项(否则注释掉)

      implementation('cn.leancloud:realtime-android:8.1.0') {
          exclude group: 'com.google.code.gson', module: 'gson'
          exclude group: 'com.squareup.okhttp3', module: 'okhttp'
      }
      implementation('cn.leancloud:storage-android:8.1.0') {
          exclude group: 'com.google.code.gson', module: 'gson'
          exclude group: 'com.squareup.okhttp3', module: 'okhttp'
      }
      implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
      
    • 海外 Google Billing Library 已经升级到4.1.0,如果需要接入Google支付,请手动在dependencies中加入:

      implementation 'com.android.billingclient:billing:4.1.0'
      

    注意:full仅为测试时使用,出包上传打包工具时请引用 sdk 工程。full、sdk 两个工程任选其一,不可同时引入。

  4. demo的使用方法,可以直接使用 Android Studio(版本3.0以上,本demo使用的是3.2.1版本)打开项目即可。

  5. 接入时:将 gradle.properties 中的配置拷贝到自己工程的gradle.properties中。此次ap地区的包新增了AndroidX,所以可能需要用到分包功能,设置 MULTI_DEX_ENABLED=true 即可

  6. 将 Pickle/assets下的 web目录 拷贝到 游戏主工程 的assets目录下

  7. 请将sample中的AndroidManifest.xml文件中application节点下注册的activity(除了SampleActivity)全部拷贝到自己的AndroidManifest.xml中,<uses-permission>权限也一样拷贝。

  8. 如果需要 firebase-analytics服务 或 firebase广告 功能,需要在主项目的res/values/strings.xml配置google_app_id,具体的值跟assets/google-services.json 文件里的 mobilesdk_app_id 字段值保持一致(即换成游戏自己的值)

    <string name="google_app_id" translatable="false">1:708621039584:android:93401bbc238fc561</string>
    
  9. 对于ap的包,必须将以下内容加到游戏主工程的build.gradle里(注意不是根目录那个build.gradle),具体加到 android {} 代码块里面:

    android {
        // 防止androidx一些文件冲突,这个必须加上
        packagingOptions {
            exclude 'META-INF/androidx.*'
            exclude 'META-INF/proguard/androidx-annotations.pro'
            doNotStrip "*/armeabi-v7a/*.so"
            doNotStrip "*/x86/*.so"
            doNotStrip "*/arm64-v8a/*.so"
            doNotStrip "*/x86_64/*.so"
            doNotStrip "armeabi.so"
        }
    }
    
  10. 找到根目录下的build.gradle,如果gradle下载某些库失败,可以注释掉 google() 和 jcenter(),并使用maven镜像

    allprojects {
        repositories {
            google()
            jcenter()
            // google and jcenter mirrors for china
            maven { url 'https://maven.aliyun.com/repository/google/' }
            maven { url 'https://maven.aliyun.com/repository/jcenter/' }
            // huawei mirrors
            maven { url 'https://developer.huawei.com/repo/' }
            // paypal braintree mirrors
            maven {
                url 'https://cardinalcommerce.bintray.com/android'
                credentials {
                    username 'braintree-team-sdk@cardinalcommerce'
                    password '220cc9476025679c4e5c843666c27d97cfb0f951'
                }
            }
        }
        buildscript {
            repositories {
                google()
                jcenter()
                // google and jcenter mirrors for china
                maven { url 'https://maven.aliyun.com/repository/google/' }
                maven { url 'https://maven.aliyun.com/repository/jcenter/' }
                // huawei mirrors
                maven { url 'https://developer.huawei.com/repo/' }
                // paypal braintree mirrors
                maven {
                    url 'https://cardinalcommerce.bintray.com/android'
                    credentials {
                        username 'braintree-team-sdk@cardinalcommerce'
                        password '220cc9476025679c4e5c843666c27d97cfb0f951'
                    }
                }
            }
            dependencies {
                classpath 'com.android.tools.build:gradle:4.2.1'
                classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
                classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
                // NOTE: Do not place your application dependencies here; they belong
                // in the individual module build.gradle files
            }
        }
    }
    
  11. 出包时必须引入的是sdk的工程(facebook-sdk、谷歌推送类库、谷歌登录类库 根据需要引入)

  12. 在自己的build.gradle中引入sdk、full或者google工程就可以了,根据需求自行添加。参考demo的gradle,里面有详细介绍。配置需要注意的部分如下:

    • sourceSets中即!111!那行是针对繁体官网包过滤微信的类而配置,大陆官网包需要将这行代码注释掉。
    • dependencies多注意!nnn!所注释的内容描述。
      sourceSets {
           main {
               manifest.srcFile 'AndroidManifest.xml'
               java.srcDirs = ['src']
               // !111! 当测试大陆官网包时,下面这行代码请注释掉
               java { exclude 'com/denachina/pickle/wxapi/**' }
               resources.srcDirs = ['src']
               aidl.srcDirs = ['src']
               renderscript.srcDirs = ['src']
               res.srcDirs = ['res']
               assets.srcDirs = ['assets']
               jniLibs.srcDirs = ['libs']
           }
      }
       buildTypes {
           debug {
          minifyEnabled false
          zipAlignEnabled false
          shrinkResources false
      
          // !333! cn/ost 简体商店使用debug签名
          // signingConfig signingConfigs.debug
      
          // !444! tw/gp/gp-d 繁体商店使用release签名
          signingConfig signingConfigs.release
          }
      
          release {
          minifyEnabled false
          zipAlignEnabled false
          shrinkResources false
          multiDexKeepFile file("proguard-project.txt")
          signingConfig signingConfigs.release
          }
      }
      
      dependencies {
      
           // v4 包必须引入
          implementation project(':support-v4')
          implementation project(':coordinator-v4')
          implementation project(':media-v4')
      
          //=== 注意:以下三个工程3选一,
          // 但是出包的时候【必须】选择【sdk】,
          // 另外两个仅供接入时测试时使用,里面含sdk,不可同时使用 ===
      
          // !555! 出包时必须导入sdk,上传打包工具时请务必只包含sdk。请将 !111! 注释掉
          implementation project(':sdk')
      
          //=== 下面两个仅供调试时使用,仅提供登录和支付功能的测试,其他功能(推送、广告等)可通过打包工具打进去。
          // full已经包含sdk,请勿重复导入sdk!===
          // !666! 测试 官网商店 时可以选择使用full,含sdk。请将 !111! 注释掉
          // implementation project(':full')
      }
      
  13. 海外华为接入配置:

    • 主工程build.gradle新增如下依赖:

      implementation 'com.huawei.agconnect:agconnect-core:1.4.0.300'
      
      implementation('com.huawei.hms:hwid:5.0.5.301') {
          exclude group: 'com.android.support', module: 'support-annotations'
      }
      
      implementation 'com.huawei.hms:iap:5.0.4.301'
      
    • 主工程assets目录下新增 agconnect-services.json ,该文件可以从华为开发者后台获取

    • manifest新增如下配置,其中pay_rsa_pub从华为后台获取

      <application>
      
          <meta-data
              android:name="pay_rsa_pub"
              android:value="MIIBojANxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=" />
      
          <provider
              android:name="com.huawei.agconnect.core.provider.AGConnectInitializeProvider"
              android:authorities="${applicationId}.AGCInitializeProvider"
              android:exported="false" />
      
          <service
              android:name="com.huawei.agconnect.core.ServiceDiscovery"
              android:exported="false" />
      
          <meta-data
              android:name="com.huawei.hms.client.service.name:iap"
              android:value="iap:5.0.4.301" />
      
      </application>
      
    • 需要把huawei的maven镜像加上:

      maven { url 'https://developer.huawei.com/repo/' }
      
  14. 如果需要支持PGS2.0 (Android on PC),请遵循以下步骤:

    • 主工程build.gradle新增如下依赖:

      // 需要PGS2.0(Android on PC)功能时,请引入
      implementation 'com.google.android.gms:play-services-base:17.5.0'
      implementation 'com.google.android.gms:play-services-basement:17.5.0'
      implementation 'com.google.android.gms:play-services-drive:17.0.0'
      implementation 'com.google.android.gms:play-services-tasks:17.0.0'
      
    • 确保主工程manifest有如下meta-data,value为google-services.json里的project_number

      <meta-data
          android:name="com.google.android.gms.games.APP_ID"
          android:value="@string/googleProjectNumber" />
      
      <!-- PGSLoginFlag为true时,走打包工具才会打入pgs插件 -->
      <meta-data
          android:name="PGSLoginFlag"
          android:value="true" />
      
    • 在Google Play Console后台获取 OAuth client ID 并在 res/values/strings.xml 添加(或修改)如下string的值:

      <string name="pgs_oauth_web_client_id" translatable="false">489676736225-81balv9a9v2vrd66npb2rj3rppk9vdp6.apps.googleusercontent.com</string>
      
    • 如果需要使用谷歌成就,可以使用 LCMSDK 的如下接口(前提是接了PGS插件),用法如下:

      // 显示谷歌成就
      LCMSDK.showAchievements(SampleActivity.this, 9003);
      // 解锁谷歌成就
      LCMSDK.unlockAchievement(SampleActivity.this, "test");
      // 谷歌成就增加
      LCMSDK.achievementIncrement(SampleActivity.this, "test", 1);
      
  15. 如果需要展示适龄提示,请添加(或修改)如下meta-data,用来控制适龄提示框显示的位置(不添加该meta-data默认不展示):

    <!-- 配置适龄提示悬浮框的默认显示位置(竖屏不支持左右下角)
            0:左上角
            1:右上角
            2:左下角
            3:右下角
            -1:不显示
            不配置不显示 -->
    <meta-data
        android:name="rating_reminder_location"
        android:value="1" />
    
  16. 如果需要支持Google儿童模式,请添加(或修改)如下meta-data,用来控制儿童模式的开关(不添加该meta-data默认关闭):

    <!-- Google渠道"判断用户是否未成年"功能开关 -->
    <meta-data
        android:name="check_underage_enabled"
        android:value="true" />
    

四、Eclipse接入步骤

下面说明eclipse如何接入:
  1. 将zip解压后目录如下:

  1. 此次更新为了区别sample和sdk,将目录分为library和sample两个目录 游戏接入时应引入library中的几个工程。sample中为演示功能,方便测试。sample中包含library 中的几个工程,其中xxx-v4的三个包,这三个基础包必须要游戏接入方手动引入。此目的为 了解决R文件问题,不可合并

  2. 接入时如果需要测试自己登录和支付功能,请将根据接入的商店引用相应的工程。

    • 引入规则:
    • full : 是除纯google以外其他的商店(测试时也需要引入facebook-sdk)
    • google : 纯google商店(测试时也需要引入facebook-sdk)
    • sdk : 不含任何商店纯sdk
    • xxx-v4系列:三个v4工程必须引入
    • facebook-sdk facebok基础库,用到facebook相关功能(包含登录,广告等)的包需要引入
    • 注意:full,google,仅为测试时使用。出包上传打包工具时请引用【sdk】工程
    • full,google,sdk 三个工程任选其一,不可同时引入,但出包时必须换成引用sdk----这点再次强调一下,facebook-sdk 使用到facebook相关功能(包含登录,广告等)时请引入此包。
  3. demo的使用方法:直接用eclipse打开sample工程即可(例:直接打开: 201908015/sample目录)。

  4. 接入时请根据自己的需求导入所需要的工程即可。请参考2

  5. 将samples目录下的Pickle中的AndroidManifest.xml文件中application节点下注册的activity(除了SampleActivity)全部拷贝到自己的AndroidManifest.xml中,<uses-permission>权限也一样拷贝。

  6. 出包时必须引入的是sdk的工程,(facebook-sdk看需求引入:需要facebook登录,广告等功能时必须引入)其他的工程请勿引用(其他工程仅供测试时使用)。

五、LCMSDK的接入

1. sdk的初始化接入流程

1)检查隐私协议并初始化sdk
  • init()接口: 在Activity的OnCreate()方法中进行初始化。
        // 1.如果需要权限提示,如下写法(根据最新政策,国内不建议用此种方式)
        // 这里传入permissionDialog,(google-play-store 上架的游戏/应用 用到),可不接,传null即可 ,如2。

//        Map<String, Boolean> map = new HashMap<>();
//        map.put(Manifest.permission.READ_EXTERNAL_STORAGE, false);
//        map.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, false);
//        map.put(Manifest.permission.READ_PHONE_STATE, false);
//        PermissionDefaultDialog permissionDialog = PermissionDefaultDialog.createDefault(this, map);
//        LCMSDK.init(this, lcmEventHandler, map, permissionDialog);

        // 2.如果不需要权限提示,如下写法:
        LCMSDK.init(SampleActivity.this, lcmEventHandler);

2)权限动态申请
  • 为应对国内最新政策,所有敏感权限必须在用到时动态申请(LCMSDK 提供 registerPermissions()、registerReadPhonePermission()、registerReadStoragePermission()、registerWriteStoragePermission() 等接口),比如分享功能,需要在分享前动态申请存储权限。
    private void checkPermissionBeforeSharing(final String type, final int scene, final int shareType, final String title, final String description, final String webUrl) {
        LCMSDK.registerReadStoragePermission(this, new PermissionUtils.OnRegisterPermissionListener() {
            @Override
            public void onRegisterPermissionsComplete(String... deniedPermissions) {
                if (deniedPermissions == null || deniedPermissions.length == 0) {
                    share(type, scene, shareType, title, description, webUrl);
                }
            }
        });
    }

  • 在Activity的 onRequestPermissionsResult 方法里别忘了调用 LCMSDK.onRequestPermissionsResult() 方法:
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        LCMSDK.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

3)EventHandler回调
  1. 在初始化时需要传入EventHandler回调接口。具体处理下文有介绍,也可以参考Demo。EventHandler是LCMSDK的重要的一个监听器,它实现了游戏与LCMSDK的交互,包括登录,强更,公告等都是通过这个监听器回传给游戏的。
    // 创建接口回调对象。调用init接口需要传入。
    lcmEventHandler = new LCMSDK.EventHandler() {
        @Override
        public void onInitComplete(LCMInitializer lcmInitialization) {
            // 初始化完成
        }

        @Override
        public void onRemoteMessage(String message, String extras) {
            // 推送消息
        }

        @Override
        public void onSessionError(LCMError error) {
            // session错误回调
        }

        @Override
        public void onSessionUpdate(String accessToken, User user) {
            // session更新
        }

        @Override
        public void onUpdate(LCMUpdater updater) {
            // 强更
        }

        @Override
        public void onAnnouncement(LCMAnnouncement announcement) {
            // 公告
        }

        @Override
        public void onActivation(LCMActivation activation) {                // 激活码

        }

        @Override
        public void onLogoutComplete(String extra) {
            // 登出游戏成功
        }

        @Override
        public void onLoginComplete(String accessToken, User user) {
            // 登录游戏成功
        }

        @Override
        public void onQuitComplete(String extra) {
            // 退出
        }
    }

  1. 关于EventHandler接口的定义,可以参考 Android API
  2. 对EventHandler的详细说明:请看 集成代码到自己的应用:6.实现最简单的EventHandler对象:
4)sdk生命周期绑定
  • LCMSDK需要与主Activity的生命周期保持一致,需要绑定主Activity的生命周期
    相应的绑定如下:

    LCMSDK中的方法 (参数) Actiivty的生命周期
    init(this,xx...) (此方法请参考上文介绍) onCreate()
    onResume(this) onResume()
    onPause(this) onPause()
    onStop(this) onStop()
    onReStart(this) onReStart()
    onDestory(this) onDestory()
    onActivityResult(this,requestCode, resultCode, data) onActivityResult()
    onNewIntent(this, intent) onNewIntent()
    onConfigurationChanged(this, newConfig) onConfigurationChanged()
    onRequestPermissionsResult(requestCode, permissions, grantResults) onRequestPermissionsResult()
    quit() onBackPressed()
5)配置闪屏图片(Splash)
  1. LCMSDK支持splash闪屏,在调用LCM init接口的时候,闪屏会出现,并在onInitComplete回调中消失。
  2. 不配置闪屏文件表示默认无闪屏。
  3. 游戏方若需要配置自己splash闪屏图片,则需要替换工程目录res/drawable-hdpi/lcm_splash_l.png和res/drawable-hdpi/lcm_splash_p.png两张图片,其中lcm_splash_l.png对应横屏游戏,lcm_splash_p.png对应竖屏游戏,有其一即可,游戏根据自己的横竖屏设置选择放入对应的闪屏图片。
  4. 注:闪屏图片是可以在资源文件中替换的,游戏的闪屏图片最好不要带有不可替换的内容,以至于在某些情况下该图片会被替换成其他图片,比如接入大陆渠道时,部分渠道方会要求使用渠道方的闪屏图片,则打包工具会将游戏自己的闪屏图片替换成渠道方的。

2. 配置文件appinfo.conf的配置说明

  • 可参考Demo中res/raw目录下的appinfo.conf。
  • {"region":"ap","env":"live","sandbox":"false","appVersion":"1.0","productId":"pickle","storeType":"LCM_A_TW","md5":"LCM_A_TW"}

    参数 说明
    region 地区:大陆为cn ,海外为ap
    env 游戏环境:配置live即可
    sandbox 是否是沙箱环境:沙箱服为true,正式服为false
    appVersion 游戏版本:例如:1.0
    productId 为ope后台注册的应用名称
    storeType 商店类型:大陆D商店为LCM_A_CN,台湾D商店为LCM_A_TW,GOOGLE和GOOGLE—D商店为GOOGLE,ONESTORE商店为ONESTORE, ONESTORE-D商店为ONESTORE2。可以参考Demo的配置。
    md5 签名文件的md5,需在ope后台配置。

接入完成以后,运行验证: 在EventHandler中的onLoginComplete() 回调中获取accessToken即接入成功了(具体可见Demo)。

3. 登录、登出

1) 登录接入
  • 完成上述的基本配置以后登录的功能就接好了。
  • EventHandler的回调中有onLoginComplete(String accessToken, User user)回调,登录后需要一些处理可以在此方法中处理,比如登录后公告,需要在次回调中调用 LCMSDK.checkAnnouncement()进行处理。(可参考Demo)
2) 登出接入
  • 调用接口 LCMSDK.logout() 可实现登出功能
  • EventHandler的回调onLogoutComplete(String extra)中可做登出完成的一些处理,如:重新初始化登录界面:LCMSDK.login()。(可参考Demo)

4. 支付

1)支付接入流程
     VCBundle.getAsList(SampleActivity.this, new VCBundleCallback() {
            @Override
            public void onComplete(List<VCBundle> bundles, LCMError error) {
                if (error == null) {
                    // 获取到商品列表,游戏可以自己展示,处理。
                    vcBundleList = bundles;
                    // 检查订单,必接
                    LCMSDK.recover(SampleActivity.this, vcBundleList,
                            new LCMSDK.OnRepayListener() {
                                @Override
                                public void onComplete(String transactionId, JSONObject jo) {}

                                 @Override
                                public void onError(int errorCode, String errorMsg) {}
                    });
                } else {
                    //handle error.
                }
            }
     });
  1. 支付的使用方式
    • 新增: VCBundle的接口,使用VCbundle对象调用buy()方法即可,此方式已经将实名制认证封装在里面。使用此方法可以省去实名制认证。
    vcBundle.buy(SampleActivity.this, purchaseMemo, new VCBundle.PurchaseCallback() {
         @Override
         public void onComplete(Wallet wallet, JSONObject payInfo, String memo, LCMError error) {
             // 后续处理见Demo
             doPurchase(vcBundle, wallet, parent, payInfo, error);
         }
    });
  1. 实名制认证
    • 实名制认证只有大陆自营商店才有,应国家政策要求,国内必须接入,但不会影响到其他商店的支付接入。
    • 请参考: 实名制认证
  2. Google商店支付
  3. DeNA自营商店大陆商店
    请参考:DeNA自营商店

  4. DeNA港澳台商店
    请参考:DeNA港澳台商店

  5. OneStore商店

  6. 支付回调错误码说明

    错误码 (errorCode) ErrorType 说明
    200 BANK_CREATE_ORDER_ERROR 创建订单错误
    205 BANK_PURCHASE_FAILURE 购买失败
    206 BANK_PURCHASE_CANCEL 购买取消
    216 BANK_PURCHASE_RESULT_UNKNOWN 购买结果未知
    217 BANK_GET_CURRENT_BALANCE_ERROR 获取当前余额失败
    218 BANK_GET_BALANCE_INFO_ERROR 获取余额信息失败
    220 BANK_PURCHASE_NO_GOOGLE_ACCOUNT 购买失败 no google account
    222 BANK_REPAY_ERROR 重新购买失败
    299 BANK_NOTIFY_ERROR 通知服务端失败
    - 更多详见附录.

5. 公告

1)公告接入流程
  • 公告是在EventHandler的onAnnouncement(LCMAnnouncement announcement)中做处理的。
  • 如果游戏不需要自定义UI可使用:
     announcement.applyDefault(new LCMAnnouncement.DefaultAnnouncementCallBack() {
             @Override
             public void callback() {
                // 执行正常进入游戏的逻辑,祥见pickle,SampleActivity.java.
                sampleStartToLoginToGame();
             }
});

  • 如果游戏需要自定义UI,需要接入者手动调用 announcement.continueProcessing();
    只有调用了此方法LCMSDK才会继续登录流程,但是该方法不能滥用,介入者需自行判断使用时机。
    例如:在自己写的弹窗的确定按钮点击事件中调用此方法。

6. 推送

1) 推送接入流程
  • 推送分为大陆商店的推送(百度推送)和Google的推送(FCM推送)
  • 推送在EventHandler的回调方法是onRemoteMessage(String message, String extras)
    游戏可根据需求自行处理。
  • 百度推送接入: 请参考   百度推送文档
  • Google推送接入: 请参考  FCM推送文档
  • 信鸽推送接入:详见信鸽官方文挡(https://xg.qq.com/docs/android_access/xg_push_introduction.html)
    信鸽推送集成步骤:
    1、前往信鸽管理台(https://xg.qq.com/),使用QQ号码登陆,进入应用注册页,填写“应用名称”和“应用包名”(必须要跟APP一致),选择“操作系统”和“分类”,最后点击“创建应用”。应用创建成功后,点击“应用配置”即可看到 APP 专属的 AccessId 和 AccessKey 等信息。
    2、前往华为开放平台(http://developer.huawei.com/)详细步骤参考(https://xg.qq.com/docs/android_access/huawei_push.html)注册,创建应用,得到appId和AppSecret。(配置到信鸽管理后台海外厂商通道中)
    3、前往小米开放平台(https://dev.mi.com/console/appservice/push.html),详细步骤参考(https://xg.qq.com/docs/android_access/mi_push.html)注册,创建应用,得到appId和appKey,和appSecret。(配置到信鸽管理后台海外厂商通道中)
    4、前往魅族推送官网(https://open.flyme.cn/open-web/views/push.html),详细步骤参考(https://xg.qq.com/docs/android_access/meizu_push.html) 注册,创建应用,得到appId和appKey,和appSecret。(配置到信鸽管理后台海外厂商通道中)
    5、经过上诉的步骤所得的小米和魅族appidappkey需要配置到ope后台上。
    6、经过以上配置就可以了。

7. 强更

1)强更接入流程
  • 强更会在EventHandler中的onUpdate(LCMUpdater updater)回调给游戏
  • 可参考Demo中的处理,Demo中使用默认处理
        @Override
            public void onUpdate(LCMUpdater updater) {
                //TODO 强制更新回调这里(推荐自定义UI接入方式)(必接)
                /* 游戏收到该回调后可通过显示LCM默认强更UI或者自定义强更页面,
                如果需要设置下载路径可通过 :
                updater.setTargetFilePath("/sdcard/dwonload/xxx.apk")
                */
                updater.showDefaultUI();
            }

8. onSessionError处理

  • 游戏研发需要在回调函数onSessionError判断错误码类型,展示对应的错误信息弹窗。

    错误码 (errorCode) LCMError.ErrorType 说明
    108 AUTH_SESSION_OCCUPIED 异地登录,账号在另一台设备上登录了,挤掉线
    116 AUTH_USER_FREEZE_TEMPORARY 临时冻结账户
    117 AUTH_USER_FREEZE_PERMANENT 永久冻结账户
    119 AUTH_CREDENTIAL_NO_GOOGLE_ACCOUNT 谷歌账号未登录处理(针对海外包,大陆包忽略)
    409 BIND_ACCOUNT_ERROR 绑定账号错误,该facebook/line账号已经被link过,请换一个facebook/line账号进行link.(针对海外包,大陆包忽略)
  • 详情请参考Demo。

9. 游戏打点事件(创角事件)

1)游戏打点接入流程

10. 悬浮窗(DeNA自营商店商店接入需要)

1)悬浮窗接入
  • 配置悬浮框的默认显示位置
  • 0:左上角

    • 1:右上角
    • 2:左下角
    • 3:右下角
    • -1:则不显示悬浮框
    • 默认显示 0: 左上角
  • 在清单文件中配置

    <meta-data android:name="menubar_default_position" android:value="0"/>
    
2)全面屏、刘海屏适配 配置
  • 为了悬浮窗能够适配刘海屏和全面屏,游戏可以配置以下属性到application节点下

  • 全面屏适配可以参考pickle中的代码,用于适配9.0的刘海屏

    final View decorView = getWindow().getDecorView();
    decorView.post(new Runnable() {
        @Override
        public void run() {
            // 9.0 api 刘海屏适配,允许使用刘海品区域
            if (Build.VERSION.SDK_INT >= 28) {
                WindowInsets rootWindowInsets = decorView.getRootWindowInsets();
                if (rootWindowInsets != null) {
                    DisplayCutout cutout = rootWindowInsets.getDisplayCutout();
                    if (cutout != null) {
                        LCMLog.d("有刘海");
                        WindowManager.LayoutParams lp = getWindow().getAttributes();
                        lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                        getWindow().setAttributes(lp);
                    }
                }
            }
        }
    });
    
  • mainfest中的配置

    <!--适配全面屏 start-->
    <meta-data
        android:name="android.max_aspect"
        android:value="2.4" />
    <!--华为刘海区域使用配置-->
    <meta-data
        android:name="android.notch_support"
        android:value="true" />
    <!--小米刘海区域使用配置-->
    <meta-data
        android:name="notch.config"
        android:value="portrait|landscape" />
    <!--VIVO刘海区域使用配置-->
    <meta-data
        android:name="android.vendor.full_screen"
        android:value="true" />
    <!--适配全面屏 end-->
    
  • 广点通广告需要修改Manifest里的配置(默认会通过打包工具修改,需要联系LCM相关人员)

    <meta-data
        android:name="GDT_USER_ACTION_SET_ID"
        android:value="1105943961" />
    <meta-data
        android:name="GDT_APP_SECRET_KEY"
        android:value="a5b9c17846b8626c3b5bc49f96dcd9f7" />
    

11.其他(非必接)

1)本地推送
2)激活码
3)客服系统
4)lid的Link/Load
5) 同设备的lid的重置和切换(reset、switch)
6) facebook分享
//在清单文件里配置参数,{facebook id}换成facebook数字id
<provider android:authorities="com.facebook.app.FacebookContentProvider{facebook id}"
android:name="com.facebook.FacebookContentProvider"
android:exported="true"/>

//ShareObject各个参数的传参说明,可以结合示例
class ShareObject {
    //分享方式: wechat , facebook  , qq
    public String type = "wechat";
    //消息标题    限制长度不超过512Bytes
    public String title;
    //消息描述    限制长度不超过1KB
    public String description;
    // 发送的目标场景
    // 分享到对话,好友:  0
    // 分享到朋友圈,空间:1
    public int scene;
    //透传参数
    public String transaction;
    //html链接     限制长度不超过10KB
    public String webUrl;
    //分享类型: 0 图片分享 , 1 网页分享 , 2 视频链接分享
    public int shareType;
    //分享图片地址  对应图片内容大小不超过10MB
    public String imagePath;
    //分享图片     对应图片内容大小不超过10MB
    public Bitmap imageBitmap;
    //video链接    只限facebook
    public String videoUrl;
}

//以下为调用facebook图片分享示例

ShareInterface.ShareObject fbShareObject = new ShareInterface.ShareObject();
fbShareObject.type = "facebook";
String fbShareIMGUrl = getShareIMGUrl();
fbShareObject.imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + fbShareIMGUrl;
fbShareObject.scene = 0;
fbShareObject.shareType = 0;
fbShareObject.title = "Pickle facebook分享";
fbShareObject.description = "Pickle facebook分享";
fbShareObject.webUrl = "https://www.qq.com";

LCMSDK.share(SampleActivity.this, fbShareObject, new OnShare() {
    @Override
    public void onSuccess(JSONObject response) {
        ToastUtils.toast(getApplicationContext(), "分享成功");
    }

    @Override
    public void onError(int errorCode, String errorMsg) {
        if (errorCode == 1003) {
            ToastUtils.toast(getApplicationContext(), "取消分享");
        } else {
            ToastUtils.toast(getApplicationContext(), errorMsg);
        }
    }
});
7) facebook好友列表获取(lcm已经将facebook好友转换为lid列表)
LCMSDK.getFriendsList(SampleActivity.this, new OnGetFriends() {
    @Override
    public void onGetFriends(List<String> friends) {
        if(friends!=null&&friends.size()>0){
            ToastUtils.toast(getApplicationContext(), "当前共同好友lid:"+friends.toString());
        }else{
            ToastUtils.toast(getApplicationContext(), "当前还没有共同使用的好友~");
        }
    }
});
8) line分享
ShareInterface.ShareObject lineShareObject = new ShareInterface.ShareObject();
lineShareObject.type = "line";
lineShareObject.imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + getShareIMGUrl();
lineShareObject.scene = 0;
lineShareObject.shareType = 0;
lineShareObject.title = "Pickle LINE分享";
lineShareObject.description = "Pickle LINE分享";

LCMSDK.share(SampleActivity.this, lineShareObject, new OnShare() {
    @Override
    public void onSuccess(JSONObject response) {
        ToastUtils.toast(getApplicationContext(), "分享成功");
    }

    @Override
    public void onError(int errorCode, String errorMsg) {
        if (errorCode == 1003) {
            ToastUtils.toast(getApplicationContext(), "取消分享");
        } else if (errorCode == 1006) {
            ToastUtils.toast(getApplicationContext(), "LINE未安装");
        } else {
            ToastUtils.toast(getApplicationContext(), errorMsg);
        }
    }
});
9) 获取IMEI 或 OAID
  • 简体SDK Android 10 以上(包含10)获取MSA联盟的OAID替代之前的imei
  • Android 10以下或海外SDK仍获取deviceId作为imei
OsUtils.getImei(activity, new OsUtils.GetIdListener() {
    @Override
    public void onGetId(String id) {

    }
});
10) Google play store货币代码查询接口
  • 简体SDK Android 10 以上(包含10)获取MSA联盟的OAID替代之前的imei
  • Android 10以下或海外SDK仍获取deviceId作为imei
//此方法只为需要查询谷歌支付货币代码的情况,非必接
LCMSDK.queryPaymentCurrencyCode(SampleActivity.this, new LCMSDK.OnQueryCurrencyCode() {
    @Override
    public void onSuccess(String currencyCode) {
        LCMLog.i(TAG, "currency code: " + currencyCode);
    }

    @Override
    public void onFailure(String message) {
        LCMLog.e(TAG, message);
    }
});
11)游戏自定义打点
    /**
     * 选接,用来自定义游戏日志库配置
     *
     * @param config 日志库配置,是一个json字符串,比如:
     *               {"ALIYUN_ENDPOINT":"节点", "ALIYUN_ACCESS_KEY_ID":"KEY_ID", "ALIYUN_ACCESS_KEY_SECRET":"SECRET", "ALIYUN_PROJECT":"PROJECT", "ALIYUN_LOGSTORE":"LOGSTORE"}
     */
    public static void setGameTrackConfig(String config) {
        LogService.setGameConfig(config);
    }
    /**
     * 必接接口,游戏事件日志上报接口
     *
     * @param eventName 事件名称
     * @param eventInfo 自定义json字符串(可以包含价格、时间、商品名称、等级、角色名称、活动名称等)
     */
    public static void trackGameEvent(String eventName, String eventInfo) {
        LogService.logGameEvent(eventName, eventInfo);
    }
12)协议相关
    /**
     * 显示协议
     *
     * @param activity      context
     * @param agreementType 0:隐私协议 1:用户协议
     */
    public static void showAgreement(final Activity activity, final int agreementType) {
        。。。
    }
    /**
     * 显示个人信息收集清单界面
     *
     * @param activity      context
     */
    public static void showUserPersonalInfoCollectionList(Activity activity) {
        。。。
    }
    /**
     * 显示第三方信息共享清单功能界面
     *
     * @param activity      context
     */
    public static void showThirdPartyInfoSharingList(Activity activity) {
        。。。
    }

13. 出包

  • 960及以上版本 出包方式非常简单,首先确保自己引入的工程是sdk工程,确保自己的程序运行出的app出现闪退崩溃等情况,然后直接打出apk包上传至打包工具即可。无需其他操作。
  • 注:960及以上版本 无需参考此条!老的出包方式,请参考:LCM9.5.0及以上出包指南

14. 常见问题-FAQ

  1. Q:无法正常登陆游戏?
    A:检查appinfo.conf配置文件的storeType和md5是否配置正确。

15. 联系方式

  • 邮箱:sdk-app_cn@dena.jp

版本:RC9.8.0
日期:2022.08.23

16. 附录

  • 错误码附录

    错误码 (errorCode) LCMError.ErrorType 说明
    100 AUTH_STORE_CREDENTIAL_ERROR Get store credential error
    101 AUTH_STORE_TYPE_ERROR StoreType 错误
    102 AUTH_SESSION_ERROR 创建session错误
    103 AUTH_SOCIAL_ACCOUNT_ERROR Get social account error
    104 AUTH_STORE_ACCOUNT_ERROR 获取商店账号错误
    105 AUTH_GET_LINK_INFO_ERROR 获取绑定信息错误
    106 AUTH_LINK_ACCOUNT_ERROR 绑定账号错误
    107 AUTH_LOAD_ACCOUNT_ERROR 加载账号错误
    108 AUTH_SESSION_OCCUPIED 异地登录,账号在另一台设备上登录了,挤掉线
    111 AUTH_UNLINK_ACCOUNT_ERROR Unlink account error
    112 AUTH_GET_ALL_USER_IDS_ERROR Get all user ids error
    113 AUTH_RESET_USER_ERROR Reset user error,重置用户错误
    114 AUTH_SWITCH_USER_ERROR Switch user error,切换用户错误
    116 AUTH_USER_FREEZE_TEMPORARY 临时冻结账户
    117 AUTH_USER_FREEZE_PERMANENT 永久冻结账户
    119 AUTH_CREDENTIAL_NO_GOOGLE_ACCOUNT 谷歌账号未登录处理
    200 BANK_CREATE_ORDER_ERROR 创建订单错误
    205 BANK_PURCHASE_FAILURE 购买失败
    206 BANK_PURCHASE_CANCEL 购买取消
    216 BANK_PURCHASE_RESULT_UNKNOWN 购买结果未知
    217 BANK_GET_CURRENT_BALANCE_ERROR 获取当前余额失败
    218 BANK_GET_BALANCE_INFO_ERROR 获取余额信息失败
    220 BANK_PURCHASE_NO_GOOGLE_ACCOUNT 购买失败 no google account
    222 BANK_REPAY_ERROR 重新购买失败
    299 BANK_NOTIFY_ERROR 通知服务端失败
    901 PARAMETER_ERROR 参数错误
    903 LCM_NETWORK_ERROR 网络异常
    409 BIND_ACCOUNT_ERROR 绑定账号错误,该facebook/line账号已经被link过,请换一个facebook/line账号进行link.
    411 BIND_ACCOUNT_FREQUENT_ERROR 绑定账号太频繁,每个月只能绑定一次
Back to top