client_Hale
2018-11-19 2f3b0ec98456bd483225b033467153d17627e92c
update 易接sdk接入逻辑
2个文件已修改
50个文件已添加
3893 ■■■■■ 已修改文件
ChannelDiff/Android/yjgame/AndroidManifest.xml 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ChannelDiff/Android/yjgame/libs/yj_sdk-game_yj-release.aar 补丁 | 查看 | 原始文档 | blame | 历史
GradleDiff/yjgame/mainTemplate.gradle 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/settings.gradle 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/sp_sdk/libs/sp_common_lib.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/build.gradle 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/ahelper.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/android-support-v4.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/bugly.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/buglyagent.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/gangaonlinehelper.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/gangaonlineyijie.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/jcore-android-1.2.1.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/jpush-android-3.1.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/tracking1.3.0.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/libs/unity-classes.jar 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/proguard-rules.pro 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/game_yj/AndroidManifest.xml 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/game_yj/assets/Sonnenblume/res.bin 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/game_yj/java/com/secondworld/univeralsdk/H2EngineSDK.java 472 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/game_yj/java/com/secondworld/univeralsdk/YJPlatformUtil.java 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/game_yj/java/com/secondworld/univeralsdk/YJSplashActivity.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/AndroidManifest.xml 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/BatteryUtil.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/CodeA2U.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/CodeU2A.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/CrashCatchUtil.java 233 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/DebugUtil.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/FileUtil.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/JPushReceiver.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/LogUtil.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/MainActivity.java 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/NotchPhoneUtil.java 347 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/StaticDefine.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/UniqueID.java 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/UniversalUtil.java 401 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/WebViewUtil.java 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_ic_richpush_actionbar_back.png 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_ic_richpush_actionbar_divider.png 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_richpush_btn_selector.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_richpush_progressbar.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/drawable/app_icon.png 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/drawable/web_btn_close_icon.png 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/layout/activity_main.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/layout/jpush_popwin_layout.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/layout/jpush_webview_layout.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/values/colors.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/values/jpush_style.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/values/strings.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/values/styles.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Project/yj_sdk/src/main/res/xml/file_paths.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ChannelDiff/Android/yjgame/AndroidManifest.xml
New file
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.secondworld.univeralsdk"
    android:installLocation="auto"
    android:versionCode="1"
    android:versionName="1.1.0" >
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="26" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application
        android:name="com.snowfish.cn.ganga.helper.SFOnlineApplication"
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@drawable/app_icon"
        android:isGame="true"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen" >
        <meta-data
            android:name="android.max_aspect"
            android:value="1075838976.000000" />
        <meta-data
            android:name="com.samsung.android.keepalive.density"
            android:value="true" />
        <!-- <meta-data -->
        <!-- android:name="android.notch_support" -->
        <!-- android:value="true" /> -->
        <meta-data
            android:name="notch.config"
            android:value="none" />
        <meta-data
            android:name="android.vendor.full_screen"
            android:value="true" />
        <activity
            android:name="com.secondworld.univeralsdk.YJSplashActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.secondworld.univeralsdk.MainActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:screenOrientation="sensorLandscape" >
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
            <meta-data
                android:name="unityplayer.SkipPermissionsDialog"
                android:value="true" />
            <meta-data
                android:name="android.vendor.home_indicator"
                android:value="hide" />
            <meta-data
                android:name="android.max_aspect"
                android:value="1075419520.000000" />
            <meta-data
                android:name="com.samsung.android.keepalive.density"
                android:value="true" />
        </activity>
        <!-- 针对7.0以上的api开放的文件权限 -->
        <!-- <provider -->
        <!-- android:name="android.support.v4.content.FileProvider" -->
        <!-- android:authorities="${appId}.fileProvider" -->
        <!-- android:grantUriPermissions="true" -->
        <!-- android:exported="false"> -->
        <!-- <meta-data -->
        <!-- android:name="android.support.FILE_PROVIDER_PATHS" -->
        <!-- android:resource="@xml/file_paths" /> -->
        <!-- </provider> -->
        <!-- SNOWFISH SDK -->
        <service
            android:name="com.snowfish.a.a.s.ABGSvc"
            android:enabled="true"
            android:process="com.snowfish.a.a.bg" >
            <intent-filter>
                <action android:name="com.snowfish.a.a.s.ABGSvc" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>
        <meta-data
            android:name="com.snowfish.appid"
            android:value="{0988C5A3-101098E5}" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.channelid"
            android:value="{4ff036a1-3254eafe}" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.customer"
            android:value="SNOWFISH" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.channel"
            android:value="SNOWFISH" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.sdk.version"
            android:value="1" >
        </meta-data>
        <!-- SNOWFISH SDK -->
    </application>
</manifest>
ChannelDiff/Android/yjgame/libs/yj_sdk-game_yj-release.aar
Binary files differ
GradleDiff/yjgame/mainTemplate.gradle
New file
@@ -0,0 +1,59 @@
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
    }
}
allprojects {
   repositories {
      flatDir {
        dirs 'libs'
      }
   }
}
apply plugin: 'com.android.application'
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
**DEPS**}
android {
    compileSdkVersion **APIVERSION**
    buildToolsVersion '**BUILDTOOLS**'
    defaultConfig {
        targetSdkVersion **TARGETSDKVERSION**
        applicationId '**APPLICATIONID**'
        ndk {
            abiFilters **ABIFILTERS**
        }
    }
    lintOptions {
        abortOnError false
    }
    aaptOptions {
        noCompress '.unity3d', '.ress', '.resource', '.obb'
    }
**SIGN**
    buildTypes {
        debug {
            jniDebuggable true
        }
        release {
            // Set minifyEnabled to true if you want to run ProGuard on your project
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
            **SIGNCONFIG**
        }
    }
}
Project/settings.gradle
@@ -1 +1 @@
include ':app', ':mr_sdk', ':sp_sdk', ':js_sdk'
include ':app', ':mr_sdk', ':sp_sdk', ':js_sdk', ':yj_sdk'
Project/sp_sdk/libs/sp_common_lib.jar
Binary files differ
Project/yj_sdk/.gitignore
New file
@@ -0,0 +1 @@
/build
Project/yj_sdk/build.gradle
New file
@@ -0,0 +1,55 @@
apply plugin: 'com.android.library'
android {
    compileSdkVersion 26
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    flavorDimensions "default"
    productFlavors {
        game_yj {
            dimension "default"
            manifestPlaceholders.put("appId", "{0988C5A3-101098E5}")
//            manifestPlaceholders.put("JpushAppKey", "22186239fee975f883198cf4")
        }
    }
}
dependencies {
    implementation files('libs/ahelper.jar')
    implementation files('libs/android-support-v4.jar')
    implementation files('libs/bugly.jar')
    implementation files('libs/buglyagent.jar')
    implementation files('libs/gangaonlinehelper.jar')
    implementation files('libs/gangaonlineyijie.jar')
    implementation files('libs/jcore-android-1.2.1.jar')
    implementation files('libs/jpush-android-3.1.3.jar')
    implementation files('libs/tracking1.3.0.jar')
    compileOnly files('libs/unity-classes.jar')
}
task autoCopy_yjgame_Manifest(type: Copy) {
    dependsOn 'assembleGame_yjRelease'
    from zipTree("build/outputs/aar/yj_sdk-game_yj-release.aar")
    include "AndroidManifest.xml"
    into "C:\\Unity3D_SDK\\ChannelDiff\\Android\\yjgame\\"
}
task autoCopy_yjgame(type: Copy) {
    dependsOn autoCopy_yjgame_Manifest
    from "build/outputs/aar/"
    include "yj_sdk-game_yj-release.aar"
    into "C:\\Unity3D_SDK\\ChannelDiff\\Android\\yjgame\\libs\\"
}
Project/yj_sdk/libs/ahelper.jar
Binary files differ
Project/yj_sdk/libs/android-support-v4.jar
Binary files differ
Project/yj_sdk/libs/bugly.jar
Binary files differ
Project/yj_sdk/libs/buglyagent.jar
Binary files differ
Project/yj_sdk/libs/gangaonlinehelper.jar
Binary files differ
Project/yj_sdk/libs/gangaonlineyijie.jar
Binary files differ
Project/yj_sdk/libs/jcore-android-1.2.1.jar
Binary files differ
Project/yj_sdk/libs/jpush-android-3.1.3.jar
Binary files differ
Project/yj_sdk/libs/tracking1.3.0.jar
Binary files differ
Project/yj_sdk/libs/unity-classes.jar
Binary files differ
Project/yj_sdk/proguard-rules.pro
New file
@@ -0,0 +1,59 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-dontoptimize
-dontpreverify
-dontwarn okio.**
-keep class okio.** { *;}
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *;}
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
-keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }
-dontwarn cn.jiguang.**
-keep class cn.jiguang.** { *; }
-dontwarn cn.jiguang.android.service.**
-keep class cn.jiguang.android.service.** { *;}
-dontwarn com.google.gson.**
-keep class com.google.gson.** { *;}
-dontwarn com.tencent.bugly.**
-keep class com.tencent.bugly.** { *;}
-dontwarn com.tencent.bugly.agent.**
-keep class com.tencent.bugly.agent.** { *;}
-dontwarn android.support.**
-keep class android.support.** { *;}
-dontwarn com.reyun.tracking.**
-keep class com.reyun.tracking.** { *;}
-dontwarn com.ss.**
-keep class com.ss.tracking.** { *;}
-dontwarn com.bytedance.**
-keep class com.bytedance.** { *;}
-dontwarn okhttp3.**
-keep class okhttp3.** { *;}
-dontwarn com.secondworld.univeralsdk.**
-keep class com.secondworld.univeralsdk.** { *;}
-keep class com.snowfish.** { *; }
-dontwarn com.unity3d.**
-keep class com.unity3d.**{*;}
Project/yj_sdk/src/game_yj/AndroidManifest.xml
New file
@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.secondworld.univeralsdk"
    android:installLocation="auto"
    android:versionCode="1"
    android:versionName="1.1.0">
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:hardwareAccelerated="false"
        android:isGame="true"
        android:name="com.snowfish.cn.ganga.helper.SFOnlineApplication"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">
        <meta-data
            android:name="android.max_aspect"
            android:value="1075838976.000000" />
        <meta-data
            android:name="com.samsung.android.keepalive.density"
            android:value="true" />
        <!--<meta-data-->
            <!--android:name="android.notch_support"-->
            <!--android:value="true" />-->
        <meta-data
            android:name="notch.config"
            android:value="none" />
        <meta-data
            android:name="android.vendor.full_screen"
            android:value="true" />
        <activity
            android:name="com.secondworld.univeralsdk.YJSplashActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.secondworld.univeralsdk.MainActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:screenOrientation="sensorLandscape">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
            <meta-data
                android:name="unityplayer.SkipPermissionsDialog"
                android:value="true" />
            <meta-data
                android:name="android.vendor.home_indicator"
                android:value="hide" />
            <meta-data
                android:name="android.max_aspect"
                android:value="1075419520.000000" />
            <meta-data
                android:name="com.samsung.android.keepalive.density"
                android:value="true" />
        </activity>
        <!-- 针对7.0以上的api开放的文件权限 -->
        <!--<provider-->
        <!--android:name="android.support.v4.content.FileProvider"-->
        <!--android:authorities="${appId}.fileProvider"-->
        <!--android:grantUriPermissions="true"-->
        <!--android:exported="false">-->
        <!--<meta-data-->
        <!--android:name="android.support.FILE_PROVIDER_PATHS"-->
        <!--android:resource="@xml/file_paths" />-->
        <!--</provider>-->
        <!-- SNOWFISH SDK -->
        <service
            android:name="com.snowfish.a.a.s.ABGSvc"
            android:enabled="true"
            android:process="com.snowfish.a.a.bg" >
            <intent-filter>
                <action android:name="com.snowfish.a.a.s.ABGSvc" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>
        <meta-data
            android:name="com.snowfish.appid"
            android:value="${appId}" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.channelid"
            android:value="{4ff036a1-3254eafe}" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.customer"
            android:value="SNOWFISH" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.channel"
            android:value="SNOWFISH" >
        </meta-data>
        <meta-data
            android:name="com.snowfish.sdk.version"
            android:value="1" >
        </meta-data>
        <!-- SNOWFISH SDK -->
    </application>
