New file |
| | |
| | | <?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> |
New file |
| | |
| | | // 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** |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | include ':app', ':mr_sdk', ':sp_sdk', ':js_sdk' |
| | | include ':app', ':mr_sdk', ':sp_sdk', ':js_sdk', ':yj_sdk' |
New file |
| | |
| | | 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\\" |
| | | } |
New file |
| | |
| | | # 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.**{*;} |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
New file |
| | |
| | | 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()); |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | // } |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | 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(); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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"; |
| | | |
| | | } |
New file |
| | |
| | | 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(); |
| | | } |
| | | } |
New file |
| | |
| | | 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; |
| | | } |
| | | } |
New file |
| | |
| | | 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); |
| | | } |
| | | } |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <resources> |
| | | <color name="colorPrimary">#3F51B5</color> |
| | | <color name="colorPrimaryDark">#303F9F</color> |
| | | <color name="colorAccent">#FF4081</color> |
| | | </resources> |
New file |
| | |
| | | <?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> |
New file |
| | |
| | | <resources> |
| | | <string name="app_name">UniveralSDK</string> |
| | | <string name="sf_class_name">com.secondworld.univeralsdk.MainActivity</string> |
| | | </resources> |
New file |
| | |
| | | <resources> |
| | | |
| | | <!-- Base application theme. --> |
| | | <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> |
| | | <!-- Customize your theme here. --> |
| | | </style> |
| | | |
| | | </resources> |
New file |
| | |
| | | <?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> |