</manifest>
Project/yj_sdk/src/game_yj/assets/Sonnenblume/res.bin
Binary files differ
Project/yj_sdk/src/game_yj/java/com/secondworld/univeralsdk/H2EngineSDK.java
New file
@@ -0,0 +1,472 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.widget.Toast;
import com.snowfish.cn.ganga.helper.SFOnlineHelper;
import com.unity3d.player.UnityPlayer;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.data.JPushLocalNotification;
public class H2EngineSDK
{
    private static final String TAG = "H2EngineSDK";
    private static String APP_ID = "";
    private static boolean PushEnable = true;
    public static void HandleUnityMessage(String json)
    {
        LogUtil.i(TAG, "收到Unity发来的信息: " + json);
        Activity _activity = UnityPlayer.currentActivity;
        try
        {
            JSONObject _json = new JSONObject(json);
            int _code = _json.getInt("code");
            switch (_code)
            {
                case CodeU2A.Init:
                    APP_ID = _json.getString("appID");
                    init(_activity);
                    break;
                case CodeU2A.CopyOneAsset:
                    FileUtil.copy(_activity, _json.getString("fileName"));
                    break;
                case CodeU2A.AssetCopy:
                    FileUtil.copyAssets(_activity);
                    break;
                case CodeU2A.BatteryListenStart:
                    BatteryUtil.getInstance().start(_activity);
                    break;
                case CodeU2A.BatteryListenStop:
                    BatteryUtil.getInstance().stop(_activity);
                    break;
                case CodeU2A.UniqueID:
                    break;
                case CodeU2A.CopyContent:
                    CopyContent(_activity, _json.getString("content"));
                    break;
                case CodeU2A.OpenWebView:
                    WebViewUtil.OpenWebView(_activity, _json.getString("url"));
                    break;
                case CodeU2A.RestartApp:
                    RestartApp(_activity);
                    break;
                case CodeU2A.InstallAPK:
                    InstallApp(_activity, _json.getString("path"));
                    break;
                case CodeU2A.ExteneralStorage:
                    GetExternalStorage();
                    break;
                case CodeU2A.RequestPermission:
                    break;
                case CodeU2A.RequestManifestPermissions:
                    break;
                case CodeU2A.FreePlatformInit:
                    break;
                case CodeU2A.FreePlatformLogin:
                    YJPlatformUtil.getInstance().login(_activity);
                    break;
                case CodeU2A.FreePlatformSwitchAccount:
                    break;
                case CodeU2A.FreePlatformLogout:
                    YJPlatformUtil.getInstance().logout(_activity);
                    break;
                case CodeU2A.FreePlatformPay:
                    JSONObject _extraData = new JSONObject();
                    _extraData.put("appid", APP_ID);
                    _extraData.put("cpinfo", _json.getString("cpInfo"));
                    _extraData.put("cporderid", _json.getString("orderId"));
                    try
                    {
                        YJPlatformUtil.getInstance().pay(_activity,
                                                         _json.getString("title"),
                                                         _json.getString("cpInfo"),
                                                         (float) _json.getDouble("mount"),
                                                         URLEncoder.encode( _extraData.toString(),"utf-8"));
                    }catch (UnsupportedEncodingException e)
                    {
                        e.printStackTrace();
                    }
                    break;
                case CodeU2A.PayFinished:
                    YJPlatformUtil.getInstance().payProcessing = false;
                    break;
                case CodeU2A.CreateRole:
                    YJPlatformUtil.getInstance().createRole(_activity,
                                                            _json.getString("sid"),
                                                            _json.getString("serverName"),
                                                            _json.getString("roleID"),
                                                            _json.getString(
                                                                    "roleName").trim().replace(" ",
                                                                                               ""),
                                                            _json.getString("level"),
                                                            _json.getString(
                                                                    "familyName").trim().replace(
                                                                    " ", ""),
                                                            _json.getString("createTime"),
                                                            _json.getString("levelUpTime"),
                                                            _json.getString("vipLevel"),
                                                            _json.getString("money"));
                    break;
                case CodeU2A.RoleLogin:
                    YJPlatformUtil.getInstance().enterWorld(_activity,
                                                            _json.getString("sid"),
                                                            _json.getString("serverName"),
                                                            _json.getString("roleID"),
                                                            _json.getString(
                                                                    "roleName").trim().replace(" ",
                                                                                               ""),
                                                            _json.getString("level"),
                                                            _json.getString(
                                                                    "familyName").trim().replace(
                                                                    " ", ""),
                                                            _json.getString("createTime"),
                                                            _json.getString("levelUpTime"),
                                                            _json.getString("vipLevel"),
                                                            _json.getString("money"));
                    break;
                case CodeU2A.RoleLevelUp:
                    YJPlatformUtil.getInstance().levelUp(_activity,
                                                         _json.getString("sid"),
                                                         _json.getString("serverName"),
                                                         _json.getString("roleID"),
                                                         _json.getString("roleName").trim().replace(
                                                                 " ", ""),
                                                         _json.getString("level"),
                                                         _json.getString(
                                                                 "familyName").trim().replace(" ",
                                                                                              ""),
                                                         _json.getString("createTime"),
                                                         _json.getString("levelUpTime"),
                                                         _json.getString("vipLevel"),
                                                         _json.getString("money"));
                    break;
                case CodeU2A.ClientPackage:
                    break;
                case CodeU2A.JPushAddLocalMessage:
                    addLocalNotification(_activity,
                                         _json.getInt("id"),
                                         _json.getString("title"),
                                         _json.getString("content"),
                                         _json.getLong("fireTime"));
                    break;
                case CodeU2A.JPushRemoveLocalMessage:
                    removeNotification(_activity, _json.getInt("id"));
                    break;
            }
        } catch (JSONException e)
        {
            e.printStackTrace();
        }
    }
    // 本地推送
    public static void addLocalNotification(Activity activity, int id, String title, String content,
                                            long fireTime)
    {
        if (PushEnable)
        {
            try
            {
                JPushLocalNotification ln = new JPushLocalNotification();
                ln.setBuilderId(0);// 设置样式
                ln.setNotificationId(id);// id
                ln.setTitle(title);// 标题
                ln.setContent(content);// 内容
                ln.setBroadcastTime(fireTime);// 等待时间
                JPushInterface.addLocalNotification(activity, ln);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    public static void removeNotification(Activity activity, int id)
    {
        if (PushEnable)
        {
            JPushInterface.removeLocalNotification(activity, id);
        }
    }
    public static void GetExternalStorage()
    {
        Map<String, Object> _msg = new HashMap<>();
        _msg.put("code", CodeA2U.ExternalStorage);
        _msg.put("path", Environment.getExternalStorageDirectory().getAbsolutePath());
        UniversalUtil.sendMessageToUnity(_msg);
    }
    public static void InstallApp(Activity activity, String path)
    {
        File _file = new File(path);
        if (_file == null)
        {
            LogUtil.i(TAG, "找不到给定地址的apk: " + path);
            return;
        }
        try
        {
            Intent _intent = new Intent(Intent.ACTION_VIEW);
//            if (Build.VERSION.SDK_INT >= 23)
//            {
//                _intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//                Uri _contentUri = FileProvider.getUriForFile(activity,
//                                                             "com.shandangceshi.snxxz.fileProvider",
//                                                             _file);
//                _intent.setDataAndType(_contentUri, "application/vnd.android.package-archive");
//
//            }
//            else
//            {
            _intent.setDataAndType(Uri.fromFile(_file),
                                   "application/vnd.android.package-archive");
            _intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            }
            activity.startActivity(_intent);
        } catch (Exception e)
        {
            e.printStackTrace();
            Toast.makeText(activity, "没有找到打开此类文件的程序", Toast.LENGTH_SHORT).show();
        }
    }
    public static void CopyContent(final Activity activity, final String content)
    {
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                ClipboardManager _mgr = (ClipboardManager) activity.getSystemService(
                        Context.CLIPBOARD_SERVICE);
                ClipData _data = ClipData.newPlainText("playerId", content);
                _mgr.setPrimaryClip(_data);
            }
        });
    }
    public static void RestartApp(final Activity activity)
    {
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                new Thread()
                {
                    public void run()
                    {
                        String _pn = activity.getPackageName();
                        PackageManager _pm = activity.getPackageManager();
                        Intent _l = _pm.getLaunchIntentForPackage(_pn);
                        _l.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        activity.startActivity(_l);
                        android.os.Process.killProcess(android.os.Process.myPid());
                    }
                }.start();
                activity.finish();
            }
        });
    }
    public static void init(final Activity activity)
    {
        final int _memoryTotal = (int) (UniversalUtil.getMemTotal() / 1024);
        if (_memoryTotal < 1024)
        {
            LogUtil.i(TAG, "检测设备内存不满足运行程序标准");
            AlertDialog.Builder _builder = new AlertDialog.Builder(activity);
            _builder.setIcon(R.drawable.app_icon);
            _builder.setTitle("警告");
            _builder.setMessage("您的手机内存不足,无法正常运行游戏");
            _builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialogInterface, int i)
                {
                    android.os.Process.killProcess(android.os.Process.myPid());
                }
            });
            _builder.show();
            return;
        }
        PushEnable = activity.getPackageName().equals("com.xjaz.sp");
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                LogUtil.i(TAG, "开始执行初始化");
                GetExternalStorage();
                // ------------------------------- 设备信息 -------------------------------
                Map<String, Object> _msgStruct = new HashMap<>();
                _msgStruct.put("code", CodeA2U.DeviceInfo);
                _msgStruct.put("userAgent", System.getProperty("http.agent"));
                _msgStruct.put("mac", UniqueID.getLocalMac(activity));
                _msgStruct.put("imei", UniqueID.getDeviceId(activity));
                _msgStruct.put("android_id",
                               Settings.System.getString(activity.getContentResolver(),
                                                         Settings.System.ANDROID_ID));
                _msgStruct.put("unique_id", UniqueID.get(activity));
                _msgStruct.put("memoryTotal", _memoryTotal);
                UniversalUtil.sendMessageToUnity(_msgStruct);
                // ------------------------------- 极光推送 -------------------------------
                String _registrationID = "0";
                if (PushEnable)
                {
                    JPushInterface.setDebugMode(true);
                    JPushInterface.init(activity);
                    final long _waitingTime = System.currentTimeMillis();
                    while (true)
                    {
                        // 等待获取极光registrationID
                        if (!JPushInterface.getRegistrationID(activity).equals(""))
                        {
                            _registrationID = JPushInterface.getRegistrationID(activity);
                            break;
                        }
                        long _escapeTime = System.currentTimeMillis() - _waitingTime;
                        if (_escapeTime > 3000)
                        {
                            LogUtil.w(TAG, "等待获取极光推送registrationID超时: 3秒");
                            break;
                        }
                    }
                }
                _msgStruct.clear();
                _msgStruct.put("code", CodeA2U.PushClientID);
                _msgStruct.put("clientID", _registrationID);
                UniversalUtil.sendMessageToUnity(_msgStruct);
                _msgStruct.clear();
                _msgStruct.put("code", CodeA2U.SdkInitComplete);
                _msgStruct.put("channelPlatform", "yj");
                _msgStruct.put("yj_appid", UniversalUtil.getMetaString(activity,"yj_appid"));
                _msgStruct.put("yj_spid", UniversalUtil.getMetaString(activity,"yj_spid"));
                UniversalUtil.sendMessageToUnity(_msgStruct);
                LogUtil.i(TAG, "初始化执行完毕");
            }
        }).start();
    }
    public static void onCreate(Activity activity, Bundle savedInstanceState)
    {
        YJPlatformUtil.getInstance().onCreate(activity, savedInstanceState);
    }
    private static boolean m_IsFocus = true;
    public static void onWindowFocusChanged(boolean b)
    {
//        if (MrPlatformUtil.getInstance().payProcessing)
//        {
//            if (b)
//            {
//                Map<String, Object> _msgStruct = new HashMap<>();
//                _msgStruct.put("code", CodeA2U.FreePlatformPayCancel);
//                UniversalUtil.sendMessageToUnity(_msgStruct);
//                MrPlatformUtil.getInstance().payProcessing = false;
//            }
//        }
    }
    public static void onNewIntent(final Activity activity, final Intent intent)
    {
    }
    public static void onActivityResult(int requestCode,
                                        int resultCode,
                                        final Intent data,
                                        final Activity activity)
    {
    }
    public static void onConfigurationChanged(final Configuration newConfig) {}
    public static void onRestart(final Activity activity)
    {
        SFOnlineHelper.onRestart(activity);
    }
    public static void onStart(final Activity activity)
    {
    }
    public static void onPause(final Activity activity)
    {
        SFOnlineHelper.onPause(activity);
    }
    public static void onResume(final Activity activity)
    {
        SFOnlineHelper.onResume(activity);
//        if (YJPlatformUtil.getInstance().payProcessing)
//        {
//            Map<String, Object> _msgStruct = new HashMap<>();
//            _msgStruct.put("code", CodeA2U.FreePlatformPayCancel);
//            UniversalUtil.sendMessageToUnity(_msgStruct);
//            YJPlatformUtil.getInstance().payProcessing = false;
//        }
    }
    public static void onStop(final Activity activity)
    {
        SFOnlineHelper.onStop(activity);
    }
    public static void onDestroy(final Activity activity)
    {
        SFOnlineHelper.onDestroy(activity);
    }
}
Project/yj_sdk/src/game_yj/java/com/secondworld/univeralsdk/YJPlatformUtil.java
New file
@@ -0,0 +1,258 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import com.snowfish.cn.ganga.helper.SFOnlineHelper;
import com.snowfish.cn.ganga.helper.SFOnlineInitListener;
import com.snowfish.cn.ganga.helper.SFOnlineLoginListener;
import com.snowfish.cn.ganga.helper.SFOnlinePayResultListener;
import com.snowfish.cn.ganga.helper.SFOnlineUser;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by Administrator on 2018/9/18 0018.
 */
public class YJPlatformUtil
{
    private static SFOnlineUser USER = null;
    private final static String PAY_CALLBACK_URL = "";
    private final static String LOGIN_CHECK_URL = "";
    private static final String TAG = "YJPlatformUtil";
    private static YJPlatformUtil m_Instance;
    public static YJPlatformUtil getInstance()
    {
        if (m_Instance == null)
        {
            m_Instance = new YJPlatformUtil();
        }
        return m_Instance;
    }
    private Map<String, Object> m_Message = new HashMap<>();
    public boolean payProcessing = false;
    public void onCreate(final Activity activity, Bundle savedInstanceState)
    {
        SFOnlineHelper.onCreate(activity, new SFOnlineInitListener()
        {
            @Override
            public void onResponse(String s, String s1)
            {
                m_Message.clear();
                if (s.equalsIgnoreCase("success"))
                {
                    m_Message.put("code", CodeA2U.FreePlatformInitOk);
                    UniversalUtil.sendMessageToUnity(m_Message);
                }
                else if (s.equalsIgnoreCase("fail"))
                {
                    m_Message.put("code", CodeA2U.FreePlatformInitFail);
                    UniversalUtil.sendMessageToUnity(m_Message);
                }
            }
        });
        SFOnlineHelper.setLoginListener(activity, new SFOnlineLoginListener()
        {
            @Override
            public void onLogout(Object o)
            {
                m_Message.clear();
                //需要把游戏切换回登陆前的场景,并重新弹出登录框等操作
                m_Message.put("code", CodeA2U.FreePlatformLogoutOk);
                UniversalUtil.sendMessageToUnity(m_Message);
            }
            @Override
            public void onLoginSuccess(SFOnlineUser sfOnlineUser, Object o)
            {
                m_Message.clear();
                USER = sfOnlineUser;
                //根据回调获取用户信息
                String userName = USER.getUserName();
                String timestamp = USER.getToken();
                String token = USER.getToken();
                String userId = USER.getChannelUserId();
                try
                {
                    JSONObject _info = new JSONObject();
                    _info.put("account", userName);
                    _info.put("token", token);
                    _info.put("timeStamp", timestamp);
                    _info.put("account_id", userId);
                    _info.put("yjSdkId", USER.getChannelId());
                    _info.put("yjAppId", USER.getProductCode());
                    m_Message.put("code", CodeA2U.FreePlatformLoginOk);
                    m_Message.put("info", _info);
                    UniversalUtil.sendMessageToUnity(m_Message);
                } catch (JSONException e)
                {
                    e.printStackTrace();
                }
            }
            @Override
            public void onLoginFailed(String s, Object o)
            {
                m_Message.clear();
                m_Message.put("code", CodeA2U.FreePlatformLoginFail);
                UniversalUtil.sendMessageToUnity(m_Message);
            }
        });
    }
    public void login(final Activity activity)
    {
        SFOnlineHelper.login(activity, "Login");
    }
    public void logout(final Activity activity)
    {
        SFOnlineHelper.logout(activity, "LoginOut");
    }
    public void pay(final Activity activity, String productName, String productID, float price,
                    String extData)
    {
        SFOnlineHelper.pay(activity,
                           (int) (price * 100),
                           productName,
                           1,
                           extData,
                           PAY_CALLBACK_URL,
                           new SFOnlinePayResultListener()
                           {
                               @Override
                               public void onFailed(String s)
                               {
                                   m_Message.clear();
                                   //根据回调获取支付订单信息
                                   LogUtil.i(TAG, "Pay Fail Info: " + s);
                                   m_Message.put("code", CodeA2U.FreePlatformPayFail);
                                   UniversalUtil.sendMessageToUnity(m_Message);
                                   payProcessing = false;
                               }
                               @Override
                               public void onSuccess(String s)
                               {
                                   m_Message.clear();
                                   //根据回调获取支付订单信息
                                   LogUtil.i(TAG, "Pay Success Info: " + s);
                                   m_Message.put("code", CodeA2U.FreePlatformPayOk);
                                   UniversalUtil.sendMessageToUnity(m_Message);
                                   payProcessing = false;
                               }
                               @Override
                               public void onOderNo(String s)
                               {
                                   LogUtil.i(TAG, "Pay Order No: " + s);
                               }
                           });
        payProcessing = true;
    }
    public void createRole(final Activity activity,
                           String serverID,
                           String serverName,
                           String roleID,
                           String roleName,
                           String roleLevel,
                           String FamilyName,
                           String createTime,
                           String levelUpTime,
                           String vipLevel,
                           String surplusMoney)
    {
        SFOnlineHelper.setRoleData(activity, roleID, roleName, roleLevel, serverID, serverName);
        String _info = createGameData(serverID, serverName, roleID, roleName, roleLevel, FamilyName,
                                      createTime, levelUpTime, vipLevel, surplusMoney);
        SFOnlineHelper.setData(activity, "createrole", _info); //  创建新角色时调用       必接
    }
    public void enterWorld(Activity activity,
                           String serverID,
                           String serverName,
                           String roleID,
                           String roleName,
                           String roleLevel,
                           String FamilyName,
                           String createTime,
                           String levelUpTime,
                           String vipLevel,
                           String surplusMoney)
    {
        String _info = createGameData(serverID, serverName, roleID, roleName, roleLevel, FamilyName,
                                      createTime, levelUpTime, vipLevel, surplusMoney);
        SFOnlineHelper.setData(activity, "enterServer", _info); //  创建新角色时调用       必接
    }
    public void levelUp(final Activity activity,
                        String serverID,
                        String serverName,
                        String roleID,
                        String roleName,
                        String roleLevel,
                        String FamilyName,
                        String createTime,
                        String levelUpTime,
                        String vipLevel,
                        String surplusMoney)
    {
        String _info = createGameData(serverID, serverName, roleID, roleName, roleLevel, FamilyName,
                                      createTime, levelUpTime, vipLevel, surplusMoney);
        SFOnlineHelper.setData(activity, "levelup", _info); //  创建新角色时调用       必接
    }
    private String createGameData(String serverID,
                                  String serverName,
                                  String roleID,
                                  String roleName,
                                  String roleLevel,
                                  String FamilyName,
                                  String createTime,
                                  String levelUpTime,
                                  String vipLevel,
                                  String surplusMoney)
    {
        try
        {
            JSONObject roleInfo = new JSONObject();
            roleInfo.put("roleId", roleID);         //当前登录的玩家角色ID,必须为数字
            roleInfo.put("roleName", roleName);  //当前登录的玩家角色名,不能为空,不能为null
            roleInfo.put("roleLevel", roleLevel);   //当前登录的玩家角色等级,必须为数字,且不能为0,若无,传入1
            roleInfo.put("zoneId", serverID);       //当前登录的游戏区服ID,必须为数字,且不能为0,若无,传入1
            roleInfo.put("zoneName", serverName);//当前登录的游戏区服名称,不能为空,不能为null
            roleInfo.put("balance", surplusMoney);   //用户游戏币余额,必须为数字,若无,传入0
            roleInfo.put("vip", vipLevel);            //当前用户VIP等级,必须为数字,若无,传入1
            roleInfo.put("partyName", FamilyName);//当前角色所属帮派,不能为空,不能为null,若无,传入“无帮派”
            roleInfo.put("roleCTime", createTime);     //单位为秒,创建角色的时间
            roleInfo.put("roleLevelMTime", levelUpTime);    //单位为秒,角色等级变化时间
            return roleInfo.toString();
        } catch (JSONException ex)
        {
            ex.printStackTrace();
        }
        return null;
    }
}
Project/yj_sdk/src/game_yj/java/com/secondworld/univeralsdk/YJSplashActivity.java
New file
@@ -0,0 +1,22 @@
package  com.secondworld.univeralsdk;
import android.content.Intent;
import android.graphics.Color;
import com.snowfish.cn.ganga.helper.SFOnlineSplashActivity;
public class YJSplashActivity extends SFOnlineSplashActivity
{
    public int getBackgroundColor()
    {
        return Color.WHITE;
    }
    @Override
    public void onSplashStop()
    {
        Intent _intent = new Intent(this, MainActivity.class);
        startActivity(_intent);
        this.finish();
    }
}
Project/yj_sdk/src/main/AndroidManifest.xml
New file
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.secondworld.univeralsdk"
    android:installLocation="auto"
    android:versionCode="1"
    android:versionName="1.1.0">
    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:hardwareAccelerated="false"
        android:isGame="true"
        android:name="com.snowfish.cn.ganga.helper.SFOnlineApplication"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">
        <meta-data
            android:name="android.max_aspect"
            android:value="1075838976.000000" />
        <meta-data
            android:name="com.samsung.android.keepalive.density"
            android:value="true" />
        <!--<meta-data-->
            <!--android:name="android.notch_support"-->
            <!--android:value="true" />-->
        <meta-data
            android:name="notch.config"
            android:value="none" />
        <meta-data
            android:name="android.vendor.full_screen"
            android:value="true" />
        <activity
            android:name="com.secondworld.univeralsdk.MainActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:screenOrientation="sensorLandscape">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
            <meta-data
                android:name="unityplayer.SkipPermissionsDialog"
                android:value="true" />
            <meta-data
                android:name="android.vendor.home_indicator"
                android:value="hide" />
            <meta-data
                android:name="android.max_aspect"
                android:value="1075419520.000000" />
            <meta-data
                android:name="com.samsung.android.keepalive.density"
                android:value="true" />
        </activity>
    </application>
</manifest>
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/BatteryUtil.java
New file
@@ -0,0 +1,113 @@
package com.secondworld.univeralsdk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by Administrator on 2018/7/15 0015.
 */
public class BatteryUtil
{
    private static BatteryUtil s_Instance = null;
    public static BatteryUtil getInstance()
    {
        if (s_Instance == null)
        {
            s_Instance = new BatteryUtil();
        }
        return s_Instance;
    }
    private BatteryBroadCastReceiver m_BatteryBroadCastReceiver;
    private BatteryUtil() {}
    public void start(Context context)
    {
        m_BatteryBroadCastReceiver = new BatteryBroadCastReceiver();
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        context.registerReceiver(m_BatteryBroadCastReceiver, filter);
    }
    public void stop(Context context)
    {
        context.unregisterReceiver(m_BatteryBroadCastReceiver);
        m_BatteryBroadCastReceiver = null;
    }
    private class BatteryBroadCastReceiver extends BroadcastReceiver
    {
        private int m_BatteryLevel;
        private int m_Status;
        public BatteryBroadCastReceiver()
        {
            m_BatteryLevel = 0;
        }
        @Override
        public void onReceive(Context context, Intent intent)
        {
            if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED))
            {
                int _batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
                Map<String, Object> _msg = new HashMap<>();
                if (_batteryLevel != m_BatteryLevel)
                {
                    try
                    {
                        _msg.put("code", CodeA2U.BatteryLevel);
                        _msg.put("level", _batteryLevel);
                        UniversalUtil.sendMessageToUnity(_msg);
                        m_BatteryLevel = _batteryLevel;
                    } catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
                int _status = intent.getIntExtra("status", 0);
                if (_status != m_Status)
                {
                    _msg.clear();
                    int _transCode = 0;
                    if (_status == BatteryManager.BATTERY_STATUS_CHARGING)
                    {
                        _transCode = 2;
                    }
                    else if (_status == BatteryManager.BATTERY_STATUS_NOT_CHARGING ||
                            _status == BatteryManager.BATTERY_STATUS_DISCHARGING)
                    {
                        _transCode = 1;
                    }
                    else if (_status == BatteryManager.BATTERY_STATUS_FULL)
                    {
                        _transCode = 3;
                    }
                    _msg.put("code", CodeA2U.BatteryCharging);
                    _msg.put("status", _transCode);
                    UniversalUtil.sendMessageToUnity(_msg);
                    m_Status = _status;
                }
            }
        }
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/CodeA2U.java
New file
@@ -0,0 +1,59 @@
package com.secondworld.univeralsdk;
/**
 * Created by Administrator on 2018/7/18 0018.
 */
public class CodeA2U
{
    /**
     * 资源拷贝完成
     */
    public static final int AssetCopyFinished = 0;
    /**
     * 电量改变
     */
    public static final int BatteryLevel = 1;
    /**
     * 充电状态改变
     */
    public static final int BatteryCharging = 2;
    /**
     * 回调sdk逻辑完毕
     * */
    public static final int SdkInitComplete = 90;
    /**
     * 回调android设备信息
     * */
    public static final int DeviceInfo = 3;
    /**
     * 回调推送的独立id
     * */
    public static final int PushClientID = 4;
    /**
     * 回调外部存储根目录地址
     */
    public static final int ExternalStorage = 5;
    /**
     * --------------------------------------------------------------------------------------------
     * 以下为各自项目SDK相关
     * --------------------------------------------------------------------------------------------
     */
    // ------------------------------------------------------------------------------------------
    // 自由SDK相关回调Code
    // ------------------------------------------------------------------------------------------
    public static final int FreePlatformInitOk = 10;
    public static final int FreePlatformInitFail = 11;
    public static final int FreePlatformLoginOk = 12;
    public static final int FreePlatformLoginFail = 13;
    public static final int FreePlatformLoginCancel = 14;
    public static final int FreePlatformLogoutOk = 15;
    public static final int FreePlatformLogoutFail = 16;
    public static final int FreePlatformSwitchAccountOk = 17;
    public static final int FreePlatformPayOk = 18;
    public static final int FreePlatformPayFail = 19;
    public static final int FreePlatformPayCancel = 20;
    public static final int FreePlatformRegisterOk = 21;
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/CodeU2A.java
New file
@@ -0,0 +1,85 @@
package com.secondworld.univeralsdk;
/**
 * Created by Administrator on 2018/7/18 0018.
 */
public class CodeU2A
{
    /**
     * 执行资源拷贝
     */
    public static final int AssetCopy = 0;
    /**
     * 执行开始电量改变,充电状态改变监听
     */
    public static final int BatteryListenStart = 1;
    /**
     * 执行停止电量改变,充电状态改变监听
     */
    public static final int BatteryListenStop = 2;
    /**
     * 获取唯一识别码
     */
    public static final int UniqueID = 3;
    /**
     * 申请在AndroidManifest文件中
     */
    public static final int RequestManifestPermissions = 4;
    /**
     * 单独动态申请某一个权限
     */
    public static final int RequestPermission = 5;
    /**
     * 重启应用
     */
    public static final int RestartApp = 6;
    /**
     * 拷贝文本信息
     */
    public static final int CopyContent = 7;
    /**
     * 打开网址
     */
    public static final int OpenWebView = 8;
    /**
     * SDK初始化, 完全自动初始化的流程, 完成必要逻辑后再回调回去
     */
    public static final int Init = 9;
    /**
     * 安装应用
     */
    public static final int InstallAPK = 10;
    /**
     * 外部存储根目录地址
     */
    public static final int ExteneralStorage = 11;
    public static final int CopyOneAsset = 12;
    /**
     * --------------------------------------------------------------------------------------------
     * 以下为各自项目SDK相关
     * --------------------------------------------------------------------------------------------
     */
    /**
     * 自由sdk相关
     * */
    public static final int FreePlatformInit = 100;
    public static final int FreePlatformLogin = 101;
    public static final int FreePlatformLogout = 102;
    public static final int FreePlatformSwitchAccount = 103;
    public static final int FreePlatformPay = 104;
    public static final int PayFinished = 105;
    public static final int CreateRole = 106;
    public static final int RoleLogin = 107;
    public static final int RoleLevelUp = 108;
    /**
     * 极光推送
     * */
    public static final int JPushAddLocalMessage = 200;
    public static final int JPushRemoveLocalMessage = 201;
    /**
     * ClientPackage向sdk发送分包id
     */
    public static final int ClientPackage = 400;
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/CrashCatchUtil.java
New file
@@ -0,0 +1,233 @@
package com.secondworld.univeralsdk;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Looper;
import android.os.SystemClock;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by Administrator on 2018/7/19 0019.
 */
public class CrashCatchUtil implements Thread.UncaughtExceptionHandler
{
    private static final String TAG = "CrashCatchUtil";
    private Context m_Context;
    private Thread.UncaughtExceptionHandler m_UncaughtExceptionHandler;
    private Map<String, String> m_DevicceInfo = new HashMap<>();
    private CrashCatchUtil() {}
    private static CrashCatchUtil m_Instance;
    public static CrashCatchUtil getInstance()
    {
        if (m_Instance == null)
        {
            m_Instance = new CrashCatchUtil();
        }
        return m_Instance;
    }
    public void init(Context context)
    {
        m_Context = context;
        m_UncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        autoClear(5);
    }
    @Override
    public void uncaughtException(Thread thread, Throwable throwable)
    {
        if (!handleException(throwable) && m_UncaughtExceptionHandler != null)
        {
            m_UncaughtExceptionHandler.uncaughtException(thread, throwable);
        }
        else
        {
            SystemClock.sleep(3000);
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }
    private void recordDeviceInfo()
    {
        m_DevicceInfo.clear();
        m_DevicceInfo.put("brand", Build.BRAND);
        m_DevicceInfo.put("model", Build.MODEL);
        m_DevicceInfo.put("android_version", String.valueOf(Build.VERSION.SDK_INT));
        try
        {
            PackageManager _pkgMgr = m_Context.getPackageManager();
            PackageInfo _pkgInfo = _pkgMgr.getPackageInfo(m_Context.getPackageName(),
                                                          PackageManager.GET_ACTIVITIES);
            if (_pkgInfo != null)
            {
                m_DevicceInfo.put("versionName", _pkgInfo.versionName);
                m_DevicceInfo.put("versionCode", String.valueOf(_pkgInfo.versionCode));
            }
        } catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }
    }
    private boolean handleException(Throwable throwable)
    {
        if (throwable == null)
        {
            return false;
        }
        try
        {
            new Thread(new Runnable()
            {
                @Override
                public void run()
                {
                    Looper.prepare();
                    Toast.makeText(m_Context, "程序出现异常,即将重启", Toast.LENGTH_LONG).show();
                    Looper.loop();
                }
            }).start();
            recordDeviceInfo();
            save(throwable);
            SystemClock.sleep(3000);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return true;
    }
    private String save(Throwable throwable) throws Exception
    {
        StringBuffer sb = new StringBuffer();
        try
        {
            SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = sDateFormat.format(new Date());
            sb.append("\r\n" + date + "\n");
            for (Map.Entry<String, String> entry : m_DevicceInfo.entrySet())
            {
                String key = entry.getKey();
                String value = entry.getValue();
                sb.append(key + "=" + value + "\n");
            }
            Writer writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter(writer);
            throwable.printStackTrace(printWriter);
            Throwable cause = throwable.getCause();
            while (cause != null)
            {
                cause.printStackTrace(printWriter);
                cause = cause.getCause();
            }
            printWriter.flush();
            printWriter.close();
            String result = writer.toString();
            sb.append(result);
            String fileName = writeFile(sb.toString());
            return fileName;
        } catch (Exception e)
        {
            sb.append("写入崩溃日志时, 出现了异常状况...\r\n");
            writeFile(sb.toString());
        }
        return null;
    }
    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
    private String writeFile(String sb) throws Exception
    {
        String time = formatter.format(new Date());
        String fileName = "crash-" + time + ".log";
        String path = getPath();
        File dir = new File(getPath());
        if (!dir.exists())
        {
            dir.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(path + fileName, true);
        fos.write(sb.getBytes());
        fos.flush();
        fos.close();
        return fileName;
    }
    private String getPath()
    {
        return m_Context.getExternalFilesDir("").getAbsolutePath()
                + File.separator
                + "crash"
                + File.separator;
    }
    /**
     * 文件删除
     *
     * @param autoClearDay 文件保存天数
     */
    public void autoClear(final int autoClearDay)
    {
        delete(getPath(), new FilenameFilter()
        {
            @Override
            public boolean accept(File file, String filename)
            {
                String s = FileUtil.getFileNameWithoutExtension(filename);
                int day = autoClearDay < 0 ? autoClearDay : -1 * autoClearDay;
                String date = "crash-" + getOtherDay(day);
                return date.compareTo(s) >= 0;
            }
        });
    }
    private void delete(String path, FilenameFilter filter)
    {
        File _file = new File(path);
        if (!_file.exists())
        {
            return;
        }
        File[] _files = _file.listFiles(filter);
        for (int i = _files.length - 1; i >= 0; i--)
        {
            _files[i].delete();
        }
    }
    private String getOtherDay(int offset)
    {
        Calendar _calendar = Calendar.getInstance();
        _calendar.add(Calendar.DATE, offset);
        return formatter.format(_calendar.getTime());
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/DebugUtil.java
New file
@@ -0,0 +1,59 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import java.io.File;
/**
 * Created by Administrator on 2018/7/20 0020.
 */
public class DebugUtil
{
    private final String TAG = "DebugUtil";
    private static DebugUtil s_Instance;
    public static DebugUtil getInstance()
    {
        if (s_Instance == null)
        {
            s_Instance = new DebugUtil();
        }
        return s_Instance;
    }
    private DebugUtil() {}
    private boolean m_Enable = false;
    private Activity m_Activity;
    public void init(Activity activity)
    {
        m_Activity = activity;
        String _path = Environment.getExternalStorageDirectory() + File.separator + activity.getPackageName();
        Log.i(TAG, _path);
        File _dir = new File(_path);
        if (!_dir.exists())
        {
            _dir.mkdir();
        }
        _path = _path + File.separator + "SdkDebug";
        _dir = new File(_path);
        m_Enable = _dir.exists();
        if(m_Enable){
            Log.i(TAG, "--------- SDK调试模式: 开启 ---------");
        }else{
            Log.i(TAG, "--------- SDK调试模式: 关闭 ---------");
        }
    }
    public boolean enable()
    {
        return m_Enable;
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/FileUtil.java
New file
@@ -0,0 +1,211 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
/**
 * Created by Administrator on 2018/6/14 0014.
 */
public class FileUtil
{
    private static final String TAG = "H2Engine_FileUtil";
    /**
     * Unity随包资源(StreamingAssets)拷贝至 persistentDataPath 路径下
     */
    public static void copyAssets(final Activity activity)
    {
        // 判断是否已经执行过
        SharedPreferences _sp = activity.getPreferences(Context.MODE_PRIVATE);
        Boolean _isCopied = hasCopy(activity);
        LogUtil.i(TAG, "是否已经执行过拷贝逻辑: " + _isCopied);
        // 获取当前包的版本号
        final String _currentVer = UniversalUtil.GetVersionName(activity);
        // 已经拷贝过, 则再次判断一次版本号
        // 如果版本号不相同, 则重新进行拷贝
        // 获取本地存储的版本号
        String _installVer = _sp.getString(StaticDefine.LS_KEY_VERSION, "");
        if (!_installVer.equals(_currentVer))
        {
            LogUtil.i(TAG, "版本比较过后发现不同: " + _installVer + " != " + _currentVer);
            SharedPreferences.Editor _editor = _sp.edit();
            // 存储此次的版本信息
            _editor.putString(StaticDefine.LS_KEY_VERSION, _currentVer);
            _editor.apply();
            if (_isCopied)
            {
                // 将本地存储修改为未拷贝过
                deleteRecord(activity);
                _isCopied = false;
            }
        }
        if (_isCopied)
        {
            Map<String, Object> _msg = new HashMap<>();
            _msg.put("code", CodeA2U.AssetCopyFinished);
            UniversalUtil.sendMessageToUnity(_msg);
            return;
        }
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                String _dest = activity.getExternalFilesDir("").getAbsolutePath();
                AssetManager _assetMgr = activity.getAssets();
                try
                {
                    String[] _fileNames = _assetMgr.list("android");
                    if (_fileNames != null)
                    {
                        for (String _fileName : _fileNames)
                        {
                            copy(activity, "android" + File.separator + _fileName,
                                 _dest + File.separator + _fileName);
                        }
                    }
                    recordCopy(activity);
                    Map<String, Object> _msg = new HashMap<>();
                    _msg.put("code", CodeA2U.AssetCopyFinished);
                    UniversalUtil.sendMessageToUnity(_msg);
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    public static void copy(Context context, String fileName)
    {
        String _originalPath = "android" + File.separator + fileName;
        String _destPath = context.getExternalFilesDir(
                "").getAbsolutePath() + File.separator + fileName;
        String _destDir = _destPath.substring(0, _destPath.lastIndexOf('/') + 1);
        File _file = new File(_destDir);
        if(!_file.exists())
        {
            LogUtil.i(TAG,"单独拷贝 => 不存在指定路径: " + _destDir + ", 这里创建...");
            _file.mkdir();
        }
        try
        {
            InputStream _is = context.getAssets().open(_originalPath);
            FileOutputStream _fos = new FileOutputStream(new File(_destPath));
            byte[] _buffer = new byte[1024];
            int _byteCount;
            while ((_byteCount = _is.read(_buffer)) != -1)
            {
                _fos.write(_buffer, 0, _byteCount);
            }
            _fos.flush();
            _is.close();
            _fos.close();
            LogUtil.i("FileUtil", "单独拷贝 => 文件: " + _originalPath + " 已拷贝至: " + _destPath);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    public static void copy(Context context, String original, String dest)
    {
        try
        {
            String _fileNames[] = context.getAssets().list(original);
            if (_fileNames.length > 0)
            {
                File _dir = new File(dest);
                _dir.mkdir();
                LogUtil.i("FileUtil", "[" + original + "] 是一个文件夹, 创建文件夹: [" + dest + "]");
                for (String _fileName : _fileNames)
                {
                    copy(context, original + File.separator + _fileName,
                         dest + File.separator + _fileName);
                }
            }
            else
            {
                InputStream _is = context.getAssets().open(original);
                FileOutputStream _fos = new FileOutputStream(new File(dest));
                byte[] _buffer = new byte[1024];
                int _byteCount;
                while ((_byteCount = _is.read(_buffer)) != -1)
                {
                    _fos.write(_buffer, 0, _byteCount);
                }
                _fos.flush();
                _is.close();
                _fos.close();
                LogUtil.i("FileUtil", "文件: " + original + " 已拷贝至: " + dest);
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    public static String getFileNameWithoutExtension(String fileName)
    {
        return fileName.substring(0, fileName.lastIndexOf("."));
    }
    private static boolean hasCopy(Context context)
    {
        File _file = new File(context.getExternalFilesDir(""), "/assetCopyFinish.txt");
        return _file.exists();
    }
    private static void deleteRecord(Context context)
    {
        File _file = new File(context.getExternalFilesDir(""), "/assetCopyFinish.txt");
        if (_file.exists())
        {
            _file.delete();
        }
    }
    private static void recordCopy(Context context)
    {
        File _file = new File(context.getExternalFilesDir(""), "/assetCopyFinish.txt");
        try
        {
            FileOutputStream _fos = new FileOutputStream(_file);
            Writer _writer = new OutputStreamWriter(_fos, "UTF-8");
            _writer.write(1);
            _writer.close();
            _fos.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/JPushReceiver.java
New file
@@ -0,0 +1,147 @@
package com.secondworld.univeralsdk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import cn.jpush.android.api.JPushInterface;
/**
 * Created by Administrator on 2018/6/16 0016.
 */
public class JPushReceiver extends BroadcastReceiver
{
    private static final String TAG = "JPushReceiver";
    @Override
    public void onReceive(Context context, Intent intent)
    {
        try
        {
            Bundle bundle = intent.getExtras();
            Log.d(TAG,
                  "[MyReceiver] onReceive - " + intent.getAction() + ", extras: " + printBundle(
                          bundle));
            if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction()))
            {
                String regId = bundle.getString(JPushInterface.EXTRA_REGISTRATION_ID);
                Log.d(TAG, "[MyReceiver] 接收Registration Id : " + regId);
                //send the Registration Id to your server...
                Map<String, Object> _msgStruct = new HashMap<>();
                _msgStruct.put("code", CodeA2U.PushClientID);
                _msgStruct.put("clientID", regId);
                UniversalUtil.sendMessageToUnity(_msgStruct);
            }
            else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction()))
            {
                processCustomMessage(context, bundle);
            }
            else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction()))
            {
                Log.d(TAG, "[MyReceiver] 接收到推送下来的通知");
                int notifactionId = bundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);
                Log.d(TAG, "[MyReceiver] 接收到推送下来的通知的ID: " + notifactionId);
            }
            else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction()))
            {
                Log.d(TAG, "[MyReceiver] 用户点击打开了通知");
                //打开自定义的Activity
                Intent i = new Intent(context, MainActivity.class);
                i.putExtras(bundle);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                context.startActivity(i);
            }
            else if (JPushInterface.ACTION_RICHPUSH_CALLBACK.equals(intent.getAction()))
            {
                Log.d(TAG, "[MyReceiver] 用户收到到RICH PUSH CALLBACK: " + bundle.getString(
                        JPushInterface.EXTRA_EXTRA));
                //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等..
            }
            else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction()))
            {
                boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE,
                                                           false);
                Log.w(TAG,
                      "[MyReceiver]" + intent.getAction() + " connected state change to " + connected);
            }
            else
            {
                Log.d(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction());
            }
        } catch (Exception e)
        {
        }
    }
    // 打印所有的 intent extra 数据
    private static String printBundle(Bundle bundle)
    {
        StringBuilder sb = new StringBuilder();
//        for (String key : bundle.keySet()) {
//            if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
//                sb.append("\nkey:" + key + ", value:" + bundle.getInt(key));
//            }else if(key.equals(JPushInterface.EXTRA_CONNECTION_CHANGE)){
//                sb.append("\nkey:" + key + ", value:" + bundle.getBoolean(key));
//            } else if (key.equals(JPushInterface.EXTRA_EXTRA)) {
//                if (TextUtils.isEmpty(bundle.getString(JPushInterface.EXTRA_EXTRA))) {
//                    Logger.i(TAG, "This message has no Extra data");
//                    continue;
//                }
//
//                try {
//                    JSONObject json = new JSONObject(bundle.getString(JPushInterface.EXTRA_EXTRA));
//                    Iterator<String> it =  json.keys();
//
//                    while (it.hasNext()) {
//                        String myKey = it.next();
//                        sb.append("\nkey:" + key + ", value: [" +
//                                          myKey + " - " +json.optString(myKey) + "]");
//                    }
//                } catch (JSONException e) {
//                    Logger.e(TAG, "Get message extra JSON error!");
//                }
//
//            } else {
//                sb.append("\nkey:" + key + ", value:" + bundle.get(key));
//            }
//        }
        return sb.toString();
    }
//    public static final String KEY_TITLE = "title";
//    public static final String KEY_MESSAGE = "message";
//    public static final String KEY_EXTRAS = "extras";
    //send msg to MainActivity
    private void processCustomMessage(Context context, Bundle bundle)
    {
        Log.d(TAG, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!![MyReceiver] 接收到推送下来的自定义消息: " + bundle.getString(
                JPushInterface.EXTRA_MESSAGE));
//        if (MainActivity.isForeground) {
//            String message = bundle.getString(JPushInterface.EXTRA_MESSAGE);
//            String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
//            Intent msgIntent = new Intent(MainActivity.MESSAGE_RECEIVED_ACTION);
//            msgIntent.putExtra(MainActivity.KEY_MESSAGE, message);
//            if (!UniversalUtil.isEmpty(extras)) {
//                try {
//                    JSONObject extraJson = new JSONObject(extras);
//                    if (extraJson.length() > 0) {
//                        msgIntent.putExtra(MainActivity.KEY_EXTRAS, extras);
//                    }
//                } catch (JSONException e) {
//
//                }
//
//            }
//            LocalBroadcastManager.getInstance(context).sendBroadcast(msgIntent);
//        }
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/LogUtil.java
New file
@@ -0,0 +1,114 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * Created by Administrator on 2018/7/25 0025.
 */
public class LogUtil
{
    private static final String Global_TAG = "h2EngineSdk";
    private static final String TAG = "LogUtil";
    public static boolean UPLOAD = false;
    private static boolean SAVE = false;
    private static boolean SHOW = true;
    private final static SimpleDateFormat m_DateFormatMS = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss.SSS");
    private final static SimpleDateFormat m_DateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
    private static Activity m_Activity;
    public static void init(Activity activity, boolean showLog)
    {
        m_Activity = activity;
        SHOW = showLog;
        File _file = new File(getPath());
        if (_file.exists())
        {
            SAVE = true;
            i(TAG, "启动本地log存储功能");
        }
        else
        {
            SAVE = false;
            i(TAG, "未启动本地log存储功能");
        }
    }
    public static void i(String tag, String content)
    {
        content = ("[" + m_DateFormatMS.format(new Date()) + "]") + "[" + tag + "] " + content;
        Log.i(Global_TAG, content);
        if (SAVE)
        {
            write(content);
        }
    }
    public static void w(String tag, String content)
    {
        content = ("[" + m_DateFormatMS.format(new Date()) + "]") + "[" + tag + "] " + content;
        Log.w(Global_TAG, content);
        if (SAVE)
        {
            write(content);
        }
    }
    public static void e(String tag, String content)
    {
        content = ("[" + m_DateFormatMS.format(new Date()) + "]") + "[" + tag + "] " + content;
        Log.e(Global_TAG, content);
        if (SAVE)
        {
            write(content);
        }
    }
    private static String getPath()
    {
        if (m_Activity.getExternalFilesDir("") == null)
        {
            Log.i(TAG,"m_Activity.getExternalFilesDir(\"\") == null");
            return "";
        }
        return m_Activity.getExternalFilesDir("").getAbsolutePath()
                + File.separator
                + "debugLog"
                + File.separator;
    }
    private static void write(String content)
    {
        try
        {
            String time = m_DateFormatDay.format(new Date());
            String fileName = "log_" + time + ".log";
            FileOutputStream fos = new FileOutputStream(getPath() + fileName, true);
            fos.write(content.getBytes());
            fos.flush();
            fos.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    public static void upLoad()
    {
        if (!UPLOAD)
        {
            return;
        }
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/MainActivity.java
New file
@@ -0,0 +1,200 @@
package com.secondworld.univeralsdk;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Process;
import android.provider.Settings;
import android.support.v4.content.PermissionChecker;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity
{
    private static final String TAG = "MainActivity";
    public static boolean isForeground = false;
    // 启用6.0以上权限回调code
    // private static final int CODE_REQUEST_PERMISSION = 1000;
    private RelativeLayout m_MainContainer;
    private int mType;
    private boolean isNotch = false;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        LogUtil.i(TAG, "onCreate");
        LogUtil.init(this, true);
        setContentView(R.layout.activity_main);
        m_MainContainer = (RelativeLayout) findViewById(R.id.main_container);
        String _brand = NotchPhoneUtil.getDeviceBrand();
        if (_brand.toUpperCase().contains("VIVO"))
        {
            isNotch = NotchPhoneUtil.HasNotchVivo(MainActivity.this);
            mType = 1;
        }
        else if (_brand.toUpperCase().contains("HUAWEI")
                || _brand.toUpperCase().contains("HONOR"))
        {
//            isNotch = NotchPhoneUtil.hasNotchAtHuawei(this);;
//            mType = 2;
        }
        else if (_brand.toUpperCase().contains("OPPO"))
        {
            isNotch = NotchPhoneUtil.HasNotchOPPO(MainActivity.this);
            mType = 3;
        }
        else if (_brand.toUpperCase().contains("XIAOMI"))
        {
            isNotch = NotchPhoneUtil.HasNotchXiaoMi();
            mType = 4;
        }
        NotchPhoneUtil.onConfigurationChanged(this, isNotch, mType, m_MainContainer);
        FrameLayout _frameLayout = (FrameLayout) findViewById(R.id.unity_view);
        View unityView = mUnityPlayer.getView();
        _frameLayout.addView(unityView);
        H2EngineSDK.onCreate(this, savedInstanceState);
    }
    @Override
    public void onWindowFocusChanged(boolean b)
    {
        super.onWindowFocusChanged(b);
        H2EngineSDK.onWindowFocusChanged(b);
    }
    @Override
    protected void onNewIntent(Intent intent)
    {
        super.onNewIntent(intent);
        H2EngineSDK.onNewIntent(this, intent);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        H2EngineSDK.onActivityResult(requestCode, resultCode, data, this);
        super.onActivityResult(requestCode, resultCode, data);
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        NotchPhoneUtil.onConfigurationChanged(this, isNotch, mType, m_MainContainer);
        H2EngineSDK.onConfigurationChanged(newConfig);
        super.onConfigurationChanged(newConfig);
    }
    @Override
    protected void onStart()
    {
        H2EngineSDK.onStart(this);
        super.onStart();
    }
    @Override
    protected void onStop()
    {
        isForeground = false;
        H2EngineSDK.onStop(this);
        super.onStop();
    }
    @Override
    protected void onResume()
    {
        isForeground = true;
        H2EngineSDK.onResume(this);
        super.onResume();
        // 检测本地存储权限是否有, 没有的话要提示用户
        if (PermissionChecker.checkPermission(this,
                                              Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                              Process.myPid(), Process.myUid(),
                                              getPackageName()) != PackageManager.PERMISSION_GRANTED
                || PermissionChecker.checkPermission(this,
                                                     Manifest.permission.READ_EXTERNAL_STORAGE,
                                                     Process.myPid(), Process.myUid(),
                                                     getPackageName()) != PackageManager.PERMISSION_GRANTED)
        {
            new AlertDialog.Builder(this)
                    .setMessage("应用没有存储读取权限,点击确定至设置中开启,否则无法继续游戏.")
                    .setCancelable(false)
                    .setPositiveButton("确定",
                                       new DialogInterface.OnClickListener()
                                       {
                                           @Override
                                           public void onClick(DialogInterface dialogInterface,
                                                               int i)
                                           {
                                               UniversalUtil.hasGoToSetting = true;
                                               Intent intent = new Intent(
                                                       Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                               Uri uri = Uri.fromParts("package",
                                                                       getPackageName(),
                                                                       null);
                                               intent.setData(uri);
                                               startActivity(intent);
                                           }
                                       })
                    .setNegativeButton("拒绝",
                                       new DialogInterface.OnClickListener()
                                       {
                                           @Override
                                           public void onClick(DialogInterface dialogInterface,
                                                               int i)
                                           {
                                               finish();
                                           }
                                       })
                    .show();
        }
    }
    @Override
    protected void onPause()
    {
        H2EngineSDK.onPause(this);
        super.onPause();
    }
    @Override
    protected void onDestroy()
    {
        H2EngineSDK.onDestroy(this);
        super.onDestroy();
    }
    @Override
    protected void onRestart()
    {
        H2EngineSDK.onRestart(this);
        super.onRestart();
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/NotchPhoneUtil.java
New file
@@ -0,0 +1,347 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.content.Context;
import android.view.Surface;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import java.lang.reflect.Method;
/**
 * Created by Administrator on 2018/9/11 0011.
 */
public class NotchPhoneUtil
{
    private final static String TAG = "Notch";
    /**
     * 华为手机判断是不是刘海手机
     *
     * @param context
     * @return
     */
    public static boolean hasNotchAtHuawei(Context context)
    {
        boolean ret = false;
        try
        {
            ClassLoader classLoader = context.getClassLoader();
            Class HwNotchSizeUtil = classLoader.loadClass(
                    "com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
            ret = (boolean) get.invoke(HwNotchSizeUtil);
        } catch (ClassNotFoundException e)
        {
            LogUtil.e(TAG, "hasNotchAtHuawei ClassNotFoundException");
        } catch (NoSuchMethodException e)
        {
            LogUtil.e(TAG, "hasNotchAtHuawei NoSuchMethodException");
        } catch (Exception e)
        {
            LogUtil.e(TAG, "hasNotchAtHuawei Exception");
        } finally
        {
            return ret;
        }
    }
    /**
     * 华为手机获取刘海的宽高
     * int[0]值为刘海宽度 int[1]值为刘海高度
     */
    public static int[] getNotchSizeAtHuawei(Context context)
    {
        int[] ret = new int[]{0, 0};
        try
        {
            ClassLoader cl = context.getClassLoader();
            Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("getNotchSize");
            ret = (int[]) get.invoke(HwNotchSizeUtil);
        } catch (ClassNotFoundException e)
        {
            LogUtil.e(TAG, "getNotchSizeAtHuawei ClassNotFoundException");
        } catch (NoSuchMethodException e)
        {
            LogUtil.e(TAG, "getNotchSizeAtHuawei NoSuchMethodException");
        } catch (Exception e)
        {
            LogUtil.e(TAG, "getNotchSizeAtHuawei Exception");
        } finally
        {
            return ret;
        }
    }
    /**
     * OPPO判断是不是刘海手机,
     * OPPO不提供接口获取刘海尺寸,目前其有刘海屏的机型尺寸规格都是统一的。不排除以后机型会有变化。
     * 刘海区域则都是宽度为324px, 高度为80px。
     *
     * @param context
     * @return
     */
    public static boolean HasNotchOPPO(Context context)
    {
        return context.getPackageManager().hasSystemFeature(
                "com.oppo.feature.screen.heteromorphism");
    }
    public static final int VIVO_NOTCH = 0x00000020;//是否有刘海
    /**
     * vivo判断是不是刘海手机
     */
    public static boolean HasNotchVivo(Context context)
    {
        boolean ret = false;
        try
        {
            ClassLoader classLoader = context.getClassLoader();
            Class FtFeature = classLoader.loadClass("android.util.FtFeature");
            Method method = FtFeature.getMethod("isFeatureSupport", int.class);
            ret = (boolean) method.invoke(FtFeature, VIVO_NOTCH);
        } catch (ClassNotFoundException e)
        {
            LogUtil.e(TAG, "hasNotchAtVivo ClassNotFoundException");
        } catch (NoSuchMethodException e)
        {
            LogUtil.e(TAG, "hasNotchAtVivo NoSuchMethodException");
        } catch (Exception e)
        {
            LogUtil.e(TAG, "hasNotchAtVivo Exception");
        } finally
        {
            return ret;
        }
    }
    /**
     * 小米手机判断是不是刘海手机
     *
     * @return
     */
    public static boolean HasNotchXiaoMi()
    {
        Boolean _hasNotchXiaoMi = getPropertyInt("ro.miui.notch", 0) == 1 ? true : false;
        LogUtil.i(TAG,"是否是小米刘海手机: " + _hasNotchXiaoMi);
        return _hasNotchXiaoMi;
    }
    private static int getPropertyInt(String key,int defaultValue)
    {
        int value = defaultValue;
        try
        {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class);
            value = (int) (get.invoke(c, key, "unknown"));
        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            return value;
        }
    }
    /**
     * 小米手机获取刘海的高度
     */
    public static int getStatusBarHeight(Context context)
    {
        int statusBarHeight = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen",
                                                              "android");
        if (resourceId > 0)
        {
            statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }
    /**
     * 屏幕旋转汇总的方法
     *
     * @param activity
     * @param isNotch
     * @param type
     * @param viewGroup
     */
    public static void onConfigurationChanged(Activity activity, Boolean isNotch, int type,
                                              ViewGroup viewGroup)
    {
        if (getDisplayRotation(activity) == 0)
        {
            if (isNotch)
            {
                switch (type)
                {
                    case 1:   //vivo
                        FrameLayout.LayoutParams lpvivo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                        lpvivo.topMargin = dp2px(activity, 32);
                        lpvivo.leftMargin = 0;
                        lpvivo.rightMargin = 0;
                        viewGroup.setLayoutParams(lpvivo);
                        break;
                    case 2: //HUAWEI
                        int[] sizeAtHuawei = NotchPhoneUtil.getNotchSizeAtHuawei(activity);
                        FrameLayout.LayoutParams lphuawei = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                        lphuawei.topMargin = sizeAtHuawei[1];
                        lphuawei.leftMargin = 0;
                        lphuawei.rightMargin = 0;
                        viewGroup.setLayoutParams(lphuawei);
                        break;
                    case 3:  //OPPO  目前都为 80px
                        FrameLayout.LayoutParams lpOppo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                        lpOppo.topMargin = 80;
                        lpOppo.leftMargin = 0;
                        lpOppo.rightMargin = 0;
                        viewGroup.setLayoutParams(lpOppo);
                        break;
                    case 4:  //Xiaomi
                        int sizeAtXiaomi = NotchPhoneUtil.getStatusBarHeight(activity);
                        FrameLayout.LayoutParams lpXiaomi = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                        lpXiaomi.topMargin = sizeAtXiaomi;
                        lpXiaomi.leftMargin = 0;
                        lpXiaomi.rightMargin = 0;
                        viewGroup.setLayoutParams(lpXiaomi);
                        break;
                }
            }
        }
        else if (getDisplayRotation(activity) == 90)
        {
            leftAndRightChange(activity, isNotch, type, viewGroup);
        }
        else if (getDisplayRotation(activity) == 180)
        {
        }
        else if (getDisplayRotation(activity) == 270)
        {
            leftAndRightChange(activity, isNotch, type, viewGroup);
        }
    }
    /**
     * 左右横屏都是让 leftMargin  和rightMargin 空出一个刘海的距离
     *
     * @param activity
     * @param isNotch
     * @param type
     * @param viewGroup
     */
    private static void leftAndRightChange(Activity activity, Boolean isNotch, int type,
                                           ViewGroup viewGroup)
    {
        if (isNotch)
        {
            switch (type)
            {
                case 1:   //vivo
                    FrameLayout.LayoutParams lpvivo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                    lpvivo.leftMargin = dp2px(activity, 32);
                    lpvivo.rightMargin = dp2px(activity, 32);
                    lpvivo.topMargin = 0;
                    lpvivo.bottomMargin = 0;
                    viewGroup.setLayoutParams(lpvivo);
                    break;
                case 2: //HUAWEI
                    int[] sizeAtHuawei = NotchPhoneUtil.getNotchSizeAtHuawei(activity);
                    FrameLayout.LayoutParams lphuawei = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                    lphuawei.leftMargin = sizeAtHuawei[1];
                    lphuawei.rightMargin = sizeAtHuawei[1];
                    lphuawei.topMargin = 0;
                    lphuawei.bottomMargin = 0;
                    viewGroup.setLayoutParams(lphuawei);
                    break;
                case 3:  //OPPO  目前都为 80px
                    FrameLayout.LayoutParams lpOppo = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                    lpOppo.leftMargin = 80;
                    lpOppo.rightMargin = 80;
                    lpOppo.topMargin = 0;
                    lpOppo.bottomMargin = 0;
                    viewGroup.setLayoutParams(lpOppo);
                    break;
                case 4:  //Xiaomi
                    int sizeAtXiaomi = NotchPhoneUtil.getStatusBarHeight(activity);
                    FrameLayout.LayoutParams lpXiaomi = (FrameLayout.LayoutParams) viewGroup.getLayoutParams();
                    lpXiaomi.leftMargin = sizeAtXiaomi;
                    lpXiaomi.rightMargin = sizeAtXiaomi;
                    lpXiaomi.topMargin = 0;
                    lpXiaomi.bottomMargin = 0;
                    viewGroup.setLayoutParams(lpXiaomi);
                    break;
            }
        }
    }
    /**
     * 获取当前屏幕旋转角度
     *
     * @param activity
     * @return 0表示是竖屏; 90表示是左横屏; 180表示是反向竖屏; 270表示是右横屏
     */
    public static int getDisplayRotation(Activity activity)
    {
        if (activity == null)
        {
            return 0;
        }
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        switch (rotation)
        {
            case Surface.ROTATION_0:
                return 0;
            case Surface.ROTATION_90:
                return 90;
            case Surface.ROTATION_180:
                return 180;
            case Surface.ROTATION_270:
                return 270;
        }
        return 0;
    }
    /**
     * px转dp
     *
     * @param context
     * @param dipValue
     */
    public static int dp2px(Context context, float dipValue)
    {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }
    /**
     * 获取手机厂商
     *
     * @return 手机厂商   Xiaomi   HUAWEI   vivo
     */
    public static String getDeviceBrand()
    {
        return android.os.Build.BRAND;
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/StaticDefine.java
New file
@@ -0,0 +1,18 @@
package com.secondworld.univeralsdk;
/**
 * Created by Administrator on 2018/6/14 0014.
 */
public class StaticDefine {
    public static final String UnityGameObjectName = "SDKUtility";
    public static final String UnityHandleFuncName = "HandleSdkMessage";
    public static final String LS_KEY_VERSION = "H2Engine_App_Version";
    public static final String LS_KEY_COPIED = "H2Engine_Copy_Finished";
    public final static String LS_KEY_IMEI = "H2Engine_DEVICE_IMEI";
    public final static String LS_KEY_MAC = "H2Engine_DEVICE_MAC";
    public final static String LS_KEY_ANDROID_ID = "H2Engine_DEVICE_ANDROID_ID";
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/UniqueID.java
New file
@@ -0,0 +1,226 @@
package com.secondworld.univeralsdk;
import android.Manifest;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.support.v4.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.MessageDigest;
import java.util.UUID;
/**
 * Created by Administrator on 2018/7/12 0012.
 */
public class UniqueID
{
    public static String get(Context context)
    {
        String _id = read(context);
        if (_id != null && !_id.equals(""))
        {
            return _id;
        }
        StringBuffer _buffer = new StringBuffer();
        _id = getDeviceId(context);
        _buffer.append(_id);
        _id = getLocalMac(context).replace(":", "");
        _buffer.append(_id);
        if (_buffer == null || _buffer.length() <= 0)
        {
            UUID _uuid = UUID.randomUUID();
            _id = _uuid.toString().replace("-", "");
            _buffer.append(_id);
        }
        _id = getMD5(_buffer.toString(), false);
        if (_id.length() > 0)
        {
            save(_id, context);
        }
        return _id;
    }
    private static String read(Context context)
    {
        File _file = new File(context.getExternalFilesDir(""), "/tsw_device_unique_id.txt");
        if (!_file.exists())
        {
            return null;
        }
        StringBuffer _buffer = new StringBuffer();
        try
        {
            FileInputStream _fis = new FileInputStream(_file);
            InputStreamReader _isr = new InputStreamReader(_fis, "UTF-8");
            Reader _in = new BufferedReader(_isr);
            int _index;
            while ((_index = _in.read()) > -1)
            {
                _buffer.append((char) _index);
            }
            _in.close();
            return _buffer.toString();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }
    private static void save(String id, Context context)
    {
        File _file = new File(context.getExternalFilesDir(""), "/tsw_device_unique_id.txt");
        try
        {
            Log.i("UniqueIDUtil", "path: " + _file.getAbsolutePath());
            FileOutputStream _fos = new FileOutputStream(_file);
            Writer _writer = new OutputStreamWriter(_fos, "UTF-8");
            _writer.write(id);
            _writer.close();
            _fos.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    public static String getAndroidID(Context context)
    {
        return Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
    }
    public static String getDeviceId(Context context)
    {
        SharedPreferences _sp = context.getSharedPreferences(context.getPackageName(),
                                                             Context.MODE_PRIVATE);
        String _deviceId = _sp.getString(StaticDefine.LS_KEY_IMEI, "");
        if (!_deviceId.equals(""))
        {
            return _deviceId;
        }
        TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        if (ContextCompat.checkSelfPermission(context,
                                              Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)
        {
            _deviceId = tm.getDeviceId();
            SharedPreferences.Editor _e = _sp.edit();
            _e.putString(StaticDefine.LS_KEY_IMEI, _deviceId);
            _e.apply();
            return _deviceId;
        }
        return "";
    }
    public static String getLocalMac(Context context)
    {
        SharedPreferences _sp = context.getSharedPreferences(context.getPackageName(),
                                                             Context.MODE_PRIVATE);
        String _macAddress = _sp.getString(StaticDefine.LS_KEY_MAC, "");
        if (!_macAddress.equals(""))
        {
            return _macAddress;
        }
        StringBuffer _buffer = new StringBuffer();
        NetworkInterface _networkInterface;
        try
        {
            _networkInterface = NetworkInterface.getByName("eth1");
            if (_networkInterface == null)
            {
                _networkInterface = NetworkInterface.getByName("wlan0");
            }
            if (_networkInterface == null)
            {
                return "";
            }
            byte[] _addresses = _networkInterface.getHardwareAddress();
            for (byte b : _addresses)
            {
                _buffer.append(String.format("%02X:", b));
            }
            if (_buffer.length() > 0)
            {
                _buffer.deleteCharAt(_buffer.length() - 1);
            }
            _macAddress = _buffer.toString();
            SharedPreferences.Editor _e = _sp.edit();
            _e.putString(StaticDefine.LS_KEY_MAC, _macAddress);
            _e.apply();
        } catch (SocketException e)
        {
            e.printStackTrace();
            return "";
        }
        return _macAddress;
    }
    public static String getMD5(String message, boolean upperCase)
    {
        String md5str = "";
        try
        {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] input = message.getBytes();
            byte[] buff = md.digest(input);
            md5str = bytesToHex(buff, upperCase);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return md5str;
    }
    private static String bytesToHex(byte[] bytes, boolean upperCase)
    {
        StringBuffer md5str = new StringBuffer();
        int digital;
        for (int i = 0; i < bytes.length; i++)
        {
            digital = bytes[i];
            if (digital < 0)
            {
                digital += 256;
            }
            if (digital < 16)
            {
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        if (upperCase)
        {
            return md5str.toString().toUpperCase();
        }
        return md5str.toString().toLowerCase();
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/UniversalUtil.java
New file
@@ -0,0 +1,401 @@
package com.secondworld.univeralsdk;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Process;
import android.provider.Settings;
import android.support.v4.content.PermissionChecker;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Map;
/**
 * Created by Administrator on 2018/6/15 0015.
 */
public class UniversalUtil
{
    private final static String TAG = "UniversalUtil";
    /**
     * 获得应用的版本号
     */
    public static String GetVersionName(Context context)
    {
        PackageManager _packageManager = context.getPackageManager();
        PackageInfo _packageInfo = null;
        try
        {
            _packageInfo = _packageManager.getPackageInfo(context.getPackageName(), 0);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        if (_packageInfo != null)
        {
            return _packageInfo.versionName;
        }
        return null;
    }
    public static void sendMessageToUnity(Map<String, Object> jsonMap)
    {
        if (jsonMap == null || jsonMap.isEmpty())
        {
            return;
        }
        JSONObject _jsonObject = new JSONObject(jsonMap);
        UnityPlayer.UnitySendMessage(StaticDefine.UnityGameObjectName,
                                     StaticDefine.UnityHandleFuncName,
                                     _jsonObject.toString());
    }
    public static void InstallAPK(Context context, final String path)
    {
        File _file = new File(path);
        if (_file == null)
        {
            Toast.makeText(context, "给定的地址[" + path + "]找不到要安装的应用文件", Toast.LENGTH_SHORT).show();
            return;
        }
        try
        {
            Intent _intent = new Intent(Intent.ACTION_VIEW);
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
//            {
//                _intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//                Uri _contentUri = FileProvider.getUriForFile(context,
//                                                             context.getPackageName() + ".fileProvider",
//                                                             _file);
//                _intent.setDataAndType(_contentUri, "application/vnd.android.package-archive");
//            }
//            else
//            {
            _intent.setDataAndType(Uri.fromFile(_file),
                                   "application/vnd.android.package-archive");
            _intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            }
            context.startActivity(_intent);
        } catch (Exception e)
        {
            e.printStackTrace();
            Toast.makeText(context, "找不到打开此类型文件的程序", Toast.LENGTH_SHORT).show();
        }
    }
    public static void CopyTextToClipboard(final Activity activity, final String text)
    {
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                ClipboardManager _mgr = (ClipboardManager) activity.getSystemService(
                        Context.CLIPBOARD_SERVICE);
                ClipData _data = ClipData.newPlainText("playerId", text);
                _mgr.setPrimaryClip(_data);
            }
        });
    }
    public static long getMemTotal()
    {
        try
        {
            FileReader fileReader = new FileReader("/proc/meminfo");
            BufferedReader bufferedReader = new BufferedReader(fileReader, 4 * 1024);
            String str;
            while ((str = bufferedReader.readLine()) != null)
            {
                if (str.contains("MemTotal"))
                {
                    break;
                }
            }
            bufferedReader.close();
            fileReader.close();
            String[] array = str.split("\\s+");
            // 获得系统总内存,单位是KB
            return Integer.valueOf(array[1]).intValue();
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return 0;
    }
    public static String getPublicIp(boolean useHttps)
    {
        String _ip;
        try
        {
            URL ipify = useHttps ? new URL("https://api.ipify.org") : new URL(
                    "http://api.ipify.org");
            URLConnection conn = ipify.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            _ip = in.readLine();
            in.close();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return "";
    }
    public static String getIP(Context context)
    {
        NetworkInfo info = ((ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
        if (info != null && info.isConnected())
        {
            if (info.getType() == ConnectivityManager.TYPE_MOBILE)
            {//当前使用2G/3G/4G网络
                try
                {
                    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); )
                    {
                        NetworkInterface intf = en.nextElement();
                        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); )
                        {
                            InetAddress inetAddress = enumIpAddr.nextElement();
                            if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address)
                            {
                                return inetAddress.getHostAddress();
                            }
                        }
                    }
                } catch (SocketException e)
                {
                    e.printStackTrace();
                }
            }
            else if (info.getType() == ConnectivityManager.TYPE_WIFI)
            {//当前使用无线网络
                WifiManager wifiManager = (WifiManager) context.getSystemService(
                        Context.WIFI_SERVICE);
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                return intIP2StringIP(wifiInfo.getIpAddress());
            }
        }
        else
        {
            //当前无网络连接,请在设置中打开网络
        }
        return null;
    }
    private static String intIP2StringIP(int ip)
    {
        return (ip & 0xFF) + "." +
                ((ip >> 8) & 0xFF) + "." +
                ((ip >> 16) & 0xFF) + "." +
                (ip >> 24 & 0xFF);
    }
    public static boolean hasRWP = false;
    public static boolean hasGoToSetting = false;
    public static void CheckWriteAndReadExternalStorage(final Activity activity)
    {
        //Log.i("MainActivity", "CheckWriteAndReadExternalStorage 开始 hasGoToSetting: " + hasGoToSetting);
        if (hasRWP && !hasGoToSetting)
        {
            //Log.i("MainActivity", "1111 有权限");
            return;
        }
        if (PermissionChecker.checkPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                              Process.myPid(), Process.myUid(),
                                              activity.getPackageName()) == PackageManager.PERMISSION_GRANTED)
        {
            //Log.i("MainActivity", "有权限");
            hasRWP = true;
            if (hasGoToSetting)
            {
                //Log.i("MainActivity", "去过设置界面, 这里重启");
                activity.runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        new Thread()
                        {
                            public void run()
                            {
                                String _packageName = activity.getPackageName();
                                Intent _launch = activity.getBaseContext().getPackageManager().getLaunchIntentForPackage(
                                        _packageName);
                                _launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                activity.startActivity(_launch);
                                Process.killProcess(Process.myPid());
                            }
                        }.start();
                        activity.finish();
                    }
                });
            }
            return;
        }
        if (!hasRWP)
        {
            new AlertDialog.Builder(activity)
                    .setMessage("应用没有存储读取权限,点击确定至设置中开启,否则无法继续游戏.")
                    .setCancelable(false)
                    .setPositiveButton("确定",
                                       new DialogInterface.OnClickListener()
                                       {
                                           @Override
                                           public void onClick(DialogInterface dialogInterface,
                                                               int i)
                                           {
                                               UniversalUtil.hasGoToSetting = true;
                                               Intent intent = new Intent(
                                                       Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                               Uri uri = Uri.fromParts("package",
                                                                       activity.getPackageName(),
                                                                       null);
                                               intent.setData(uri);
                                               activity.startActivity(intent);
                                           }
                                       })
                    .setNegativeButton("拒绝",
                                       new DialogInterface.OnClickListener()
                                       {
                                           @Override
                                           public void onClick(DialogInterface dialogInterface,
                                                               int i)
                                           {
                                               activity.finish();
                                           }
                                       })
                    .show();
        }
    }
    public static boolean checkPermission22(Activity activity, String permission)
    {
        PackageManager _pkgMgr = activity.getPackageManager();
        LogUtil.i(TAG, "开始检测权限: " + permission);
        try
        {
            PermissionInfo _info = _pkgMgr.getPermissionInfo(permission,
                                                             PackageManager.GET_META_DATA);
            LogUtil.i(TAG, "  |-- 保护级别: " + _info.protectionLevel);
            if (_info.protectionLevel != PermissionInfo.PROTECTION_DANGEROUS && _info.protectionLevel != 4097)
            {
                LogUtil.i(TAG, "  |-- 不是危险权限.");
                return false;
            }
        } catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }
        int _result = PermissionChecker.checkPermission(activity, permission,
                                                        Process.myPid(), Process.myUid(),
                                                        activity.getPackageName());
        LogUtil.i(TAG, "  |-- 获取类型: " + _result);
        if (_result == PackageManager.PERMISSION_GRANTED)
        {
            LogUtil.i(TAG, permission + " 有这个权限.");
            return false;
        }
        return true;
    }
    public static String getMetaString(Activity activity, String key)
    {
        PackageManager _pkgMgr = activity.getPackageManager();
        ApplicationInfo _appInfo;
        try
        {
            _appInfo = _pkgMgr.getApplicationInfo(activity.getPackageName(),
                                                  PackageManager.GET_META_DATA);
            return _appInfo.metaData.getString(key);
        } catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }
        return null;
    }
    public static int getMetaInt(Activity activity, String key)
    {
        LogUtil.i(TAG, "将要获取的MetaKey: " + key);
        PackageManager _pkgMgr = activity.getPackageManager();
        ApplicationInfo _appInfo;
        try
        {
            _appInfo = _pkgMgr.getApplicationInfo(activity.getPackageName(),
                                                  PackageManager.GET_META_DATA);
            return _appInfo.metaData.getInt(key);
        } catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }
        return -1;
    }
    public static boolean isEmpty(String s) {
        if (null == s)
            return true;
        if (s.length() == 0)
            return true;
        if (s.trim().length() == 0)
            return true;
        return false;
    }
}
Project/yj_sdk/src/main/java/com/secondworld/univeralsdk/WebViewUtil.java
New file
@@ -0,0 +1,185 @@
package com.secondworld.univeralsdk;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.RelativeLayout;
/**
 * Created by Administrator on 2018/8/1 0001.
 */
public class WebViewUtil
{
    private static Activity m_Activity;
    private static String m_ReceivedUrl;
    private static WebView m_WebView;
    private static Button m_BtnClose;
    public static void OpenWebView(final Activity activity, final String url)
    {
        m_Activity = activity;
        m_ReceivedUrl = url;
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                if (m_WebView != null && m_WebView.getVisibility() == View.VISIBLE)
                {
                    processClose();
                    return;
                }
                DisplayMetrics _dm = new DisplayMetrics();
                m_Activity.getWindowManager().getDefaultDisplay().getMetrics(_dm);
                final float _scale = _dm.widthPixels * 1f / 1344;
                final int _width = (int) (_scale * 982);
                final int _height = (int) (_scale * 560);
                m_BtnClose = (Button) m_Activity.findViewById(R.id.webView_btn_close);
                ViewGroup.MarginLayoutParams _margin = new ViewGroup.MarginLayoutParams(
                        m_BtnClose.getLayoutParams());
                RelativeLayout.LayoutParams _params = new RelativeLayout.LayoutParams(_margin);
                _params.width = 0;
                _params.height = 0;
                _params.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.webView);
                _params.addRule(RelativeLayout.ALIGN_RIGHT, R.id.webView);
                m_BtnClose.setLayoutParams(_params);
                m_BtnClose.setOnClickListener(new View.OnClickListener()
                {
                    @Override
                    public void onClick(View view)
                    {
                        processClose();
                    }
                });
                m_WebView = (WebView) m_Activity.findViewById(R.id.webView);
                ViewGroup.MarginLayoutParams margin = new ViewGroup.MarginLayoutParams(
                        m_WebView.getLayoutParams());
                RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(margin);
                layoutParams.width = 0;
                layoutParams.height = 0;
                layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
                m_WebView.setLayoutParams(layoutParams);
                m_WebView.getSettings().setJavaScriptEnabled(true);
                m_WebView.setWebViewClient(new WebViewClient()
                {
                    @Override
                    public void onReceivedError(WebView view, int errorCode, String description,
                                                String failingUrl)
                    {
                        super.onReceivedError(view, errorCode, description, failingUrl);
                        view.loadUrl(m_ReceivedUrl);
                    }
                    @Override
                    public boolean shouldOverrideUrlLoading(WebView view, String url)
                    {
                        if (url.startsWith("http") || url.startsWith("https"))
                        { //http和https协议开头的执行正常的流程
                            view.loadUrl(url);
                            return true;
                        }
                        else
                        {  //其他的URL则会开启一个Acitity然后去调用原生APP
                            return super.shouldOverrideUrlLoading(view, url);
                        }
                    }
                    @Override
                    public WebResourceResponse shouldInterceptRequest(WebView view, String url)
                    {
                        if (url.startsWith("http") || url.startsWith("https"))
                        { //http和https协议开头的执行正常的流程
                            return super.shouldInterceptRequest(view, url);
                        }
                        else
                        {  //其他的URL则会开启一个Acitity然后去调用原生APP
                            try
                            {
                                Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                                m_Activity.startActivity(in);
                            } catch (ActivityNotFoundException e)
                            {
                                e.printStackTrace();
                            }
                            return null;
                        }
                    }
                });
                m_WebView.setWebChromeClient(new WebChromeClient()
                {
                    @Override
                    public void onReceivedTitle(WebView view, String title)
                    {
                        if (title.contains("I'm QQ"))
                        {
                            m_WebView.loadUrl(m_ReceivedUrl);
                        }
                        super.onReceivedTitle(view, title);
                    }
                    @Override
                    public void onProgressChanged(WebView view, int newProgress)
                    {
                        if (newProgress == 100)
                        {
                            if (view.getUrl().contains("noticeweb"))
                            {
                                ViewGroup.MarginLayoutParams margin = new ViewGroup.MarginLayoutParams(
                                        m_WebView.getLayoutParams());
                                RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
                                        margin);
                                layoutParams.width = _width;
                                layoutParams.height = _height;
                                layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT,
                                                     RelativeLayout.TRUE);
                                m_WebView.setLayoutParams(layoutParams);
                                ViewGroup.MarginLayoutParams _margin = new ViewGroup.MarginLayoutParams(
                                        m_BtnClose.getLayoutParams());
                                RelativeLayout.LayoutParams _params = new RelativeLayout.LayoutParams(
                                        _margin);
                                _params.width = (int) (180 * _scale);
                                _params.height = (int) (72 * _scale);
                                _params.rightMargin = (int) (250 * _scale);
                                _params.bottomMargin = (int) (10 * _scale);
                                _params.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.webView);
                                _params.addRule(RelativeLayout.ALIGN_RIGHT, R.id.webView);
                                m_BtnClose.setLayoutParams(_params);
                            }
                        }
                    }
                });
                m_WebView.loadUrl(m_ReceivedUrl);
                m_WebView.setVisibility(View.VISIBLE);
                m_BtnClose.setVisibility(View.VISIBLE);
            }
        });
    }
    private static void processClose()
    {
        m_WebView.clearFocus();
        m_WebView.clearCache(true);
        m_WebView.clearHistory();
        m_WebView.clearFormData();
        m_WebView.setVisibility(View.INVISIBLE);
        m_BtnClose.setVisibility(View.INVISIBLE);
    }
}
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_ic_richpush_actionbar_back.png
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_ic_richpush_actionbar_divider.png
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_richpush_btn_selector.xml
New file
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- 获得焦点但未按下时的背景图片 -->
    <item
        android:state_focused="true"
        android:state_enabled="true"
        android:state_pressed="false"
        android:drawable="@drawable/jpush_ic_richpush_actionbar_back" />
     <!-- 按下时的背景图片 -->
    <item
        android:state_enabled="true"
        android:state_pressed="true"
        android:drawable="@android:color/darker_gray" />
    <!-- 按下时的背景图片 -->
    <item
        android:state_enabled="true"
        android:state_checked="true"
        android:drawable="@android:color/darker_gray" />
    <!-- 默认时的背景图片 -->
    <item android:drawable="@drawable/jpush_ic_richpush_actionbar_back" />
</selector>
Project/yj_sdk/src/main/res/drawable-hdpi/jpush_richpush_progressbar.xml
New file
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- 背景  gradient是渐变,corners定义的是圆角 -->
    <item android:id="@android:id/background">
        <shape>
            <solid android:color="#ffffff" />
        </shape>
    </item>
    <!-- 进度条 -->
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <solid android:color="#4393ea" />
            </shape>
        </clip>
    </item>
</layer-list>
Project/yj_sdk/src/main/res/drawable/app_icon.png
Project/yj_sdk/src/main/res/drawable/web_btn_close_icon.png
Project/yj_sdk/src/main/res/layout/activity_main.xml
New file
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:id="@+id/unity_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <WebView
        android:id="@+id/webView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:visibility="invisible" />
    <Button
        android:id="@+id/webView_btn_close"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/webView"
        android:layout_alignRight="@id/webView"
        android:background="@drawable/web_btn_close_icon"
        android:text="我知道了"
        android:textSize="16dp"
        android:visibility="invisible" />
</RelativeLayout>
Project/yj_sdk/src/main/res/layout/jpush_popwin_layout.xml
New file
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/popLayoutId"
    style="@style/MyDialogStyle"
    android:orientation="vertical"
    android:layout_width="280dp"
    android:layout_height="250dp" >
        <WebView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/wvPopwin"/>
</LinearLayout>
Project/yj_sdk/src/main/res/layout/jpush_webview_layout.xml
New file
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<cn.jpush.android.ui.FullScreenView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/actionbarLayoutId"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <RelativeLayout
        android:id="@+id/rlRichpushTitleBar"
        android:layout_width="match_parent"
        android:layout_height="40.0dp"
        android:background="#29313a">
        <ImageButton
            android:id="@+id/imgRichpushBtnBack"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="9dp"
            android:layout_marginRight="10dp"
            android:background="@drawable/jpush_richpush_btn_selector" />
        <ImageView
            android:id="@+id/imgView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@id/imgRichpushBtnBack"
            android:clickable="false"
            android:src="@drawable/jpush_ic_richpush_actionbar_divider" />
        <TextView
            android:id="@+id/tvRichpushTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="7dp"
            android:layout_marginRight="5dp"
            android:layout_toRightOf="@id/imgView"
            android:clickable="false"
            android:text=" "
            android:textSize="20sp"
            android:textColor="#ffffff" />
    </RelativeLayout>
    <ProgressBar
        android:id="@+id/pushPrograssBar"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:progress="0"
        android:progressDrawable="@drawable/jpush_richpush_progressbar"
        style="?android:attr/progressBarStyleHorizontal" />
    <WebView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/fullWebView"
        android:background="#000000" />
</cn.jpush.android.ui.FullScreenView>
Project/yj_sdk/src/main/res/values/colors.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>
Project/yj_sdk/src/main/res/values/jpush_style.xml
New file
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="MyDialogStyle">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:backgroundDimEnabled">true</item>
    </style>
</resources>
Project/yj_sdk/src/main/res/values/strings.xml
New file
@@ -0,0 +1,4 @@
<resources>
    <string name="app_name">UniveralSDK</string>
    <string name="sf_class_name">com.secondworld.univeralsdk.MainActivity</string>
</resources>
Project/yj_sdk/src/main/res/values/styles.xml
New file
@@ -0,0 +1,8 @@
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>
</resources>
Project/yj_sdk/src/main/res/xml/file_paths.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/com.shandangceshi.snxxz/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>