Compare commits
294 Commits
v4.2.0-200
...
video_only
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a826234d0 | |||
| 9f5ffb084a | |||
| b5d4cbe718 | |||
| b39a47c0bd | |||
| 5ea6647bf7 | |||
| 6fcd8397b6 | |||
| 3478aaba2f | |||
| 1f0b9a95e2 | |||
| 5cdc1635ca | |||
| 3db784509b | |||
| e8f63ea99f | |||
| 97ac4b03a3 | |||
| 883a948b7b | |||
| ebb279c42f | |||
| 261e0cc45a | |||
| 0357a0a71e | |||
| d87de59427 | |||
| d5ee01a2e1 | |||
| 3563637919 | |||
| d881e08aee | |||
| f5ff838d2f | |||
| 52c1b08e59 | |||
| 652972f49d | |||
| 0d122cf8ba | |||
| 2b115c4058 | |||
| cfca7db4ef | |||
| 5f66c029fb | |||
| 8635652fe2 | |||
| a890ad532c | |||
| 65c9d2be2a | |||
| 9620e26f6a | |||
| e4ca1d8406 | |||
| 74ebaa592b | |||
| f9b689efdb | |||
| ed458f08ad | |||
| 9822646acc | |||
| 4259078420 | |||
| 3b9db4e964 | |||
| b7e6cd08fd | |||
| bba1e6f10c | |||
| 3fe2973968 | |||
| b16d33d9fa | |||
| e1a7ed9049 | |||
| 11354030e8 | |||
| ee109060fc | |||
| eebc0c1096 | |||
| 4ec45e2a27 | |||
| 12143f7f95 | |||
| 7025dc45bd | |||
| 772e7861e2 | |||
| ff71c9a3e8 | |||
| b7001cc996 | |||
| 83658e47f8 | |||
| 0699d3ccc4 | |||
| f80b998e98 | |||
| 91e84be708 | |||
| f589c286c6 | |||
| 379650a0f5 | |||
| 3796eb46bd | |||
| c240048c5e | |||
| 2f81c9240d | |||
| da0dc3df97 | |||
| d73c0f2044 | |||
| a6f9e12082 | |||
| 20f8ba0de5 | |||
| f7342a944e | |||
| 1086574b33 | |||
| 59e30d432d | |||
| 58631d540c | |||
| 08763aeb2d | |||
| 039d0ca06c | |||
| f39574c8b3 | |||
| 6067a52fb1 | |||
| a1298547d1 | |||
| 49d5514a25 | |||
| 09c414a02c | |||
| 6a6378f635 | |||
| 920050efc8 | |||
| 103ecc10d3 | |||
| f90e9a8085 | |||
| caa37ead4b | |||
| d18eeaf346 | |||
| b98d287843 | |||
| 66fb57f708 | |||
| 3911c10827 | |||
| c29972df50 | |||
| 8001ce2603 | |||
| b1079e84d8 | |||
| c6cf8aab1c | |||
| 4d7718e3af | |||
| 9cdbcd4935 | |||
| d396ebda44 | |||
| 6ab8bdc422 | |||
| 15352bb379 | |||
| b68536b561 | |||
| 762ee8d300 | |||
| 8dfda56586 | |||
| 93126517b6 | |||
| 04a8f5772c | |||
| 9687ddcd54 | |||
| 04c49cbad7 | |||
| 6addea7d73 | |||
| 229eaa0859 | |||
| 3876096f52 | |||
| bad3ab19c6 | |||
| b2100fe0e5 | |||
| 5998bb9d4a | |||
| fefe29a0b8 | |||
| a16554da21 | |||
| 6efc1e06bb | |||
| e51439d584 | |||
| 907bad48bc | |||
| 582df7da58 | |||
| 28f18a558c | |||
| 658fb8579c | |||
| 45632052e5 | |||
| 311211747a | |||
| 010995b16d | |||
| c82e981f4e | |||
| f9803fa244 | |||
| f21d86c8a7 | |||
| 8db525542e | |||
| 49cf093a44 | |||
| f2302ffc50 | |||
| f85685fd52 | |||
| a80419e4bd | |||
| 0e7b6bb097 | |||
| b795df2de8 | |||
| e99e8328ab | |||
| 500c77d6ed | |||
| 3c13431bd3 | |||
| d5e426a7f0 | |||
| 8a37e0bdf4 | |||
| 230eec78c1 | |||
| 8bb74461e6 | |||
| b0d0d3ca45 | |||
| 356c9432ec | |||
| 31e14fd47b | |||
| c0644dc705 | |||
| 1a43589bb1 | |||
| defd6d9a14 | |||
| 77b4e8f73d | |||
| 61ef40f9b5 | |||
| 13dd5c9892 | |||
| d20aef7107 | |||
| 8c9cd6e0ec | |||
| 487c2fd0a5 | |||
| 0ffdef080b | |||
| ba76dbbd15 | |||
| 7cfe82af47 | |||
| 567977089a | |||
| a258fe1d20 | |||
| 28cf1ab114 | |||
| 0e49c074ec | |||
| 85249f1d94 | |||
| 38bda5ec02 | |||
| 0cc24956e0 | |||
| c17bcd9765 | |||
| 9f1642f577 | |||
| 9c01f75e8b | |||
| a460722ae5 | |||
| 37330c2ab2 | |||
| 5db25f966e | |||
| 4749c743e9 | |||
| f5b614cc63 | |||
| 34b8b00cb2 | |||
| 6af86d871c | |||
| 0b7fade38b | |||
| 3237834f9a | |||
| 53e9554f08 | |||
| 70ee3001c2 | |||
| d7ae2b2aa4 | |||
| 9c9dbfb105 | |||
| c633c228db | |||
| ad82005881 | |||
| 815a0d0600 | |||
| e02f9db81d | |||
| c422b96da4 | |||
| 40a64996d7 | |||
| cbfca66d51 | |||
| f4a110c94d | |||
| f601fd2339 | |||
| e3217eaf22 | |||
| 540515ab41 | |||
| e1c02a6138 | |||
| a508576785 | |||
| 84e57d5c91 | |||
| 62b1005dbf | |||
| 04a5450a41 | |||
| 2ac4dd6c5a | |||
| 441a569f30 | |||
| f319201e74 | |||
| 47b2fa60d8 | |||
| 4d15c15b2d | |||
| 3702094d98 | |||
| 6185ca595d | |||
| 358b93029b | |||
| 38044b1d2b | |||
| 90877738b3 | |||
| 477613d21f | |||
| a77ee0fa70 | |||
| 036fa444c6 | |||
| d83e1e413f | |||
| 19986099ff | |||
| f23dd6a662 | |||
| 951d306765 | |||
| 8adfaa88a3 | |||
| fcb76e71e5 | |||
| 2da536f667 | |||
| 2034b1c587 | |||
| ea2e169199 | |||
| 2cf6c2747c | |||
| dd24b6243a | |||
| 81fc6aa6cb | |||
| 8e3bcf6b5b | |||
| 8e181c9846 | |||
| 7a737da328 | |||
| 5545c112b7 | |||
| a6f187d444 | |||
| 3ad72ee1f8 | |||
| 2cc100b887 | |||
| 761c5dc0bf | |||
| 80d3f140f4 | |||
| b72621ee2b | |||
| 7896f3ee46 | |||
| d33c15e47b | |||
| ddcd3f8169 | |||
| 42f66cd543 | |||
| c0efd4a8e4 | |||
| a4df780a8b | |||
| e8ac144454 | |||
| d543181b92 | |||
| 02cfb7515b | |||
| 4b71e44c51 | |||
| 68f7e1fa58 | |||
| 2f66588455 | |||
| f39cf38313 | |||
| 1141604d20 | |||
| 6b575f0169 | |||
| 6428179c54 | |||
| 44445e6e34 | |||
| fb48316069 | |||
| ea5312d606 | |||
| 5cb6f9e296 | |||
| fdb1d255ba | |||
| 153b19c966 | |||
| ba79d009e6 | |||
| 47f9c967b1 | |||
| 97ab6108cf | |||
| 8e9da6e1f5 | |||
| aca29abde6 | |||
| dac3f7e2d7 | |||
| 9f9254a835 | |||
| 58e3ef83e0 | |||
| 76bb5d1052 | |||
| afff3446c4 | |||
| 2fa6e9c549 | |||
| cb4bcedba7 | |||
| 5dbe10a8a8 | |||
| 13ca69c569 | |||
| 19e18226bd | |||
| 6b51a198c2 | |||
| 5ad38457af | |||
| ee3043875a | |||
| 92c8a698f3 | |||
| 41f78c365b | |||
| 4b8053beee | |||
| 8008266389 | |||
| 1ce04241f6 | |||
| a37701f148 | |||
| add1339f4a | |||
| f29b8da6d0 | |||
| de968a4820 | |||
| 859a2a5672 | |||
| ddddda10a5 | |||
| 30d6dabe4f | |||
| 7655cc25be | |||
| 52824e5baa | |||
| 014c80cd18 | |||
| a7a48ccf77 | |||
| 99eddec84a | |||
| 6b382ab080 | |||
| d492cfdace | |||
| 256f0af0e9 | |||
| e9583284d0 | |||
| b670a9c1c4 | |||
| 33d86a7995 | |||
| 80ce5052d9 | |||
| ec805653bb | |||
| 798c4a2089 | |||
| 0686f70df6 | |||
| 3c30564ab6 | |||
| f04070e846 | |||
| fc279839fa |
@ -6,7 +6,7 @@ apply plugin: 'kotlin-kapt'
|
||||
// apkChannelPackage
|
||||
apply plugin: 'channel'
|
||||
|
||||
apply from: 'tinker-support.gradle'
|
||||
//apply from: 'tinker-support.gradle'
|
||||
|
||||
android {
|
||||
|
||||
@ -45,6 +45,9 @@ android {
|
||||
abiFilters "armeabi-v7a"
|
||||
}
|
||||
|
||||
renderscriptTargetApi 18
|
||||
renderscriptSupportModeEnabled true
|
||||
|
||||
// 由于app只针对中文用户,所以仅保留zh资源,其他删掉
|
||||
resConfigs "zh"
|
||||
|
||||
@ -189,6 +192,7 @@ dependencies {
|
||||
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stetho}"
|
||||
debugImplementation "com.squareup.okhttp3:logging-interceptor:${okHttp}"
|
||||
debugImplementation "com.gu.android:toolargetool:${toolargetool}"
|
||||
debugImplementation "com.github.nichbar:WhatTheStack:$whatTheStack"
|
||||
|
||||
implementation "androidx.core:core:${core}"
|
||||
implementation "androidx.fragment:fragment:${fragment}"
|
||||
@ -245,7 +249,7 @@ dependencies {
|
||||
implementation "com.sina.weibo.sdk:core:${weiboSDK}"
|
||||
|
||||
// bugly with tinker support
|
||||
implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
|
||||
// implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
|
||||
|
||||
implementation "com.google.android:flexbox:${flexbox}"
|
||||
|
||||
@ -285,9 +289,9 @@ dependencies {
|
||||
|
||||
debugImplementation "com.github.nichbar.chucker:library:$chucker"
|
||||
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
|
||||
implementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
|
||||
implementation "com.bytedance.ies.ugc.aweme:opensdk-china-external:$bytedanceAweme"
|
||||
implementation "com.bytedance.ies.ugc.aweme:opensdk-common:$bytedanceAweme"
|
||||
// implementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
|
||||
// implementation "com.bytedance.ies.ugc.aweme:opensdk-china-external:$bytedanceAweme"
|
||||
// implementation "com.bytedance.ies.ugc.aweme:opensdk-common:$bytedanceAweme"
|
||||
|
||||
implementation "com.aliyun.dpa:oss-android-sdk:${oss}"
|
||||
|
||||
@ -303,12 +307,12 @@ dependencies {
|
||||
implementation "com.github.PhilJay:MPAndroidChart:${chart}"
|
||||
|
||||
implementation project(':libraries:LGLibrary')
|
||||
implementation project(':libraries:MTA')
|
||||
// implementation project(':libraries:MTA')
|
||||
implementation project(':libraries:QQShare')
|
||||
implementation project(':libraries:TalkingData')
|
||||
implementation project(':libraries:UmengPush')
|
||||
// implementation project(':libraries:TalkingData')
|
||||
// implementation project(':libraries:UmengPush')
|
||||
// implementation project(':libraries:WechatShare')
|
||||
implementation project(':libraries:im')
|
||||
// implementation project(':libraries:im')
|
||||
implementation project(':libraries:Matisse')
|
||||
}
|
||||
File propFile = file('sign.properties')
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/libs/gid-1.3.jar
Normal file
BIN
app/libs/gid-1.3.jar
Normal file
Binary file not shown.
@ -254,4 +254,8 @@
|
||||
-keep class com.taobao.wireless.security.**{*;}
|
||||
-keep class com.ut.secbody.**{*;}
|
||||
-keep class com.taobao.dp.**{*;}
|
||||
-keep class com.alibaba.wireless.security.**{*;}
|
||||
-keep class com.alibaba.wireless.security.**{*;}
|
||||
|
||||
-keep class com.alibaba.sdk.android.**{*;}
|
||||
-keep class com.ut.**{*;}
|
||||
-keep class com.ta.**{*;}
|
||||
@ -27,6 +27,8 @@
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<!-- 修改系统设置的权限 -->
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<!-- 创建快捷方式的权限 -->
|
||||
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
@ -36,8 +38,6 @@
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<!--可选,穿山甲提供“获取地理位置权限”和“不给予地理位置权限,开发者传入地理位置参数”两种方式上报用户位置,两种方式均可不选,添加位置权限或参数将帮助投放定位广告-->
|
||||
<!--请注意:无论通过何种方式提供给穿山甲用户地理位置,均需向用户声明地理位置权限将应用于穿山甲广告投放,穿山甲不强制获取地理位置信息-->
|
||||
<!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
|
||||
@ -47,13 +47,13 @@
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.shuyu.gsyvideoplayer,
|
||||
com.shuyu.gsyvideoplayer.lib,
|
||||
com.haroldadmin.whatthestack,
|
||||
com.shuyu.gsyvideoplayer.armv7a,
|
||||
com.shuyu.gsyvideoplayer.x86,
|
||||
com.shuyu.gsy.base,
|
||||
com.google.android.exoplayer2,
|
||||
tv.danmaku.ijk.media.exo2,
|
||||
pl.droidsonroids.gif,
|
||||
com.donkingliang.consecutivescroller" />
|
||||
pl.droidsonroids.gif" />
|
||||
|
||||
<!-- 去掉 SDK 一些流氓权限 -->
|
||||
<uses-permission
|
||||
@ -69,7 +69,7 @@
|
||||
|
||||
<!--android:largeHeap = "true"-->
|
||||
<application
|
||||
android:name="com.halo.assistant.TinkerApp"
|
||||
android:name="com.halo.assistant.HaloApp"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/logo"
|
||||
android:label="@string/app_name"
|
||||
@ -562,6 +562,35 @@
|
||||
android:name=".video.label.VideoLabelActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.border.AvatarBorderActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.background.PersonalityBackgroundActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.background.BackgroundPreviewActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.background.BackgroundClipActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar"/>
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.excellentcomments.ExcellentCommentsActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".simulatorgame.SimulatorGameActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".simulatorgame.SimulatorManagementActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.PushProxyActivity"
|
||||
@ -589,11 +618,11 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
|
||||
|
||||
<activity
|
||||
android:name="${applicationId}.douyinapi.DouYinEntryActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity="${applicationId}"
|
||||
android:exported="true" />
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
<!-- android:launchMode="singleTask"-->
|
||||
<!-- android:taskAffinity="${applicationId}"-->
|
||||
<!-- android:exported="true" />-->
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
@ -628,45 +657,45 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="com.gh.gamecenter.UMENG" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="com.gh.gamecenter.UMENG" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<!--魅族push应用定义消息receiver声明 -->
|
||||
<receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">
|
||||
<intent-filter>
|
||||
<!-- 接收push消息 -->
|
||||
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
|
||||
<!-- 接收register消息 -->
|
||||
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
|
||||
<!-- 接收unregister消息-->
|
||||
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
|
||||
<!-- 兼容低版本Flyme3推送服务配置 -->
|
||||
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
|
||||
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
|
||||
<!-- <!–魅族push应用定义消息receiver声明 –>-->
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <!– 接收push消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.MESSAGE" />-->
|
||||
<!-- <!– 接收register消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 接收unregister消息–>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 兼容低版本Flyme3推送服务配置 –>-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.REGISTRATION" />-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.RECEIVE" />-->
|
||||
|
||||
<category android:name="${applicationId}" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- <category android:name="${applicationId}" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<receiver
|
||||
android:name="com.gh.common.im.ImReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="com.gh.im" />
|
||||
<action android:name="action_finish" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- <receiver-->
|
||||
<!-- android:name="com.gh.common.im.ImReceiver"-->
|
||||
<!-- android:enabled="true">-->
|
||||
<!-- <intent-filter android:priority="2147483647">-->
|
||||
<!-- <action android:name="com.gh.im" />-->
|
||||
<!-- <action android:name="action_finish" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.client.appid"
|
||||
android:value="@string/huawei_push_appid" />
|
||||
<!-- <meta-data-->
|
||||
<!-- android:name="com.huawei.hms.client.appid"-->
|
||||
<!-- android:value="@string/huawei_push_appid" />-->
|
||||
|
||||
<service
|
||||
android:name="com.gh.base.GHUmengNotificationService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
<!-- <service-->
|
||||
<!-- android:name="com.gh.base.GHUmengNotificationService"-->
|
||||
<!-- android:permission="android.permission.BIND_JOB_SERVICE" />-->
|
||||
|
||||
<!--<service android:name = "com.gh.gamecenter.statistics.AppStaticService" />-->
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
{"v":"5.6.9","fr":30,"ip":0,"op":20,"w":66,"h":66,"nm":"bottom bar tab/论坛/选中/E","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"矩形","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[110,110,100]},{"t":13,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.5],[1.5,-2.5],[2.5,-1.5],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.5]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-1.25],[1.5,-1.25],[2.5,-0.25],[2.5,0],[0,1.896],[-2.5,0],[-2.5,-0.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":9,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.938],[1.5,-2.938],[2.5,-1.938],[2.5,0],[0,2.833],[-2.5,0],[-2.5,-1.938]],"c":true}]},{"t":13,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.5],[1.5,-2.5],[2.5,-1.5],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":20,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"路径 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,34.599,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.2,0],[2.19,-0.35],[0,-1.82],[0,0],[0,0],[-1.98,0],[0,0],[0,0],[0,0],[-0.72,0.53],[0,0],[0,0],[0,2.05],[0,0],[1.8,0.28]],"o":[[-2.19,0],[-1.8,0.28],[0,0],[0,0],[0.1,1.96],[0,0],[0,0],[0,0],[0.58,0.65],[0,0],[0,0],[2.05,0],[0,0],[0,-1.82],[-2.2,-0.35]],"v":[[-0.003,-9.745],[-6.583,-9.215],[-9.712,-5.555],[-9.712,3.465],[-9.702,3.665],[-6.003,7.175],[-3.383,7.175],[-2.122,9.065],[-2.023,9.185],[0.277,9.405],[3.238,7.175],[5.997,7.175],[9.717,3.465],[9.717,-5.555],[6.587,-9.215]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-9.712,-9.745],"ix":5},"e":{"a":0,"k":[9.712,9.745],"ix":6},"t":1,"nm":"color","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[33,33,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":9,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":13,"s":[90,90,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"w":66,"h":66,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}
|
||||
{"v":"5.6.9","fr":30,"ip":0,"op":20,"w":66,"h":66,"nm":"bottom bar tab/论坛/选中/E","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"白-修正","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[110,110,100]},{"t":13,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-1.3],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.3],[-1.3,-2.5],[1.3,-2.5]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-0.102],[2.5,0],[0,2.109],[-2.5,0],[-2.5,-0.102],[-1.3,-1.302],[1.3,-1.302]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":9,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.498,-1.845],[2.5,0],[0,2.734],[-2.5,0],[-2.502,-1.845],[-1.302,-3.045],[1.298,-3.045]],"c":true}]},{"t":13,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-1.3],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.3],[-1.3,-2.5],[1.3,-2.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"蓝","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33.76,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.8,0.42],[-3.44,-0.79],[-0.09,-1.71],[0,0],[0,0],[1.98,-0.1],[0,0],[0,0],[0,0],[0.62,0.57],[0,0],[0,0],[0,0],[0,0],[0,0],[0.2,1.89],[0,0],[0,0],[0,0]],"o":[[3.44,-0.79],[1.74,0.41],[0,0],[0,0],[0,2],[0,0],[0,0],[0,0],[-0.69,0.52],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.94,0],[0,0],[0,0],[0,0],[0,-1.8]],"v":[[-6.39,-8.971],[6.39,-8.971],[9.49,-5.471],[9.5,-5.271],[9.5,3.249],[5.95,6.989],[5.75,6.999],[3.25,6.999],[0.3,9.209],[-1.95,9.089],[-2.06,8.969],[-2.17,8.849],[-2.21,8.779],[-3.4,6.999],[-5.75,6.999],[-9.48,3.639],[-9.49,3.449],[-9.5,3.249],[-9.5,-5.271]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-9.5,-9.561],"ix":5},"e":{"a":0,"k":[9.5,9.561],"ix":6},"t":1,"nm":"color","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[33,33,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":9,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":13,"s":[90,90,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"w":66,"h":66,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}
|
||||
360
app/src/main/assets/privacy_policies.html
Normal file
360
app/src/main/assets/privacy_policies.html
Normal file
@ -0,0 +1,360 @@
|
||||
<html lang="en"><head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>隐私政策</title>
|
||||
<style>
|
||||
* {
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content-area">
|
||||
<p>
|
||||
<b>欢迎您使用光环game!</b>
|
||||
<br>
|
||||
</p>
|
||||
<p>更新日期:2020年11月20日</p>
|
||||
<p>生效日期:2020年11月30日</p>
|
||||
<p>
|
||||
当您使用或开启相关功能或使用服务时,为了实现功能、服务所必需,受制于手机系统限制,我们会申请您的设备信息权限;除非是为实现基本业务服务功能或根据法律法规要求所必需的必要信息,您均可以拒绝提供且不影响其他功能或服务。
|
||||
</p>
|
||||
<p>
|
||||
为了让您正常观看视频和记录浏览账户登录功能,我们会申请您的储存权限;
|
||||
</p>
|
||||
<p>以下为完整《隐私权限政策》</p>
|
||||
<p>
|
||||
光环game(简称“我们”)深知个人信息对您的重要性,我们将依据《中华人民共和国网络安全法》、《信息安全技术
|
||||
个人信息安全规范》(GB/T
|
||||
35273-2017)以及其他相关法律法规和技术规范收集和使用您的个人信息,以帮助我们向您提供更优质的产品和/或服务,
|
||||
保护您的个人信息及隐私安全。我们制定本“隐私指引”并特别提示:希望您在使用光环game及相关服务前仔细阅读并理解本隐私政策,以便做出适当的选择。
|
||||
</p>
|
||||
<p>
|
||||
下文将帮您详细了解我们如何收集、使用、存储、传输、共享、转让(如适用)与保护个人信息;帮您了解查询、访问、删除、更正、撤回授权个人信息的方式。其中,
|
||||
<b>
|
||||
有关您个人信息权益的条款重要内容我们已用加粗形式提示,请特别关注。
|
||||
</b>
|
||||
</p>
|
||||
<p><b>1.我们处理个人信息的法律依据</b></p>
|
||||
<p><b>2.我们如何共享、转让、公开披露个人信息</b></p>
|
||||
<p><b>3.我们如何收集和使用个人信息</b></p>
|
||||
<p><b>4.我们如何存储个人信息</b></p>
|
||||
<p><b>5.我们如何保护个人信息的安全</b></p>
|
||||
<p><b>6.管理您的个人信息</b></p>
|
||||
<p><b>7.未成年人使用条款</b></p>
|
||||
<p><b>8.隐私政策的修订和通知</b></p>
|
||||
<p><b>9.联系我们</b></p>
|
||||
<p><b>1.我们处理个人信息的法律依据</b></p>
|
||||
<p>
|
||||
如果您是中华人民共和国大陆地区的用户,我们将依据《中华人民共和国网络安全法》、《信息安全技术个人信息安全规范》(GB/T
|
||||
35273-2017)以及其他相关法律法规收集和使用您的个人信息,为您提供产品或服务。
|
||||
</p>
|
||||
<p>
|
||||
我们通常只会在征得您同意的情况下收集您的个人信息。在某些情况下,我们可能还会基于法律义务或者履行合同之必需向您收集个人信息,或者可能需要个人信息来保护您的重要利益或其他人的利益。
|
||||
</p>
|
||||
<p><b>2.我们如何共享、转让、公开披露个人信息</b></p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>1</b>
|
||||
<b>共享您的个人信息</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)我们不会与任何公司、组织和个人共享您的个人信息,但以下情况除外:
|
||||
</p>
|
||||
<p>
|
||||
(2)事先获得您的明确授权或同意:
|
||||
获得您的明确同意后,我们会与其他方共享您的个人信息;
|
||||
</p>
|
||||
<p>
|
||||
(3)在法定情形下的共享:
|
||||
根据适用的法律法规、法律程序、政府的强制命令或司法裁定而需共享您的个人信息;
|
||||
</p>
|
||||
<p>
|
||||
(4)在法律要求或允许的范围内,为了保护光环game及其用户或社会公众的利益、财产或安全免遭损害而有必要提供您的个人信息给第三方;
|
||||
</p>
|
||||
<p>
|
||||
(5)与我们的关联公司共享:
|
||||
您的个人信息可能会在我们的关联公司之间共享。我们会对共享的个人信息进行匿名化处理,且这种共享受本指引所声明目的的约束。关联公司如要改变个人信息的处理目的,将再次征求您的授权同意。
|
||||
</p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>2</b>
|
||||
<b>转让</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)我们不会转让您的个人信息给任何其他第三方,除非征得您的明确同意。
|
||||
</p>
|
||||
<p>
|
||||
(2)随着我们业务的持续发展,我们将有可能进行合并、收购、资产转让,您的个人信息有可能因此而被转移。在发生前述变更时,我们将按照法律法规及不低于本隐私政策所载明的安全标准要求继受方保护您的个人信息,否则我们将要求继受方重新征得您的授权同意。
|
||||
</p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>3</b>
|
||||
<b>披露</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)我们不会公开披露您的信息,除非遵循国家法律法规规定或者获得您的同意。我们公开披露您的个人信息会采用符合行业内标准的安全保护措施。
|
||||
</p>
|
||||
<p>
|
||||
(2)基于法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会向有权机关披露您的个人信息。但我们保证,在上述情况发生时,我们会要求披露请求方必须出具与之相应的有效法律文件,并对被披露的信息采取符合法律和业界标准的安全防护措施。
|
||||
</p>
|
||||
<p>(3)对违规账号、欺诈行为进行处罚公告时,我们会披露相关账号的信息。</p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>4</b>
|
||||
<b>依法豁免征得同意共享、转让、公开披露的个人信息</b>
|
||||
</p>
|
||||
<p>
|
||||
请您理解,在下列情形中,根据法律法规及国家标准,我们共享、转让、公开披露您的个人信息无需征得您的授权同意:
|
||||
</p>
|
||||
<p>(1)与国家安全、国防安全直接相关的;</p>
|
||||
<p>(2)与公共安全、公共卫生、重大公共利益直接相关的;</p>
|
||||
<p>(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;</p>
|
||||
<p>
|
||||
(4)出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
|
||||
</p>
|
||||
<p>(5)您自行向社会公众公开的个人信息;</p>
|
||||
<p>
|
||||
(6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
|
||||
</p>
|
||||
<p><b>3.我们如何收集和使用个人信息</b></p>
|
||||
<p>
|
||||
我们会遵循正当、合法、必要的原则,出于本指引所述的以下目的,收集和使用您在使用服务过程中主动提供或因使用产品或服务而产生的个人信息。
|
||||
</p>
|
||||
<p>
|
||||
我们收集和使用的您的个人信息类型包括两种:第一种:我们产品或服务的核心业务功能所必需的信息:此类信息为产品或服务正常运行的必备信息,您须授权我们收集。如您拒绝提供,您将无法正常使用我们的功能,以"仅浏览(游客身份)"
|
||||
的状态体验;第二种:我们产品或服务的附加业务功能可能需要收集的信息:此信息为非核心业务功能所需的信息,您可以选择是否授权我们收集。如您拒绝提供,将导致附加业务功能无法实现或无法达到我们拟达到的效果,但不影响您对核心业务功能的正常使用。
|
||||
</p>
|
||||
<p>
|
||||
如果我们要将您的个人信息用于本指引未载明的其它用途,或基于特定目的将收集而来的信息用于其他目的,我们将以合理的方式向您告知,并在使用前再次征得您的同意。
|
||||
</p>
|
||||
<p><b>3.1实现产品或服务的基本功能</b></p>
|
||||
<p>
|
||||
(1)手机管理和内容资源下载功能。为实现手机管理及手机内容资源下载的基本功能,我们会通过手机系统的公用接口收集经过MD5算法加密的国际移动设备身份码(IMEI)和网络设备地址(MAC),以及手机型号、手机系统版本号、系统编号、系统ID号、屏幕分辨率、上网类型、手机中软件的名称、版本号、版本名、包名、软件使用时间和频率、软件崩溃信息、设备和软件相关的信息。这些信息是提供服务所必须收集的基础信息,如您拒绝提供上述权限将可能导致您无法使用我们的服务。
|
||||
</p>
|
||||
<p>
|
||||
(2)软件升级管理功能。为实现手机软件下载、安装、升级、卸载软件管理功能,在您使用产品时,我们会采集您手机中已安装软件的软件名称、版本号、版本名、软件包名信息并上传到我们的服务器进行软件版本比对。发现有更新的版本,我们会提示您升级相应的软件。上述软件信息为实现此功能所必需,不涉及您个人身份敏感信息。
|
||||
</p>
|
||||
<p>
|
||||
(3)过滤无法使用的软件功能。为了过滤您手机无法使用的软件,我们会收集您手机的手机型号、手机系统版本号、系统版本号、屏幕分辨率信息,并依据这些信息排除您手机无法使用的软件,以保证您在光环game下载的软件都可安装使用。
|
||||
</p>
|
||||
<p><b>3.2关于获取手机设备信息的说明</b></p>
|
||||
<p>
|
||||
(1)为方便区分每个用户的个人信息等,本软件需获取用户的手机设备信息。(2)为了保障软件与服务的安全运行,我们会收集您的硬件型号、操作系统版本号、国际移动设备识别码、唯一设备标识符、网络设备硬件地址、IP
|
||||
地址、WLAN接入点、蓝牙、基站、软件版本号、网络接入方式、类型、状态、网络质量数据、操作、使用、服务日志。
|
||||
</p>
|
||||
<p>
|
||||
(3)为了预防恶意程序及安全运营所必需,我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据、应用来源。
|
||||
</p>
|
||||
<p>
|
||||
(4)我们可能使用您的账户信息、设备信息、服务日志信息以及我们关联公司、合作方在获得您授权或依法可以共享的信息,用于判断账户安全、进行身份验证、检测及防范安全事件。
|
||||
</p>
|
||||
<p>(5)具体会发生获取手机设备信息场景如下说明:</p>
|
||||
<p>
|
||||
①首次启动光环game ②评论详情-发送评论功能 ③视频投稿-上传视频功能 ④视频详情-关注up主功能
|
||||
</p>
|
||||
<p><b>3.3帮助您成为我们的在线用户</b></p>
|
||||
<p>(1)注册账号/登录账号</p>
|
||||
<p>
|
||||
a.当您注册、登录我们相关服务时,您可以通过手机号创建账号,并且您可以完善相关的网络身份识别信息(头像、昵称、密码),收集这些信息是为了帮助您完成注册。您还可以根据自身需求选择填写性别、生日、地区及个人介绍来完善您的信息。
|
||||
</p>
|
||||
<p>(2)认证用户</p>
|
||||
<p>
|
||||
a.在您使用身份认证的功能或服务时,根据相关法律法规,您可能需要提供您的真实身份信息(真实姓名、身份证号码、电话号码)以完成实名验证。
|
||||
</p>
|
||||
<p>
|
||||
b.这些信息属于个人敏感信息,您可以拒绝提供,但您将可能无法获得相关服务,但不影响其他功能与服务的正常使用。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>4</b>
|
||||
<b>信息发布功能</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)注册成为光环game用户后,可在光环game平台上发布评论、视频,还可以对别人的视频评论作出回复、赞同、感谢。
|
||||
</p>
|
||||
<p>
|
||||
(2)上述功能基于相册(图片库/视频库)的图片/视频访问及上传的附加服务,我们会请求您授权相机、照片、麦克风权限,您可以使用该功能上传您的照片/图片/视频,以实现发布照片/图片/视频的功能、与其他用户进行照片/图片分享等功能。如您拒绝提供该权限和内容的,仅会使您无法使用该功能,但并不影响您正常使用产品与/或服务的其他功能。
|
||||
</p>
|
||||
<p>
|
||||
(3)您发布视频内容或回答时,我们将收集您发布的信息,并展示您的昵称、头像、发布内容。
|
||||
</p>
|
||||
<p>
|
||||
(4)用户因使用我们的产品或者服务而被我们收集的信息,例如其他用户发布的信息中可能含有您的部分信息(如:在评论、留言、发布图文、音视频中涉及到与您相关的信息)。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>5</b>
|
||||
<b>浏览、关注与收藏功能</b>
|
||||
</p>
|
||||
<p>(1)您可浏览的内容包括视频、评论。</p>
|
||||
<p>
|
||||
(2)在浏览的过程中,您还可以关注您感兴趣的用户、收藏,并收藏上述内容。
|
||||
</p>
|
||||
<p>
|
||||
(3)为此,
|
||||
我们可能会收集您使用时的设备信息,如设备型号、唯一设备标识符、操作系统、分辨率、电信运营商等软硬件信息。
|
||||
我们还可能收集您的浏览器类型,以此来为您提供信息展示的最优方案。
|
||||
</p>
|
||||
<p>
|
||||
(4)此外,在您使用浏览和收藏功能的过程中,我们会自动收集您使用的详细情况,并作为有关的
|
||||
网络日志保存。
|
||||
</p>
|
||||
<p>
|
||||
(5)您浏览和发布的内容及评论信息,您上传的视频作品、您使用的语言、访问的日期和时间、及您的操作系统、软件版本号、登录IP
|
||||
信息。
|
||||
</p>
|
||||
<p>
|
||||
(6)在此过程中,
|
||||
我们会收集您的浏览记录,浏览记录包括您浏览的视频、评论,您可以自主清楚浏览缓存。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>6</b>
|
||||
<b>互动交流</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)您主动关注您感兴趣的up主、视频并与之进行互动,进行浏览、评论、收藏、点赞或分享内容时,我们会收集您关注的账号,并向您展示您关注账号发布内容。
|
||||
</p>
|
||||
<p>
|
||||
(2)您使用推荐通讯录好友功能时,我们会请求通讯录权限,并将通讯录中的信息进行高强度加密算法处理后,用于向您推荐通信录中的好友。通讯录信息属于个人敏感信息,拒绝提供该信息仅会使您无法使用上述功能,但不影响您正常使用“光环game”及相关服务的其他功能。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>7</b>
|
||||
<b>收集、使用个人信息目的变更</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)请您了解,随着我们业务的发展,可能会对“光环game”的功能和提供的服务有所调整变化。
|
||||
</p>
|
||||
<p>
|
||||
(2)原则上,当新功能或服务与我们当前提供的功能或服务相关时,收集与使用的个人信息将与原处理目的具有直接或合理关联。
|
||||
</p>
|
||||
<p>
|
||||
(3)在与原处理目的无直接或合理关联的场景下,我们收集、使用您的个人信息,会再次进行告知,并征得您的同意。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>8</b>
|
||||
<b>依法豁免征得同意收集和使用的个人信息</b>
|
||||
</p>
|
||||
<p>
|
||||
请您理解,在下列情形中,根据法律法规及相关国家标准,我们收集和使用您的个人信息无需征得您的授权同意:
|
||||
</p>
|
||||
<p>(1)与国家安全、国防安全直接相关的;</p>
|
||||
<p>(2)与公共安全、公共卫生、重大公共利益直接相关的;</p>
|
||||
<p>(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;</p>
|
||||
<p>
|
||||
(4)出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
|
||||
</p>
|
||||
<p>(5)所收集的您的个人信息是您自行向社会公众公开的;</p>
|
||||
<p>
|
||||
(6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
|
||||
</p>
|
||||
<p>(7)根据您的要求签订或履行合同所必需的;</p>
|
||||
<p>
|
||||
(8)用于维护软件及相关服务的安全稳定运行所必需的,例如发现、处置软件及相关服务的故障;
|
||||
</p>
|
||||
<p>(9)为合法的新闻报道所必需的;</p>
|
||||
<p>
|
||||
(10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的。
|
||||
</p>
|
||||
<p>(11)法律法规规定的其他情形。</p>
|
||||
<p>
|
||||
特别提示您注意,如信息无法单独或结合其他信息识别到您的个人身份,其不属于法律意义上您的个人信息;当您的信息可以单独或结合其他信息识别到您的个人身份时或我们将无法与任何特定个人信息建立联系的数据与其他您的个人信息结合使用时,这些信息在结合使用期间,将作为您的个人信息按照本隐私政策处理与保护。
|
||||
</p>
|
||||
<p><b>4.我们如何存储个人信息</b></p>
|
||||
<p><b>4.1 存储地点</b></p>
|
||||
<p>
|
||||
(1)我们依照法律法规的规定,将在境内运营过程中收集和产生的您的个人信息存储于中华人民共和国境内。
|
||||
</p>
|
||||
<p>
|
||||
(2)目前,我们不会将上述信息传输至境外,如果我们向境外传输,我们将会遵循相关国家规定或者征求您的同意。
|
||||
</p>
|
||||
<p><b>4.2存储期限</b></p>
|
||||
<p>
|
||||
(1)我们仅在为提供“光环game”及服务之目的所必需的期间内保留您的个人信息:您发布的视频、评论、点赞及相关信息,在您未撤回、删除或未注销账号期间,我们会保留相关信息。
|
||||
</p>
|
||||
<p>
|
||||
(2)超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
|
||||
</p>
|
||||
<p><b>5.我们如何保护个人信息的安全</b></p>
|
||||
<p>
|
||||
(1)我们非常重视您个人信息的安全,将努力采取合理的安全措施(包括技术方面和管理方面)来保护您的个人信息,防止您提供的个人信息被不当使用或未经授权的情况下被访问、公开披露、使用、修改、损坏、丢失或泄漏。
|
||||
</p>
|
||||
<p>
|
||||
(2)我们会使用不低于行业同行的加密技术、匿名化处理及相关合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
|
||||
</p>
|
||||
<p>
|
||||
(3)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
|
||||
</p>
|
||||
<p>
|
||||
(4)尽管已经采取了上述合理有效措施,并已经遵守了相关法律规定要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保您提供给我们的个人信息的安全性。
|
||||
</p>
|
||||
<p>
|
||||
(5)您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人。
|
||||
</p>
|
||||
<p>
|
||||
(6)我们会制定应急处理预案,并在发生用户信息安全事件时立即启动应急预案,努力阻止这些安全事件的影响和后果扩大。一旦发生用户信息安全事件(泄露、丢失)后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已经采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施。我们将及时将事件相关情况以推送通知、邮件、信函、短信及相关形式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照相关监管部门要求,上报用户信息安全事件的处置情况。
|
||||
</p>
|
||||
<p>
|
||||
(7)您一旦离开“光环game”及相关服务,浏览或使用其他网站、服务及内容资源,我们将没有能力和直接义务保护您在光环game及相关服务之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于“光环game”的链接或引导。
|
||||
</p>
|
||||
<p><b>6.管理您的个人信息</b></p>
|
||||
<p>
|
||||
我们非常重视您对个人信息的管理,并尽全力保护您的隐私,对于您个人信息的查询、访问、修改、删除、撤回同意授权、注销账号、投诉举报以及设置隐私功能的相关权利,以使您有能力保障您的隐私和信息安全。
|
||||
</p>
|
||||
<p><b>6.1 访问、删除、更正您的个人信息</b></p>
|
||||
<p>(1)访问个人账号信息</p>
|
||||
<p>a. 您可以查询、访问您的头像、用户名、简介、性别、生日、地区</p>
|
||||
<p>b.您可以在光环game的“个人主页”中进行查询、访问。</p>
|
||||
<p>(2)查询访问、更正、取消您关注账号、查询访问粉丝</p>
|
||||
<p>a.进入“关注”在关注列表中查询、访问、取消关注您关注的账号。</p>
|
||||
<p>b.您可以通过点击“设置”—点击“清理缓存”。</p>
|
||||
<p>(3)访问隐私政策</p>
|
||||
<p>
|
||||
a.您可以在注册页面,或者在登录个人账号“设置”—“关于”查看本隐私政策的全部内容
|
||||
</p>
|
||||
<p>
|
||||
b.请您了解,本隐私政策中所述的“光环game”及相关服务可能会根据您所使用的手机型号、系统版本、软件应用程序版本、移动客户端等因素而有所不同。最终的产品和服务以您所使用的“光环game”软件及相关服务为准。
|
||||
</p>
|
||||
<p>(6)停止运营向您告知</p>
|
||||
<p>
|
||||
a.如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理。
|
||||
</p>
|
||||
<p><b>7.未成年人条款</b></p>
|
||||
<p>
|
||||
a.若您是未满18周岁的未成年人,在使用“光环game”及相关服务前,应在您的父母或其他监护人监护、指导下共同阅读并同意本隐私政策。
|
||||
</p>
|
||||
<p>
|
||||
b.我们根据国家相关法律法规的规定保护未成年人的个人信息,只会在法律允许、父母或其他监护人明确同意或保护未成年人所必要的情况下收集、使用、储存、共享、转让或披露未成年人的个人信息;如果我们发现在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关信息。
|
||||
</p>
|
||||
<p>
|
||||
c.若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过公司本隐私政策公示的联系方式与我们联系。
|
||||
</p>
|
||||
<p><b>8.隐私政策的修订和通知</b></p>
|
||||
<p>
|
||||
(1)为了给您提供更好的服务,光环game及相关服务将不时更新与变化,我们会适时对本隐私政策进行修订,这些修订构成本隐私政策的一部分并具有等同于本隐私政策的效力,未经您明确同意,我们不会削减您依据当前生效的本隐私政策所应享受的权利。
|
||||
</p>
|
||||
<p>
|
||||
(2)本隐私政策更新后,我们会在光环game发出更新版本,并在更新后的条款生效前通过公告或其他适当的方式提醒您更新的内容,以便您及时了解本隐私政策的最新版本。
|
||||
</p>
|
||||
<p><b>9.联系我们</b></p>
|
||||
<p>
|
||||
如果您对我们的隐私政策及对您个人信息的处理有任何疑问、意见、建议、或投诉,请通过以下方式与我们联系
|
||||
</p>
|
||||
<p>
|
||||
广州市来特悦游信息科技有限公司注册地址:广州市天河区中山大道建工路13、15号3-6层5楼512房(仅限办公用途)
|
||||
</p>
|
||||
<p>在线客服QQ:3624425003</p>
|
||||
<p>信息保护事务联系电话:020-85526920</p>
|
||||
<p>在一般情况下,我们会在15个工作日内对您的请求予以答复</p>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
||||
161
app/src/main/assets/user_regulation.html
Normal file
161
app/src/main/assets/user_regulation.html
Normal file
@ -0,0 +1,161 @@
|
||||
<html lang="en"><head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>光环助手软件许可及服务协议</title>
|
||||
<style>
|
||||
* {
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content-area">
|
||||
<p><b></b></p>
|
||||
<p>
|
||||
<b>光环</b>
|
||||
<b>game</b>
|
||||
<b>软件许可及服务协议</b>
|
||||
</p>
|
||||
<p><b>更新日期:2020年11月20日</b></p>
|
||||
<p><b>生效日期:2020年11月30日</b></p>
|
||||
<p><b>首部及导言</b></p>
|
||||
<p>欢迎使用光环game软件许可及服务</p>
|
||||
<p>
|
||||
各位用户在使用光环game前,请您务必审慎阅读、并充分理解本协议中的各项条款,
|
||||
<b>
|
||||
特别是免除或者限制责任的条款,以及开通或使用某项服务的单独协议,并选择接受或不接受。
|
||||
</b>
|
||||
除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本软件及相关服务。您的下载、安装、使用、登录等行为即视为您已阅读并同意上述协议的约束。
|
||||
</p>
|
||||
<p>如果您未满18周岁,请在法定监护人的陪同下阅读本协议及其他上述协议。</p>
|
||||
<p><b>一、权利声明</b></p>
|
||||
<p>
|
||||
“光环game”的一切知识产权,以及与“光环game”相关的所有信息内容,包括但不限于:文字表述及其组合、图标、图饰、图像、图表、色彩、界面设计、版面框架、有关数据、附加程序、印刷材料或电子文档等均为光环game所有,受著作权法和国际著作权条约以及其他知识产权法律法规的保护。
|
||||
</p>
|
||||
<p><b>二、软件使用规范</b></p>
|
||||
<p>
|
||||
2.1
|
||||
本软件是基于Android(安卓)系统手机、平板电脑(PAD)等设备开发的一款软件,提供注册登录、观看视频、视频投稿等功能
|
||||
</p>
|
||||
<p>2.2 软件的下载、安装和使用</p>
|
||||
<p>
|
||||
本软件为免费软件,用户可以非商业性、无限制数量地从光环game授权的渠道下载、安装及使用本软件。
|
||||
</p>
|
||||
<p>
|
||||
<b>如果您从未经光环</b>
|
||||
<b>game</b>
|
||||
<b>授权的第三方获取本软件或与本软件名称相同的安装程序,光环</b>
|
||||
<b>game</b>
|
||||
<b>无法保证该软件能够正常使用,并对因此给您造成的损失不予负责。</b>
|
||||
</p>
|
||||
<p>2.3 软件的复制、分发和传播</p>
|
||||
<p>
|
||||
本产品以研究交流为目的。用户可以非商业性、无限制数量地复制、分发和传播本软件产品。但必须保证每一份复制、分发和传播都是完整和真实的,
|
||||
包括所有有关本软件产品的软件、电子文档, 版权和商标,亦包括本协议。
|
||||
</p>
|
||||
<p>2.4 软件的更新</p>
|
||||
<p>
|
||||
为了改善用户体验、完善服务内容,光环game将不断努力开发新的服务,并为您不时提供软件更新(这些更新可能会采取软件替换、修改、功能强化、版本升级等形式)。为了保证本软件及服务的安全性和功能的一致性,光环game有权不经向您特别通知而对软件进行更新,或者对软件的部分功能效果进行改变或限制。本软件新版本发布后,旧版本的软件可能无法使用。光环game不保证旧版本软件继续可用及相应的客户服务,请您随时核对并下载最新版本。
|
||||
</p>
|
||||
<p><b>三、用户使用须知</b></p>
|
||||
<p>3.1 您理解并同意:</p>
|
||||
<p>
|
||||
为了向您提供有效的服务,本软件会利用您移动通讯终端的处理器和带宽等资源。本软件使用过程中可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担相关费用.
|
||||
</p>
|
||||
<p>3.2您理解并同意:</p>
|
||||
<p>
|
||||
<b>
|
||||
如果因您不正当使用本软件造成了不良影响,或因使用本软件造成的包括但不限于数据异常等问题,均由使用者自行承担,光环团队不对任意类型的使用结果承担责任;
|
||||
</b>
|
||||
</p>
|
||||
<p>3.3您理解并同意:</p>
|
||||
<p>
|
||||
本软件不含任何破坏用户移动通讯设备数据和获取用户隐私信息的恶意代码,不会泄露用户的个人信息和隐私;
|
||||
</p>
|
||||
<p>3.4您理解并同意:</p>
|
||||
<p>
|
||||
<b>
|
||||
对于包括但不限于互联网网络故障、计算机故障、手机故障或病毒、信息损坏或丢失、计算机系统问题,或其它任何基于不可抗力原因而产生的损失,光环团队不承担任何责任。
|
||||
</b>
|
||||
</p>
|
||||
<p>3.5您理解并同意:</p>
|
||||
<p>光环game发布、收录的视频均不代表光环立场。</p>
|
||||
<p>3.6您理解并同意:</p>
|
||||
<p>
|
||||
用户应在遵守法律及本协议的前提下使用本软件。用户无权实施包括但不限于下列行为:
|
||||
</p>
|
||||
<p>3.6.1 不得删除或者改变本软件上的所有权利管理电子信息</p>
|
||||
<p>
|
||||
3.6.2
|
||||
不得故意避开或者破坏著作权人为保护本软件著作权而采取的技术措施;
|
||||
</p>
|
||||
<p>3.6.3 用户不得利用本软件误导、欺骗他人; </p>
|
||||
<p>
|
||||
3.6.4
|
||||
违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行;
|
||||
</p>
|
||||
<p>3.6.5 未经允许,进入计算机信息网络或者使用计算机信息网络资源; </p>
|
||||
<p>3.6.6 未经允许,对计算机信息网络功能进行删除、修改或者增加; </p>
|
||||
<p>
|
||||
3.6.7
|
||||
未经允许,对计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加;
|
||||
</p>
|
||||
<p>
|
||||
3.6.8
|
||||
破坏本软件系统或网站的正常运行,故意传播计算机病毒等破坏性程序;
|
||||
</p>
|
||||
<p>3.6.9 其他任何危害计算机信息网络安全的行为。 </p>
|
||||
<p>3.7 您理解并同意:</p>
|
||||
<p>
|
||||
本软件经过详细的测试,但不能保证与所有的软硬件系统完全兼容,不能保证本软件完全没有错误。如果出现不兼容及软件错误的情况,用户可通过各反馈途径将情况告知光环团队,获得技术支持。如果无法解决兼容性问题,用户可以删除本软件。
|
||||
</p>
|
||||
<p><b>四、争议解决处理</b></p>
|
||||
<p>
|
||||
本《协议》的解释、效力及纠纷的解决,适用于中华人民共和国法律。若用户和光环game之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户在此完全同意将纠纷或争议提交光环game所在地法院管辖
|
||||
</p>
|
||||
<p>
|
||||
<b>五</b>
|
||||
<b>、关于获取手机设备信息的说明</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)为方便区分每个用户的个人信息等,本软件需获取用户的手机设备信息,用于用户登录、视频评论互动交流等用户相关的行为
|
||||
</p>
|
||||
<p>
|
||||
(2)为了保障软件与服务的安全运行,我们会收集您的硬件型号、操作系统版本号、国际移动设备识别码、唯一设备标识符、网络设备硬件地址、IP
|
||||
地址、WLAN接入点、蓝牙、基站、软件版本号、网络接入方式、类型、状态、网络质量数据、操作、使用、服务日志。
|
||||
</p>
|
||||
<p>
|
||||
(3)为了预防恶意程序及安全运营所必需,我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据、应用来源。
|
||||
</p>
|
||||
<p>
|
||||
(4)我们可能使用您的账户信息、设备信息、服务日志信息以及我们关联公司、合作方在获得您授权或依法可以共享的信息,用于判断账户安全、进行身份验证、检测及防范安全事件。
|
||||
</p>
|
||||
<p>(5)具体会发生获取手机设备信息场景如下说明:</p>
|
||||
<p>
|
||||
1) 首次启动光环game 2) 评论详情-发送评论功能 3)
|
||||
视频投稿-上传视频功能 4) 视频详情-关注up主功能
|
||||
</p>
|
||||
<p><b>七、其他</b></p>
|
||||
<p>
|
||||
7.1
|
||||
本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。
|
||||
</p>
|
||||
<p>
|
||||
7.2
|
||||
如果本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,或违反任何适用的法律,则该条款被视为删除,但本协议的其余条款仍应有效并且有约束力。
|
||||
</p>
|
||||
<p>
|
||||
7.3
|
||||
光环有权随时根据有关法律、法规的变化以及公司经营状况和经营策略的调整等修改本协议。修改后的协议会在软件设置内发布。
|
||||
当发生有关争议时,以最新的协议文本为准。如果不同意改动的内容,用户可以自行删除本软件。如果用户继续使用本软件,则视为您接受本协议的变动。
|
||||
</p>
|
||||
<p> 7.4 光环在法律允许的最大范围内对本协议拥有解释权与修改权。</p>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
||||
@ -4,10 +4,6 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
@ -18,6 +14,9 @@ import com.lightgame.view.NoScrollableViewPager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import butterknife.BindView;
|
||||
|
||||
/**
|
||||
@ -73,10 +72,13 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getIntent() != null) mCheckedIndex = getIntent().getIntExtra(PAGE_INDEX, 0);
|
||||
mFragmentsList = new ArrayList<>();
|
||||
initFragmentList(mFragmentsList);
|
||||
mTabTitleList = new ArrayList<>();
|
||||
initTabTitleList(mTabTitleList);
|
||||
mFragmentsList = new ArrayList<>(restoreFragments());
|
||||
if (mFragmentsList.isEmpty() || mFragmentsList.size() != mTabTitleList.size()) {
|
||||
mFragmentsList.clear();
|
||||
initFragmentList(mFragmentsList);
|
||||
}
|
||||
|
||||
mViewPager.setOffscreenPageLimit(mFragmentsList.size());
|
||||
mViewPager.addOnPageChangeListener(this);
|
||||
@ -100,6 +102,20 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex);
|
||||
}
|
||||
|
||||
private ArrayList<Fragment> restoreFragments() {
|
||||
String tag = "android:switcher:" + mViewPager.getId() + ":";
|
||||
ArrayList<Fragment> fragments = new ArrayList<>();
|
||||
int childCount = mTabTitleList.size();
|
||||
for (int index = 0; index < childCount; index++) {
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag + index);
|
||||
if (fragment != null) {
|
||||
fragments.add(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
|
||||
@ -4,10 +4,10 @@ import android.app.Activity;
|
||||
import android.app.Application.ActivityLifecycleCallbacks;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.gh.common.im.ImManager;
|
||||
import com.gh.common.notifier.Notifier;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.AppManager;
|
||||
|
||||
/**
|
||||
@ -34,23 +34,27 @@ public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallba
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
|
||||
DataUtils.onResume(activity);
|
||||
CurrentActivityHolder.getActivitySet().add(activity);
|
||||
ImManager.updateFloatingWindow();
|
||||
//FIXME 这里应该只是部分Activity需要
|
||||
try {
|
||||
// 初始化gameMap
|
||||
DownloadManager.getInstance(activity).initGameMap();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
if (HaloApp.isUserAcceptPrivacyPolicy(activity)) {
|
||||
DataUtils.onResume(activity);
|
||||
//FIXME 这里应该只是部分Activity需要
|
||||
try {
|
||||
// 初始化gameMap
|
||||
DownloadManager.getInstance(activity).initGameMap();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
DataUtils.onPause(activity);
|
||||
CurrentActivityHolder.getActivitySet().remove(activity);
|
||||
|
||||
if (HaloApp.isUserAcceptPrivacyPolicy(activity)) {
|
||||
DataUtils.onPause(activity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,229 +1,229 @@
|
||||
package com.gh.base
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.text.htmlEncode
|
||||
import com.gh.common.notifier.Notifier
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.PushEntity
|
||||
import com.gh.gamecenter.entity.PushMessageEntity
|
||||
import com.gh.gamecenter.entity.PushMessageUnreadEntity
|
||||
import com.gh.gamecenter.entity.PushNotificationEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_CLICK
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_REMOVE
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.google.gson.Gson
|
||||
import com.umeng.message.UmengMessageService
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.android.agoo.common.AgooConstants
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import java.util.*
|
||||
|
||||
class GHUmengNotificationService : UmengMessageService() {
|
||||
|
||||
companion object {
|
||||
const val ACTION_UMENG = "com.gh.gamecenter.UMENG"
|
||||
const val MESSAGE_FROM_SYSTEM = "message_from_system"
|
||||
const val HALO_MESSAGE_DIALOG = "HALO_MESSAGE_DIALOG"
|
||||
const val HALO_MESSAGE_CENTER = "HALO_MESSAGE_CENTER"
|
||||
const val ANSWER = "answer"
|
||||
const val FOLLOW_QUESTION = "follow_question"
|
||||
const val NOTIFICATION_ID = 2015
|
||||
const val DISPLAY_TYPE_NOTIFICATION = "notification"
|
||||
const val DISPLAY_TYPE_CUSTOM = "custom"
|
||||
const val MESSAGE_ID = "message_id"
|
||||
const val NOTIFICATION_MESSAGE_ID = "notification_message_id" // 通知中心消息 ID
|
||||
const val PUSH_ID = "push_id"
|
||||
}
|
||||
|
||||
val notificationTags = arrayOf("GH_UMENG_TAG_1", "GH_UMENG_TAG_2", "GH_UMENG_TAG_3")
|
||||
val gson = Gson()
|
||||
|
||||
override fun onMessage(context: Context, intent: Intent) {
|
||||
val message = intent.getStringExtra(AgooConstants.MESSAGE_BODY)
|
||||
val isMessageFromSystem = intent.getBooleanExtra(MESSAGE_FROM_SYSTEM, false)
|
||||
|
||||
try {
|
||||
val pushData = message.toObject<PushEntity>()
|
||||
pushData?.let { handlePushData(context, it, message, isMessageFromSystem) }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePushData(context: Context, pushData: PushEntity, message: String, isMessageFromSystem: Boolean) {
|
||||
val notificationManager = context.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
if (pushData.displayType == DISPLAY_TYPE_NOTIFICATION) {
|
||||
// 其它类型的透传信息
|
||||
// 显示到通知栏
|
||||
val msg = message.toObject<PushNotificationEntity>()
|
||||
val data = msg?.extra?.data
|
||||
|
||||
// 系统推送(非自定义信息),直接处理跳转
|
||||
if (isMessageFromSystem) {
|
||||
val intent = Intent()
|
||||
intent.setClass(context, UmengMessageReceiver::class.java)
|
||||
intent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
intent.putExtra(EntranceUtils.KEY_TYPE, UmengMessageReceiver.DIRECT_ONLY)
|
||||
intent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
intent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
context.sendBroadcast(intent)
|
||||
return
|
||||
}
|
||||
|
||||
// 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
|
||||
if (data != null
|
||||
&& data.link?.link == "system"
|
||||
&& !UserManager.getInstance().isLoggedIn) {
|
||||
return
|
||||
}
|
||||
|
||||
val clickIntent = Intent()
|
||||
val removeIntent = Intent()
|
||||
|
||||
clickIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
clickIntent.putExtra(MESSAGE_ID, msg?.msgId)
|
||||
clickIntent.putExtra(PUSH_ID, data?.pushId)
|
||||
clickIntent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
|
||||
|
||||
removeIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
|
||||
removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
|
||||
val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
|
||||
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
|
||||
removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
val notification = NotificationCompat.Builder(context, "Halo_Push")
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setTicker(pushData.body?.ticker)
|
||||
.setContentTitle(pushData.body?.title)
|
||||
.setContentText(pushData.body?.text?.fromHtml())
|
||||
.setContentIntent(clickPendingIntent)
|
||||
.setDeleteIntent(deletePendingIntent)
|
||||
.build()
|
||||
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
|
||||
|
||||
notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
|
||||
} else {
|
||||
if (UserManager.getInstance().isLoggedIn &&
|
||||
HALO_MESSAGE_DIALOG == pushData.body?.custom &&
|
||||
MessageUnreadRepository.unreadLiveData.value != null) {
|
||||
// 回答了问题或者关注了问题的消息
|
||||
val msg = gson.fromJson(message, PushMessageEntity::class.java)
|
||||
val data = msg?.extra?.data
|
||||
|
||||
val type = if (ANSWER == data?.type) {
|
||||
"回答了你的问题"
|
||||
} else {
|
||||
"回答了你关注的问题"
|
||||
}
|
||||
|
||||
val userName = StringUtils.shrinkStringWithDot(data?.userEntity?.name, 8)
|
||||
val displayText = userName + type
|
||||
|
||||
if (Notifier.isActivityValid(CurrentActivityHolder.getCurrentActivity()) &&
|
||||
Notifier.shouldShowNotifier(data?.answer?.id + displayText)) {
|
||||
Notifier.create(CurrentActivityHolder.getCurrentActivity())
|
||||
.setText(displayText)
|
||||
.setDuration(5000)
|
||||
.setIcon(data?.userEntity?.icon)
|
||||
.setOnClickListener(View.OnClickListener {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceUtils.KEY_ANSWER_ID, data?.answer?.id)
|
||||
bundle.putString(EntranceUtils.KEY_ENTRANCE, EntranceUtils.ENTRANCE_UMENG)
|
||||
bundle.putString(EntranceUtils.KEY_TO, AnswerDetailActivity::class.java.name)
|
||||
EntranceUtils.jumpActivity(context, bundle)
|
||||
|
||||
MtaHelper.onEvent("消息弹窗", type, "Does not contains any parameter.")
|
||||
|
||||
// 标记已读
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("type", type)
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
|
||||
RetrofitManager.getInstance(application).api.postMessageRead(UserManager.getInstance().userId, data?.id, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
MessageUnreadRepository.loadMessageUnreadData()
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
e?.printStackTrace()
|
||||
}
|
||||
})
|
||||
Notifier.hide()
|
||||
})
|
||||
.show(false)
|
||||
Notifier.tagNotifierAsShowed(data?.answer?.id + displayText)
|
||||
}
|
||||
} else if (HALO_MESSAGE_CENTER == pushData.body?.custom) {
|
||||
// 消息中心逻辑
|
||||
val msg = gson.fromJson(message, PushMessageUnreadEntity::class.java)
|
||||
val data = msg?.extra?.data
|
||||
data?.let { MessageUnreadRepository.loadMessageUnreadData() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 规则:最多三条消息,以旧换新
|
||||
*
|
||||
* @return NotificationTag
|
||||
*/
|
||||
private fun getNotificationTag(context: Context): String {
|
||||
val sp = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val edit = sp.edit()
|
||||
|
||||
val timeTagMap = HashMap<Long, String>()
|
||||
for (tag in notificationTags) {
|
||||
val time = sp.getLong(tag, 0)
|
||||
if (time == 0L) {
|
||||
edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
return tag
|
||||
} else {
|
||||
timeTagMap[time] = tag
|
||||
}
|
||||
}
|
||||
|
||||
val minTime = Collections.min(timeTagMap.keys)
|
||||
val tag = timeTagMap[minTime]
|
||||
edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
return if (TextUtils.isEmpty(tag)) notificationTags[0] else tag!!
|
||||
}
|
||||
}
|
||||
//package com.gh.base
|
||||
//
|
||||
//import android.app.Notification
|
||||
//import android.app.NotificationChannel
|
||||
//import android.app.NotificationManager
|
||||
//import android.app.PendingIntent
|
||||
//import android.content.Context
|
||||
//import android.content.Intent
|
||||
//import android.os.Build
|
||||
//import android.os.Bundle
|
||||
//import android.preference.PreferenceManager
|
||||
//import android.text.TextUtils
|
||||
//import android.view.View
|
||||
//import androidx.core.app.NotificationCompat
|
||||
//import androidx.core.text.htmlEncode
|
||||
//import com.gh.common.notifier.Notifier
|
||||
//import com.gh.common.util.*
|
||||
//import com.gh.gamecenter.R
|
||||
//import com.gh.gamecenter.entity.PushEntity
|
||||
//import com.gh.gamecenter.entity.PushMessageEntity
|
||||
//import com.gh.gamecenter.entity.PushMessageUnreadEntity
|
||||
//import com.gh.gamecenter.entity.PushNotificationEntity
|
||||
//import com.gh.gamecenter.manager.UserManager
|
||||
//import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
//import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_CLICK
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_REMOVE
|
||||
//import com.gh.gamecenter.retrofit.Response
|
||||
//import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
//import com.google.gson.Gson
|
||||
//import com.umeng.message.UmengMessageService
|
||||
//import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
//import io.reactivex.schedulers.Schedulers
|
||||
//import okhttp3.MediaType
|
||||
//import okhttp3.RequestBody
|
||||
//import okhttp3.ResponseBody
|
||||
//import org.android.agoo.common.AgooConstants
|
||||
//import org.json.JSONObject
|
||||
//import retrofit2.HttpException
|
||||
//import java.util.*
|
||||
//
|
||||
//class GHUmengNotificationService : UmengMessageService() {
|
||||
//
|
||||
// companion object {
|
||||
// const val ACTION_UMENG = "com.gh.gamecenter.UMENG"
|
||||
// const val MESSAGE_FROM_SYSTEM = "message_from_system"
|
||||
// const val HALO_MESSAGE_DIALOG = "HALO_MESSAGE_DIALOG"
|
||||
// const val HALO_MESSAGE_CENTER = "HALO_MESSAGE_CENTER"
|
||||
// const val ANSWER = "answer"
|
||||
// const val FOLLOW_QUESTION = "follow_question"
|
||||
// const val NOTIFICATION_ID = 2015
|
||||
// const val DISPLAY_TYPE_NOTIFICATION = "notification"
|
||||
// const val DISPLAY_TYPE_CUSTOM = "custom"
|
||||
// const val MESSAGE_ID = "message_id"
|
||||
// const val NOTIFICATION_MESSAGE_ID = "notification_message_id" // 通知中心消息 ID
|
||||
// const val PUSH_ID = "push_id"
|
||||
// }
|
||||
//
|
||||
// val notificationTags = arrayOf("GH_UMENG_TAG_1", "GH_UMENG_TAG_2", "GH_UMENG_TAG_3")
|
||||
// val gson = Gson()
|
||||
//
|
||||
// override fun onMessage(context: Context, intent: Intent) {
|
||||
// val message = intent.getStringExtra(AgooConstants.MESSAGE_BODY)
|
||||
// val isMessageFromSystem = intent.getBooleanExtra(MESSAGE_FROM_SYSTEM, false)
|
||||
//
|
||||
// try {
|
||||
// val pushData = message.toObject<PushEntity>()
|
||||
// pushData?.let { handlePushData(context, it, message, isMessageFromSystem) }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun handlePushData(context: Context, pushData: PushEntity, message: String, isMessageFromSystem: Boolean) {
|
||||
// val notificationManager = context.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
//
|
||||
// if (pushData.displayType == DISPLAY_TYPE_NOTIFICATION) {
|
||||
// // 其它类型的透传信息
|
||||
// // 显示到通知栏
|
||||
// val msg = message.toObject<PushNotificationEntity>()
|
||||
// val data = msg?.extra?.data
|
||||
//
|
||||
// // 系统推送(非自定义信息),直接处理跳转
|
||||
// if (isMessageFromSystem) {
|
||||
// val intent = Intent()
|
||||
// intent.setClass(context, UmengMessageReceiver::class.java)
|
||||
// intent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
// intent.putExtra(EntranceUtils.KEY_TYPE, UmengMessageReceiver.DIRECT_ONLY)
|
||||
// intent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
// intent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
// context.sendBroadcast(intent)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
|
||||
// if (data != null
|
||||
// && data.link?.link == "system"
|
||||
// && !UserManager.getInstance().isLoggedIn) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// val clickIntent = Intent()
|
||||
// val removeIntent = Intent()
|
||||
//
|
||||
// clickIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
// clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
// clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
// clickIntent.putExtra(MESSAGE_ID, msg?.msgId)
|
||||
// clickIntent.putExtra(PUSH_ID, data?.pushId)
|
||||
// clickIntent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
// clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
|
||||
//
|
||||
// removeIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
// removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
|
||||
// removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
//
|
||||
// val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
|
||||
// clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
|
||||
// removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
// notificationManager.createNotificationChannel(channel)
|
||||
// }
|
||||
//
|
||||
// val notification = NotificationCompat.Builder(context, "Halo_Push")
|
||||
// .setSmallIcon(R.drawable.ic_notification)
|
||||
// .setTicker(pushData.body?.ticker)
|
||||
// .setContentTitle(pushData.body?.title)
|
||||
// .setContentText(pushData.body?.text?.fromHtml())
|
||||
// .setContentIntent(clickPendingIntent)
|
||||
// .setDeleteIntent(deletePendingIntent)
|
||||
// .build()
|
||||
// notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
|
||||
//
|
||||
// notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
|
||||
// } else {
|
||||
// if (UserManager.getInstance().isLoggedIn &&
|
||||
// HALO_MESSAGE_DIALOG == pushData.body?.custom &&
|
||||
// MessageUnreadRepository.unreadLiveData.value != null) {
|
||||
// // 回答了问题或者关注了问题的消息
|
||||
// val msg = gson.fromJson(message, PushMessageEntity::class.java)
|
||||
// val data = msg?.extra?.data
|
||||
//
|
||||
// val type = if (ANSWER == data?.type) {
|
||||
// "回答了你的问题"
|
||||
// } else {
|
||||
// "回答了你关注的问题"
|
||||
// }
|
||||
//
|
||||
// val userName = StringUtils.shrinkStringWithDot(data?.userEntity?.name, 8)
|
||||
// val displayText = userName + type
|
||||
//
|
||||
// if (Notifier.isActivityValid(CurrentActivityHolder.getCurrentActivity()) &&
|
||||
// Notifier.shouldShowNotifier(data?.answer?.id + displayText)) {
|
||||
// Notifier.create(CurrentActivityHolder.getCurrentActivity())
|
||||
// .setText(displayText)
|
||||
// .setDuration(5000)
|
||||
// .setIcon(data?.userEntity?.icon)
|
||||
// .setOnClickListener(View.OnClickListener {
|
||||
// val bundle = Bundle()
|
||||
// bundle.putString(EntranceUtils.KEY_ANSWER_ID, data?.answer?.id)
|
||||
// bundle.putString(EntranceUtils.KEY_ENTRANCE, EntranceUtils.ENTRANCE_UMENG)
|
||||
// bundle.putString(EntranceUtils.KEY_TO, AnswerDetailActivity::class.java.name)
|
||||
// EntranceUtils.jumpActivity(context, bundle)
|
||||
//
|
||||
// MtaHelper.onEvent("消息弹窗", type, "Does not contains any parameter.")
|
||||
//
|
||||
// // 标记已读
|
||||
// val jsonObject = JSONObject()
|
||||
// jsonObject.put("type", type)
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
//
|
||||
// RetrofitManager.getInstance(application).api.postMessageRead(UserManager.getInstance().userId, data?.id, body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(object : Response<ResponseBody>() {
|
||||
// override fun onResponse(response: ResponseBody?) {
|
||||
// super.onResponse(response)
|
||||
// MessageUnreadRepository.loadMessageUnreadData()
|
||||
// }
|
||||
//
|
||||
// override fun onFailure(e: HttpException?) {
|
||||
// e?.printStackTrace()
|
||||
// }
|
||||
// })
|
||||
// Notifier.hide()
|
||||
// })
|
||||
// .show(false)
|
||||
// Notifier.tagNotifierAsShowed(data?.answer?.id + displayText)
|
||||
// }
|
||||
// } else if (HALO_MESSAGE_CENTER == pushData.body?.custom) {
|
||||
// // 消息中心逻辑
|
||||
// val msg = gson.fromJson(message, PushMessageUnreadEntity::class.java)
|
||||
// val data = msg?.extra?.data
|
||||
// data?.let { MessageUnreadRepository.loadMessageUnreadData() }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 规则:最多三条消息,以旧换新
|
||||
// *
|
||||
// * @return NotificationTag
|
||||
// */
|
||||
// private fun getNotificationTag(context: Context): String {
|
||||
// val sp = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
// val edit = sp.edit()
|
||||
//
|
||||
// val timeTagMap = HashMap<Long, String>()
|
||||
// for (tag in notificationTags) {
|
||||
// val time = sp.getLong(tag, 0)
|
||||
// if (time == 0L) {
|
||||
// edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
// return tag
|
||||
// } else {
|
||||
// timeTagMap[time] = tag
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// val minTime = Collections.min(timeTagMap.keys)
|
||||
// val tag = timeTagMap[minTime]
|
||||
// edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
// return if (TextUtils.isEmpty(tag)) notificationTags[0] else tag!!
|
||||
// }
|
||||
//}
|
||||
@ -4,16 +4,20 @@ import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
import com.gh.common.util.ClickUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.lightgame.utils.RuntimeUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
* @Date 17/05/2017
|
||||
@ -58,6 +62,18 @@ public class BaseDialogFragment extends DialogFragment {
|
||||
public boolean onBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(@NonNull FragmentManager manager, @Nullable String tag) {
|
||||
Fragment fragment = manager.findFragmentByTag(tag);
|
||||
if (fragment != null) {
|
||||
FragmentTransaction transaction = manager.beginTransaction();
|
||||
transaction.show(fragment);
|
||||
transaction.commit();
|
||||
} else {
|
||||
super.show(manager, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,15 +3,6 @@ package com.gh.base.fragment;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CheckedTextView;
|
||||
@ -21,6 +12,7 @@ import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.lightgame.view.NoScrollableViewPager;
|
||||
@ -28,6 +20,10 @@ import com.lightgame.view.NoScrollableViewPager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import butterknife.BindView;
|
||||
|
||||
/**
|
||||
@ -83,10 +79,27 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) mCheckedIndex = getArguments().getInt(PAGE_INDEX, 0);
|
||||
mFragmentsList = new ArrayList<>();
|
||||
initFragmentList(mFragmentsList);
|
||||
mTabTitleList = new ArrayList<>();
|
||||
initTabTitleList(mTabTitleList);
|
||||
mFragmentsList = new ArrayList<>(restoreFragments());
|
||||
if (mFragmentsList.isEmpty() || mFragmentsList.size() != mTabTitleList.size()) {
|
||||
mFragmentsList.clear();
|
||||
initFragmentList(mFragmentsList);
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Fragment> restoreFragments() {
|
||||
String tag = "android:switcher:" + mViewPager.getId() + ":";
|
||||
ArrayList<Fragment> fragments = new ArrayList<>();
|
||||
int childCount = mTabTitleList.size();
|
||||
for (int index = 0; index < childCount; index++) {
|
||||
Fragment fragment = getChildFragmentManager().findFragmentByTag(tag + index);
|
||||
if (fragment != null) {
|
||||
fragments.add(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
package com.gh.base.fragment
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
@ -13,9 +11,8 @@ import com.gh.base.adapter.FragmentAdapter
|
||||
import com.gh.common.view.TabIndicatorView
|
||||
import com.gh.gamecenter.R
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import com.lightgame.utils.Utils
|
||||
import com.lightgame.view.NoScrollableViewPager
|
||||
import java.util.*
|
||||
|
||||
abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeListener {
|
||||
|
||||
@ -72,9 +69,15 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
super.onFragmentFirstVisible()
|
||||
mTabTitleList.clear()
|
||||
mFragmentsList.clear()
|
||||
|
||||
initFragmentList(mFragmentsList)
|
||||
initTabTitleList(mTabTitleList)
|
||||
mFragmentsList.addAll(restoreFragments())
|
||||
if (mFragmentsList.isEmpty() || mFragmentsList.size != mTabTitleList.size) {
|
||||
mFragmentsList.clear()
|
||||
initFragmentList(mFragmentsList)
|
||||
}
|
||||
|
||||
mViewPager.offscreenPageLimit = mFragmentsList.size
|
||||
mViewPager.addOnPageChangeListener(this)
|
||||
@ -95,6 +98,19 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex)
|
||||
}
|
||||
|
||||
private fun restoreFragments(): ArrayList<Fragment> {
|
||||
val tag = "android:switcher:${mViewPager.id}:"
|
||||
val fragments = ArrayList<Fragment>()
|
||||
val childCount = mTabTitleList.size
|
||||
for (index in 0 until childCount) {
|
||||
val fragment = childFragmentManager.findFragmentByTag("$tag$index")
|
||||
if (fragment != null) {
|
||||
fragments.add(fragment)
|
||||
}
|
||||
}
|
||||
return fragments
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
|
||||
override fun onPageSelected(position: Int) {}
|
||||
|
||||
@ -13,13 +13,16 @@ import com.gh.common.view.dsbridge.CompletionHandler
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.ImageViewerActivity
|
||||
import com.gh.gamecenter.LoginActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.Badge
|
||||
import com.gh.gamecenter.entity.MtaEvent
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.security.BindPhoneActivity
|
||||
import com.gh.gamecenter.user.LoginTag
|
||||
import com.gh.gamecenter.user.UserRepository
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@ -51,7 +54,7 @@ class DefaultJsApi(var context: Context) {
|
||||
|
||||
@JavascriptInterface
|
||||
fun getUserInfo(msg: Any): String {
|
||||
return UserManager.getInstance().userInfoEntity.toJson()
|
||||
return UserManager.getInstance().userInfoEntity?.toJson() ?: ""
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -70,9 +73,9 @@ class DefaultJsApi(var context: Context) {
|
||||
val userInfoEntity = UserManager.getInstance().userInfoEntity
|
||||
if (msg.toString().isNotEmpty()) {
|
||||
val badge = msg.toString().toObject() ?: Badge()
|
||||
userInfoEntity.badge = badge
|
||||
userInfoEntity?.badge = badge
|
||||
} else {
|
||||
userInfoEntity.badge = null
|
||||
userInfoEntity?.badge = null
|
||||
}
|
||||
UserManager.getInstance().userInfoEntity = userInfoEntity
|
||||
}
|
||||
@ -215,7 +218,44 @@ class DefaultJsApi(var context: Context) {
|
||||
DialogUtils.showLowVersionDialog(context)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun shareBase64Image(event: Any) {
|
||||
val imageShareEvent = event.toString().toObject() ?: ImageShareEvent()
|
||||
val context = CurrentActivityHolder.getCurrentActivity()
|
||||
Base64ImageHolder.image = imageShareEvent.image.run {
|
||||
if (this.startsWith("data:image/png;base64")) this.split(",")[1] else this
|
||||
}
|
||||
MessageShareUtils.getInstance(context).shareFromWeb(context, imageShareEvent.type)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun bindPhone(msg: Any) {
|
||||
val intent = BindPhoneActivity.getNormalIntent(context, false)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun updateTitle(msg: Any) {
|
||||
if (context is WebActivity) {
|
||||
runOnUiThread { (context as WebActivity).setNavigationTitle(msg.toString()) }
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun logoutExitWebViewAndRedirectToLogin() {
|
||||
UserRepository.getInstance(context).logout()
|
||||
if (context is Activity) {
|
||||
AppExecutor.uiExecutor.executeWithDelay(Runnable {
|
||||
context.ifLogin("内部网页")
|
||||
(context as Activity).finish()
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
|
||||
|
||||
@Keep
|
||||
internal data class ImageShareEvent(var image: String = "", var type: String = "")
|
||||
|
||||
}
|
||||
|
||||
@ -6,10 +6,12 @@ import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.util.Base64
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DirectUtils.directToFeedback
|
||||
import com.gh.common.util.DirectUtils.directToGameDetailVideoStreaming
|
||||
import com.gh.common.util.DirectUtils.directToGameServerCalendar
|
||||
import com.gh.common.util.DirectUtils.directToGameVideo
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.DirectUtils.directToQa
|
||||
import com.gh.common.util.DirectUtils.directToVideoDetail
|
||||
import com.gh.common.util.GsonUtils.gson
|
||||
import com.gh.gamecenter.LibaoDetailActivity
|
||||
@ -277,7 +279,33 @@ object DefaultUrlHandler {
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_FORUM -> {
|
||||
DirectUtils.directToForum(context);
|
||||
DirectUtils.directToForum(context)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_SUGGESTION -> {
|
||||
val platform = uri.getQueryParameter(EntranceUtils.KEY_PLATFORM)
|
||||
val platformName = PlatformUtils.getInstance(context).getPlatformName(platform)
|
||||
val gameId = uri.getQueryParameter(EntranceUtils.KEY_GAMEID)
|
||||
val packageMd5 = uri.getQueryParameter(EntranceUtils.KEY_PACKAGE_MD5)
|
||||
val content = if (TextUtils.isEmpty(gameId) || TextUtils.isEmpty(packageMd5)) String.format("%s-%s-V%s,",
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
if (TextUtils.isEmpty(platformName)) platform else platformName,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_VERSION)) else String.format("%s-%s-V%s\n游戏ID:%s\n游戏包MD5:%s\n",
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
if (TextUtils.isEmpty(platformName)) platform else platformName,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_VERSION), gameId, packageMd5)
|
||||
val qaId = uri.getQueryParameter("qa_id") ?: ""
|
||||
val qaTitle = uri.getQueryParameter(EntranceUtils.KEY_QA_TITLE)
|
||||
if (!TextUtils.isEmpty(qaId)) {
|
||||
directToQa(context, qaTitle, qaId)
|
||||
} else {
|
||||
directToFeedback(context, content, EntranceUtils.ENTRANCE_BROWSER)
|
||||
}
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_HELP_AND_FEEDBACK -> {
|
||||
val position = uri.getQueryParameter("position") ?: ""
|
||||
DirectUtils.directToHelpAndFeedback(context, position.toInt())
|
||||
}
|
||||
else -> DialogUtils.showLowVersionDialog(context)
|
||||
}
|
||||
|
||||
@ -64,7 +64,9 @@ object FixedRateJobHelper {
|
||||
|
||||
// 更新游戏屏蔽信息
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % REGION_SETTING_PERIOD == 0L) {
|
||||
RegionSettingHelper.getRegionSetting()
|
||||
if (HaloApp.getInstance().isRunningForeground) {
|
||||
RegionSettingHelper.getRegionSetting()
|
||||
}
|
||||
}
|
||||
|
||||
// 提交视频浏览记录数据
|
||||
|
||||
@ -1,39 +1,39 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.gh.common.im.ImManager
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.m7.imkfsdk.chat.ChatActivity
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* 可使用 [LocalBroadcastManager] 来进行简单的模块间消息通知
|
||||
*/
|
||||
|
||||
class LocalBroadcastReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
intent?.let {
|
||||
when (intent.action) {
|
||||
ChatActivity.ACTION_DISMISS_FLOATING_WINDOW -> {
|
||||
ImManager.dismissFloatingWindow()
|
||||
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api.postImEnding(UserManager.getInstance().userId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe()
|
||||
}
|
||||
|
||||
ChatActivity.ACTION_HIDE_UNREAD_DOT -> {
|
||||
ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
}
|
||||
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//package com.gh.common
|
||||
//
|
||||
//import android.content.BroadcastReceiver
|
||||
//import android.content.Context
|
||||
//import android.content.Intent
|
||||
//import com.gh.common.im.ImManager
|
||||
//import com.gh.gamecenter.manager.UserManager
|
||||
//import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
//import com.halo.assistant.HaloApp
|
||||
//import com.m7.imkfsdk.chat.ChatActivity
|
||||
//import io.reactivex.schedulers.Schedulers
|
||||
//
|
||||
///**
|
||||
// * 可使用 [LocalBroadcastManager] 来进行简单的模块间消息通知
|
||||
// */
|
||||
//
|
||||
//class LocalBroadcastReceiver : BroadcastReceiver() {
|
||||
//
|
||||
// override fun onReceive(context: Context?, intent: Intent?) {
|
||||
// intent?.let {
|
||||
// when (intent.action) {
|
||||
// ChatActivity.ACTION_DISMISS_FLOATING_WINDOW -> {
|
||||
// ImManager.dismissFloatingWindow()
|
||||
//
|
||||
// RetrofitManager.getInstance(HaloApp.getInstance().application).api.postImEnding(UserManager.getInstance().userId)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .subscribe()
|
||||
// }
|
||||
//
|
||||
// ChatActivity.ACTION_HIDE_UNREAD_DOT -> {
|
||||
// ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
// }
|
||||
//
|
||||
// else -> return
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -1,29 +1,8 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.preference.PreferenceManager
|
||||
import com.gh.base.GHUmengNotificationService
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.util.edit
|
||||
import com.gh.common.util.toJson
|
||||
import com.gh.common.util.toObject
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.entity.AliasEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import com.umeng.commonsdk.UMConfigure
|
||||
import com.umeng.message.IUmengRegisterCallback
|
||||
import com.umeng.message.PushAgent
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.android.agoo.huawei.HuaWeiRegister
|
||||
import org.android.agoo.mezu.MeizuRegister
|
||||
import org.android.agoo.xiaomi.MiPushRegistar
|
||||
import org.json.JSONObject
|
||||
|
||||
object PushManager {
|
||||
|
||||
@ -36,103 +15,103 @@ object PushManager {
|
||||
|
||||
@JvmStatic
|
||||
fun init(channel: String) {
|
||||
tryWithDefaultCatch {
|
||||
//初始化友盟推送
|
||||
UMConfigure.init(mApplication, Config.UMENG_APPKEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Config.UMENG_MESSAGE_SECRET)
|
||||
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
runOnIoThread { registerDevice() }
|
||||
|
||||
// 注册小米、华为和魅族通道
|
||||
MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
|
||||
HuaWeiRegister.register(mApplication)
|
||||
MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
|
||||
|
||||
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
|
||||
mPreviousAlias = aliasInSp?.toObject()
|
||||
|
||||
if (mPreviousAlias == null) {
|
||||
getAndSetAlias()
|
||||
}
|
||||
|
||||
// 完全自定义处理(透传)
|
||||
pushAgent.setPushIntentServiceClass(GHUmengNotificationService::class.java)
|
||||
}
|
||||
// tryWithDefaultCatch {
|
||||
// //初始化友盟推送
|
||||
// UMConfigure.init(mApplication, Config.UMENG_APPKEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Config.UMENG_MESSAGE_SECRET)
|
||||
//
|
||||
// val pushAgent = PushAgent.getInstance(mApplication)
|
||||
//
|
||||
// runOnIoThread { registerDevice() }
|
||||
//
|
||||
// // 注册小米、华为和魅族通道
|
||||
// MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
|
||||
// HuaWeiRegister.register(mApplication)
|
||||
// MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
|
||||
//
|
||||
// val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
|
||||
// mPreviousAlias = aliasInSp?.toObject()
|
||||
//
|
||||
// if (mPreviousAlias == null) {
|
||||
// getAndSetAlias()
|
||||
// }
|
||||
//
|
||||
// // 完全自定义处理(透传)
|
||||
// pushAgent.setPushIntentServiceClass(GHUmengNotificationService::class.java)
|
||||
// }
|
||||
}
|
||||
|
||||
private fun registerDevice() {
|
||||
PushAgent.getInstance(mApplication).register(object : IUmengRegisterCallback {
|
||||
override fun onSuccess(dToken: String) {
|
||||
//注册成功会返回device token
|
||||
deviceToken = dToken
|
||||
getAndSetAlias()
|
||||
Utils.log("deviceToken::$dToken")
|
||||
}
|
||||
|
||||
override fun onFailure(s: String, s1: String) {
|
||||
Utils.log("deviceToken::" + "注册失败")
|
||||
}
|
||||
})
|
||||
// PushAgent.getInstance(mApplication).register(object : IUmengRegisterCallback {
|
||||
// override fun onSuccess(dToken: String) {
|
||||
// //注册成功会返回device token
|
||||
// deviceToken = dToken
|
||||
// getAndSetAlias()
|
||||
// Utils.log("deviceToken::$dToken")
|
||||
// }
|
||||
//
|
||||
// override fun onFailure(s: String, s1: String) {
|
||||
// Utils.log("deviceToken::" + "注册失败")
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getAndSetAlias() {
|
||||
if (deviceToken.isNullOrEmpty()) {
|
||||
registerDevice()
|
||||
return
|
||||
}
|
||||
|
||||
val meta = MetaUtil.getMeta()
|
||||
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("device_token", deviceToken)
|
||||
jsonObject.put("imei", meta.imei)
|
||||
jsonObject.put("android_id", meta.android_id)
|
||||
jsonObject.put("model", meta.model)
|
||||
jsonObject.put("manufacturer", meta.manufacturer)
|
||||
jsonObject.put("os", meta.os)
|
||||
jsonObject.put("os_version", meta.android_version)
|
||||
jsonObject.put("mac", meta.mac)
|
||||
jsonObject.put("gid", meta.gid)
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
|
||||
RetrofitManager.getInstance(mApplication).api.getAlias(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
{ setAlias(it) },
|
||||
{ it.printStackTrace() }
|
||||
)
|
||||
// if (deviceToken.isNullOrEmpty()) {
|
||||
// registerDevice()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// val meta = MetaUtil.getMeta()
|
||||
//
|
||||
// val jsonObject = JSONObject()
|
||||
// jsonObject.put("device_token", deviceToken)
|
||||
// jsonObject.put("imei", meta.imei)
|
||||
// jsonObject.put("android_id", meta.android_id)
|
||||
// jsonObject.put("model", meta.model)
|
||||
// jsonObject.put("manufacturer", meta.manufacturer)
|
||||
// jsonObject.put("os", meta.os)
|
||||
// jsonObject.put("os_version", meta.android_version)
|
||||
// jsonObject.put("mac", meta.mac)
|
||||
// jsonObject.put("gid", meta.gid)
|
||||
//
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
//
|
||||
// RetrofitManager.getInstance(mApplication).api.getAlias(body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .subscribe(
|
||||
// { setAlias(it) },
|
||||
// { it.printStackTrace() }
|
||||
// )
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setAlias(alias: AliasEntity) {
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
mPreviousAlias = alias
|
||||
PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
putString(SP_PUSH_ALIAS, mPreviousAlias?.toJson())
|
||||
}
|
||||
|
||||
pushAgent.setAlias(alias.alias, alias.aliasType) { b, s ->
|
||||
Utils.log("注册别名 $b + $s")
|
||||
}
|
||||
// val pushAgent = PushAgent.getInstance(mApplication)
|
||||
//
|
||||
// mPreviousAlias = alias
|
||||
// PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
// putString(SP_PUSH_ALIAS, mPreviousAlias?.toJson())
|
||||
// }
|
||||
//
|
||||
// pushAgent.setAlias(alias.alias, alias.aliasType) { b, s ->
|
||||
// Utils.log("注册别名 $b + $s")
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteAlias() {
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
mPreviousAlias?.let {
|
||||
pushAgent.deleteAlias(it.alias, it.aliasType) { b, s ->
|
||||
Utils.log("删除别名 $b + $s")
|
||||
}
|
||||
}
|
||||
PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
putString(SP_PUSH_ALIAS, "")
|
||||
}
|
||||
mPreviousAlias = null
|
||||
// val pushAgent = PushAgent.getInstance(mApplication)
|
||||
//
|
||||
// mPreviousAlias?.let {
|
||||
// pushAgent.deleteAlias(it.alias, it.aliasType) { b, s ->
|
||||
// Utils.log("删除别名 $b + $s")
|
||||
// }
|
||||
// }
|
||||
// PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
// putString(SP_PUSH_ALIAS, "")
|
||||
// }
|
||||
// mPreviousAlias = null
|
||||
}
|
||||
}
|
||||
3
app/src/main/java/com/gh/common/Typealias.kt
Normal file
3
app/src/main/java/com/gh/common/Typealias.kt
Normal file
@ -0,0 +1,3 @@
|
||||
package com.gh.common
|
||||
|
||||
typealias OnFastClickListener = (isSuccess: Boolean) -> Unit
|
||||
@ -5,8 +5,6 @@ import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.util.GsonUtils;
|
||||
import com.gh.common.util.PackageHelper;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
@ -25,6 +23,7 @@ import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
@ -241,6 +240,9 @@ public class Config {
|
||||
public static boolean isGameDomeSwitchOpen() {
|
||||
return getSettings() != null && getSettings().getGameDomeSwitch().equals("on");
|
||||
}
|
||||
public static boolean isPermissionPopupSwitchOpen() {
|
||||
return getSettings() != null && getSettings().getPermissionPopupSwitch().equals("on");
|
||||
}
|
||||
|
||||
public static void fixHideFunction() {
|
||||
SharedPreferences preferences = PreferenceManager.
|
||||
|
||||
@ -51,11 +51,17 @@ public class Constants {
|
||||
|
||||
public static final String EXTRA_DOWNLOAD_TYPE = "extra_download_type";
|
||||
public static final String SILENT_UPDATE = "静默更新";
|
||||
public static final String SIMULATOR_DOWNLOAD = "下载模拟器";
|
||||
public static final String SIMULATOR_GAME = "simulator_game";
|
||||
public static final String SIMULATOR_DOWNLOAD_START_TIME = "simulator_download_start_time";
|
||||
public static final String LAST_GHZS_UPDATE_FILE_SIZE = "last_ghzs_update_file_size";
|
||||
|
||||
// 新用户首次启动光环的时间
|
||||
public static final String SP_INITIAL_USAGE_TIME = "initial_usage_time";
|
||||
|
||||
public static final String SP_IMEI = "imei";
|
||||
public static final String SP_ANDROID_ID = "android_id";
|
||||
|
||||
//引导设置 “通知管理” 引导弹窗
|
||||
public static final String SP_SHOWED_NOTIFICATION_LOGIN = "show_notification_login_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_QUESTION = "show_notification_question_hint";
|
||||
@ -115,6 +121,14 @@ public class Constants {
|
||||
public static final String SP_WECHAT_SHOW_BIND_PHONE_TIME = "wechat_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
public static final String SP_WEIBO_SHOW_BIND_PHONE_TIME = "weibo_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
public static final String SP_DOUYIN_SHOW_BIND_PHONE_TIME = "douyin_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
//隐私政策是否有更新
|
||||
public static final String SP_PRIVACY_CURRENT_MD5 = "sp_privacy_current_md5";
|
||||
public static final String SP_PRIVACY_MINE_MD5 = "sp_privacy_mine_md5";
|
||||
public static final String SP_PRIVACY_SETTING_MD5 = "sp_privacy_setting_md5";
|
||||
public static final String SP_PRIVACY_MD5 = "sp_privacy_md5";
|
||||
|
||||
public static final String SP_IS_USER_ACCEPTED_PRIVACY_STATEMENT = "has_user_accepted_privacy_statement";
|
||||
public static final String SP_BRAND_NEW_USER = "brand_new_user";
|
||||
|
||||
//手机号码匹配规则
|
||||
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
||||
@ -132,16 +146,32 @@ public class Constants {
|
||||
public static final String REGULATION_TEST_ADDRESS_DEV = "https://static-web.ghzs.com/etiquette-dev/index.html#/";
|
||||
public static final String REGULATION_TEST_ADDRESS = "https://static-web.ghzs.com/etiquette/index.html#/";
|
||||
|
||||
// 徽章
|
||||
public static final String BADGE_ADDRESS_DEV = "http://resource.ghzs.com/page/badge_dev/index.html#/";
|
||||
public static final String BADGE_ADDRESS = "http://resource.ghzs.com/page/badge_pro/index.html#/";
|
||||
// 徽章中心
|
||||
public static final String BADGE_ADDRESS_DEV = "https://static-web.ghzs.com/badge-dev/index.html#/";
|
||||
public static final String BADGE_ADDRESS = "https://static-web.ghzs.com/badge/index.html#/";
|
||||
|
||||
// 徽章详情
|
||||
public static final String BADGE_DETAIL_ADDRESS_DEV = "https://static-web.ghzs.com/badge-dev/index.html#/badgedetail";
|
||||
public static final String BADGE_DETAIL_ADDRESS = "https://static-web.ghzs.com/badge/index.html#/badgedetail";
|
||||
|
||||
// 分享个人主页地址
|
||||
public static final String SHARE_USER_HOME_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs-userhome-dev/index.html#/";
|
||||
public static final String SHARE_USER_HOME_ADDRESS = "https://static-web.ghzs.com/ghzs-userhome/index.html#/";
|
||||
|
||||
// 腾讯企点地址
|
||||
public static final String TENCENT_QIDIAN_ADDRESS = "https://url.cn/D80iyMVV?_type=wpa&qidian=true";
|
||||
public static final String TENCENT_QIDIAN_ADDRESS = "https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2355094296&fid=457&key=c76dcb2e3d582b6ffbfb5bb22cde85ff&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true";
|
||||
|
||||
//版规声明
|
||||
public static final String FORUM_REGULATIONS_NEWS_ID = "5f4db9cc34d44d01b92fd670";
|
||||
|
||||
//帮助内容详情
|
||||
public static final String HELP_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content=";
|
||||
public static final String HELP_ADDRESS = "https://static-web.ghzs.com/ghzs_help/help.html?content=";
|
||||
|
||||
// 注销页面
|
||||
public static final String LOGOUT_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content=5f6b1f02786564003944a693";
|
||||
public static final String LOGOUT_ADDRESS = "https://static-web.ghzs.com/ghzs_help/help.html?content=5f534111b1f72909fc225672";
|
||||
|
||||
//最少需要多少数据才能上传
|
||||
public static final int DATA_AMOUNT = 20;
|
||||
|
||||
|
||||
@ -32,6 +32,9 @@ public class ItemViewType {
|
||||
public static final int IMAGE_SLIDE_ITEM = 23;
|
||||
public static final int VERTICAL_SLIDE_ITEM = 24;
|
||||
public static final int COLUMN_COLLECTION = 25;
|
||||
public static final int GALLERY_SLIDE = 27; // 首页自动滚动画廊专题
|
||||
public static final int GALLERY = 28; // 首页倾斜画廊专题
|
||||
public static final int BLANK_DIVIDER = 29; // 空白补充区域
|
||||
|
||||
/**
|
||||
* 普通列表
|
||||
|
||||
@ -14,12 +14,6 @@ import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.base.OnViewClickListener;
|
||||
import com.gh.common.constant.Config;
|
||||
@ -28,6 +22,8 @@ import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorDownloadManager;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
@ -72,11 +68,18 @@ import com.lightgame.utils.Utils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
/**
|
||||
* Created by khy on 12/02/18.
|
||||
*/
|
||||
@ -436,6 +439,15 @@ public class BindingAdapters {
|
||||
case PLUGIN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
ApkEntity apk = gameEntity.getApk().get(0);
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
|
||||
if (gameEntity.getSimulator() != null) {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(v.getContext(), gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(v.getContext(), gameEntity.getSimulator(),
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
@ -461,6 +473,20 @@ public class BindingAdapters {
|
||||
break;
|
||||
case LAUNCH_OR_OPEN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
//启动模拟器游戏
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
return;
|
||||
}
|
||||
|
||||
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
|
||||
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
@ -516,9 +542,12 @@ public class BindingAdapters {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton()));
|
||||
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton()));
|
||||
progressBar.getContext().startActivity(i);
|
||||
break;
|
||||
case UPDATING:
|
||||
Utils.toast(progressBar.getContext(), "正在加急更新版本,敬请后续留意");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@ -548,10 +577,14 @@ public class BindingAdapters {
|
||||
} else {
|
||||
if (offStatus != null && "dialog".equals(offStatus)) {
|
||||
progressBar.setText("查看");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
} else if ("updating".equals(offStatus)) {
|
||||
progressBar.setText("更新中");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.UPDATING);
|
||||
} else {
|
||||
progressBar.setText("暂无");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
}
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@ -26,21 +26,12 @@ import com.gh.gamecenter.UserInfoEditActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.AuthDialogEntity
|
||||
import com.gh.gamecenter.entity.AuthDialogLevel
|
||||
import com.gh.gamecenter.entity.DeviceDialogEntity
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.user.UserViewModel
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.halo.assistant.fragment.user.UserInfoEditFragment
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class CertificationDialog(context: Context, private val authDialogEntity: AuthDialogEntity, val gameId: String, val listener: DialogUtils.ConfirmListener) :
|
||||
Dialog(context, R.style.GhAlertDialog) {
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.util.PermissionHelper
|
||||
import com.gh.common.util.PermissionHelper.INSTALL_PERMISS_CODE
|
||||
import com.gh.common.util.goneIf
|
||||
import com.gh.gamecenter.R
|
||||
import kotlin.random.Random
|
||||
|
||||
class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
|
||||
|
||||
lateinit var mView: View
|
||||
var mCallBack: (() -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
mView = inflater.inflate(R.layout.dialog_install_permission, null, false)
|
||||
return mView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val closeTv = mView.findViewById<TextView>(R.id.closeTv)
|
||||
val closeIv = mView.findViewById<ImageView>(R.id.closeIv)
|
||||
val activateTv = mView.findViewById<TextView>(R.id.activateTv)
|
||||
val switchLottie = mView.findViewById<LottieAnimationView>(R.id.switchLottie)
|
||||
|
||||
switchLottie.setAnimation("lottie/install_permission_switch.json")
|
||||
switchLottie.playAnimation()
|
||||
|
||||
val randomNumber = Random.nextInt(2)
|
||||
closeTv.goneIf(randomNumber == 0)
|
||||
closeIv.goneIf(randomNumber != 0)
|
||||
closeTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), "文案样式_点击以后再说")
|
||||
dismiss()
|
||||
}
|
||||
closeIv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), "图标样式_点击关闭")
|
||||
dismiss()
|
||||
}
|
||||
activateTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), if (randomNumber == 0) "文案样式_点击立即开启" else "图标样式_点击立即开启")
|
||||
PermissionHelper.toInstallPermissionSetting(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISS_CODE) {
|
||||
mCallBack?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEvent(): String = "安装引导弹窗"
|
||||
|
||||
override fun getKey(): String = "引导弹窗"
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(activity: AppCompatActivity, callBack: (() -> Unit)?) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
if (!Config.isPermissionPopupSwitchOpen()) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
val haveInstallPermission = activity.packageManager.canRequestPackageInstalls();
|
||||
if (haveInstallPermission) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
|
||||
}
|
||||
var installPermissionDialogFragment = activity.supportFragmentManager.findFragmentByTag(InstallPermissionDialogFragment::class.java.simpleName) as? InstallPermissionDialogFragment
|
||||
if (installPermissionDialogFragment != null) {
|
||||
installPermissionDialogFragment.mCallBack = callBack
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(installPermissionDialogFragment)
|
||||
transaction.commit()
|
||||
} else {
|
||||
installPermissionDialogFragment = InstallPermissionDialogFragment().apply {
|
||||
mCallBack = callBack
|
||||
}
|
||||
installPermissionDialogFragment.show(activity.supportFragmentManager, InstallPermissionDialogFragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,6 @@ package com.gh.common.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.res.AssetManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
@ -48,7 +47,7 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
val index = Random.nextInt(2)
|
||||
val jsonArray = JSONArray(jsonString)
|
||||
val jsonObj = jsonArray.getJSONObject(index)
|
||||
if (!jsonObj.has(mNotificationUgc!!.value)) {
|
||||
if (!jsonObj.has(mNotificationUgc?.value)) {
|
||||
Utils.log("ugc type error")
|
||||
return
|
||||
}
|
||||
|
||||
154
app/src/main/java/com/gh/common/dialog/PrivacyDialogFragment.kt
Normal file
154
app/src/main/java/com/gh/common/dialog/PrivacyDialogFragment.kt
Normal file
@ -0,0 +1,154 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.gh.base.fragment.BaseDialogFragment
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
class PrivacyDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private val mLocalPrivacyHtml = "file:///android_asset/privacy_policies.html"
|
||||
private val mLocalRegulationHtml = "file:///android_asset/user_regulation.html"
|
||||
|
||||
var containerView: View? = null
|
||||
var mCallBack: ((isSuccess: Boolean) -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
containerView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_privacy_protocol, null, false)
|
||||
return containerView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
|
||||
val mWebViewRegulation = containerView?.findViewById<WebView>(R.id.webView2)
|
||||
|
||||
mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
|
||||
mWebViewRegulation?.isHorizontalScrollBarEnabled = false
|
||||
|
||||
val mTitlePrivacyTv = containerView?.findViewById<TextView>(R.id.privacyTitleTv)
|
||||
val mTitleRegulationTv = containerView?.findViewById<TextView>(R.id.userRegulationTitleTv)
|
||||
|
||||
val settingsArrayList = arrayListOf(mWebViewPrivacy?.settings, mWebViewRegulation?.settings)
|
||||
|
||||
for (settings in settingsArrayList) {
|
||||
settings?.javaScriptEnabled = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
settings?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
|
||||
}
|
||||
// 避免提示网页有害信息不能访问
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
settings?.safeBrowsingEnabled = false
|
||||
}
|
||||
|
||||
// 适配大于屏幕宽度的页面
|
||||
settings?.useWideViewPort = true
|
||||
settings?.loadWithOverviewMode = true
|
||||
settings?.domStorageEnabled = true
|
||||
|
||||
// 自适应屏幕
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
settings?.layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||
}
|
||||
}
|
||||
|
||||
// if (NetworkUtils.isNetworkConnected(requireContext())) {
|
||||
// mWebViewPrivacy?.loadUrl(requireContext().getString(R.string.privacy_policy_url))
|
||||
// mWebViewRegulation?.loadUrl(requireContext().getString(R.string.user_regulation_url))
|
||||
// } else {
|
||||
mWebViewPrivacy?.loadUrl(mLocalPrivacyHtml)
|
||||
mWebViewRegulation?.loadUrl(mLocalRegulationHtml)
|
||||
// }
|
||||
|
||||
// val client = object : WebViewClient() {
|
||||
// override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
|
||||
// super.onReceivedError(view, request, error)
|
||||
// if (view == mWebViewPrivacy) {
|
||||
// view?.loadUrl(mLocalPrivacyHtml)
|
||||
// } else {
|
||||
// view?.loadUrl(mLocalRegulationHtml)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// mWebViewPrivacy?.webViewClient = client
|
||||
// mWebViewRegulation?.webViewClient = client
|
||||
|
||||
mTitlePrivacyTv?.setOnClickListener {
|
||||
mTitlePrivacyTv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
|
||||
mTitleRegulationTv?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_F5F5F5))
|
||||
|
||||
mWebViewPrivacy?.visibility = View.VISIBLE
|
||||
mWebViewRegulation?.visibility = View.GONE
|
||||
}
|
||||
|
||||
mTitleRegulationTv?.setOnClickListener {
|
||||
mTitlePrivacyTv?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_F5F5F5))
|
||||
mTitleRegulationTv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
|
||||
|
||||
mWebViewPrivacy?.visibility = View.GONE
|
||||
mWebViewRegulation?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
containerView?.findViewById<View>(R.id.refuseTv)?.setOnClickListener {
|
||||
mCallBack?.invoke(false)
|
||||
dismiss()
|
||||
}
|
||||
containerView?.findViewById<View>(R.id.agreeTv)?.setOnClickListener {
|
||||
mCallBack?.invoke(true)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val createDialog = super.onCreateDialog(savedInstanceState)
|
||||
createDialog.setCanceledOnTouchOutside(false)
|
||||
createDialog.setOnKeyListener(object : DialogInterface.OnKeyListener {
|
||||
override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
val window = createDialog.window
|
||||
window?.setGravity(Gravity.CENTER)
|
||||
return createDialog
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val width = requireContext().resources.displayMetrics.widthPixels - 60F.dip2px()
|
||||
val height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
dialog?.window?.setLayout(width, height)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(activity: AppCompatActivity, callBack: ((isSuccess: Boolean) -> Unit)?) {
|
||||
var privacyDialogFragment = activity.supportFragmentManager.findFragmentByTag(PrivacyDialogFragment::class.java.simpleName) as? PrivacyDialogFragment
|
||||
if (privacyDialogFragment != null) {
|
||||
privacyDialogFragment.mCallBack = callBack
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(privacyDialogFragment)
|
||||
transaction.commit()
|
||||
} else {
|
||||
privacyDialogFragment = PrivacyDialogFragment().apply {
|
||||
mCallBack = callBack
|
||||
}
|
||||
privacyDialogFragment.show(activity.supportFragmentManager, PrivacyDialogFragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,7 +170,7 @@ class ReserveDialogFragment
|
||||
}
|
||||
|
||||
private fun setMobileIndexHint(reserveMobile: String?) {
|
||||
var userMobile = UserManager.getInstance().userInfoEntity.mobile
|
||||
var userMobile = UserManager.getInstance().userInfoEntity?.mobile
|
||||
if (reserveMobile == userMobile) userMobile = null
|
||||
|
||||
if (!reserveMobile.isNullOrEmpty()) {
|
||||
|
||||
@ -17,6 +17,10 @@ data class ExposureEntity(
|
||||
val downloadType: String? = "",
|
||||
val downloadCompleteType: String? = "",
|
||||
|
||||
// 下载地址的 host 和 path
|
||||
var host: String? = "",
|
||||
var path: String? = "",
|
||||
|
||||
// 统计启动弹窗相关数据用的 (ugly)
|
||||
@SerializedName("dialog_id")
|
||||
var welcomeDialogId: String? = "",
|
||||
|
||||
@ -26,6 +26,8 @@ data class ExposureEvent(
|
||||
@PrimaryKey
|
||||
val id: String = UUID.randomUUID().toString()) : Parcelable {
|
||||
companion object {
|
||||
|
||||
// TODO 建一个 exposureEvent 池规避反复生成对象
|
||||
@JvmStatic
|
||||
fun createEvent(gameEntity: GameEntity?, source: List<ExposureSource>, eTrace: List<ExposureEvent>? = null, event: ExposureType = ExposureType.EXPOSURE): ExposureEvent {
|
||||
if (gameEntity?.getApk()?.size == 1) {
|
||||
|
||||
@ -43,7 +43,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
if (layoutManager == null) layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
|
||||
layoutManager?.run {
|
||||
visibleState = ExposureThrottleBus.VisibleState(findFirstCompletelyVisibleItemPosition(), findLastCompletelyVisibleItemPosition())
|
||||
visibleState = ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus?.postVisibleState(visibleState!!)
|
||||
}
|
||||
}
|
||||
@ -55,7 +55,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
|
||||
for (pos in visibleState.firstCompletelyVisible..visibleState.lastCompletelyVisible) {
|
||||
for (pos in visibleState.firstVisiblePosition..visibleState.lastVisiblePosition) {
|
||||
try {
|
||||
exposable.getEventByPosition(pos)?.let { eventList.add(it) }
|
||||
exposable.getEventListByPosition(pos)?.let { eventList.addAll(it) }
|
||||
|
||||
@ -3,6 +3,7 @@ package com.gh.common.exposure
|
||||
import com.aliyun.sls.android.sdk.model.LogGroup
|
||||
import com.gh.common.exposure.time.TimeUtil
|
||||
import com.gh.common.util.toJson
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.loghub.LgLOG
|
||||
import com.gh.loghub.LoghubHelper
|
||||
@ -94,15 +95,18 @@ object ExposureManager {
|
||||
*/
|
||||
fun commitSavedExposureEvents(forced: Boolean = false) {
|
||||
exposureExecutor.execute {
|
||||
if (exposureSet.size < STORE_SIZE && !forced || exposureSet.size == 0) return@execute
|
||||
tryWithDefaultCatch {
|
||||
// TODO 初始化 loghubHelper 去掉这个 tryCatch 块
|
||||
if (exposureSet.size < STORE_SIZE && !forced || exposureSet.size == 0) return@execute
|
||||
|
||||
val exposureList = exposureSet.toList()
|
||||
// uploadLogGroup 是一个异步方法,LoghubHelper 里面实现了重传功能,所以这里交给它就好了
|
||||
loghubHelper.uploadLogGroup(buildLogGroup(exposureList))
|
||||
val exposureList = exposureSet.toList()
|
||||
// uploadLogGroup 是一个异步方法,LoghubHelper 里面实现了重传功能,所以这里交给它就好了
|
||||
loghubHelper.uploadLogGroup(buildLogGroup(exposureList))
|
||||
|
||||
Utils.log("Exposure", "提交了${exposureList.size}条曝光记录")
|
||||
exposureSet.removeAll(exposureList)
|
||||
exposureDao.deleteMany(exposureList)
|
||||
Utils.log("Exposure", "提交了${exposureList.size}条曝光记录")
|
||||
exposureSet.removeAll(exposureList)
|
||||
exposureDao.deleteMany(exposureList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,21 +38,21 @@ class ExposureThrottleBus(var onSuccess: Consumer<VisibleState>, var onError: Co
|
||||
mPublishSubject.onNext(visibleState)
|
||||
}
|
||||
|
||||
class VisibleState(val firstCompletelyVisible: Int, val lastCompletelyVisible: Int) {
|
||||
class VisibleState(val firstVisiblePosition: Int, val lastVisiblePosition: Int) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
||||
val that = other as VisibleState
|
||||
|
||||
if (firstCompletelyVisible != that.firstCompletelyVisible) return false
|
||||
if (firstVisiblePosition != that.firstVisiblePosition) return false
|
||||
|
||||
return lastCompletelyVisible == that.lastCompletelyVisible
|
||||
return lastVisiblePosition == that.lastVisiblePosition
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = firstCompletelyVisible
|
||||
result = 31 * result + lastCompletelyVisible
|
||||
var result = firstVisiblePosition
|
||||
result = 31 * result + lastVisiblePosition
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,8 @@ object ExposureUtils {
|
||||
fun logADownloadCompleteExposureEvent(entity: GameEntity,
|
||||
platform: String?,
|
||||
trace: String?,
|
||||
host: String? = "unknown",
|
||||
path: String? = "unknown",
|
||||
downloadType: DownloadType) {
|
||||
val gameEntity = entity.clone()
|
||||
gameEntity.platform = platform
|
||||
@ -47,6 +49,8 @@ object ExposureUtils {
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
event = ExposureType.DOWNLOAD_COMPLETE)
|
||||
exposureEvent.payload.host = host
|
||||
exposureEvent.payload.path = path
|
||||
ExposureManager.log(exposureEvent)
|
||||
ExposureManager.commitSavedExposureEvents(forced = true)
|
||||
}
|
||||
|
||||
@ -5,17 +5,17 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.telephony.TelephonyManager
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.leon.channel.helper.ChannelReaderUtil
|
||||
import com.walkud.rom.checker.RomIdentifier
|
||||
import java.io.File
|
||||
|
||||
object MetaUtil {
|
||||
|
||||
@ -23,9 +23,11 @@ object MetaUtil {
|
||||
private var channel = ""
|
||||
|
||||
private var m: Meta? = null
|
||||
private var imei: String? = null
|
||||
private var androidId: String? = null
|
||||
|
||||
fun refreshMeta() {
|
||||
m = Meta(mac = getMac(),
|
||||
m = Meta(mac = "",
|
||||
imei = getIMEI(),
|
||||
model = getModel(),
|
||||
manufacturer = getManufacturer(),
|
||||
@ -57,57 +59,48 @@ object MetaUtil {
|
||||
return channel
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MAC address
|
||||
* TODO check > 6.0 results
|
||||
*/
|
||||
fun getMac(): String? {
|
||||
|
||||
var mac: String = ""
|
||||
|
||||
//Plan A
|
||||
try {
|
||||
mac = File("/sys/class/net/wlan0/address").inputStream().bufferedReader().use { it.readText() }
|
||||
if (!TextUtils.isEmpty(mac)) return mac.trim()
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
// Plan B
|
||||
try {
|
||||
mac = File("/sys/class/net/eth0/address").inputStream().bufferedReader().use { it.readText() }
|
||||
if (!TextUtils.isEmpty(mac)) return mac.trim()
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
// Plan C
|
||||
val wifiManager = application.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
try {
|
||||
mac = wifiManager.connectionInfo.macAddress
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
return mac.trim()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMEI
|
||||
*/
|
||||
fun getIMEI(): String? {
|
||||
@JvmStatic
|
||||
fun getIMEI(): String {
|
||||
|
||||
if (application.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED)
|
||||
if (!HaloApp.isUserAcceptPrivacyPolicy(HaloApp.getInstance().application)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (imei != null) {
|
||||
return imei ?: ""
|
||||
}
|
||||
|
||||
imei = SPUtils.getString(Constants.SP_IMEI)
|
||||
|
||||
if (!TextUtils.isEmpty(imei)) {
|
||||
return imei ?: ""
|
||||
}
|
||||
|
||||
if (application.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
|
||||
return ""
|
||||
}
|
||||
|
||||
val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
return telephonyManager.imei
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
return "".apply {
|
||||
imei = this
|
||||
SPUtils.setString(Constants.SP_IMEI, this)
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 26) {
|
||||
return (telephonyManager.imei ?: "").apply {
|
||||
imei = this
|
||||
SPUtils.setString(Constants.SP_IMEI, this)
|
||||
}
|
||||
}
|
||||
|
||||
return telephonyManager.getDeviceId()
|
||||
return (telephonyManager.getDeviceId() ?: "").apply {
|
||||
imei = this
|
||||
SPUtils.setString(Constants.SP_IMEI, this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -119,14 +112,35 @@ object MetaUtil {
|
||||
return Build.MANUFACTURER
|
||||
}
|
||||
|
||||
fun getAndroidId(): String? {
|
||||
var android_id: String = ""
|
||||
try {
|
||||
android_id = Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
@JvmStatic
|
||||
fun getAndroidId(): String {
|
||||
|
||||
if (!HaloApp.isUserAcceptPrivacyPolicy(HaloApp.getInstance().application)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (androidId != null) {
|
||||
return androidId ?: ""
|
||||
}
|
||||
|
||||
androidId = SPUtils.getString(Constants.SP_ANDROID_ID)
|
||||
|
||||
if (!TextUtils.isEmpty(androidId)) {
|
||||
return androidId ?: ""
|
||||
}
|
||||
|
||||
return try {
|
||||
Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID).apply {
|
||||
androidId = this
|
||||
SPUtils.setString(Constants.SP_ANDROID_ID, this)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
androidId = ""
|
||||
SPUtils.setString(Constants.SP_ANDROID_ID, "")
|
||||
""
|
||||
}
|
||||
return android_id
|
||||
|
||||
}
|
||||
|
||||
fun getAndroidSDK(): Int? {
|
||||
|
||||
@ -62,7 +62,7 @@ object RegionSettingHelper {
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getRegionSetting() {
|
||||
debounceActionWithInterval(R.string.name, 3000) {
|
||||
debounceActionWithInterval(R.string.app_name, 3000) {
|
||||
// 使用默认的 Schdulers.io() 可能会触发 OOM
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.sensitiveApi
|
||||
|
||||
10
app/src/main/java/com/gh/common/iinterface/IOffsetable.kt
Normal file
10
app/src/main/java/com/gh/common/iinterface/IOffsetable.kt
Normal file
@ -0,0 +1,10 @@
|
||||
package com.gh.common.iinterface
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
interface IOffsetable {
|
||||
fun getOffset(position: Int): Int
|
||||
|
||||
fun updateOffset(position: Int, offset: Int)
|
||||
|
||||
fun resetOffset()
|
||||
}
|
||||
@ -1,67 +1,67 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.core.view.ViewCompat
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
object ImHintHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun show(activity: Activity?) {
|
||||
activity?.let {
|
||||
var hintView = retrieveHintViewFromActivity(it)
|
||||
if (hintView == null) {
|
||||
hintView = ImHintView(it)
|
||||
hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
|
||||
val decorView = it.window.decorView as ViewGroup
|
||||
it.runOnUiThread {
|
||||
decorView.addView(hintView)
|
||||
}
|
||||
} else {
|
||||
hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun dismiss(activity: Activity?) {
|
||||
activity?.let {
|
||||
clearCurrent(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun retrieveHintViewFromActivity(activity: Activity?) : ImHintView? {
|
||||
(activity?.window?.decorView as? ViewGroup)?.let {
|
||||
for (i in 0..it.childCount) {
|
||||
val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
if (childView != null && childView.windowToken != null) {
|
||||
return childView
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun clearCurrent(activity: Activity?) {
|
||||
(activity?.window?.decorView as? ViewGroup)?.let {
|
||||
for (i in 0..it.childCount) {
|
||||
val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
if (childView != null && childView.windowToken != null) {
|
||||
ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRemoveViewRunnable(childView: View?): Runnable {
|
||||
return Runnable {
|
||||
childView?.let {
|
||||
(childView.parent as? ViewGroup)?.removeView(childView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//package com.gh.common.im
|
||||
//
|
||||
//import android.app.Activity
|
||||
//import androidx.core.view.ViewCompat
|
||||
//import android.view.View
|
||||
//import android.view.ViewGroup
|
||||
//
|
||||
//object ImHintHelper {
|
||||
//
|
||||
// @JvmStatic
|
||||
// fun show(activity: Activity?) {
|
||||
// activity?.let {
|
||||
// var hintView = retrieveHintViewFromActivity(it)
|
||||
// if (hintView == null) {
|
||||
// hintView = ImHintView(it)
|
||||
// hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
//
|
||||
// val decorView = it.window.decorView as ViewGroup
|
||||
// it.runOnUiThread {
|
||||
// decorView.addView(hintView)
|
||||
// }
|
||||
// } else {
|
||||
// hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @JvmStatic
|
||||
// fun dismiss(activity: Activity?) {
|
||||
// activity?.let {
|
||||
// clearCurrent(it)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun retrieveHintViewFromActivity(activity: Activity?) : ImHintView? {
|
||||
// (activity?.window?.decorView as? ViewGroup)?.let {
|
||||
// for (i in 0..it.childCount) {
|
||||
// val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
// if (childView != null && childView.windowToken != null) {
|
||||
// return childView
|
||||
// }
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
// private fun clearCurrent(activity: Activity?) {
|
||||
// (activity?.window?.decorView as? ViewGroup)?.let {
|
||||
// for (i in 0..it.childCount) {
|
||||
// val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
// if (childView != null && childView.windowToken != null) {
|
||||
// ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun getRemoveViewRunnable(childView: View?): Runnable {
|
||||
// return Runnable {
|
||||
// childView?.let {
|
||||
// (childView.parent as? ViewGroup)?.removeView(childView)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -1,45 +1,45 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.gamecenter.R
|
||||
import kotlinx.android.synthetic.main.view_im_hint.view.*
|
||||
|
||||
class ImHintView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
: RelativeLayout(context, attrs, defStyle) {
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.view_im_hint, this)
|
||||
|
||||
ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat() - 1)
|
||||
|
||||
ivContainer.setOnClickListener {
|
||||
if (context is Activity) {
|
||||
ImManager.startChatActivity(context)
|
||||
ImManager.removeNotification()
|
||||
}
|
||||
}
|
||||
|
||||
val lp = ivContainer.layoutParams as RelativeLayout.LayoutParams
|
||||
|
||||
lp.setMargins(0, 0, dp2px(30f), dp2px(106f) + DisplayUtils.retrieveNavigationHeight(context))
|
||||
}
|
||||
|
||||
fun showDot(show: Boolean) {
|
||||
if (show) {
|
||||
unreadDot.visibility = View.VISIBLE
|
||||
} else {
|
||||
unreadDot.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun dp2px(dp: Float): Int {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.applicationContext.resources.displayMetrics).toInt()
|
||||
}
|
||||
}
|
||||
//package com.gh.common.im
|
||||
//
|
||||
//import android.app.Activity
|
||||
//import android.content.Context
|
||||
//import android.util.AttributeSet
|
||||
//import android.util.TypedValue
|
||||
//import android.view.View
|
||||
//import android.widget.RelativeLayout
|
||||
//import androidx.core.view.ViewCompat
|
||||
//import com.gh.common.util.DisplayUtils
|
||||
//import com.gh.gamecenter.R
|
||||
//import kotlinx.android.synthetic.main.view_im_hint.view.*
|
||||
//
|
||||
//class ImHintView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
// : RelativeLayout(context, attrs, defStyle) {
|
||||
//
|
||||
// init {
|
||||
// inflate(context, R.layout.view_im_hint, this)
|
||||
//
|
||||
// ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat() - 1)
|
||||
//
|
||||
// ivContainer.setOnClickListener {
|
||||
// if (context is Activity) {
|
||||
// ImManager.startChatActivity(context)
|
||||
// ImManager.removeNotification()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// val lp = ivContainer.layoutParams as RelativeLayout.LayoutParams
|
||||
//
|
||||
// lp.setMargins(0, 0, dp2px(30f), dp2px(106f) + DisplayUtils.retrieveNavigationHeight(context))
|
||||
// }
|
||||
//
|
||||
// fun showDot(show: Boolean) {
|
||||
// if (show) {
|
||||
// unreadDot.visibility = View.VISIBLE
|
||||
// } else {
|
||||
// unreadDot.visibility = View.GONE
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun dp2px(dp: Float): Int {
|
||||
// return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.applicationContext.resources.displayMetrics).toInt()
|
||||
// }
|
||||
//}
|
||||
@ -1,25 +1,9 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import com.gh.base.CurrentActivityHolder
|
||||
import com.gh.common.runOnIoThread
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.HelpAndFeedbackActivity
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.MessageActivity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.m7.imkfsdk.KfStartHelper
|
||||
import com.m7.imkfsdk.utils.Utils
|
||||
import com.moor.imkf.ChatListener
|
||||
import com.moor.imkf.IMChat
|
||||
import com.moor.imkf.IMChatManager
|
||||
import com.moor.imkf.IMMessage
|
||||
import com.moor.imkf.utils.MoorUtils
|
||||
|
||||
object ImManager {
|
||||
|
||||
@ -35,57 +19,57 @@ object ImManager {
|
||||
|
||||
@JvmStatic
|
||||
fun attachIm() {
|
||||
try {
|
||||
if (UserManager.getInstance().userInfoEntity != null &&
|
||||
currentUserId != UserManager.getInstance().userId) {
|
||||
currentUserId = UserManager.getInstance().userId
|
||||
MoorUtils.init(HaloApp.getInstance().application)
|
||||
Utils.init(HaloApp.getInstance().application)
|
||||
IMChatManager.getInstance().init(
|
||||
HaloApp.getInstance().application,
|
||||
ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
IM_KEY,
|
||||
UserManager.getInstance().userInfoEntity.name + "(" + UserManager.getInstance().userId + ")",
|
||||
UserManager.getInstance().userId)
|
||||
|
||||
shouldShowFloatingWindow = SPUtils.getBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId)
|
||||
shouldShowFloatingWindowDot = SPUtils.getBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId)
|
||||
updateFloatingWindow()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// if (UserManager.getInstance().userInfoEntity != null &&
|
||||
// currentUserId != UserManager.getInstance().userId) {
|
||||
// currentUserId = UserManager.getInstance().userId
|
||||
// MoorUtils.init(HaloApp.getInstance().application)
|
||||
// Utils.init(HaloApp.getInstance().application)
|
||||
// IMChatManager.getInstance().init(
|
||||
// HaloApp.getInstance().application,
|
||||
// ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
// IM_KEY,
|
||||
// UserManager.getInstance().userInfoEntity?.name + "(" + UserManager.getInstance().userId + ")",
|
||||
// UserManager.getInstance().userId)
|
||||
//
|
||||
// shouldShowFloatingWindow = SPUtils.getBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId)
|
||||
// shouldShowFloatingWindowDot = SPUtils.getBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId)
|
||||
// updateFloatingWindow()
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun detachIm() {
|
||||
try {
|
||||
IMChatManager.getInstance().quitSDk()
|
||||
shouldShowFloatingWindow = false
|
||||
updateFloatingWindow()
|
||||
removeNotification()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// IMChatManager.getInstance().quitSDk()
|
||||
// shouldShowFloatingWindow = false
|
||||
// updateFloatingWindow()
|
||||
// removeNotification()
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun startChatActivity(activity: Activity, inputContent: String? = "", requestCode: Int? = null) {
|
||||
if (!UserManager.getInstance().userId.isNullOrEmpty()) {
|
||||
try {
|
||||
SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, false)
|
||||
shouldShowFloatingWindowDot = false
|
||||
val chatHelper = KfStartHelper(activity, UserManager.getInstance().userInfoEntity.icon, inputContent, requestCode)
|
||||
chatHelper.initSdkChat(
|
||||
ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
IM_KEY,
|
||||
UserManager.getInstance().userInfoEntity.name + "(" + UserManager.getInstance().userId + ")"
|
||||
+ "[" + BuildConfig.VERSION_NAME + "]",
|
||||
UserManager.getInstance().userId)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
// if (!UserManager.getInstance().userId.isNullOrEmpty()) {
|
||||
// try {
|
||||
// SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, false)
|
||||
// shouldShowFloatingWindowDot = false
|
||||
// val chatHelper = KfStartHelper(activity, UserManager.getInstance().userInfoEntity?.icon, inputContent, requestCode)
|
||||
// chatHelper.initSdkChat(
|
||||
// ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
// IM_KEY,
|
||||
// UserManager.getInstance().userInfoEntity?.name + "(" + UserManager.getInstance().userId + ")"
|
||||
// + "[" + BuildConfig.VERSION_NAME + "]",
|
||||
// UserManager.getInstance().userId)
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -104,50 +88,50 @@ object ImManager {
|
||||
|
||||
@JvmStatic
|
||||
fun removeNotification() {
|
||||
val notificationManager = HaloApp.getInstance().application?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.cancel(ImReceiver.NOTIFICATION_ID)
|
||||
// val notificationManager = HaloApp.getInstance().application?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// notificationManager.cancel(ImReceiver.NOTIFICATION_ID)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun updateFloatingWindow() {
|
||||
try {
|
||||
CurrentActivityHolder.getCurrentActivity()?.let {
|
||||
if (isActivityValid(it)) {
|
||||
if (shouldShowFloatingWindow) {
|
||||
ImHintHelper.show(it)
|
||||
} else {
|
||||
ImHintHelper.dismiss(it)
|
||||
removeNotification()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// CurrentActivityHolder.getCurrentActivity()?.let {
|
||||
// if (isActivityValid(it)) {
|
||||
// if (shouldShowFloatingWindow) {
|
||||
// ImHintHelper.show(it)
|
||||
// } else {
|
||||
// ImHintHelper.dismiss(it)
|
||||
// removeNotification()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun sendFeedbackMessage(message: String) {
|
||||
val fromToMessage = IMMessage.createTxtMessage(message)
|
||||
runOnIoThread {
|
||||
tryWithDefaultCatch {
|
||||
IMChat.getInstance().sendMessage(fromToMessage, object : ChatListener {
|
||||
override fun onProgress(p0: Int) {}
|
||||
override fun onSuccess() {}
|
||||
override fun onFailed() {}
|
||||
})
|
||||
}
|
||||
}
|
||||
// val fromToMessage = IMMessage.createTxtMessage(message)
|
||||
// runOnIoThread {
|
||||
// tryWithDefaultCatch {
|
||||
// IMChat.getInstance().sendMessage(fromToMessage, object : ChatListener {
|
||||
// override fun onProgress(p0: Int) {}
|
||||
// override fun onSuccess() {}
|
||||
// override fun onFailed() {}
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateShouldShowFloatingWindow(show: Boolean) {
|
||||
SPUtils.setBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId, show)
|
||||
shouldShowFloatingWindow = show
|
||||
// SPUtils.setBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId, show)
|
||||
// shouldShowFloatingWindow = show
|
||||
}
|
||||
|
||||
fun updateShouldShowFloatingWindowDot(show: Boolean) {
|
||||
SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, show)
|
||||
shouldShowFloatingWindowDot = show
|
||||
// SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, show)
|
||||
// shouldShowFloatingWindowDot = show
|
||||
}
|
||||
|
||||
private fun isActivityValid(activity: Activity): Boolean {
|
||||
|
||||
@ -1,20 +1,9 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.gh.base.CurrentActivityHolder
|
||||
import com.gh.common.util.doOnMainProcessOnly
|
||||
import com.gh.gamecenter.R
|
||||
import com.m7.imkfsdk.chat.ChatActivity
|
||||
import com.m7.imkfsdk.utils.Utils
|
||||
import com.moor.imkf.IMChatManager
|
||||
|
||||
class ImReceiver : BroadcastReceiver() {
|
||||
|
||||
@ -26,54 +15,54 @@ class ImReceiver : BroadcastReceiver() {
|
||||
var notificationManager: NotificationManager? = null
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
context?.doOnMainProcessOnly {
|
||||
intent?.let {
|
||||
if (intent.action == IMChatManager.NEW_MSG_ACTION) {
|
||||
notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// 判断 ImActivity 是否在最顶端
|
||||
if (CurrentActivityHolder.getCurrentActivity() is ChatActivity) {
|
||||
ImManager.showFloatingWindow()
|
||||
ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
} else {
|
||||
val contentIntent = Intent(Utils.getApp(), ChatActivity::class.java)
|
||||
|
||||
contentIntent.putExtra("PeerId", "")
|
||||
contentIntent.putExtra("type", "peedId")
|
||||
|
||||
contentIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val resultPendingIntent = PendingIntent.getActivity(
|
||||
Utils.getApp(),
|
||||
0,
|
||||
contentIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
// 新的通知
|
||||
val builder = NotificationCompat.Builder(Utils.getApp(), "Halo_IM")
|
||||
val notification = builder.setTicker("您有新的消息")
|
||||
.setDefaults(Notification.DEFAULT_ALL)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setContentIntent(resultPendingIntent)
|
||||
.setContentTitle("光环助手客服回复")
|
||||
.setContentText("您有新的消息")
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel("Halo_IM", "Halo_IM", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
notificationManager?.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
if (notification != null) {
|
||||
notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||
ImManager.showFloatingWindow()
|
||||
}
|
||||
}
|
||||
} else if (intent.action == IMChatManager.FINISH_ACTION) {
|
||||
ImManager.dismissFloatingWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
// context?.doOnMainProcessOnly {
|
||||
// intent?.let {
|
||||
// if (intent.action == IMChatManager.NEW_MSG_ACTION) {
|
||||
// notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// // 判断 ImActivity 是否在最顶端
|
||||
// if (CurrentActivityHolder.getCurrentActivity() is ChatActivity) {
|
||||
// ImManager.showFloatingWindow()
|
||||
// ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
// } else {
|
||||
// val contentIntent = Intent(Utils.getApp(), ChatActivity::class.java)
|
||||
//
|
||||
// contentIntent.putExtra("PeerId", "")
|
||||
// contentIntent.putExtra("type", "peedId")
|
||||
//
|
||||
// contentIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
// val resultPendingIntent = PendingIntent.getActivity(
|
||||
// Utils.getApp(),
|
||||
// 0,
|
||||
// contentIntent,
|
||||
// PendingIntent.FLAG_UPDATE_CURRENT
|
||||
// )
|
||||
//
|
||||
// // 新的通知
|
||||
// val builder = NotificationCompat.Builder(Utils.getApp(), "Halo_IM")
|
||||
// val notification = builder.setTicker("您有新的消息")
|
||||
// .setDefaults(Notification.DEFAULT_ALL)
|
||||
// .setSmallIcon(R.drawable.ic_notification)
|
||||
// .setWhen(System.currentTimeMillis())
|
||||
// .setContentIntent(resultPendingIntent)
|
||||
// .setContentTitle("光环助手客服回复")
|
||||
// .setContentText("您有新的消息")
|
||||
// .setAutoCancel(true)
|
||||
// .build()
|
||||
//
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// val channel = NotificationChannel("Halo_IM", "Halo_IM", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
// notificationManager?.createNotificationChannel(channel)
|
||||
// }
|
||||
//
|
||||
// if (notification != null) {
|
||||
// notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||
// ImManager.showFloatingWindow()
|
||||
// }
|
||||
// }
|
||||
// } else if (intent.action == IMChatManager.FINISH_ACTION) {
|
||||
// ImManager.dismissFloatingWindow()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import com.aliyun.sls.android.sdk.model.Log
|
||||
import com.aliyun.sls.android.sdk.model.LogGroup
|
||||
import com.gh.common.exposure.ExposureEntity
|
||||
import com.gh.common.exposure.meta.Meta
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.loghub.LoghubHelper
|
||||
import org.json.JSONObject
|
||||
import java.util.concurrent.Executors
|
||||
@ -69,13 +70,16 @@ object LoghubUtils {
|
||||
|
||||
fun commitSavedLoghubEvents() {
|
||||
loghubEventExecutor.execute {
|
||||
if (loghubEventSet.isEmpty()) return@execute
|
||||
// TODO 初始化 loghubHelper 去掉这个 tryCatch 块
|
||||
tryWithDefaultCatch {
|
||||
if (loghubEventSet.isEmpty()) return@execute
|
||||
|
||||
val exposureList = loghubEventSet.toList()
|
||||
val exposureList = loghubEventSet.toList()
|
||||
|
||||
createLogGroupAndUpload()
|
||||
loghubEventSet.removeAll(exposureList)
|
||||
loghubEventDao.deleteMany(exposureList)
|
||||
createLogGroupAndUpload()
|
||||
loghubEventSet.removeAll(exposureList)
|
||||
loghubEventDao.deleteMany(exposureList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import com.gh.common.util.ApkActiveUtils
|
||||
import com.gh.common.util.RandomUtils
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
|
||||
// 热门卡牌的仓库
|
||||
@ -16,7 +16,7 @@ object RemenkapaiRepository {
|
||||
@JvmStatic
|
||||
fun getRemenkapai(size: Int): Observable<List<GameEntity>> {
|
||||
return if (remenkapaiList.isEmpty()) {
|
||||
RetrofitManager.getInstance(getApplication()).sensitiveApi.remenkapai
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).sensitiveApi.remenkapai
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map { gameList -> filterEntityWithoutApk(gameList) }
|
||||
.map { pickRandomSizeEntity(size) }
|
||||
|
||||
@ -0,0 +1,243 @@
|
||||
package com.gh.common.simulator
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.AppExecutor.uiExecutor
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.dialog.TrackableDialog
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.PackageInstaller.getDownloadPath
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.ApkEntity
|
||||
import com.gh.gamecenter.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.entity.TrackableEntity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.*
|
||||
import com.lightgame.utils.Utils
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class SimulatorDownloadManager private constructor() {
|
||||
|
||||
private var app_pb_progress: ProgressBar? = null
|
||||
private var appProgressSize: TextView? = null
|
||||
private var appProgressRemain: TextView? = null
|
||||
private var appProgressPercent: TextView? = null
|
||||
private var appProgressFilling: View? = null
|
||||
private var appProgressAnchor: View? = null
|
||||
private var downloadDialog: Dialog? = null
|
||||
|
||||
private var simulatorLocation: SimulatorLocation? = null
|
||||
private var simulator: SimulatorEntity? = null
|
||||
private var gameId: String = ""
|
||||
private var gameName: String = ""
|
||||
private var downloadType: String = ""
|
||||
|
||||
private val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity?) {
|
||||
if (downloadEntity?.isSimulatorDownload() == true) {
|
||||
val size = downloadEntity.progress.toFloat() / 1024 / 1024
|
||||
val df = DecimalFormat("0.00")
|
||||
appProgressSize!!.text = "${df.format(size.toDouble())}MB"
|
||||
appProgressRemain!!.text = String.format("剩余%s", SpeedUtils.getRemainSecondTime(downloadEntity.size,
|
||||
downloadEntity.progress, downloadEntity.speed * 1024))
|
||||
app_pb_progress!!.progress = (downloadEntity.percent * 10).toInt()
|
||||
|
||||
val width = app_pb_progress!!.width
|
||||
val marLeft = (downloadEntity.percent / 100 * width).toInt()
|
||||
val anchorLp = appProgressAnchor!!.layoutParams
|
||||
if (anchorLp is ConstraintLayout.LayoutParams) {
|
||||
anchorLp.leftMargin = marLeft
|
||||
appProgressAnchor!!.layoutParams = anchorLp
|
||||
}
|
||||
|
||||
val fillingLp = appProgressFilling!!.layoutParams
|
||||
fillingLp.width = marLeft + DisplayUtils.dip2px(5f)
|
||||
appProgressFilling!!.layoutParams = fillingLp
|
||||
|
||||
appProgressPercent?.text = if (downloadEntity.percent != 100.0) "${downloadEntity.percent}%" else "100%"
|
||||
when {
|
||||
DownloadStatus.done == downloadEntity.status -> {
|
||||
val locationStr = if (simulatorLocation == SimulatorLocation.LAUNCH) "${simulatorLocation?.value}《${gameName}》" else simulatorLocation?.value
|
||||
val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk")
|
||||
val startTime = downloadEntity.getMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME)
|
||||
LogUtils.uploadSimulatorDownload("simulator_download_complete", fileName, simulator?.id, downloadEntity.name, gameId, locationStr, downloadType, startTime)
|
||||
DownloadManager.getInstance(HaloApp.getInstance().application).cancel(downloadEntity.url, false, true)
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
DownloadStatus.neterror == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络不稳定,下载任务已暂停")
|
||||
}
|
||||
DownloadStatus.timeout == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络不稳定,下载任务已暂停")
|
||||
}
|
||||
DownloadStatus.notfound == downloadEntity.status -> {
|
||||
ToastUtils.showToast("下载链接异常,请稍后重试")
|
||||
}
|
||||
DownloadStatus.hijack == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络劫持,请稍后重试")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation) {
|
||||
showDownloadDialog(context, simulator, location, "", "", null)
|
||||
}
|
||||
|
||||
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation, gameId: String = "", gameName: String = "", cancelCallback: (() -> Unit)? = null) {
|
||||
this.simulatorLocation = location
|
||||
this.simulator = simulator
|
||||
this.gameId = gameId
|
||||
this.gameName = gameName
|
||||
//判断是否隐藏
|
||||
if (simulator?.active == false) {
|
||||
showNoneEmulatorDialog(context)
|
||||
return
|
||||
}
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(context, simulator?.apk?.packageName)
|
||||
val versionFromInstalledApp = PackageUtils.getVersionByPackage(simulator?.apk?.packageName)
|
||||
val shouldShowUpdate = Version(simulator?.apk?.version).isHigherThan(versionFromInstalledApp)
|
||||
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
|
||||
val message = if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
|
||||
val positiveText = if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size})" else "下载(${simulator?.apk?.size})"
|
||||
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
|
||||
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
|
||||
|
||||
val trackableEntity = TrackableEntity("模拟器下载",
|
||||
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
|
||||
logShowEvent = true
|
||||
)
|
||||
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, {
|
||||
if (shouldShowUpdate && isInstalled){
|
||||
cancelCallback?.invoke()
|
||||
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
|
||||
}
|
||||
}, {
|
||||
showDownloadingDialog(context, simulator)
|
||||
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载")
|
||||
})
|
||||
}
|
||||
|
||||
private fun showDownloadingDialog(context: Context, simulator: SimulatorEntity?) {
|
||||
val msg = FileUtils.isCanDownload(context, simulator?.apk?.size)
|
||||
if (!msg.isNullOrEmpty()) {
|
||||
Utils.toast(context, msg)
|
||||
return
|
||||
}
|
||||
if (NetworkUtils.isMobileConnected(context)) {
|
||||
Utils.toast(context, "当前使用移动数据进行下载")
|
||||
}
|
||||
|
||||
downloadDialog = TrackableDialog(context, R.style.GhAlertDialog, "模拟器下载", "下载中弹窗")
|
||||
downloadDialog?.window?.setBackgroundDrawableResource(R.color.transparent)
|
||||
|
||||
val view = View.inflate(context, R.layout.download_simulator_dialog, null)
|
||||
|
||||
app_pb_progress = view.findViewById(R.id.progress)
|
||||
appProgressSize = view.findViewById(R.id.size)
|
||||
appProgressRemain = view.findViewById(R.id.remain)
|
||||
appProgressAnchor = view.findViewById(R.id.progress_anchor)
|
||||
appProgressPercent = view.findViewById(R.id.percent)
|
||||
appProgressFilling = view.findViewById(R.id.progress_filling)
|
||||
|
||||
view.findViewById<View>(R.id.app_tv_cancel).setOnClickListener {
|
||||
DownloadManager.getInstance(context).pause(simulator?.apk?.url)
|
||||
MtaHelper.onEvent("模拟器下载", "下载中弹窗", "点击关闭")
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
|
||||
downloadDialog?.setOnDismissListener {
|
||||
DownloadManager.getInstance(context).removeObserver(dataWatcher)
|
||||
}
|
||||
|
||||
downloadDialog?.setCanceledOnTouchOutside(false)
|
||||
downloadDialog?.setCancelable(false)
|
||||
downloadDialog?.closeOptionsMenu()
|
||||
downloadDialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
downloadDialog?.setContentView(view)
|
||||
val params = downloadDialog?.window?.attributes
|
||||
params?.width = context.resources.displayMetrics.widthPixels - DisplayUtils.dip2px(60f)
|
||||
downloadDialog?.window?.attributes = params
|
||||
|
||||
download(context, simulator)
|
||||
}
|
||||
|
||||
private fun showNoneEmulatorDialog(context: Context) {
|
||||
val dialog = DialogUtils.showNewAlertDialog(context, "安装模拟器", "模拟器游戏需要先下载安装对应的模拟器,才可以运行", "取消", "暂无下载", null, {
|
||||
ToastUtils.showToast("该模拟器暂未提供下载")
|
||||
})
|
||||
dialog?.window?.findViewById<TextView>(R.id.confirm)?.setTextColor(ContextCompat.getColor(context, R.color.text_cccccc))
|
||||
}
|
||||
|
||||
private fun download(context: Context, simulator: SimulatorEntity?) {
|
||||
val apkEntity = simulator?.apk ?: return
|
||||
DownloadManager.getInstance(context).pauseAll()
|
||||
|
||||
val entity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.url)
|
||||
if (entity != null) {
|
||||
when (entity.status) {
|
||||
DownloadStatus.pause, DownloadStatus.subscribe,
|
||||
DownloadStatus.neterror, DownloadStatus.timeout -> {
|
||||
DownloadManager.getInstance(context).addObserver(dataWatcher)
|
||||
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance(context).resume(entity, true) }, 200)
|
||||
downloadDialog?.show()
|
||||
}
|
||||
DownloadStatus.done -> DataChanger.notifyDataChanged(entity)
|
||||
|
||||
else -> createDownload(context, apkEntity, simulator)
|
||||
}
|
||||
} else {
|
||||
createDownload(context, apkEntity, simulator)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDownload(context: Context, apkEntity: ApkEntity, simulator: SimulatorEntity) {
|
||||
DownloadManager.getInstance(context).addObserver(dataWatcher)
|
||||
val downloadEntity = DownloadEntity()
|
||||
downloadEntity.url = apkEntity.url
|
||||
downloadEntity.name = simulator.name
|
||||
downloadEntity.path = getDownloadPath(simulator.name, apkEntity.format)
|
||||
downloadEntity.platform = apkEntity.getPlatform()
|
||||
downloadEntity.packageName = apkEntity.packageName
|
||||
downloadEntity.versionName = apkEntity.version
|
||||
|
||||
downloadEntity.addMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE, Constants.SIMULATOR_DOWNLOAD)
|
||||
downloadEntity.addMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME, (System.currentTimeMillis() / 1000).toString())
|
||||
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance(context).add(downloadEntity) }, 200)
|
||||
|
||||
val locationStr = if (simulatorLocation == SimulatorLocation.LAUNCH) "${simulatorLocation?.value}《${gameName}》" else simulatorLocation?.value
|
||||
val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk")
|
||||
LogUtils.uploadSimulatorDownload("simulator_download", fileName, simulator.id, simulator.name, gameId, locationStr, downloadType, "")
|
||||
|
||||
downloadDialog?.show()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var instance: SimulatorDownloadManager? = null
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(): SimulatorDownloadManager {
|
||||
return instance ?: synchronized(this) {
|
||||
instance ?: SimulatorDownloadManager().also { instance = it }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class SimulatorLocation(val value: String) {
|
||||
LAUNCH("启动"),
|
||||
SIMULATOR_GAME("模拟器游戏"),
|
||||
SIMULATOR_MANAGE("模拟器游戏-模拟器管理")
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,219 @@
|
||||
package com.gh.common.simulator
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadDao
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.AppManager
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import java.io.File
|
||||
|
||||
|
||||
object SimulatorGameManager {
|
||||
|
||||
private val gamePath = FileUtils.getDownloadPath(HaloApp.getInstance().application, "emulator_game")
|
||||
|
||||
@JvmStatic
|
||||
fun getPathByType(type: String) = "${gamePath}/${type}"
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGames(names: List<String>) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
names.forEach { name ->
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
val file = File(downloadEntity.path)
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
DownloadDao.getInstance(HaloApp.getInstance().application).delete(downloadEntity.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGame(name: String) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
val file = File(downloadEntity.path)
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
DownloadDao.getInstance(HaloApp.getInstance().application).delete(downloadEntity.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun findDownloadEntityByUrl(url: String?): DownloadEntity? {
|
||||
val downloadEntity = DownloadDao.getInstance(HaloApp.getInstance().application).get(url)
|
||||
if (downloadEntity != null) {
|
||||
val isFileCompleted = DownloadManager.getInstance(HaloApp.getInstance().application).isFileCompleted(url)
|
||||
if (downloadEntity.isSimulatorGame() && isFileCompleted) {
|
||||
return downloadEntity
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isSimulatorGame(gameEntity: GameEntity) = gameEntity.category == "simulator"
|
||||
|
||||
|
||||
@JvmStatic
|
||||
fun launchSimulatorGame(downloadEntity: DownloadEntity, gameEntity: GameEntity) {
|
||||
val versionFromInstalledApp = PackageUtils.getVersionByPackage(gameEntity.simulator?.apk?.packageName)
|
||||
val shouldShowUpdate = Version(gameEntity.simulator?.apk?.version).isHigherThan(versionFromInstalledApp)
|
||||
if (shouldShowUpdate) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(AppManager.getInstance().recentActiveActivity, gameEntity.simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
|
||||
?: "") {
|
||||
jumpToSimulator(downloadEntity, gameEntity)
|
||||
}
|
||||
} else {
|
||||
jumpToSimulator(downloadEntity, gameEntity)
|
||||
}
|
||||
}
|
||||
|
||||
private fun jumpToSimulator(downloadEntity: DownloadEntity, gameEntity: GameEntity) {
|
||||
val intent = Intent()
|
||||
intent.data = Uri.fromFile(File(downloadEntity.path))
|
||||
if (gameEntity.simulatorType == "FBA") {
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
intent.putExtra("rom_name", apkEntity.packageName)
|
||||
}
|
||||
intent.putExtra("default_path", downloadEntity.path.substring(0, downloadEntity.path.lastIndexOf('/')))
|
||||
intent.putExtra("game_type", gameEntity.simulatorType)
|
||||
intent.putExtra("title", downloadEntity.name)
|
||||
intent.putExtra("icon", gameEntity.icon ?: "")
|
||||
intent.putExtra("meta", LogUtils.getMetaObject().toString())
|
||||
intent.putExtra("simulatorId", gameEntity.simulator?.id)
|
||||
intent.putExtra("simulatorName", gameEntity.simulator?.name)
|
||||
intent.putExtra("gameId", gameEntity.id)
|
||||
|
||||
val destActivity = "com.gh.emu.RequestPermissionActivity"
|
||||
intent.setClassName(gameEntity.simulator?.apk?.packageName ?: "", destActivity)
|
||||
try {
|
||||
AppManager.getInstance().recentActiveActivity.startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
ToastUtils.showToast("模拟器安装错误")
|
||||
}
|
||||
|
||||
recordPlaySimulatorGames(gameEntity.id)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录设备下载的模拟器游戏
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun recordDownloadSimulatorGames(gameId: String) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_id"] = gameId
|
||||
requestMap["package"] = "-"
|
||||
val body = requestMap.createRequestBodyAny()
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.downloadSimulatorGames(HaloApp.getInstance().gid, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记已玩过
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun postPlayedGame(gameId: String, packageName: String) {
|
||||
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_id"] = gameId
|
||||
requestMap["package"] = packageName
|
||||
val body = requestMap.toRequestBody()
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.postPlayedGame(UserManager.getInstance().userId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录启动设备上的模拟器游戏
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun recordPlaySimulatorGames(gameId: String) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_id"] = gameId
|
||||
requestMap["package"] = "-"
|
||||
val body = requestMap.createRequestBodyAny()
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.playedSimulatorGames(HaloApp.getInstance().gid, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteSimulatorGame(gameId: String, callback: () -> Unit) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.deleteSimulatorGame(HaloApp.getInstance().gid, gameId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
callback.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteSimulatorGames(gameIds: List<String>, callback: () -> Unit) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_ids"] = gameIds
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.deleteSimulatorGames(HaloApp.getInstance().gid, requestMap.toRequestBody())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
callback.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@JvmStatic
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteAllSimulatorGame() {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.deleteAllSimulatorGame(HaloApp.getInstance().gid)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.gh.common.structure
|
||||
|
||||
class FixedSizeLinkedHashSet<T>(var maxSize: Int) : LinkedHashSet<T>() {
|
||||
override fun add(element: T): Boolean {
|
||||
if (size == maxSize) {
|
||||
pop()
|
||||
}
|
||||
return super.add(element);
|
||||
}
|
||||
|
||||
private fun pop() {
|
||||
if (size > 0) {
|
||||
remove(iterator().next())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,9 +21,7 @@ object ActivationHelper {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendActivationInfo() {
|
||||
// 能获取到 IMEI 并且之前没发送过激活信息才发
|
||||
if (!mHasSentActivatedInfo
|
||||
&& Util_System_Phone_State.canGetImei(HaloApp.getInstance().application)) {
|
||||
if (!mHasSentActivatedInfo) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.api.postActivationInfo()
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -5,11 +5,12 @@ import com.gh.gamecenter.entity.SettingsEntity
|
||||
|
||||
object AdHelper {
|
||||
|
||||
// 搜索为空/求版本/意见反馈-功能收录/发现
|
||||
// 搜索为空/求版本/意见反馈-功能收录/发现/模拟器游戏
|
||||
const val LOCATION_SEARCH_EMPTY = "search_empty"
|
||||
const val LOCATION_GAME_REQUEST_VERSION = "game_request_version"
|
||||
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
|
||||
const val LOCATION_DISCOVER = "discover"
|
||||
const val LOCATION_SIMULATOR_GAME = "simulator_game"
|
||||
|
||||
fun getAd(location: String): SettingsEntity.AD? {
|
||||
val adList = Config.getSettings()?.adList ?: return null
|
||||
@ -34,4 +35,19 @@ object AdHelper {
|
||||
return discoverAdList
|
||||
}
|
||||
|
||||
fun getAdForLocation(location: String): SettingsEntity.AD? {
|
||||
val adList = Config.getSettings()?.adList ?: return null
|
||||
|
||||
var result: SettingsEntity.AD? = null
|
||||
run outside@ {
|
||||
for (ad in adList) {
|
||||
if (ad.location == location) {
|
||||
result = ad
|
||||
return@outside
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,10 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.alibaba.wireless.security.jaq.avmp.IJAQAVMPSignComponent
|
||||
import com.alibaba.wireless.security.open.SecurityGuardManager
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object AntiBotHelper {
|
||||
@JvmStatic
|
||||
val manager by lazy {
|
||||
SecurityGuardManager.getInstance(HaloApp.getInstance().application).getInterface(IJAQAVMPSignComponent::class.java).apply {
|
||||
this.initialize()
|
||||
}
|
||||
}
|
||||
// @JvmStatic
|
||||
// val manager by lazy {
|
||||
// SecurityGuardManager.getInstance(HaloApp.getInstance().application).getInterface(IJAQAVMPSignComponent::class.java).apply {
|
||||
// this.initialize()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
@ -14,9 +15,17 @@ import com.halo.assistant.HaloApp;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.renderscript.Allocation;
|
||||
import androidx.renderscript.Element;
|
||||
import androidx.renderscript.RenderScript;
|
||||
import androidx.renderscript.ScriptIntrinsicBlur;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/10/21.
|
||||
*/
|
||||
@ -114,6 +123,14 @@ public class BitmapUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapByFile(String filepath, int w, int h) {
|
||||
return getBitmapByFile(filepath, w, h, Bitmap.Config.RGB_565);
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapByFile(String filepath, Bitmap.Config config) {
|
||||
return getBitmapByFile(filepath, 0, 0, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件路径返回bitmap
|
||||
*
|
||||
@ -122,12 +139,12 @@ public class BitmapUtils {
|
||||
* @param h 高
|
||||
* @return bitmap
|
||||
*/
|
||||
public static Bitmap getBitmapByFile(String filepath, int w, int h) {
|
||||
public static Bitmap getBitmapByFile(String filepath, int w, int h, Bitmap.Config config) {
|
||||
try {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
// 设置为ture只获取图片大小
|
||||
options.inJustDecodeBounds = true;
|
||||
options.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
options.inPreferredConfig = config;
|
||||
// 返回为空
|
||||
BitmapFactory.decodeFile(filepath, options);
|
||||
int width = options.outWidth;
|
||||
@ -135,8 +152,8 @@ public class BitmapUtils {
|
||||
float scaleWidth = 0.f, scaleHeight = 0.f;
|
||||
if (width > w || height > h) {
|
||||
// 缩放
|
||||
scaleWidth = ((float) width) / w;
|
||||
scaleHeight = ((float) height) / h;
|
||||
if (w > 0) scaleWidth = ((float) width) / w;
|
||||
if (h > 0) scaleHeight = ((float) height) / h;
|
||||
}
|
||||
options.inJustDecodeBounds = false;
|
||||
int scale = (int) Math.ceil(Math.max(scaleWidth, scaleHeight));
|
||||
@ -189,6 +206,7 @@ public class BitmapUtils {
|
||||
|
||||
/**
|
||||
* Drawable转Bitmap
|
||||
*
|
||||
* @param isSquare 是否是正方形
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable, boolean isSquare) {
|
||||
@ -196,7 +214,7 @@ public class BitmapUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
int w,h;
|
||||
int w, h;
|
||||
|
||||
// 取 drawable 的长宽
|
||||
w = drawable.getIntrinsicWidth();
|
||||
@ -227,4 +245,108 @@ public class BitmapUtils {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改bitmap透明度
|
||||
*
|
||||
* @param sourceImg
|
||||
* @param config
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap getTransparentBitmap(Bitmap sourceImg, Bitmap.Config config, int number) {
|
||||
int[] argb = new int[sourceImg.getWidth() * sourceImg.getHeight()];
|
||||
sourceImg.getPixels(argb, 0, sourceImg.getWidth(), 0, 0, sourceImg
|
||||
.getWidth(), sourceImg.getHeight());// 获得图片的ARGB值
|
||||
number = number * 255 / 100;
|
||||
for (int i = 0; i < argb.length; i++) {
|
||||
argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);
|
||||
}
|
||||
sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(), sourceImg
|
||||
.getHeight(), config);
|
||||
return sourceImg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 高斯模糊
|
||||
*
|
||||
* @param context
|
||||
* @param image
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
public static Bitmap getBlurBitmap(Context context, Bitmap image, @IntRange(from = 1, to = 25) int radius) {
|
||||
// 计算图片缩小后的长宽
|
||||
int width = Math.round(image.getWidth() * 0.8f);
|
||||
int height = Math.round(image.getHeight() * 0.8f);
|
||||
|
||||
// 将缩小后的图片做为预渲染的图片。
|
||||
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
|
||||
// 创建一张渲染后的输出图片。
|
||||
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
|
||||
// 创建RenderScript内核对象
|
||||
RenderScript rs = RenderScript.create(context);
|
||||
// 创建一个模糊效果的RenderScript的工具对象
|
||||
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
|
||||
|
||||
// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。
|
||||
// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。
|
||||
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
|
||||
Allocation tmpOut = Allocation.createTyped(rs, tmpIn.getType());
|
||||
// 设置渲染的模糊程度, 25f是最大模糊度
|
||||
blurScript.setRadius(radius);
|
||||
// 设置blurScript对象的输入内存
|
||||
blurScript.setInput(tmpIn);
|
||||
// 将输出数据保存到输出内存中
|
||||
blurScript.forEach(tmpOut);
|
||||
|
||||
// 将数据填充到Allocation中
|
||||
tmpOut.copyTo(outputBitmap);
|
||||
|
||||
return outputBitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存图片
|
||||
*
|
||||
* @param bitmap
|
||||
* @param path
|
||||
*/
|
||||
public static void saveBitmap(Bitmap bitmap, String path) {
|
||||
File file = new File(path);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
FileOutputStream out;
|
||||
try {
|
||||
out = new FileOutputStream(file);
|
||||
if (bitmap.compress(Bitmap.CompressFormat.PNG, 80, out)) {
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap compressBitmap(Bitmap bitmap) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
Matrix matrix = new Matrix();
|
||||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
result.compress(Bitmap.CompressFormat.WEBP, 100, bos);
|
||||
|
||||
while (bos.toByteArray().length > 400 * 1024) {
|
||||
System.out.println(bos.toByteArray().length);
|
||||
matrix.setScale(0.9f, 0.9f);
|
||||
result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);
|
||||
bos.reset();
|
||||
result.compress(Bitmap.CompressFormat.WEBP, 100, bos);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,8 +16,8 @@ import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
@ -84,11 +84,16 @@ object CommentHelper {
|
||||
listener: OnCommentOptionClickListener? = null) {
|
||||
val context = view.context
|
||||
val dialogOptions = ArrayList<String>()
|
||||
dialogOptions.add("复制")
|
||||
if (commentEntity.user.id != UserManager.getInstance().userId) {
|
||||
dialogOptions.add("投诉")
|
||||
}
|
||||
if (isVideoAuthor || (videoId != null && commentEntity.user.id == UserManager.getInstance().userId)) {
|
||||
dialogOptions.add("删除评论")
|
||||
} else if (articleId != null && (commentEntity.user.id == UserManager.getInstance().userId ||
|
||||
commentEntity.me?.isModerator == true || commentEntity.me?.isArticleOrAnswerAuthor == true)) {
|
||||
dialogOptions.add("删除评论")
|
||||
}
|
||||
dialogOptions.add("复制")
|
||||
dialogOptions.add("投诉")
|
||||
|
||||
commentEntity.me?.let {
|
||||
if (ignoreModerator) return@let
|
||||
@ -128,7 +133,7 @@ object CommentHelper {
|
||||
|
||||
"投诉" -> {
|
||||
context.ifLogin("回答详情-评论-投诉") {
|
||||
showReportTypeDialog(context) { reportType ->
|
||||
showReportTypeDialog(context, !videoId.isNullOrEmpty()) { reportType ->
|
||||
|
||||
val commentListener = object : PostCommentUtils.PostCommentListener {
|
||||
override fun postSuccess(response: JSONObject?) {
|
||||
@ -189,7 +194,7 @@ object CommentHelper {
|
||||
var canHighlightCommentDirectly = false
|
||||
var canHideCommentDirectly = false
|
||||
|
||||
if (me.moderatorPermissions.topAnswerComment > Permissions.GUEST
|
||||
if (me.isModerator || me.moderatorPermissions.topAnswerComment > Permissions.GUEST
|
||||
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.GUEST) {
|
||||
dialogOptions.add(highlight)
|
||||
if (me.moderatorPermissions.topAnswerComment > Permissions.REPORTER
|
||||
@ -198,7 +203,7 @@ object CommentHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (me.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|
||||
if (me.isModerator || me.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|
||||
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST) {
|
||||
dialogOptions.add(hide)
|
||||
if (me.moderatorPermissions.hideAnswerComment > Permissions.REPORTER
|
||||
@ -263,10 +268,10 @@ object CommentHelper {
|
||||
val errorJson = JSONObject(string)
|
||||
val errorCode = errorJson.getInt("code")
|
||||
if (errorCode == 403059) {
|
||||
Utils.toast(getApplication(), "权限错误,请刷新后重试")
|
||||
Utils.toast(HaloApp.getInstance().application, "权限错误,请刷新后重试")
|
||||
return
|
||||
} else {
|
||||
Utils.toast(getApplication(), e.message())
|
||||
Utils.toast(HaloApp.getInstance().application, e.message())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,10 +317,10 @@ object CommentHelper {
|
||||
val errorJson = JSONObject(string)
|
||||
val errorCode = errorJson.getInt("code")
|
||||
if (errorCode == 403059) {
|
||||
Utils.toast(getApplication(), "权限错误,请刷新后重试")
|
||||
Utils.toast(HaloApp.getInstance().application, "权限错误,请刷新后重试")
|
||||
return
|
||||
} else {
|
||||
Utils.toast(getApplication(), e.message())
|
||||
Utils.toast(HaloApp.getInstance().application, e.message())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,16 +351,22 @@ object CommentHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showReportTypeDialog(context: Context, reportCallback: (reportType: String) -> Unit) {
|
||||
private fun showReportTypeDialog(context: Context, isVideoComment: Boolean, reportCallback: (reportType: String) -> Unit) {
|
||||
val reportTypes = arrayListOf("垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它")
|
||||
|
||||
DialogUtils.showListDialog(context, reportTypes, null) { text ->
|
||||
val jsonObject = JSONObject()
|
||||
try {
|
||||
jsonObject.put("reason", text)
|
||||
reportCallback.invoke(jsonObject.toString())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
if (!isVideoComment) {
|
||||
DialogUtils.showListDialog(context, reportTypes, null) { text ->
|
||||
val jsonObject = JSONObject()
|
||||
try {
|
||||
jsonObject.put("reason", text)
|
||||
reportCallback.invoke(jsonObject.toString())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DialogUtils.showVideoComplaintDialog(context, reportTypes, null) { text ->
|
||||
reportCallback.invoke(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,8 +12,6 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.gamecenter.CommentDetailActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
|
||||
@ -22,6 +20,7 @@ import com.gh.gamecenter.entity.MeEntity;
|
||||
import com.gh.gamecenter.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -40,6 +39,8 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.ResponseBody;
|
||||
@ -279,6 +280,9 @@ public class CommentUtils {
|
||||
if (TextUtils.isEmpty(articleId)) {
|
||||
entrance = "社区文章详情-评论-点赞";
|
||||
}
|
||||
if (TextUtils.isEmpty(videoId)) {
|
||||
entrance = "视频流-评论-点赞";
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
@ -330,6 +334,97 @@ public class CommentUtils {
|
||||
});
|
||||
});
|
||||
}
|
||||
public static void voteVideoComment(final Context context,
|
||||
String answerId,
|
||||
String articleId,
|
||||
String articleCommunityId,
|
||||
String videoId,
|
||||
final CommentEntity commentEntity,
|
||||
final TextView commentLikeCountTv,
|
||||
final ImageView commentLikeIv,
|
||||
final OnVoteListener listener) {
|
||||
|
||||
String entrance = "视频流-评论-点赞";
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
|
||||
PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, commentEntity.getId(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
if (listener != null) {
|
||||
listener.onVote();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable e) {
|
||||
commentEntity.setVote(commentEntity.getVote() - 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
commentLikeIv.setImageResource(R.drawable.comment_vote_unselect);
|
||||
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
|
||||
if (commentEntity.getVote() == 0) {
|
||||
commentLikeCountTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (e instanceof HttpException) {
|
||||
HttpException exception = (HttpException) e;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "网络异常,点赞失败");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static void unVoteVideoComment(final Context context,
|
||||
String videoId,
|
||||
final CommentEntity commentEntity,
|
||||
final TextView commentLikeCountTv,
|
||||
final ImageView commentLikeIv) {
|
||||
String entrance = "视频流-评论-取消点赞";
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.unVoteVideoComment(videoId, commentEntity.getId())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(@Nullable ResponseBody response) {
|
||||
super.onResponse(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@Nullable HttpException e) {
|
||||
super.onFailure(e);
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
|
||||
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
|
||||
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
try {
|
||||
if (e != null && e.response().errorBody() != null) {
|
||||
ErrorHelper.handleError(context, e.response().errorBody().string(), false);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 设置评论item 用户相关的view(点赞/头像/用户名)
|
||||
|
||||
@ -2,10 +2,10 @@ package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.common.loghub.LoghubUtils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
@ -53,10 +53,13 @@ public class DataLogUtils {
|
||||
String channel = HaloApp.getInstance().getChannel();
|
||||
map.put("version", version);
|
||||
map.put("user", user);
|
||||
map.put("device_id", Util_System_Phone_State.getDeviceId(context));
|
||||
map.put("device_id", MetaUtil.getIMEI());
|
||||
map.put("channel", channel);
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if ("search-hot-tag".equals(topic) || "game".equals(topic) || "slide".equals(topic)) {
|
||||
params.put("meta", LogUtils.getMetaObject().toString());
|
||||
}
|
||||
params.put("topic", topic);
|
||||
params.put("source", "GH-ASSIST-Client");
|
||||
params.put("time", String.valueOf(Utils.getTime(context)));
|
||||
|
||||
@ -6,7 +6,6 @@ import android.content.Context;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gid.GidCallback;
|
||||
@ -14,13 +13,6 @@ import com.gh.gid.GidHelper;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
import com.tencent.stat.MtaSDkException;
|
||||
import com.tencent.stat.StatConfig;
|
||||
import com.tencent.stat.StatCrashReporter;
|
||||
import com.tencent.stat.StatReportStrategy;
|
||||
import com.tencent.stat.StatService;
|
||||
import com.tendcloud.tenddata.TCAgent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -44,71 +36,71 @@ public class DataUtils {
|
||||
return;
|
||||
}
|
||||
//TalkingData
|
||||
try {
|
||||
TCAgent.LOG_ON = false;
|
||||
TCAgent.init(context, Config.TALKINGDATA_APPID, channel);
|
||||
/**
|
||||
*
|
||||
* 不要启用!!!!不要启用,全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
*/
|
||||
TCAgent.setReportUncaughtExceptions(false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// TCAgent.LOG_ON = false;
|
||||
// TCAgent.init(context, Config.TALKINGDATA_APPID, channel);
|
||||
// /**
|
||||
// *
|
||||
// * 不要启用!!!!不要启用,全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
// */
|
||||
// TCAgent.setReportUncaughtExceptions(false);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
//MTA
|
||||
try {
|
||||
/**
|
||||
*
|
||||
* 不要启用!!!!全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
*/
|
||||
StatConfig.setAutoExceptionCaught(false);
|
||||
|
||||
StatCrashReporter crashReporter = StatCrashReporter.getStatCrashReporter(context);
|
||||
crashReporter.setJavaCrashHandlerStatus(false);
|
||||
// crashReporter.setEnableInstantReporting(true);
|
||||
|
||||
StatConfig.setDebugEnable(false);
|
||||
|
||||
// 设置数据上报策略
|
||||
// 测试渠道的时候即时上传,方便查看日志
|
||||
if (Config.DEFAULT_CHANNEL.equals(HaloApp.getInstance().getChannel())) {
|
||||
StatConfig.setStatSendStrategy(StatReportStrategy.INSTANT);
|
||||
} else {
|
||||
StatConfig.setStatSendStrategy(StatReportStrategy.PERIOD);
|
||||
StatConfig.setSendPeriodMinutes(5);
|
||||
}
|
||||
|
||||
// 设置启用Tlink
|
||||
StatConfig.setTLinkStatus(true);
|
||||
|
||||
StatConfig.init(context);
|
||||
StatConfig.setInstallChannel(channel);
|
||||
StatConfig.setAntoActivityLifecycleStat(true);
|
||||
StatConfig.setAppVersion(PackageUtils.getVersionName());
|
||||
|
||||
// 开启收集服务
|
||||
StatService.startStatService(context, Config.MTA_APPKEY, com.tencent.stat.common.StatConstants.VERSION);
|
||||
StatService.registerActivityLifecycleCallbacks(context);
|
||||
} catch (MtaSDkException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// /**
|
||||
// *
|
||||
// * 不要启用!!!!全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
// */
|
||||
// StatConfig.setAutoExceptionCaught(false);
|
||||
//
|
||||
// StatCrashReporter crashReporter = StatCrashReporter.getStatCrashReporter(context);
|
||||
// crashReporter.setJavaCrashHandlerStatus(false);
|
||||
//// crashReporter.setEnableInstantReporting(true);
|
||||
//
|
||||
// StatConfig.setDebugEnable(false);
|
||||
//
|
||||
// // 设置数据上报策略
|
||||
// // 测试渠道的时候即时上传,方便查看日志
|
||||
// if (Config.DEFAULT_CHANNEL.equals(HaloApp.getInstance().getChannel())) {
|
||||
// StatConfig.setStatSendStrategy(StatReportStrategy.INSTANT);
|
||||
// } else {
|
||||
// StatConfig.setStatSendStrategy(StatReportStrategy.PERIOD);
|
||||
// StatConfig.setSendPeriodMinutes(5);
|
||||
// }
|
||||
//
|
||||
// // 设置启用Tlink
|
||||
// StatConfig.setTLinkStatus(true);
|
||||
//
|
||||
// StatConfig.init(context);
|
||||
// StatConfig.setInstallChannel(channel);
|
||||
// StatConfig.setAntoActivityLifecycleStat(true);
|
||||
// StatConfig.setAppVersion(PackageUtils.getVersionName());
|
||||
//
|
||||
// // 开启收集服务
|
||||
// StatService.startStatService(context, Config.MTA_APPKEY, com.tencent.stat.common.StatConstants.VERSION);
|
||||
// StatService.registerActivityLifecycleCallbacks(context);
|
||||
// } catch (MtaSDkException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
// init bugly
|
||||
try {
|
||||
CrashReport.setIsDevelopmentDevice(context, Config.DEFAULT_CHANNEL.equals(channel));
|
||||
|
||||
CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
|
||||
strategy.setEnableANRCrashMonitor(false);
|
||||
strategy.setEnableNativeCrashMonitor(false);
|
||||
strategy.setAppChannel(channel);
|
||||
strategy.setAppVersion(PackageUtils.getVersionName());
|
||||
|
||||
CrashReport.initCrashReport(context, Config.BUGLY_APPID, false, strategy);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// CrashReport.setIsDevelopmentDevice(context, Config.DEFAULT_CHANNEL.equals(channel));
|
||||
//
|
||||
// CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
|
||||
// strategy.setEnableANRCrashMonitor(false);
|
||||
// strategy.setEnableNativeCrashMonitor(false);
|
||||
// strategy.setAppChannel(channel);
|
||||
// strategy.setAppVersion(PackageUtils.getVersionName());
|
||||
//
|
||||
// CrashReport.initCrashReport(context, Config.BUGLY_APPID, false, strategy);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -121,7 +113,7 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void getGid() {
|
||||
GidHelper.getInstance().registerDevice(new GidCallback() {
|
||||
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
|
||||
@Override
|
||||
public void onSuccess(String gid) {
|
||||
Utils.log("Gid", gid);
|
||||
@ -147,20 +139,17 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2) {
|
||||
TCAgent.onEvent(var0, var1, var2);
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty(var1, var2);
|
||||
StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
// StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
public static void onPause(Activity var0) {
|
||||
TCAgent.onPageEnd(var0, var0.getClass().getSimpleName());
|
||||
StatService.onPause(var0);
|
||||
// StatService.onPause(var0);
|
||||
}
|
||||
|
||||
public static void onResume(Activity var0) {
|
||||
TCAgent.onPageStart(var0, var0.getClass().getSimpleName());
|
||||
StatService.onResume(var0);
|
||||
// StatService.onResume(var0);
|
||||
}
|
||||
|
||||
// 游戏启动
|
||||
@ -172,13 +161,12 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2, Map<String, Object> var3) {
|
||||
TCAgent.onEvent(var0, var1, var2, var3);
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty("label", var2);
|
||||
for (String key : var3.keySet()) {
|
||||
prop.setProperty(key, var3.get(key) + "");
|
||||
}
|
||||
StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
// StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
public static void trackTimeEvent(Context context, String eventId, int costTime, String... kv) {
|
||||
@ -196,7 +184,7 @@ public class DataUtils {
|
||||
|
||||
if (prop.size() == 0) return;
|
||||
|
||||
StatService.trackCustomKVTimeIntervalEvent(context, costTime, eventId, prop);
|
||||
// StatService.trackCustomKVTimeIntervalEvent(context, costTime, eventId, prop);
|
||||
}
|
||||
|
||||
// 游戏下载
|
||||
@ -244,13 +232,13 @@ public class DataUtils {
|
||||
public static void onError(Context context, Throwable throwable) {
|
||||
//bugly 作为默认处理异常的类库,已经上报了,此处不重复上报
|
||||
try {
|
||||
CrashReport.postCatchedException(throwable);
|
||||
// CrashReport.postCatchedException(throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
//talkingdata
|
||||
try {
|
||||
TCAgent.onError(context, throwable);
|
||||
// TCAgent.onError(context, throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import android.view.View;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
@ -66,6 +67,9 @@ public class DetailDownloadUtils {
|
||||
if ("dialog".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "查看详情" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE_WITH_HINT);
|
||||
} else if ("updating".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "更新中" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.UPDATING);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "暂无下载" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
@ -148,13 +152,25 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
break;
|
||||
case done:
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
if (SimulatorGameManager.isSimulatorGame(viewHolder.gameEntity)){
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(viewHolder.context, viewHolder.gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (isInstalled){
|
||||
viewHolder.mDownloadPb.setText(R.string.launch);
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
|
||||
}else{
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
}
|
||||
}else{
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case cancel:
|
||||
case hijack:
|
||||
|
||||
@ -3,12 +3,12 @@ package com.gh.common.util
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import android.preference.PreferenceManager
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.entity.TimeEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Phone_State
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@ -60,7 +60,7 @@ object DeviceTokenUtils {
|
||||
lunchType = LunchType.FIRST
|
||||
}
|
||||
// 保存deviceId
|
||||
var deviceId = Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application)
|
||||
var deviceId = MetaUtil.getIMEI()
|
||||
if (deviceId.isNullOrEmpty()) {
|
||||
deviceId = Utils.getTime(HaloApp.getInstance().application).toString()
|
||||
}
|
||||
|
||||
@ -6,26 +6,21 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.tencent.stat.StatConfig;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
@ -46,14 +41,14 @@ public class DeviceUtils {
|
||||
context = context.getApplicationContext();
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("os", "Android");
|
||||
object.put("imei", Util_System_Phone_State.getDeviceId(context));
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("mac", getMac(context));
|
||||
object.put("model", MODEL);
|
||||
object.put("manufacturer", MANUFACTURER);
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("android_sdk", Build.VERSION.SDK_INT);
|
||||
object.put("android_version", android.os.Build.VERSION.RELEASE);
|
||||
object.put("ip", getIPAddress(context));
|
||||
object.put("ip", "");
|
||||
object.put("network", getNetwork(context));
|
||||
return object;
|
||||
}
|
||||
@ -62,10 +57,10 @@ public class DeviceUtils {
|
||||
public static JSONObject getUserDevice(Context context) { // 判断新老用户device数据
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("IMEI", Util_System_Phone_State.getDeviceId(context));
|
||||
object.put("ANDROID_ID", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("IMEI", MetaUtil.getIMEI());
|
||||
object.put("ANDROID_ID", MetaUtil.getAndroidId());
|
||||
object.put("MAC", getMac(context));
|
||||
object.put("MTA_ID", StatConfig.getMid(context));
|
||||
// object.put("MTA_ID", StatConfig.getMid(context));
|
||||
object.put("MANUFACTURER", MANUFACTURER);
|
||||
object.put("MODEL", MODEL);
|
||||
object.put("ANDROID_SDK", Build.VERSION.SDK_INT);
|
||||
@ -78,39 +73,39 @@ public class DeviceUtils {
|
||||
}
|
||||
|
||||
public static String getMac(Context context) {
|
||||
String str = "";
|
||||
String macSerial = "";
|
||||
try {
|
||||
Process pp = Runtime.getRuntime().exec(
|
||||
"cat /sys/class/net/wlan0/address ");
|
||||
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
|
||||
LineNumberReader input = new LineNumberReader(ir);
|
||||
|
||||
while (null != str) {
|
||||
str = input.readLine();
|
||||
if (str != null) {
|
||||
macSerial = str.trim();// 去空格
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if ("".equals(macSerial)) {
|
||||
try {
|
||||
return loadFileAsString("/sys/class/net/eth0/address")
|
||||
.toUpperCase().substring(0, 17);
|
||||
} catch (FileNotFoundException e) {
|
||||
// do nothing
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
if (TextUtils.isEmpty(macSerial)) { // 备用方案
|
||||
macSerial = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).getConnectionInfo().getMacAddress();
|
||||
}
|
||||
return macSerial;
|
||||
// String str = "";
|
||||
// String macSerial = "";
|
||||
// try {
|
||||
// Process pp = Runtime.getRuntime().exec(
|
||||
// "cat /sys/class/net/wlan0/address ");
|
||||
// InputStreamReader ir = new InputStreamReader(pp.getInputStream());
|
||||
// LineNumberReader input = new LineNumberReader(ir);
|
||||
//
|
||||
// while (null != str) {
|
||||
// str = input.readLine();
|
||||
// if (str != null) {
|
||||
// macSerial = str.trim();// 去空格
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception ex) {
|
||||
// ex.printStackTrace();
|
||||
// }
|
||||
// if ("".equals(macSerial)) {
|
||||
// try {
|
||||
// return loadFileAsString("/sys/class/net/eth0/address")
|
||||
// .toUpperCase().substring(0, 17);
|
||||
// } catch (FileNotFoundException e) {
|
||||
// // do nothing
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// if (TextUtils.isEmpty(macSerial)) { // 备用方案
|
||||
// macSerial = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).getConnectionInfo().getMacAddress();
|
||||
// }
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String loadFileAsString(String fileName) throws Exception {
|
||||
@ -242,8 +237,7 @@ public class DeviceUtils {
|
||||
|
||||
@Nullable
|
||||
public static String getTelephonySubscriberId(Context context) {
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
return tm.getSubscriberId();
|
||||
return "";
|
||||
}
|
||||
|
||||
// ping domain
|
||||
@ -273,7 +267,6 @@ public class DeviceUtils {
|
||||
return memInfo.totalMem / (1024 * 1024);
|
||||
}
|
||||
|
||||
|
||||
// 只能获取WiFi的IpAddress
|
||||
public static String getCurrentIpAddress() {
|
||||
String ipAddress = "0.0.0.0";
|
||||
|
||||
@ -8,8 +8,11 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.CountDownTimer;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
@ -24,18 +27,23 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.AppExecutor;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.TrackableDialog;
|
||||
@ -46,12 +54,13 @@ import com.gh.common.view.MaxHeightNestedScrollView;
|
||||
import com.gh.gamecenter.AboutActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.SuggestionActivity;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder;
|
||||
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.ImprintContentItemBinding;
|
||||
import com.gh.gamecenter.databinding.PrivacyItemBinding;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.Badge;
|
||||
import com.gh.gamecenter.entity.BadgeEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
|
||||
import com.gh.gamecenter.entity.SettingsEntity;
|
||||
@ -65,6 +74,9 @@ import com.lightgame.utils.AppManager;
|
||||
import com.lightgame.utils.Util_System_Keyboard;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -326,6 +338,82 @@ public class DialogUtils {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* ios 风格弹窗
|
||||
*
|
||||
* @param context
|
||||
* @param title 标题
|
||||
* @param message 内容
|
||||
* @param negative 取消按钮文本
|
||||
* @param positive 确认按钮文本
|
||||
* @param clListener 取消按钮监听
|
||||
* @param cmListener 确认按钮监听
|
||||
*/
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, TrackableEntity trackableEntity, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
context = checkDialogContext(context);
|
||||
final Dialog dialog;
|
||||
if (trackableEntity != null) {
|
||||
dialog = new TrackableDialog(context,
|
||||
R.style.GhAlertDialog,
|
||||
trackableEntity.getEvent(),
|
||||
trackableEntity.getKey(),
|
||||
trackableEntity.getValue(),
|
||||
trackableEntity.getCancelValue(),
|
||||
trackableEntity.getKeyBackValue(),
|
||||
trackableEntity.getLogShowEvent());
|
||||
} else {
|
||||
dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
}
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_new_alert, null);
|
||||
|
||||
TextView titleTv = contentView.findViewById(R.id.title);
|
||||
TextView contentTv = contentView.findViewById(R.id.content);
|
||||
TextView cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
TextView confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
View middleLine = contentView.findViewById(R.id.middle_line);
|
||||
|
||||
titleTv.setText(title);
|
||||
contentTv.setText(message);
|
||||
cancelBtn.setText(negative);
|
||||
confirmBtn.setText(positive);
|
||||
if (negative.isEmpty()) {
|
||||
cancelBtn.setVisibility(View.GONE);
|
||||
middleLine.setVisibility(View.GONE);
|
||||
confirmBtn.setTextColor(ContextCompat.getColor(context, R.color.text_333333));
|
||||
}
|
||||
if (positive.isEmpty()) {
|
||||
confirmBtn.setVisibility(View.GONE);
|
||||
middleLine.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
if (clListener != null) clListener.onCancel();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
if (cmListener != null) cmListener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
return showNewAlertDialog(context, title, message, negative, positive, null, clListener, cmListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Material Design 风格弹窗
|
||||
*
|
||||
@ -899,7 +987,7 @@ public class DialogUtils {
|
||||
params.horizontalMargin = 0;
|
||||
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
|
||||
int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
|
||||
int maxHeight = DisplayUtils.dip2px(546);
|
||||
int maxHeight = DisplayUtils.dip2px(446);
|
||||
if (height > maxHeight) {
|
||||
params.height = maxHeight;
|
||||
} else {
|
||||
@ -935,8 +1023,10 @@ public class DialogUtils {
|
||||
if (hierarchy != null) {
|
||||
if (position == 0) {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_storage);
|
||||
} else {
|
||||
} else if (position == 1) {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_phone_state);
|
||||
} else {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_sdk);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -959,9 +1049,8 @@ public class DialogUtils {
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击隐私政策");
|
||||
Intent intent = WebActivity.getPrivacyPolicyIntent(activityContext);
|
||||
activityContext.startActivity(intent);
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击隐私政策");
|
||||
DirectUtils.directToExternalBrowser(context, context.getString(R.string.privacy_policy_url));
|
||||
}
|
||||
}, skipText.length() - 9, skipText.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
@ -975,11 +1064,26 @@ public class DialogUtils {
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击用户协议");
|
||||
activityContext.startActivity(WebActivity.getWebIntent(activityContext));
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击用户协议");
|
||||
DirectUtils.directToExternalBrowser(context, context.getString(R.string.disclaimer_url));
|
||||
}
|
||||
}, skipText.length() - 4, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
/*skipText.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击第三方SDK接入说明");
|
||||
activityContext.startActivity(WebActivity.getThirdPartySdkStatementIntent(activityContext));
|
||||
}
|
||||
}, skipText.length() - 10, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);*/
|
||||
|
||||
title.setText(entity.getTitle());
|
||||
linkContent.setText(skipText);
|
||||
linkContent.setMovementMethod(new LinkMovementMethod());
|
||||
@ -989,30 +1093,30 @@ public class DialogUtils {
|
||||
allowButton.setOnClickListener(view -> {
|
||||
dialog.dismiss();
|
||||
callback.onCallback();
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
|
||||
});
|
||||
|
||||
disallowButton.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
showPrivacyPolicyDisallowDialog(activityContext, entity, callback);
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
|
||||
});
|
||||
|
||||
dialog.setOnCancelListener(cd -> {
|
||||
if (isCanceledByClickOutsideOfDialog.get()) {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
|
||||
isCanceledByClickOutsideOfDialog.set(false);
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
|
||||
// 用户未同意隐私策略不应该触发 MTA 事件
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
|
||||
|
||||
try {
|
||||
dialog.setCancelable(false);
|
||||
@ -1033,14 +1137,16 @@ public class DialogUtils {
|
||||
View reviewButton = contentView.findViewById(R.id.review_button);
|
||||
|
||||
backButton.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "退出应用");
|
||||
// 用户未同意隐私策略不应该触发 MTA 事件
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "退出应用");
|
||||
dialog.dismiss();
|
||||
AppManager.getInstance().appExit(activityContext);
|
||||
});
|
||||
reviewButton.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "再次查看");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "再次查看");
|
||||
callback.onCallback();
|
||||
dialog.dismiss();
|
||||
showPrivacyPolicyDialog(activityContext, entity, callback);
|
||||
//showPrivacyPolicyDialog(activityContext, entity, callback);
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
@ -1574,29 +1680,222 @@ public class DialogUtils {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showUploadVideoChangeLabelDialog(Context context, @NonNull ConfirmListener confirmListener) {
|
||||
public static void showVideoComplaintDialog(Context context,
|
||||
List<String> options,
|
||||
List<String> disabledOptions,
|
||||
OptionCallback callback) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
Dialog dialog = new Dialog(context);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_upload_video_change_label, null);
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.dialog_video_complaint, null, false);
|
||||
LinearLayout complaintContainer = view.findViewById(R.id.complaintContainer);
|
||||
ConstraintLayout otherComplaintContainer = view.findViewById(R.id.otherComplaintContainer);
|
||||
EditText complaintCommentEt = view.findViewById(R.id.complaintCommentEt);
|
||||
TextView backTv = view.findViewById(R.id.backTv);
|
||||
TextView commitTv = view.findViewById(R.id.commitTv);
|
||||
Context finalContext = context;
|
||||
//添加透明阴影,实现类似 clipPadding=false 效果
|
||||
complaintCommentEt.setShadowLayer(complaintCommentEt.getExtendedPaddingBottom(), 0f, 0f, Color.TRANSPARENT);
|
||||
|
||||
View cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
View confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
ExtensionsKt.setTextChangedListener(complaintCommentEt, (s, start, before, count) -> {
|
||||
commitTv.setTextColor(ContextCompat.getColor(finalContext, s.toString().trim().isEmpty() ? R.color.text_999999 : R.color.theme_font));
|
||||
return null;
|
||||
});
|
||||
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
confirmListener.onConfirm();
|
||||
dialog.dismiss();
|
||||
for (String option : options) {
|
||||
TextView reportTv = new TextView(context);
|
||||
reportTv.setText(option);
|
||||
reportTv.setTextSize(16f);
|
||||
if (disabledOptions != null && disabledOptions.contains(option)) {
|
||||
reportTv.setTextColor(ContextCompat.getColor(context, R.color.btn_gray));
|
||||
} else {
|
||||
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
|
||||
reportTv.setBackgroundResource(R.drawable.textview_white_style);
|
||||
}
|
||||
reportTv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
reportTv.setPadding(DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 17f),
|
||||
DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 17f));
|
||||
if (option.equals("其它")) {
|
||||
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_complaint_arrow_right);
|
||||
drawable.setBounds(0, 0, DisplayUtils.dip2px(6f), DisplayUtils.dip2px(10f));
|
||||
reportTv.setCompoundDrawables(null, null, drawable, null);
|
||||
}
|
||||
complaintContainer.addView(reportTv);
|
||||
|
||||
reportTv.setOnClickListener(v -> {
|
||||
if (option.equals("其它")) {
|
||||
complaintContainer.setVisibility(View.GONE);
|
||||
otherComplaintContainer.setVisibility(View.VISIBLE);
|
||||
complaintCommentEt.requestFocus();
|
||||
Util_System_Keyboard.showSoftKeyboard(finalContext, complaintCommentEt);
|
||||
} else {
|
||||
dialog.cancel();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("reason", reportTv.getText().toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
callback.onClicked(jsonObject.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
backTv.setOnClickListener(v -> {
|
||||
Util_System_Keyboard.hideSoftKeyboard(finalContext, complaintCommentEt);
|
||||
complaintContainer.setVisibility(View.VISIBLE);
|
||||
otherComplaintContainer.setVisibility(View.GONE);
|
||||
});
|
||||
commitTv.setOnClickListener(v -> {
|
||||
if (complaintCommentEt.getText().toString().isEmpty()) {
|
||||
ToastUtils.INSTANCE.showToast("请先输入说明~");
|
||||
return;
|
||||
}
|
||||
dialog.cancel();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("reason", "其它");
|
||||
jsonObject.put("description", complaintCommentEt.getText().toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
callback.onClicked(jsonObject.toString());
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40f);
|
||||
window.setAttributes(params);
|
||||
}
|
||||
}
|
||||
|
||||
public static void showViewBadgeDialog(Context context, Badge badge, ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_view_badge, null);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
|
||||
ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);
|
||||
|
||||
ImageUtils.display(badgeView, badge.getIcon());
|
||||
titleTv.setText(badge.getName());
|
||||
|
||||
// 领取条件文本超过一行就不显示
|
||||
if (badge.getActions() == null || badge.getActions().isEmpty() || badge.getActions().size() > 1) {
|
||||
contentTv.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
contentTv.setText(badge.getActions().get(0).getText());
|
||||
contentTv.post(() -> {
|
||||
if (contentTv.getLineCount() > 1) contentTv.setVisibility(View.INVISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
Animation animation = AnimationUtils.loadAnimation(context, R.anim.anim_badge_light_bg);
|
||||
badgeLightBg.startAnimation(animation);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
badgeLightBg.clearAnimation();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showReceiveBadgeDialog(Context context, BadgeEntity badge, ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_receive_badge, null);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
|
||||
ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);
|
||||
TextView receiveTv = contentView.findViewById(R.id.dialog_ok);
|
||||
|
||||
ImageUtils.display(badgeView, badge.getIcon());
|
||||
titleTv.setText(badge.getName());
|
||||
|
||||
// 领取条件文本超过一行就不显示
|
||||
if (badge.getActions() == null || badge.getActions().isEmpty() || badge.getActions().size() > 1) {
|
||||
contentTv.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
contentTv.setText(badge.getActions().get(0).getText());
|
||||
contentTv.post(() -> {
|
||||
if (contentTv.getLineCount() > 1) contentTv.setVisibility(View.INVISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
if ("self".equals(badge.getReceive().getType())) {
|
||||
receiveTv.setText(R.string.receive_badge);
|
||||
} else {
|
||||
receiveTv.setText(R.string.apply_badge);
|
||||
}
|
||||
|
||||
Animation animation = AnimationUtils.loadAnimation(context, R.anim.anim_badge_light_bg);
|
||||
badgeLightBg.startAnimation(animation);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
badgeLightBg.clearAnimation();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showPassRegulationDialog(Context context, String icon) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_pass_regulation, null);
|
||||
SimpleDraweeView userIcon = contentView.findViewById(R.id.dialog_icon);
|
||||
|
||||
ImageUtils.display(userIcon, icon);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showShortCutPermissionDialog(Context context) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_shortcut_permission, null);
|
||||
|
||||
Context finalContext = context;
|
||||
contentView.findViewById(R.id.dialog_positive).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + finalContext.getPackageName()));
|
||||
finalContext.startActivity(intent);
|
||||
});
|
||||
|
||||
contentView.findViewById(R.id.dialog_negative).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
|
||||
@ -8,6 +8,7 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.base.BaseActivity_TabLayout
|
||||
import com.gh.base.ToolBarActivity
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout
|
||||
import com.gh.common.AppExecutor
|
||||
@ -62,6 +63,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import retrofit2.HttpException
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* 跳转用的方法
|
||||
@ -260,7 +264,7 @@ object DirectUtils {
|
||||
* 跳转至QA
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToQa(context: Context, text: String, id: String) {
|
||||
fun directToQa(context: Context, text: String? = "", id: String) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, QaActivity::class.java.simpleName)
|
||||
@ -768,7 +772,29 @@ object DirectUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBadgeWall(context: Context, userId: String?, name: String?, icon: String?) {
|
||||
context.startActivity(WebActivity.getBadgeCenterIntent(context, userId, name, icon))
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.BADGE_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.BADGE_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s?user_id=%s&name=%s&icon=%s×tamp=%d", url, userId, name, URLEncoder.encode(icon), (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至徽章详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBadgeDetail(context: Context, userId: String?, badgeId: String?) {
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.BADGE_DETAIL_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.BADGE_DETAIL_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s?user_id=%s&badge_id=%s×tamp=%d", url, userId, badgeId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1005,4 +1031,16 @@ object DirectUtils {
|
||||
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_ASK) })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至使用帮助与反馈
|
||||
* @param position 使用帮助:[HelpAndFeedbackActivity.HELP_ITEM],意见反馈:[HelpAndFeedbackActivity.SUGGESTION_ITEM]
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToHelpAndFeedback(context: Context, position: Int = HelpAndFeedbackActivity.HELP_ITEM) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, HelpAndFeedbackActivity::class.java.name)
|
||||
bundle.putInt(BaseActivity_TabLayout.PAGE_INDEX, position)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,8 @@ import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorDownloadManager;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.download.DownloadManager;
|
||||
@ -34,6 +36,7 @@ import com.lightgame.download.DownloadStatus;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@ -195,6 +198,10 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setText("查看");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
} else if ("updating".equals(offStatus)) {
|
||||
holder.gameDownloadBtn.setText("更新中");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.download_button_updating_style);
|
||||
} else {
|
||||
holder.gameDownloadBtn.setText("暂无");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
|
||||
@ -223,9 +230,18 @@ public class DownloadItemUtils {
|
||||
if (entryMap != null && !entryMap.isEmpty()) {
|
||||
DownloadEntity downloadEntity = entryMap.get(apkEntity.getPlatform());
|
||||
if (downloadEntity != null) {
|
||||
// 更改进度条和提示文本的状态
|
||||
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
|
||||
return;
|
||||
if (ExtensionsKt.isSimulatorGame(downloadEntity)) {
|
||||
if (downloadEntity.getStatus() != DownloadStatus.done) {
|
||||
// 更改进度条和提示文本的状态
|
||||
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 更改进度条和提示文本的状态
|
||||
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -468,7 +484,7 @@ public class DownloadItemUtils {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton());
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton());
|
||||
context.startActivity(i);
|
||||
});
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
@ -506,7 +522,115 @@ public class DownloadItemUtils {
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clickCallback 供那些需要知道点击回调的地方使用,只要触发了点击事件就响应回调(未登录状态下点击预约也要响应回调)
|
||||
*/
|
||||
public static void setOnClickListenerWithInvokeCallbackForAllState(final Context context,
|
||||
final TextView downloadBtn,
|
||||
final GameEntity gameEntity,
|
||||
final int position,
|
||||
final RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter,
|
||||
final String entrance,
|
||||
final String location,
|
||||
final ExposureEvent traceEvent,
|
||||
@Nullable final EmptyCallback clickCallback) {
|
||||
|
||||
if (gameEntity.isReservable()) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(context, () -> {
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
|
||||
gameEntity,
|
||||
() -> {
|
||||
LogUtils.logReservation(gameEntity, traceEvent);
|
||||
adapter.notifyItemChanged(position);
|
||||
}
|
||||
);
|
||||
dialogFragment.show(((AppCompatActivity) context).getSupportFragmentManager(), "reserve");
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
if ("download".equals(gameEntity.getReserveStatus())) {
|
||||
ReservationHelper.showDeleteReservationDialog(context, () -> {
|
||||
ReservationHelper.deleteReservation(gameEntity, () -> {
|
||||
adapter.notifyItemChanged(position);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(context, () -> {
|
||||
ReservationHelper.cancelReservation(gameEntity, () -> {
|
||||
adapter.notifyItemChanged(position);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (gameEntity.getApk().size() == 0 && gameEntity.getH5Link() != null) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
|
||||
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
|
||||
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
|
||||
if (isPlay) {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton());
|
||||
context.startActivity(i);
|
||||
});
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
EmptyCallback clickRunnable = () -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent);
|
||||
};
|
||||
|
||||
// 启动不需要请求存储权限
|
||||
if (downloadBtn.getText().toString().equals(context.getString(R.string.launch))) {
|
||||
clickRunnable.onCallback();
|
||||
} else {
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(context, clickRunnable);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(context, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
traceEvent,
|
||||
entrance,
|
||||
location);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void onNormalClick(final Context context,
|
||||
@ -541,6 +665,7 @@ public class DownloadItemUtils {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.getId(), gameEntity.getName(), entrance);
|
||||
} else if (str.equals(context.getString(R.string.attempt))) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
@ -570,8 +695,30 @@ public class DownloadItemUtils {
|
||||
});
|
||||
}
|
||||
} else if (str.equals(context.getString(R.string.install))) {
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
|
||||
if (gameEntity.getSimulator() != null) {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(context, gameEntity.getSimulator(),
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(),null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
install(context, gameEntity, position, adapter);
|
||||
} else if (str.equals(context.getString(R.string.launch))) {
|
||||
//启动模拟器游戏
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(context, gameEntity, downloadBtn, entrance, location, false, traceEvent);
|
||||
return;
|
||||
}
|
||||
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.getName());
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import com.gh.gamecenter.R
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus
|
||||
import com.walkud.rom.checker.RomIdentifier
|
||||
|
||||
object DownloadNotificationHelper {
|
||||
|
||||
@ -29,6 +30,7 @@ object DownloadNotificationHelper {
|
||||
const val ACTION_DOWNLOAD = "com.gh.gamecenter.DOWNLOAD"
|
||||
|
||||
private val mNotifyMap: MutableMap<String, Long> = mutableMapOf()
|
||||
private val mShouldUseAlternativeNotificationIcon by lazy { RomIdentifier.getRom().versionName == null }
|
||||
|
||||
private fun getNotificationManager(): NotificationManager {
|
||||
return HaloApp.getInstance().application.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
@ -43,6 +45,7 @@ object DownloadNotificationHelper {
|
||||
val xapkStatus = entity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
|
||||
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SILENT_UPDATE) return
|
||||
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SIMULATOR_DOWNLOAD) return
|
||||
|
||||
val intent = Intent()
|
||||
if (entity.status == DownloadStatus.done && xapkStatus != XapkUnzipStatus.FAILURE.name) {
|
||||
@ -65,7 +68,7 @@ object DownloadNotificationHelper {
|
||||
val whenTime = 1000 * 60 * (System.currentTimeMillis() / 1000 / 60)
|
||||
val builder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
|
||||
.setContentTitle(entity.name)
|
||||
.setSmallIcon(R.mipmap.logo)
|
||||
.setSmallIcon(getNotificationIcon())
|
||||
.setContentIntent(pendingIntent)
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setWhen(whenTime)
|
||||
@ -112,7 +115,8 @@ object DownloadNotificationHelper {
|
||||
|| entity.status == DownloadStatus.overflow
|
||||
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
|
||||
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty()
|
||||
&& xapkStatus != XapkUnzipStatus.FAILURE.name)) {
|
||||
&& xapkStatus != XapkUnzipStatus.FAILURE.name)
|
||||
||entity.status == DownloadStatus.done && entity.isSimulatorGame()) {//模拟器游戏下载完需要cancel掉通知
|
||||
requireUpdateNotificationGroupDelay = true
|
||||
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
|
||||
} else {
|
||||
@ -139,32 +143,35 @@ object DownloadNotificationHelper {
|
||||
}
|
||||
|
||||
private fun updateNotificationGroup() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val notificationManager = getNotificationManager()
|
||||
val activeNotifications = notificationManager.activeNotifications
|
||||
var downloadNotificationSize = 0
|
||||
var downloadGroupNotificationSize = 0
|
||||
for (activeNotification in activeNotifications) {
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_ID) {
|
||||
downloadNotificationSize++
|
||||
// 部分华为设备调用 getActiveNotifications() 方法时会触发方法内的空指针,这里整体包裹处理了
|
||||
tryCatchInRelease {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val notificationManager = getNotificationManager()
|
||||
val activeNotifications = notificationManager.activeNotifications
|
||||
var downloadNotificationSize = 0
|
||||
var downloadGroupNotificationSize = 0
|
||||
for (activeNotification in activeNotifications) {
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_ID) {
|
||||
downloadNotificationSize++
|
||||
}
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_FOLD_ID) {
|
||||
downloadGroupNotificationSize++
|
||||
}
|
||||
}
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_FOLD_ID) {
|
||||
downloadGroupNotificationSize++
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadNotificationSize == 0 && downloadGroupNotificationSize != 0) {
|
||||
// 删除组可能会把组内所有通知一并删除
|
||||
notificationManager.cancel(DOWNLOAD_NOTIFICATION_FOLD_ID)
|
||||
} else if (downloadNotificationSize != 0 && downloadGroupNotificationSize == 0) {
|
||||
val groupBuilder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
|
||||
.setSmallIcon(R.mipmap.logo)
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setGroupSummary(true)
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText("下载任务"))
|
||||
val groupNotification = groupBuilder.build()
|
||||
groupNotification.flags = groupNotification.flags or Notification.FLAG_NO_CLEAR
|
||||
notificationManager.notify(DOWNLOAD_NOTIFICATION_FOLD_ID, groupNotification)
|
||||
if (downloadNotificationSize == 0 && downloadGroupNotificationSize != 0) {
|
||||
// 删除组可能会把组内所有通知一并删除
|
||||
notificationManager.cancel(DOWNLOAD_NOTIFICATION_FOLD_ID)
|
||||
} else if (downloadNotificationSize != 0 && downloadGroupNotificationSize == 0) {
|
||||
val groupBuilder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
|
||||
.setSmallIcon(getNotificationIcon())
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setGroupSummary(true)
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText("下载任务"))
|
||||
val groupNotification = groupBuilder.build()
|
||||
groupNotification.flags = groupNotification.flags or Notification.FLAG_NO_CLEAR
|
||||
notificationManager.notify(DOWNLOAD_NOTIFICATION_FOLD_ID, groupNotification)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,4 +182,8 @@ object DownloadNotificationHelper {
|
||||
addOrUpdateDownloadNotification(downloadTask)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNotificationIcon(): Int {
|
||||
return if (mShouldUseAlternativeNotificationIcon) R.drawable.ic_notification else R.mipmap.logo
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,9 @@ import android.preference.PreferenceManager
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.download.DownloadManager
|
||||
@ -26,7 +29,6 @@ import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Util_System_Phone_State
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@ -59,8 +61,8 @@ object DownloadObserver {
|
||||
if (DownloadStatus.hijack == downloadEntity.status) {
|
||||
// 链接被劫持
|
||||
processHijack(downloadEntity)
|
||||
val nameAndPlatform = (downloadEntity.name + ":"
|
||||
+ PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
// val nameAndPlatform = (downloadEntity.name + ":"
|
||||
// + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
// MtaHelper.onEvent("下载劫持",
|
||||
// "游戏名字", nameAndPlatform,
|
||||
// "网络状态", DeviceUtils.getNetwork(mApplication))
|
||||
@ -103,6 +105,9 @@ object DownloadObserver {
|
||||
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
}
|
||||
} else if (DownloadStatus.redirected == downloadEntity.status) {
|
||||
debugOnly { Utils.log("重定向完毕") }
|
||||
DownloadDataHelper.uploadRedirectEvent(downloadEntity)
|
||||
}
|
||||
if (DownloadStatus.done == downloadEntity.status) {
|
||||
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
|
||||
@ -130,20 +135,36 @@ object DownloadObserver {
|
||||
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
|
||||
}
|
||||
if (!downloadEntity.isPluggable) {
|
||||
// 是否是自动安装
|
||||
if (PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)) {
|
||||
if (FileUtils.isEmptyFile(downloadEntity.path)) {
|
||||
Utils.toast(mApplication, R.string.install_failure_hint)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else {
|
||||
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
tryWithDefaultCatch {
|
||||
PackageInstaller.install(mApplication, downloadEntity, false)
|
||||
}
|
||||
if (downloadEntity.isSimulatorGame()) {
|
||||
val gameEntity = HaloApp.get(GameEntity::class.java.simpleName, true) as? GameEntity
|
||||
if (gameEntity?.simulator != null) {
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance().application, gameEntity.simulator!!.apk!!.packageName)
|
||||
if (!isInstalled) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(AppManager.getInstance().currentActivity(), gameEntity.simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
|
||||
?: "", null)
|
||||
}
|
||||
SimulatorGameManager.recordDownloadSimulatorGames(gameEntity.id)
|
||||
SimulatorGameManager.postPlayedGame(gameEntity.id, downloadEntity.packageName)
|
||||
}
|
||||
} else {
|
||||
val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
// 是否是自动安装
|
||||
val isAutoInstall = PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)
|
||||
if (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall) {
|
||||
if (FileUtils.isEmptyFile(downloadEntity.path)) {
|
||||
Utils.toast(mApplication, R.string.install_failure_hint)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else {
|
||||
// 弹出卸载提示框
|
||||
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
|
||||
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
tryWithDefaultCatch {
|
||||
PackageInstaller.install(mApplication, downloadEntity, false)
|
||||
}
|
||||
} else {
|
||||
// 弹出卸载提示框
|
||||
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,7 +215,7 @@ object DownloadObserver {
|
||||
kv1["版本"] = platform
|
||||
kv1["状态"] = "下载完成"
|
||||
kv1["用户机型"] = Build.MODEL
|
||||
kv1["设备IMEI"] = Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application)
|
||||
kv1["设备IMEI"] = MetaUtil.getIMEI()
|
||||
kv1["网络状态"] = DeviceUtils.getNetwork(HaloApp.getInstance().application)
|
||||
kv1["光环助手版本"] = BuildConfig.VERSION_NAME
|
||||
if (downloadEntity.isUpdate) {
|
||||
@ -237,6 +258,8 @@ object DownloadObserver {
|
||||
gameVersion = downloadEntity.versionName ?: ""),
|
||||
downloadEntity.platform,
|
||||
downloadEntity.exposureTrace,
|
||||
downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown",
|
||||
downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown",
|
||||
type)
|
||||
|
||||
DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")
|
||||
|
||||
@ -8,6 +8,9 @@ import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.gh.common.avoidcallback.AvoidOnResultManager;
|
||||
import com.gh.common.avoidcallback.Callback;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
@ -23,9 +26,6 @@ import org.json.JSONObject;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
@ -89,6 +89,8 @@ public class EntranceUtils {
|
||||
public static final String HOST_TOOLBOX = "toolbox";
|
||||
public static final String HOST_FORUM_DETAIL = "forum_detail";
|
||||
public static final String HOST_GAME_RATING_DETAIL = "game_rating_detail";
|
||||
public static final String HOST_HELP_AND_FEEDBACK = "help_and_feedback";
|
||||
public static final String HOST_LAUNCH_SIMULATOR_GAME = "launch_simulator_game";
|
||||
public static final String KEY_DATA = "data";
|
||||
public static final String KEY_MESSAGE = "message";
|
||||
public static final String KEY_MESSAGE_ID = "message_id";
|
||||
@ -120,6 +122,7 @@ public class EntranceUtils {
|
||||
public static final String KEY_COMMENT_ID = "comment_id";
|
||||
public static final String KEY_SHOW_KEYBOARD_IF_NEEDED = "show_key_board_if_needed";
|
||||
public static final String KEY_PATH = "path";
|
||||
public static final String KEY_LOCAL_PATH = "local_path";
|
||||
public static final String KEY_OUTER_INFO = "outerInfo";
|
||||
public static final String KEY_OLDERUSER = "isOldUser";
|
||||
public static final String KEY_SEARCHKEY = "searchKey";
|
||||
@ -195,6 +198,9 @@ public class EntranceUtils {
|
||||
public static final String KEY_SECTION_NAME = "section_name"; // 专区专题名
|
||||
public static final String KEY_COLUMNNAME = "columnName";
|
||||
public static final String KEY_QA_ID = "qaId";
|
||||
public static final String KEY_QA_CONTENT_ID = "qaContentId";
|
||||
public static final String KEY_QA_CATEGORY_NAME = "qaCategoryName";
|
||||
public static final String KEY_QA_TITLE = "qa_title";
|
||||
public static final String KEY_QA_COLLECTION_ID = "qaCollectionId";
|
||||
public static final String KEY_SHOW_EDIT_DRAFT = "showEditDraft";
|
||||
public static final String KEY_ARTICLE_OPEN_IN_NEW_PAGE = "openArticleInNewPage";
|
||||
@ -207,6 +213,8 @@ public class EntranceUtils {
|
||||
public static final String KEY_CONFLICT_PHONE = "conflictPhone";
|
||||
public static final String KEY_CONFLICT_USER = "conflictUser";
|
||||
public static final String KEY_BBS_ID = "bbs_id";
|
||||
public static final String KEY_DIAGNOSIS = "diagnosis";
|
||||
public static final String KEY_SIMULATOR = "simulator";
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
|
||||
@ -15,6 +15,7 @@ import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.SeekBar
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -185,6 +186,10 @@ fun View.setDebouncedClickListener(action: () -> Unit) {
|
||||
setOnClickListener { debounceActionWithInterval(interval = 300L) { action.invoke() } }
|
||||
}
|
||||
|
||||
fun isPublishEnv(): Boolean {
|
||||
return BuildConfig.FLAVOR != "internal"
|
||||
}
|
||||
|
||||
/**
|
||||
* LiveData Extensions
|
||||
*/
|
||||
@ -250,24 +255,25 @@ fun String.containHtmlTag(): Boolean {
|
||||
* 用户行为相关
|
||||
*/
|
||||
fun Fragment.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
|
||||
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
|
||||
DialogUtils.showRegulationTestDialog(requireContext(),
|
||||
{ DirectUtils.directToRegulationTestPage(requireContext()) },
|
||||
{ action.invoke() })
|
||||
} else {
|
||||
// if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
|
||||
// DialogUtils.showRegulationTestDialog(requireContext(),
|
||||
// { DirectUtils.directToRegulationTestPage(requireContext()) },
|
||||
// { action.invoke() })
|
||||
// } else {
|
||||
action()
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
fun Context.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
|
||||
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
|
||||
DialogUtils.showRegulationTestDialog(this,
|
||||
{ DirectUtils.directToRegulationTestPage(this) },
|
||||
{ action.invoke() })
|
||||
} else {
|
||||
// if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
|
||||
// DialogUtils.showRegulationTestDialog(this,
|
||||
// { DirectUtils.directToRegulationTestPage(this) },
|
||||
// { action.invoke() })
|
||||
// } else {
|
||||
action()
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 在限定 interval 里只触发一次 action
|
||||
*/
|
||||
@ -425,7 +431,7 @@ fun Float.px2dip(): Int {
|
||||
return (this / scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
fun Float.sp2px():Int{
|
||||
fun Float.sp2px(): Int {
|
||||
val scale: Float = HaloApp.getInstance().application.resources.displayMetrics.scaledDensity
|
||||
return (this * scale + 0.5f).toInt()
|
||||
}
|
||||
@ -656,6 +662,14 @@ fun DownloadEntity.isSilentUpdate(): Boolean {
|
||||
return Constants.SILENT_UPDATE == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
fun DownloadEntity.isSimulatorDownload(): Boolean {
|
||||
return Constants.SIMULATOR_DOWNLOAD == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
fun DownloadEntity.isSimulatorGame(): Boolean {
|
||||
return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Process related
|
||||
*/
|
||||
@ -818,4 +832,21 @@ fun EditText.showKeyBoard() {
|
||||
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.showSoftInput(this, 0)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
|
||||
fun SeekBar.doOnSeekBarChangeListener(progressChange: ((progress: Int) -> Unit)? = null, onStopTrackingTouch: (() -> Unit)? = null) {
|
||||
this.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
progressChange?.invoke(progress)
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||
onStopTrackingTouch?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
23
app/src/main/java/com/gh/common/util/FastClickUtils.kt
Normal file
23
app/src/main/java/com/gh/common/util/FastClickUtils.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.common.OnFastClickListener
|
||||
import io.reactivex.disposables.Disposable
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
object FastClickUtils {
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
private var ref: WeakReference<OnFastClickListener>? = null
|
||||
|
||||
fun click(duration: Int = 500, onClick: OnFastClickListener) {
|
||||
ref = WeakReference(onClick)
|
||||
disposable?.dispose()
|
||||
ref?.get()?.invoke(false)
|
||||
disposable = rxTimer(1) {
|
||||
if (it >= duration) {
|
||||
ref?.get()?.invoke(true)
|
||||
disposable?.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,9 +5,8 @@ import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
@ -24,6 +23,8 @@ import com.lightgame.download.DownloadStatus;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class GameUtils {
|
||||
|
||||
/**
|
||||
@ -116,16 +117,27 @@ public class GameUtils {
|
||||
installCount++;
|
||||
}
|
||||
}
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
DownloadEntity simulatorDownloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apkEntity.getUrl());
|
||||
if (simulatorDownloadEntity != null && gameEntity.getSimulator() != null) {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (isInstalled) {
|
||||
installCount++;
|
||||
} else {
|
||||
doneCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} else if (pluginCount != 0) {
|
||||
return context.getString(R.string.pluggable);
|
||||
} else if (updateCount != 0) {
|
||||
return context.getString(R.string.update);
|
||||
} else if (installCount != 0) {
|
||||
if (installCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen()) {
|
||||
} else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.pluggable);
|
||||
} else if (updateCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.update);
|
||||
} else if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen() && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.attempt);
|
||||
} else {
|
||||
return context.getString(R.string.download);
|
||||
@ -238,7 +250,7 @@ public class GameUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
collectionEntity.setSaveApkEntity(saveApkEntity);
|
||||
return collectionEntity;
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import com.qq.gdt.action.GDTAction
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
|
||||
@ -22,32 +18,38 @@ object GdtHelper {
|
||||
const val SCORE = "SCORE"
|
||||
const val PLATFORM = "PLATFORM"
|
||||
|
||||
fun init(application: Application) {
|
||||
GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
fun init(application: Application, channel: String) {
|
||||
// if (channel == "GH_728") {
|
||||
// GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
|
||||
// } else if (channel == "GH_729") {
|
||||
// GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
|
||||
// } else {
|
||||
// GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
// }
|
||||
}
|
||||
|
||||
fun logAction(type: String) {
|
||||
GDTAction.logAction(type)
|
||||
Utils.log("GDT", type)
|
||||
// GDTAction.logAction(type)
|
||||
// Utils.log("GDT", type)
|
||||
}
|
||||
|
||||
fun logAction(type: String, vararg kv: String?) {
|
||||
try {
|
||||
val actionParam = JSONObject()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
actionParam.put(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
|
||||
GDTAction.logAction(type, actionParam)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// val actionParam = JSONObject()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// actionParam.put(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
|
||||
// GDTAction.logAction(type, actionParam)
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@ -10,6 +10,8 @@ import org.json.JSONArray
|
||||
* Created by khy on 11/10/17.
|
||||
*/
|
||||
object GsonUtils {
|
||||
|
||||
@JvmStatic
|
||||
val gson: Gson = Gson()
|
||||
val gsonThatIgnoreNull: Gson = GsonBuilder().serializeNulls().create()
|
||||
|
||||
@ -20,14 +22,22 @@ object GsonUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJsonList(json: JSONArray): List<T> {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json.toString(), type)
|
||||
return try {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json.toString(), type)
|
||||
} catch (e: Exception) {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJsonList(json: String): List<T> {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json, type)
|
||||
return try {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
gson.fromJson(json, type)
|
||||
} catch (e: Exception) {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@ -10,15 +10,22 @@ import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.facebook.common.executors.CallerThreadExecutor
|
||||
import com.facebook.common.references.CloseableReference
|
||||
import com.facebook.datasource.DataSource
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.drawee.controller.BaseControllerListener
|
||||
import com.facebook.drawee.controller.ControllerListener
|
||||
import com.facebook.drawee.drawable.ScalingUtils
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
||||
import com.facebook.imagepipeline.image.CloseableImage
|
||||
import com.facebook.imagepipeline.image.ImageInfo
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.structure.FixedSizeLinkedHashSet
|
||||
import com.gh.gamecenter.R
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.squareup.picasso.Picasso
|
||||
@ -27,7 +34,6 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
|
||||
object ImageUtils {
|
||||
|
||||
private const val PIC_MAX_FILE_SIZE: Long = 10 * 1024 * 1024
|
||||
@ -36,6 +42,8 @@ object ImageUtils {
|
||||
private val LARGE_GIF_SIZE = 80F.dip2px()
|
||||
private val STANDARD_GIF_SIZE = 60F.dip2px()
|
||||
|
||||
private val mImageUrlCacheSet by lazy { FixedSizeLinkedHashSet<String>(maxSize = 200) }
|
||||
|
||||
@JvmStatic
|
||||
fun getUploadFileMaxSize(): Long {
|
||||
val uploadLimitSize = Config.getSettings()?.image?.uploadLimitSize
|
||||
@ -221,11 +229,44 @@ object ImageUtils {
|
||||
.build()
|
||||
}
|
||||
|
||||
// 获取bitmap (使用 fresco 获取 gif bitmap 会为空,https://github.com/facebook/fresco/issues/241)
|
||||
// 所以这里换用 picasso
|
||||
/**
|
||||
* 获取bitmap (使用 fresco 获取 gif 的 bitmap 会为空,https://github.com/facebook/fresco/issues/241)
|
||||
* 所以当 url 以 .gif 结尾时换用 picasso 获取
|
||||
* 优先使用 fresco 是因为可能已经有了缓存
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getBitmap(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
if (url.endsWith(".gif")) {
|
||||
getBitmapWithPicasso(url, callback)
|
||||
} else {
|
||||
getBitmapWithFresco(url, callback)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBitmapWithFresco(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
val imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(Uri.parse(url))
|
||||
.build()
|
||||
Fresco.getImagePipeline()
|
||||
.fetchDecodedImage(imageRequest, HaloApp.getInstance().application)
|
||||
.subscribe(object : BaseBitmapDataSubscriber() {
|
||||
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
|
||||
callback.onSecond(true)
|
||||
}
|
||||
|
||||
override fun onNewResultImpl(bitmap: Bitmap?) {
|
||||
if (bitmap != null) {
|
||||
callback.onFirst(bitmap)
|
||||
} else {
|
||||
callback.onSecond(true)
|
||||
}
|
||||
}
|
||||
}, CallerThreadExecutor.getInstance())
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun getBitmapWithPicasso(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
Single.just(url)
|
||||
.map { Picasso.with(HaloApp.getInstance().application).load(url).priority(Picasso.Priority.HIGH).get() }
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -246,34 +287,56 @@ object ImageUtils {
|
||||
@JvmStatic
|
||||
fun display(view: SimpleDraweeView?, url: String?) {
|
||||
url?.let {
|
||||
// 图片是以 gif 结尾的就
|
||||
if (it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false) {
|
||||
if (view?.tag == url) return@let
|
||||
val width = view?.layoutParams?.width
|
||||
val height = view?.layoutParams?.height
|
||||
if (width != null && width > 0) {
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(resizeGif(url, width, height ?: 0))
|
||||
.setAutoPlayAnimations(true)
|
||||
.build()
|
||||
view.controller = controller
|
||||
} else {
|
||||
view?.post {
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(resizeGif(url, view.width, view.height))
|
||||
.setAutoPlayAnimations(true)
|
||||
.build()
|
||||
view.controller = controller
|
||||
}
|
||||
val width = view?.layoutParams?.width
|
||||
val height = view?.layoutParams?.height
|
||||
|
||||
var lowResUrl = ""
|
||||
var highResUrl = ""
|
||||
|
||||
// 找同一图片地址已加载过的图片作为低质量预览图
|
||||
// TODO 根据实际请求大小(w_width)来避免小图用大图作为低质量图片
|
||||
for (cachedImageUrl in mImageUrlCacheSet) {
|
||||
if (cachedImageUrl.contains(url)) {
|
||||
lowResUrl = cachedImageUrl
|
||||
break
|
||||
}
|
||||
} else {
|
||||
val width = view?.layoutParams?.width
|
||||
if (width != null && width > 0) {
|
||||
view.setImageURI(getTransformLimitUrl(url, width, view.context))
|
||||
}
|
||||
|
||||
val loadImageClosure: (autoPlay: Boolean, highResUrl: String, lowResUrl: String) -> Unit = { autoPlay, hUrl, lUrl ->
|
||||
view?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(ImageRequest.fromUri(hUrl))
|
||||
.apply {
|
||||
if (lUrl.isNotEmpty()
|
||||
&& lUrl != hUrl
|
||||
&& hUrl != view?.getTag(R.string.highResImageTag)) {
|
||||
lowResImageRequest = ImageRequest.fromUri(lUrl)
|
||||
}
|
||||
autoPlayAnimations = autoPlay
|
||||
}
|
||||
.build()
|
||||
|
||||
view?.setTag(R.string.highResImageTag, highResUrl)
|
||||
}
|
||||
|
||||
val shouldLoadAsGif = it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false
|
||||
|
||||
if (shouldLoadAsGif && view?.tag == url) return
|
||||
|
||||
if (width != null && width > 0) {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, width, height ?: 0)
|
||||
} else {
|
||||
view?.post {
|
||||
view.setImageURI(getTransformLimitUrl(url, view.width, view.context))
|
||||
getTransformLimitUrl(url, width, view.context) ?: ""
|
||||
}
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
} else {
|
||||
view?.post {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, view.width, height ?: 0)
|
||||
} else {
|
||||
getTransformLimitUrl(url, view.width, view.context) ?: ""
|
||||
}
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
}
|
||||
}
|
||||
view?.tag = url
|
||||
@ -285,12 +348,13 @@ object ImageUtils {
|
||||
fun getTransformLimitUrl(url: String?, width: Int?, context: Context?): String? {
|
||||
var transformUrl: String? = url
|
||||
if (width != null && width > 0) {
|
||||
// 加载大小是实际 ImageView 大小两倍的图片真的有意义吗?
|
||||
val transformUrlX2 = addLimitWidth(url, width * 2)
|
||||
val transformUrlX1 = addLimitWidth(url, width)
|
||||
// 当网络为 WIFI 或 4G, 且系统版本大于 5.0 && 手机内存大于 1G 才用高清图片
|
||||
if (NetworkUtils.isWifiOr4GConnected(context)
|
||||
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP
|
||||
&& DeviceUtils.getTotalRamSizeOfDevice(context) > 1000) {
|
||||
&& HaloApp.getInstance().deviceRamSize > 1024) {
|
||||
transformUrl = transformUrlX2
|
||||
} else {
|
||||
// 检查X2大图是否被缓存
|
||||
@ -302,7 +366,7 @@ object ImageUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Utils.log("displayPost::viewWidth->$width----transformUrl->$transformUrl")
|
||||
addCachedUrl(transformUrl ?: "")
|
||||
return transformUrl
|
||||
}
|
||||
|
||||
@ -312,15 +376,19 @@ object ImageUtils {
|
||||
val width = view?.layoutParams?.width
|
||||
if (width != null && width > 0) {
|
||||
view.setImageURI(addLimitWidth(url, width * 2))
|
||||
// Utils.log("displayIcon::viewWidth->" + view.width + "---transformUrl->" + transformUrl)
|
||||
} else {
|
||||
view?.post {
|
||||
view.setImageURI(addLimitWidth(url, view.width * 2))
|
||||
// Utils.log("displayIcon::viewWidth->" + view.width + "---transformUrl->" + transformUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCachedUrl(url: String) {
|
||||
if (url.startsWith("http")) {
|
||||
mImageUrlCacheSet.add(url)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun bmpToByteArray(bmp: Bitmap, needRecycle: Boolean): ByteArray {
|
||||
val output = ByteArrayOutputStream()
|
||||
@ -355,7 +423,7 @@ object ImageUtils {
|
||||
|
||||
private fun resizeGif(url: String, width: Int, height: Int): String {
|
||||
val idealSize = getIdealGifSize(width, height)
|
||||
return "$url?x-oss-process=image/resize,h_$idealSize,w_$idealSize"
|
||||
return "$url?x-oss-process=image/resize,h_$idealSize,w_$idealSize".also { addCachedUrl(it) }
|
||||
}
|
||||
|
||||
private fun getIdealGifSize(width: Int, height: Int): String {
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -19,11 +18,11 @@ public class Installation {
|
||||
private static String sID = null;
|
||||
|
||||
public synchronized static String getUUID(Context context) {
|
||||
String imei = Util_System_Phone_State.getDeviceId(context);
|
||||
String imei = MetaUtil.getIMEI();
|
||||
if (!TextUtils.isEmpty(imei)) {
|
||||
return imei;
|
||||
}
|
||||
String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
String android_id = MetaUtil.getAndroidId();
|
||||
if (!TextUtils.isEmpty(android_id)) {
|
||||
return android_id;
|
||||
}
|
||||
|
||||
@ -4,11 +4,8 @@ import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.ExposureEntity;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
@ -27,7 +24,6 @@ import com.gh.gamecenter.qa.entity.Questions;
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -36,6 +32,7 @@ import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
@ -257,14 +254,13 @@ public class LogUtils {
|
||||
try {
|
||||
object.put("version", PackageUtils.getVersionName());
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("time", Utils.getTime(context));
|
||||
object.put("network", DeviceUtils.getNetwork(context));
|
||||
object.put("user_id", UserManager.getInstance().getUserId());
|
||||
object.put("device_system", android.os.Build.VERSION.RELEASE);
|
||||
object.put("device_model", android.os.Build.MODEL);
|
||||
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance()
|
||||
.getApplication()));
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("G_ID", UserManager.getInstance().getDeviceId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -282,14 +278,13 @@ public class LogUtils {
|
||||
try {
|
||||
object.put("version", PackageUtils.getVersionName());
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("time", Utils.getTime(context));
|
||||
object.put("network", DeviceUtils.getNetwork(context));
|
||||
object.put("user_id", UserManager.getInstance().getUserId());
|
||||
object.put("device_system", android.os.Build.VERSION.RELEASE);
|
||||
object.put("device_model", android.os.Build.MODEL);
|
||||
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance()
|
||||
.getApplication()));
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("G_ID", UserManager.getInstance().getDeviceId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -522,4 +517,124 @@ public class LogUtils {
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(new EmptyResponse<>());
|
||||
}
|
||||
|
||||
public static JSONObject getMetaObject() {
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject metaObject = new JSONObject();
|
||||
try {
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("android_sdk", meta.getAndroid_sdk());
|
||||
metaObject.put("android_version", meta.getAndroid_version());
|
||||
metaObject.put("appVersion", meta.getAppVersion());
|
||||
metaObject.put("channel", meta.getChannel());
|
||||
metaObject.put("gid", meta.getGid());
|
||||
metaObject.put("imei", meta.getImei());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
metaObject.put("network", meta.getNetwork());
|
||||
metaObject.put("os", meta.getOs());
|
||||
metaObject.put("userId", meta.getUserId());
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return metaObject;
|
||||
}
|
||||
|
||||
private static void uploadCommunity(JSONObject object) {
|
||||
try {
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "community", false);
|
||||
}
|
||||
|
||||
public static void uploadAccessToBbs(String bbsId, String location) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
payload.put("location", location);//关注板块/文章外所属论坛/游戏详情/文章内所属论坛
|
||||
payload.put("bbs_id", bbsId);
|
||||
|
||||
object.put("event", "access_to_bbs");
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
uploadCommunity(object);
|
||||
}
|
||||
|
||||
public static void uploadAccessBbsTab() {
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("event", "main_tab[bbs]");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
uploadCommunity(object);
|
||||
}
|
||||
|
||||
|
||||
public static void uploadSimulatorDownload(String event, String fileName, String simulatorId, String simulatorName, String gameId, String location, String downloadType, String startTime) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
object.put("event", event);// 取值有[开始, 完成] [simulator_download, simulator_download_complete]
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
|
||||
payload.put("filename", fileName);// 下载模拟器文件名,每次新创建的下载任务文件名都不同,可以用来关联同一次的下载开始与完成
|
||||
payload.put("simulator_id", simulatorId);
|
||||
payload.put("simulator_name", simulatorName);
|
||||
payload.put("location", location);//启动《具体的游戏名称》/模拟器游戏/模拟器游戏-模拟器管理
|
||||
payload.put("game_id", gameId);//如果是 启动《游戏名称》 这种方式, 记录这个游戏具体的游戏ID
|
||||
payload.put("download_type", downloadType);// update/download 下载类型(更新/下载)
|
||||
if (!TextUtils.isEmpty(startTime) && event.equals("simulator_download_complete")) {
|
||||
payload.put("simulator_download_timestamp", startTime);// 对应的下载开始时间
|
||||
}
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
|
||||
public static void uploadSearchGame(String event, String location, String key, String searchType) {
|
||||
uploadSearchClick(event, location, key, searchType, "", "");
|
||||
}
|
||||
|
||||
public static void uploadSearchClick(String event, String location, String key, String searchType, String gameId, String gameName) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
object.put("event", event);
|
||||
object.put("location", location);
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
|
||||
payload.put("key", key); //搜索关键词
|
||||
payload.put("search_type", searchType); //搜索类型, 有四种取值 默认搜索/历史搜索/自动搜索/主动搜索
|
||||
payload.put("game_id", gameId); //event为search_click才取值
|
||||
payload.put("game_name", gameName); //event为search_click才取值
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,6 @@ package com.gh.common.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import com.bytedance.sdk.open.aweme.authorize.model.Authorization
|
||||
import com.bytedance.sdk.open.douyin.DouYinOpenApiFactory
|
||||
import com.bytedance.sdk.open.douyin.DouYinOpenConfig
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.user.LoginTag
|
||||
@ -89,9 +86,9 @@ object LoginHelper {
|
||||
}
|
||||
}
|
||||
|
||||
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
|
||||
|
||||
DouYinOpenApiFactory.init(DouYinOpenConfig(Config.DOUYIN_CLIENTKEY))
|
||||
|
||||
// DouYinOpenApiFactory.init(DouYinOpenConfig(Config.DOUYIN_CLIENTKEY))
|
||||
|
||||
Utils.log("LoginHelper initialization")
|
||||
}
|
||||
@ -163,6 +160,8 @@ object LoginHelper {
|
||||
// 微博登录
|
||||
@JvmStatic
|
||||
fun loginWithWeibo(loginCallback: LoginCallback, context: Activity) {
|
||||
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
|
||||
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
mSsoHandler = WeakReference(SsoHandler(context))
|
||||
mSsoHandler?.get()?.authorizeClientSso(object : WbAuthListener {
|
||||
@ -204,14 +203,14 @@ object LoginHelper {
|
||||
// 抖音登录
|
||||
@JvmStatic
|
||||
fun loginWithDouYin(loginCallback: LoginCallback, context: Activity) {
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
val douYinOpenApi = DouYinOpenApiFactory.create(context)
|
||||
|
||||
val request = Authorization.Request()
|
||||
request.scope = "user_info" // 用户授权时必选权限
|
||||
//request.state = "ww"; // 用于保持请求和回调的状态,授权请求后原样带回给第三方。
|
||||
//request.callerLocalEntry = "com.xxx.xxx...activity";
|
||||
douYinOpenApi.authorize(request)
|
||||
// mLoginCallback = WeakReference(loginCallback)
|
||||
// val douYinOpenApi = DouYinOpenApiFactory.create(context)
|
||||
//
|
||||
// val request = Authorization.Request()
|
||||
// request.scope = "user_info" // 用户授权时必选权限
|
||||
// //request.state = "ww"; // 用于保持请求和回调的状态,授权请求后原样带回给第三方。
|
||||
// //request.callerLocalEntry = "com.xxx.xxx...activity";
|
||||
// douYinOpenApi.authorize(request)
|
||||
}
|
||||
|
||||
interface LoginCallback {
|
||||
|
||||
@ -3,9 +3,8 @@ package com.gh.common.util;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.net.Uri;
|
||||
@ -16,6 +15,7 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
@ -26,6 +26,7 @@ import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.common.Base64ImageHolder;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -205,6 +206,48 @@ public class MessageShareUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public void shareFromWeb(Activity activity, String type) {
|
||||
// base64转bitmap
|
||||
byte[] decode = Base64.decode(Base64ImageHolder.INSTANCE.getImage(), Base64.DEFAULT);
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
|
||||
// 转完后重新置位
|
||||
Base64ImageHolder.INSTANCE.setImage("");
|
||||
|
||||
this.picName = "shareImgPic.jpg";
|
||||
this.mActivity = new WeakReference<>(activity);
|
||||
this.shareBm = bitmap;
|
||||
|
||||
// 保存图片
|
||||
File file = new File(activity.getExternalCacheDir().getPath() + "/ShareImg");
|
||||
if (!file.isDirectory()) {
|
||||
file.delete();
|
||||
file.mkdirs();
|
||||
}
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
writeBitmap(file.getPath(), picName, bitmap, false);
|
||||
|
||||
// 分享
|
||||
switch (type) {
|
||||
case "qq" :
|
||||
qqSahre();
|
||||
break;
|
||||
case "qq_zone" :
|
||||
qZoneSahre();
|
||||
break;
|
||||
case "wechat" :
|
||||
wechatSahre();
|
||||
break;
|
||||
case "wechat_moments" :
|
||||
wechatMomentsSahre();
|
||||
case "save" :
|
||||
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/";
|
||||
writeBitmap(savePath, "gh-" + new Date().getTime() + ".jpg", shareBm, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//QQ分享
|
||||
private void qqSahre() {
|
||||
Utils.toast(mContext, "分享跳转中...");
|
||||
|
||||
@ -1,61 +1,52 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Phone_State
|
||||
import com.lightgame.utils.Utils
|
||||
import com.tencent.stat.StatService
|
||||
import java.util.*
|
||||
|
||||
object MtaHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun onEvent(eventId: String, vararg kv: String?) {
|
||||
val prop = Properties()
|
||||
|
||||
if (kv.size == 1) {
|
||||
prop.setProperty(kv[0], kv[0])
|
||||
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
return
|
||||
}
|
||||
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// val prop = Properties()
|
||||
//
|
||||
// if (kv.size == 1) {
|
||||
// prop.setProperty(kv[0], kv[0])
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onEventWithTime(eventId: String, time: Int, vararg kv: String?) {
|
||||
val prop = Properties()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0 || i != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.size == 0 && kv.size == 1) {
|
||||
prop.setProperty(kv[0], kv[0])
|
||||
}
|
||||
|
||||
if (prop.size == 0) return
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
|
||||
StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
|
||||
// val prop = Properties()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0 || i != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (prop.size == 0 && kv.size == 1) {
|
||||
// prop.setProperty(kv[0], kv[0])
|
||||
// }
|
||||
//
|
||||
// if (prop.size == 0) return
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
|
||||
// StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,29 +54,29 @@ object MtaHelper {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun onEventWithBasicDeviceInfo(eventId: String, vararg kv: String) {
|
||||
val prop = Properties()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop.setProperty("光环版本", BuildConfig.VERSION_NAME)
|
||||
prop.setProperty("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
prop.setProperty("IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application))
|
||||
prop.setProperty("机型", Build.MODEL)
|
||||
prop.setProperty("厂商", Build.MANUFACTURER)
|
||||
prop.setProperty("Android版本", Build.VERSION.RELEASE)
|
||||
if (!TextUtils.isEmpty(HaloApp.getInstance().gid)) {
|
||||
prop.setProperty("GID", HaloApp.getInstance().gid)
|
||||
}
|
||||
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// val prop = Properties()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// prop.setProperty("光环版本", BuildConfig.VERSION_NAME)
|
||||
// prop.setProperty("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
// prop.setProperty("IMEI", MetaUtil.getIMEI())
|
||||
// prop.setProperty("机型", Build.MODEL)
|
||||
// prop.setProperty("厂商", Build.MANUFACTURER)
|
||||
// prop.setProperty("Android版本", Build.VERSION.RELEASE)
|
||||
// if (!TextUtils.isEmpty(HaloApp.getInstance().gid)) {
|
||||
// prop.setProperty("GID", HaloApp.getInstance().gid)
|
||||
// }
|
||||
//
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,15 +5,10 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.dialog.NotificationHintDialogFragment
|
||||
import com.gh.gamecenter.entity.NotificationHint
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
object NotificationHelper {
|
||||
|
||||
@ -159,7 +154,8 @@ object NotificationHelper {
|
||||
callBack?.invoke(false)
|
||||
} else {
|
||||
callBack?.invoke(true)
|
||||
NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
|
||||
// if (activity.supportFragmentManager.isStateSaved) return
|
||||
// NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,13 +5,16 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.FileProvider
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.dialog.InstallPermissionDialogFragment
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Utils
|
||||
import java.io.File
|
||||
|
||||
@ -35,15 +38,17 @@ object PackageInstaller {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun install(context: Context, downloadEntity: DownloadEntity, showUnzipToast: Boolean) {
|
||||
// 取消状态栏下载完成的通知,若存在
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
InstallPermissionDialogFragment.show(AppManager.getInstance().currentActivity() as AppCompatActivity) {
|
||||
// 取消状态栏下载完成的通知,若存在
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
val pkgPath = downloadEntity.path
|
||||
if (XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()) {
|
||||
XapkInstaller.install(context, downloadEntity, showUnzipToast)
|
||||
} else {
|
||||
install(context, downloadEntity.path)
|
||||
val pkgPath = downloadEntity.path
|
||||
if (XapkInstaller.XAPK_EXTENSION_NAME == pkgPath.getExtension()) {
|
||||
XapkInstaller.install(context, downloadEntity, showUnzipToast)
|
||||
} else {
|
||||
install(context, downloadEntity.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -304,6 +304,11 @@ public class PackageUtils {
|
||||
return intent != null;
|
||||
}
|
||||
|
||||
public static boolean isInstalledFromAllPackage(Context context, String packageName) {
|
||||
ArrayList<String> allPackageName = getAllPackageName(context);
|
||||
return allPackageName.contains(packageName);
|
||||
}
|
||||
|
||||
/*
|
||||
* 获取应用第一次安装的时间
|
||||
*/
|
||||
|
||||
@ -13,6 +13,8 @@ import com.tbruyelle.rxpermissions2.RxPermissions
|
||||
|
||||
object PermissionHelper {
|
||||
|
||||
const val INSTALL_PERMISS_CODE = 100
|
||||
|
||||
@JvmStatic
|
||||
fun requestReadPhoneStateAndStoragePermissionFromStartUp(context: Context) {
|
||||
if (context is FragmentActivity) {
|
||||
@ -221,5 +223,18 @@ object PermissionHelper {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启安装未知来源权限
|
||||
*/
|
||||
fun toInstallPermissionSetting(activity: Activity) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
toSystemConfig(activity)
|
||||
} else {
|
||||
val packageURI = Uri.fromParts("package", activity.packageName, null)
|
||||
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
|
||||
activity.startActivityForResult(intent, INSTALL_PERMISS_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,82 +1,82 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
|
||||
object PushHelper {
|
||||
|
||||
/**
|
||||
* 提交推送点击事件,会尝试从 SP 读取之前失败的一并提交
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun postPushClickAction(context: Context, clickEvent: UmengMessageReceiver.ClickEvent? = null) {
|
||||
val clickEventList = arrayListOf<UmengMessageReceiver.ClickEvent>()
|
||||
|
||||
clickEvent?.let { clickEventList.add(it) }
|
||||
|
||||
val failedClickEventList = SPUtils.getString(UmengMessageReceiver.SP_CLICK_EVENT)
|
||||
.toObject<ArrayList<UmengMessageReceiver.ClickEvent>>()
|
||||
|
||||
failedClickEventList?.let { clickEventList.addAll(it) }
|
||||
|
||||
// 没有要提交的事件
|
||||
if (clickEventList.size == 0) return
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), clickEventList.toJson())
|
||||
|
||||
RetrofitManager.getInstance(context)
|
||||
.api
|
||||
.postUmengReceiveInfo(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
SPUtils.setString(UmengMessageReceiver.SP_CLICK_EVENT, "")
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
SPUtils.setString(UmengMessageReceiver.SP_CLICK_EVENT, clickEventList.toJson())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将消息中心的消息标记为已读
|
||||
* [type] 跳转类型
|
||||
* [notificationMessageId] 通知中心 ID
|
||||
*/
|
||||
fun setNotificationMessageRead(context: Context, type: String, notificationMessageId: String) {
|
||||
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("type", type)
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
|
||||
RetrofitManager.getInstance(context)
|
||||
.api
|
||||
.postMessageRead(UserManager.getInstance().userId, notificationMessageId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
MessageUnreadRepository.loadMessageUnreadData()
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
e?.printStackTrace()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
//package com.gh.common.util
|
||||
//
|
||||
//import android.annotation.SuppressLint
|
||||
//import android.content.Context
|
||||
//import com.gh.gamecenter.manager.UserManager
|
||||
//import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver
|
||||
//import com.gh.gamecenter.retrofit.BiResponse
|
||||
//import com.gh.gamecenter.retrofit.Response
|
||||
//import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
//import io.reactivex.schedulers.Schedulers
|
||||
//import okhttp3.MediaType
|
||||
//import okhttp3.RequestBody
|
||||
//import okhttp3.ResponseBody
|
||||
//import org.json.JSONObject
|
||||
//import retrofit2.HttpException
|
||||
//
|
||||
//object PushHelper {
|
||||
//
|
||||
// /**
|
||||
// * 提交推送点击事件,会尝试从 SP 读取之前失败的一并提交
|
||||
// */
|
||||
// @SuppressLint("CheckResult")
|
||||
// @JvmStatic
|
||||
// fun postPushClickAction(context: Context, clickEvent: UmengMessageReceiver.ClickEvent? = null) {
|
||||
// val clickEventList = arrayListOf<UmengMessageReceiver.ClickEvent>()
|
||||
//
|
||||
// clickEvent?.let { clickEventList.add(it) }
|
||||
//
|
||||
// val failedClickEventList = SPUtils.getString(UmengMessageReceiver.SP_CLICK_EVENT)
|
||||
// .toObject<ArrayList<UmengMessageReceiver.ClickEvent>>()
|
||||
//
|
||||
// failedClickEventList?.let { clickEventList.addAll(it) }
|
||||
//
|
||||
// // 没有要提交的事件
|
||||
// if (clickEventList.size == 0) return
|
||||
//
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), clickEventList.toJson())
|
||||
//
|
||||
// RetrofitManager.getInstance(context)
|
||||
// .api
|
||||
// .postUmengReceiveInfo(body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .subscribe(object : BiResponse<ResponseBody>() {
|
||||
// override fun onSuccess(data: ResponseBody) {
|
||||
// SPUtils.setString(UmengMessageReceiver.SP_CLICK_EVENT, "")
|
||||
// }
|
||||
//
|
||||
// override fun onFailure(exception: Exception) {
|
||||
// SPUtils.setString(UmengMessageReceiver.SP_CLICK_EVENT, clickEventList.toJson())
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 将消息中心的消息标记为已读
|
||||
// * [type] 跳转类型
|
||||
// * [notificationMessageId] 通知中心 ID
|
||||
// */
|
||||
// fun setNotificationMessageRead(context: Context, type: String, notificationMessageId: String) {
|
||||
//
|
||||
// val jsonObject = JSONObject()
|
||||
// jsonObject.put("type", type)
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
//
|
||||
// RetrofitManager.getInstance(context)
|
||||
// .api
|
||||
// .postMessageRead(UserManager.getInstance().userId, notificationMessageId, body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .subscribe(object : Response<ResponseBody>() {
|
||||
// override fun onResponse(response: ResponseBody?) {
|
||||
// super.onResponse(response)
|
||||
// MessageUnreadRepository.loadMessageUnreadData()
|
||||
// }
|
||||
//
|
||||
// override fun onFailure(e: HttpException?) {
|
||||
// e?.printStackTrace()
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
@ -8,7 +8,6 @@ import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
@ -57,7 +56,7 @@ object ReservationHelper {
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
Utils.toast(getApplication(), exception.message)
|
||||
Utils.toast(HaloApp.getInstance().application, exception.message)
|
||||
exception.printStackTrace()
|
||||
}
|
||||
})
|
||||
|
||||
@ -24,9 +24,6 @@ import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WeiBoShareActivity;
|
||||
@ -53,6 +50,9 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import static com.gh.common.util.LoginHelper.WEIBO_SCOPE;
|
||||
|
||||
/**
|
||||
@ -90,7 +90,9 @@ public class ShareUtils {
|
||||
shareGh("APP分享"),
|
||||
communityArticle("文章详情"),
|
||||
video("视频"),
|
||||
web("web链接");
|
||||
web("web链接"),
|
||||
userHome("个人主页"),
|
||||
qaDetail("QA内容详情");
|
||||
|
||||
private String name;
|
||||
|
||||
@ -145,7 +147,7 @@ public class ShareUtils {
|
||||
mContext = context.getApplicationContext();
|
||||
mTencent = Tencent.createInstance(Config.TENCENT_APPID, mContext); //初始化QQ分享
|
||||
mIWXAPI = WXAPIFactory.createWXAPI(mContext, Config.WECHAT_APPID); //初始化微信分享
|
||||
WbSdk.install(mContext, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
|
||||
|
||||
}
|
||||
|
||||
public static ShareUtils getInstance(Context context) {
|
||||
@ -170,6 +172,67 @@ public class ShareUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void showShareUserHomeWindows(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
|
||||
if (activity.isFinishing()) return;
|
||||
this.mActivity = new WeakReference<>(activity);
|
||||
this.shareIcon = icon;
|
||||
this.shareUrl = url;
|
||||
this.mSummary = shareSummary;
|
||||
this.mTitle = shareTitle;
|
||||
this.mShareEntrance = shareEntrance;
|
||||
ShareUtils.shareEntrance = mShareEntrance;
|
||||
ShareUtils.resourceId = id;
|
||||
ShareUtils.shareEntity = new ShareEntity(shareUrl, mTitle, mSummary);
|
||||
LogUtils.uploadShareEnter(mShareEntrance.getName(), shareUrl, mTitle, mSummary, id);
|
||||
|
||||
View contentView = View.inflate(mActivity.get(), R.layout.popup_share_dialog, null);
|
||||
contentView.setFocusable(true);
|
||||
contentView.setFocusableInTouchMode(true);
|
||||
|
||||
View wechatType = contentView.findViewById(R.id.item_wechat);
|
||||
View wechatMomentsType = contentView.findViewById(R.id.item_wechat_moments);
|
||||
View qqType = contentView.findViewById(R.id.item_qq);
|
||||
View qqZoneType = contentView.findViewById(R.id.item_qq_zone);
|
||||
View weiboType = contentView.findViewById(R.id.item_weibo);
|
||||
|
||||
wechatType.setOnClickListener((v) -> wechatShare());
|
||||
wechatMomentsType.setOnClickListener((v) -> wechatMomentsShare());
|
||||
qqType.setOnClickListener((v) -> qqShare());
|
||||
qqZoneType.setOnClickListener((v) -> qZoneShare());
|
||||
weiboType.setOnClickListener((v) -> sinaWeiboShare());
|
||||
|
||||
popupWindow = new WeakReference<>(new SharePopupWindow(contentView, LinearLayout.LayoutParams.MATCH_PARENT
|
||||
, LinearLayout.LayoutParams.MATCH_PARENT, true));
|
||||
// popupWindow.get().setAnimationStyle(R.style.popwindow_exit_only_anim_style);
|
||||
//解决PopupWindow无法覆盖状态栏
|
||||
popupWindow.get().setClippingEnabled(false);
|
||||
|
||||
int bottomLocation = -DisplayUtils.retrieveNavigationHeight(activity);
|
||||
if (!DisplayUtils.isNavigationBarShow(activity)) {
|
||||
bottomLocation = 0;
|
||||
}
|
||||
try {
|
||||
popupWindow.get().showAtLocation(view, Gravity.NO_GRAVITY, 0, bottomLocation);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
contentView.setOnClickListener(v -> safelyDismiss());
|
||||
|
||||
contentView.setOnKeyListener((v, keyCode, event) -> {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK
|
||||
&& event.getRepeatCount() == 0
|
||||
&& popupWindow.get() != null
|
||||
&& popupWindow.get().isShowing()) {
|
||||
if (callBack != null) {
|
||||
callBack.onCancel();
|
||||
}
|
||||
safelyDismiss();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
public void showShareWindowsCallback(Activity activity, View view, String url, String icon, String shareTitle, String shareSummary, ShareEntrance shareEntrance, String id, ShareCallBack callBack) {
|
||||
if (activity.isFinishing()) return;
|
||||
this.mActivity = new WeakReference<>(activity);
|
||||
@ -270,7 +333,8 @@ public class ShareUtils {
|
||||
|
||||
switch (mShareEntrance) {
|
||||
case plugin:
|
||||
mSummary += "(光环加速版)";
|
||||
case game:
|
||||
mTitle += "_要好玩上光环";
|
||||
break;
|
||||
case askNormal:
|
||||
case answerNormal:
|
||||
@ -312,7 +376,8 @@ public class ShareUtils {
|
||||
|
||||
switch (mShareEntrance) {
|
||||
case plugin:
|
||||
mSummary += "(光环加速版)";
|
||||
case game:
|
||||
mTitle += "_要好玩上光环";
|
||||
break;
|
||||
case askNormal:
|
||||
case answerNormal:
|
||||
@ -419,8 +484,8 @@ public class ShareUtils {
|
||||
Bundle params = new Bundle();
|
||||
|
||||
switch (mShareEntrance) {
|
||||
case plugin:
|
||||
mSummary += "(光环加速版)";
|
||||
case game:
|
||||
mTitle += "_光环助手";
|
||||
break;
|
||||
case askNormal:
|
||||
case answerNormal:
|
||||
@ -468,10 +533,8 @@ public class ShareUtils {
|
||||
|
||||
switch (mShareEntrance) {
|
||||
case plugin:
|
||||
msg.title = mSummary + "(光环加速版)";
|
||||
break;
|
||||
case game:
|
||||
msg.title = mSummary;
|
||||
msg.title = mTitle + "_要好玩上光环";
|
||||
break;
|
||||
case askNormal:
|
||||
case answerNormal:
|
||||
@ -499,7 +562,12 @@ public class ShareUtils {
|
||||
|
||||
//新浪微博分享
|
||||
private void sinaWeiboShare() {
|
||||
WbSdk.install(mContext, new AuthInfo(mContext, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE));
|
||||
|
||||
if (mShareEntrance == ShareEntrance.qaDetail) {
|
||||
mTitle = "向你推荐:" + mTitle + " @光环助手 " + shareUrl;
|
||||
mSummary = "";
|
||||
}
|
||||
Activity activity = mActivity.get();
|
||||
if (activity != null) {
|
||||
Intent intent = WeiBoShareActivity.getWeiboshareIntent(
|
||||
@ -528,10 +596,8 @@ public class ShareUtils {
|
||||
smsBody = mTitle + shareUrl;
|
||||
break;
|
||||
case plugin:
|
||||
smsBody = mTitle + mSummary + "(光环加速版)" + shareUrl;
|
||||
break;
|
||||
case game:
|
||||
smsBody = mTitle + mSummary + shareUrl;
|
||||
smsBody = "向你推荐:" + mTitle + "_光环助手:" + shareUrl;
|
||||
break;
|
||||
case shareGh:
|
||||
smsBody = "这个App可以下载各种热门卡牌手游的加速版,绿色安全,超级省心,做日常效率提高3-5倍!光环助手官网地址:" + shareUrl;
|
||||
@ -543,6 +609,9 @@ public class ShareUtils {
|
||||
case communityArticle:
|
||||
smsBody = mTitle + " - 光环助手" + shareUrl;
|
||||
break;
|
||||
case qaDetail:
|
||||
smsBody = "向你推荐:" + mTitle + " @光环助手 " + shareUrl;
|
||||
break;
|
||||
default:
|
||||
smsBody = mTitle;
|
||||
break;
|
||||
@ -556,7 +625,7 @@ public class ShareUtils {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (mShareEntrance != ShareEntrance.shareGh ) {
|
||||
if (mShareEntrance != ShareEntrance.shareGh) {
|
||||
safelyDismiss();
|
||||
}
|
||||
}
|
||||
@ -683,7 +752,7 @@ public class ShareUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void safelyDismiss() {
|
||||
if (popupWindow.get() != null) {
|
||||
popupWindow.get().dismiss();
|
||||
|
||||
@ -46,6 +46,11 @@ object SPUtils {
|
||||
return sp.getInt(key, defaultValue)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLong(key: String): Long {
|
||||
return sp.getLong(key, 0)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getLong(key: String, defaultValue: Long): Long {
|
||||
return sp.getLong(key, defaultValue)
|
||||
@ -71,6 +76,11 @@ object SPUtils {
|
||||
return sp.getBoolean(key, defaultValue)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getBooleanWithContext(context: Context, key: String, defaultValue: Boolean): Boolean {
|
||||
return context.getSharedPreferences("Halo", Context.MODE_PRIVATE).getBoolean(key, defaultValue)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setString(sp: SharedPreferences, key: String, value: String? = null) {
|
||||
try {
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import com.bytedance.applog.AppLog
|
||||
import com.bytedance.applog.GameReportHelper
|
||||
import com.bytedance.applog.InitConfig
|
||||
import com.bytedance.applog.util.UriConfig
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
/**
|
||||
* 今日头条的激活统计 SDK https://gitlab.ghzs.com/pm/halo-app-issues/issues/567
|
||||
@ -18,22 +11,22 @@ object TeaHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun init(context: Context, channel: String) {
|
||||
val config = InitConfig("163824", channel)
|
||||
config.setUriConfig(UriConfig.DEFAULT)
|
||||
config.appName = "guanghuan1"
|
||||
config.setEnablePlay(true)
|
||||
AppLog.setEnableLog(false)
|
||||
AppLog.init(context, config)
|
||||
|
||||
AppLog.setOaidObserver {
|
||||
HaloApp.getInstance().oaid = it.id
|
||||
Utils.log("oaid is $it.id")
|
||||
MetaUtil.refreshMeta()
|
||||
}
|
||||
|
||||
// gameReportHelper ?!
|
||||
GameReportHelper.onEventRegister("wechat", true)
|
||||
GameReportHelper.onEventPurchase("gift", "flower", "008", 1, "wechat", "¥", true, 1)
|
||||
// val config = InitConfig("163824", channel)
|
||||
// config.setUriConfig(UriConfig.DEFAULT)
|
||||
// config.appName = "guanghuan1"
|
||||
// config.setEnablePlay(true)
|
||||
// AppLog.setEnableLog(false)
|
||||
// AppLog.init(context, config)
|
||||
//
|
||||
// AppLog.setOaidObserver {
|
||||
// HaloApp.getInstance().oaid = it.id
|
||||
// Utils.log("oaid is $it.id")
|
||||
// MetaUtil.refreshMeta()
|
||||
// }
|
||||
//
|
||||
// // gameReportHelper ?!
|
||||
// GameReportHelper.onEventRegister("wechat", true)
|
||||
// GameReportHelper.onEventPurchase("gift", "flower", "008", 1, "wechat", "¥", true, 1)
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.gh.common.util
|
||||
import java.text.ParseException
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.math.log10
|
||||
|
||||
object TimeUtils {
|
||||
|
||||
@ -21,10 +22,11 @@ object TimeUtils {
|
||||
return formatter.format(date)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getFormatTime(time: Long, pattern: String = "yyyy-MM-dd"): String {
|
||||
val f = SimpleDateFormat(pattern, Locale.CHINA)
|
||||
f.timeZone = TimeZone.getTimeZone("Asia/Shanghai")
|
||||
return f.format(Date(time * 1000))
|
||||
return f.format(Date(getJavaTimestamp(time)))
|
||||
}
|
||||
|
||||
fun getFormatDate(timestamp: Long): String {
|
||||
@ -100,4 +102,27 @@ object TimeUtils {
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getStartTimeOfToday(): Long = getStartTimeOfDay(System.currentTimeMillis())
|
||||
|
||||
@JvmStatic
|
||||
fun getStartTimeOfDay(currentTime: Long): Long {
|
||||
val calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"))
|
||||
calendar.timeInMillis = getJavaTimestamp(currentTime)
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0)
|
||||
calendar.set(Calendar.MINUTE, 0)
|
||||
calendar.set(Calendar.SECOND, 0)
|
||||
calendar.set(Calendar.MILLISECOND, 0)
|
||||
return calendar.timeInMillis
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getJavaTimestamp(timestamp: Long): Long {
|
||||
return if ((log10(timestamp.toDouble()) + 1).toInt() == 10) {
|
||||
timestamp * 1000
|
||||
} else {
|
||||
timestamp
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -56,4 +56,10 @@ object ToastUtils {
|
||||
}
|
||||
mOneTime = mTwoTime
|
||||
}
|
||||
|
||||
fun toast(message: String) {
|
||||
if (mToast != null) mToast?.cancel()
|
||||
mToast = ToastHandler.INSTANCE.getToastInstance(HaloApp.getInstance().application, message, Toast.LENGTH_SHORT)
|
||||
mToast?.show()
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,8 @@ object UploadImageUtils {
|
||||
suggestion,
|
||||
icon,
|
||||
poster,
|
||||
game_upload
|
||||
game_upload,
|
||||
user_background
|
||||
}
|
||||
|
||||
// 不处理图片,只是单纯的上传
|
||||
@ -273,11 +274,11 @@ object UploadImageUtils {
|
||||
}
|
||||
|
||||
// 防止GIF图片文件后缀不是GIF,这个FileName只是告诉服务端后缀格式,没有其他用处
|
||||
private fun getFileName(file: File): String {
|
||||
fun getFileName(file: File): String {
|
||||
val options = BitmapFactory.Options()
|
||||
options.inJustDecodeBounds = true
|
||||
BitmapFactory.decodeFile(file.absolutePath, options)
|
||||
if (options.outMimeType.contains("gif") && !file.name.toLowerCase().contains(".gif".toLowerCase())) {
|
||||
if (options.outMimeType != null && options.outMimeType.contains("gif") && !file.name.toLowerCase().contains(".gif".toLowerCase())) {
|
||||
return System.currentTimeMillis().toString() + ".gif"
|
||||
}
|
||||
return URLEncoder.encode(file.name, "utf-8")
|
||||
|
||||
@ -47,7 +47,7 @@ object VideoRecordUtils {
|
||||
}
|
||||
|
||||
fun commitVideoRecord() {
|
||||
if (videoRecordSet.isEmpty()) return
|
||||
if (videoRecordSet.isEmpty() || !::mApplication.isInitialized) return
|
||||
videoRecordExecutor.execute {
|
||||
uploadVideoRecord()
|
||||
val exposureList = videoRecordSet.toList()
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.widget.LinearLayout
|
||||
import androidx.annotation.Nullable
|
||||
import androidx.core.view.children
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.OnLifecycleEvent
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
class AutoScrollRecyclerViewContainerView(context: Context, @Nullable attrs: AttributeSet?)
|
||||
: LinearLayout(context, attrs), LifecycleObserver {
|
||||
|
||||
var autoScrollTask: AutoScrollTask?
|
||||
|
||||
private var mIsScrolling = false
|
||||
private var mIsScrollable = false
|
||||
|
||||
private var mOnItemTouchListener: RecyclerView.OnItemTouchListener? = null
|
||||
|
||||
init {
|
||||
autoScrollTask = AutoScrollTask(this)
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
if (mOnItemTouchListener == null) {
|
||||
mOnItemTouchListener = object : RecyclerView.OnItemTouchListener {
|
||||
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
|
||||
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent) = rv.scrollState == RecyclerView.SCROLL_STATE_DRAGGING
|
||||
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
|
||||
}
|
||||
}
|
||||
|
||||
for (child in children) {
|
||||
if (child is RecyclerView) {
|
||||
child.removeOnItemTouchListener(mOnItemTouchListener!!)
|
||||
child.addOnItemTouchListener(mOnItemTouchListener!!)
|
||||
}
|
||||
}
|
||||
|
||||
resumeScrolling()
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
|
||||
pauseScrolling()
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
fun resumeScrolling() {
|
||||
if (mIsScrolling) return
|
||||
|
||||
if (mIsScrolling) pauseScrolling()
|
||||
mIsScrollable = true
|
||||
mIsScrolling = true
|
||||
postDelayed(autoScrollTask, AUTO_SCROLL_INTERVAL)
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||
fun pauseScrolling() {
|
||||
mIsScrolling = false
|
||||
removeCallbacks(autoScrollTask)
|
||||
}
|
||||
|
||||
fun setLifeCycleOwner(lifeCycleOwner: Lifecycle) {
|
||||
lifeCycleOwner.addObserver(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val AUTO_SCROLL_INTERVAL: Long = 10
|
||||
}
|
||||
|
||||
class AutoScrollTask(reference: AutoScrollRecyclerViewContainerView?) : Runnable {
|
||||
private val mReference: WeakReference<AutoScrollRecyclerViewContainerView?>?
|
||||
private val mScrollSlop = if (Build.MODEL.toLowerCase(Locale.getDefault()) == "mumu") 1 else 2
|
||||
|
||||
init {
|
||||
mReference = WeakReference(reference)
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
val containerView: AutoScrollRecyclerViewContainerView? = mReference?.get()
|
||||
if (containerView != null && containerView.mIsScrolling && containerView.mIsScrollable) {
|
||||
for (child in containerView.children) {
|
||||
if (child is RecyclerView) {
|
||||
child.scrollBy(mScrollSlop, mScrollSlop)
|
||||
}
|
||||
}
|
||||
containerView.postDelayed(containerView.autoScrollTask, AUTO_SCROLL_INTERVAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
144
app/src/main/java/com/gh/common/view/AvatarBorderView.kt
Normal file
144
app/src/main/java/com/gh/common/view/AvatarBorderView.kt
Normal file
@ -0,0 +1,144 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.facebook.drawee.drawable.ScalingUtils
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchy
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
|
||||
import com.facebook.drawee.generic.RoundingParams
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.gh.common.util.ImageUtils
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.common.util.px2dip
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
|
||||
class AvatarBorderView : ConstraintLayout {
|
||||
|
||||
var avatarView: SimpleDraweeView? = null
|
||||
var borderView: SimpleDraweeView? = null
|
||||
var badgeView: SimpleDraweeView? = null
|
||||
private var mAvatarWidth = 100f
|
||||
private var mBadgeWidth = 30f
|
||||
private var mAvatarBorderColor = Color.parseColor("#ffffff")
|
||||
private var mAvatarBorderWidth = 2f.dip2px().toFloat()
|
||||
private var mRatio = 0f
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
initView(attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
initView(attrs)
|
||||
}
|
||||
|
||||
private fun initView(attrs: AttributeSet) {
|
||||
val ta = context.obtainStyledAttributes(attrs, R.styleable.AvatarBorderView)
|
||||
if (ta.hasValue(R.styleable.AvatarBorderView_avatar_width)) {
|
||||
mAvatarWidth = ta.getDimension(R.styleable.AvatarBorderView_avatar_width, mAvatarWidth)
|
||||
}
|
||||
if (ta.hasValue(R.styleable.AvatarBorderView_badge_width)) {
|
||||
mBadgeWidth = ta.getDimension(R.styleable.AvatarBorderView_badge_width, mBadgeWidth)
|
||||
}
|
||||
if (ta.hasValue(R.styleable.AvatarBorderView_border_width)) {
|
||||
mAvatarBorderWidth = ta.getDimension(R.styleable.AvatarBorderView_border_width, mAvatarBorderWidth)
|
||||
}
|
||||
if (ta.hasValue(R.styleable.AvatarBorderView_border_ratio)) {
|
||||
mRatio = ta.getFloat(R.styleable.AvatarBorderView_border_ratio, 0f)
|
||||
}
|
||||
mAvatarBorderColor = ta.getColor(R.styleable.AvatarBorderView_border_color, mAvatarBorderColor)
|
||||
ta.recycle()
|
||||
|
||||
LayoutInflater.from(context).inflate(R.layout.view_avatar_border, this, true)
|
||||
avatarView = findViewById(R.id.avatarView)
|
||||
borderView = findViewById(R.id.borderView)
|
||||
badgeView = findViewById(R.id.badgeView)
|
||||
|
||||
changeLayoutParams()
|
||||
}
|
||||
|
||||
private fun changeLayoutParams() {
|
||||
avatarView?.apply {
|
||||
val params = layoutParams
|
||||
params.width = mAvatarWidth.toInt()
|
||||
params.height = mAvatarWidth.toInt()
|
||||
layoutParams = params
|
||||
val roundingParams = RoundingParams.asCircle()
|
||||
roundingParams.borderColor = mAvatarBorderColor
|
||||
roundingParams.borderWidth = mAvatarBorderWidth
|
||||
hierarchy?.roundingParams = roundingParams
|
||||
}
|
||||
borderView?.apply {
|
||||
val params = layoutParams
|
||||
if (mRatio > 0) {
|
||||
params.width = (mAvatarWidth * mRatio).toInt()
|
||||
params.height = (mAvatarWidth * mRatio).toInt()
|
||||
} else {
|
||||
params.width = (mAvatarWidth * 3 / 2).toInt()
|
||||
params.height = (mAvatarWidth * 3 / 2).toInt()
|
||||
}
|
||||
layoutParams = params
|
||||
}
|
||||
badgeView?.apply {
|
||||
val params = layoutParams
|
||||
params.width = mBadgeWidth.toInt()
|
||||
params.height = mBadgeWidth.toInt()
|
||||
layoutParams = params
|
||||
}
|
||||
}
|
||||
|
||||
fun setAvatarWidth(width: Float) {
|
||||
mAvatarWidth = width
|
||||
changeLayoutParams()
|
||||
}
|
||||
|
||||
fun setBadgeWidth(width: Float) {
|
||||
mBadgeWidth = width
|
||||
changeLayoutParams()
|
||||
}
|
||||
|
||||
fun display(borderUrl: String? = "", avatarUrl: String? = "", badgeUrl: String? = "") {
|
||||
if (avatarUrl.isNullOrEmpty()) {
|
||||
avatarView?.setImageURI("")
|
||||
} else {
|
||||
ImageUtils.display(avatarView, avatarUrl)
|
||||
}
|
||||
displayBorder(borderUrl)
|
||||
displayUserBadge(badgeUrl)
|
||||
}
|
||||
|
||||
fun displayAvatar(avatarUrl: String? = "") {
|
||||
if (avatarUrl.isNullOrEmpty()) {
|
||||
avatarView?.setImageURI("")
|
||||
} else {
|
||||
ImageUtils.display(avatarView, avatarUrl)
|
||||
}
|
||||
}
|
||||
|
||||
fun displayBorder(borderUrl: String? = "") {
|
||||
if (!borderUrl.isNullOrEmpty()) {
|
||||
borderView?.visibility = View.VISIBLE
|
||||
ImageUtils.display(borderView, borderUrl)
|
||||
} else {
|
||||
borderView?.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
fun displayUserBadge(badgeUrl: String? = "") {
|
||||
if (badgeUrl.isNullOrEmpty()) {
|
||||
badgeView?.setImageURI("")
|
||||
badgeView?.visibility = View.GONE
|
||||
} else {
|
||||
badgeView?.visibility = View.VISIBLE
|
||||
ImageUtils.display(badgeView, badgeUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28,15 +28,16 @@ public class CircleProgressBar extends View {
|
||||
private int disableProgressColor = Color.parseColor("#999999");//禁用已经走了的进度条颜色
|
||||
private int disableTextColor = Color.parseColor("#999999");//禁用文字颜色
|
||||
|
||||
private int currentNormalColor = normalColor;
|
||||
private int currentProgressColor = progressColor;
|
||||
private int currentTextColor = textColor;
|
||||
private int currentNormalColor;
|
||||
private int currentProgressColor;
|
||||
private int currentTextColor;
|
||||
|
||||
private float textSize = 20;//文字大小
|
||||
private int progress = 0;//进度条
|
||||
private String centerText = "0%";//中心填充文字
|
||||
private Paint fontPaint = null;
|
||||
private Paint.Style progress_style = Paint.Style.STROKE;//填充式还是环形式
|
||||
private boolean mIsShowProgressText;
|
||||
|
||||
public CircleProgressBar(Context context) {
|
||||
this(context, null);
|
||||
@ -64,6 +65,11 @@ public class CircleProgressBar extends View {
|
||||
progress = array.getInt(R.styleable.CircleProgressBar_progress, progress);
|
||||
progress_style = array.getInt(R.styleable.CircleProgressBar_progress_style, 0) == 0 ? Paint.Style.STROKE : Paint.Style.FILL;
|
||||
|
||||
mIsShowProgressText = array.getBoolean(R.styleable.CircleProgressBar_show_progress, true);
|
||||
|
||||
currentNormalColor = normalColor;
|
||||
currentProgressColor = progressColor;
|
||||
currentTextColor = textColor;
|
||||
array.recycle();
|
||||
initPaint();
|
||||
}
|
||||
@ -113,10 +119,12 @@ public class CircleProgressBar extends View {
|
||||
mPaint.setColor(currentProgressColor);
|
||||
canvas.drawArc(rectF, 270, progress, progress_style == Paint.Style.FILL, mPaint);
|
||||
|
||||
fontMetrics = fontPaint.getFontMetrics();
|
||||
float textWidth = fontPaint.measureText(centerText);
|
||||
float textHeight = fontPaint.ascent() + fontPaint.descent();
|
||||
canvas.drawText(centerText, width / 2 - textWidth / 2, height / 2 - textHeight / 2, fontPaint);
|
||||
if (mIsShowProgressText) {
|
||||
fontMetrics = fontPaint.getFontMetrics();
|
||||
float textWidth = fontPaint.measureText(centerText);
|
||||
float textHeight = fontPaint.ascent() + fontPaint.descent();
|
||||
canvas.drawText(centerText, width / 2 - textWidth / 2, height / 2 - textHeight / 2, fontPaint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
package com.gh.common.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -37,6 +40,9 @@ public class CropImageCustom extends RelativeLayout {
|
||||
mHorizontalPadding = (int) TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, mHorizontalPadding, getResources()
|
||||
.getDisplayMetrics());
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CropImageCustom);
|
||||
mHorizontalPadding = (int) ta.getDimension(R.styleable.CropImageCustom_horizontalPadding, mHorizontalPadding);
|
||||
ta.recycle();
|
||||
|
||||
mZoomImageView.setHorizontalPadding(mHorizontalPadding, mRatio);
|
||||
mClipImageView.setHorizontalPadding(mHorizontalPadding, mRatio);
|
||||
|
||||
94
app/src/main/java/com/gh/common/view/CustomSeekBar.kt
Normal file
94
app/src/main/java/com/gh/common/view/CustomSeekBar.kt
Normal file
@ -0,0 +1,94 @@
|
||||
package com.gh.common.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.AppCompatSeekBar
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.common.util.px2dip
|
||||
import com.gh.common.util.sp2px
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
/**
|
||||
* 自定义滑块顶部带进度显示的SeekBar
|
||||
*/
|
||||
class CustomSeekBar : AppCompatSeekBar {
|
||||
|
||||
private var mProgressTextColor = Color.parseColor("#2496FF")
|
||||
private var mProgressTextSize = 14f
|
||||
private var mProgressTextPaddingBottom = 4f
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
initView(attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
initView(attrs)
|
||||
}
|
||||
|
||||
private fun initView(attrs: AttributeSet) {
|
||||
val ta = context.obtainStyledAttributes(attrs, R.styleable.CustomSeekBar)
|
||||
mProgressTextColor = ta.getColor(R.styleable.CustomSeekBar_progressTextColor, mProgressTextColor)
|
||||
if (ta.hasValue(R.styleable.CustomSeekBar_progressTextSize)) {
|
||||
mProgressTextSize = ta.getDimension(R.styleable.CustomSeekBar_progressTextSize, mProgressTextSize)
|
||||
mProgressTextSize = DisplayUtils.px2sp(context, mProgressTextSize).toFloat()
|
||||
}
|
||||
if (ta.hasValue(R.styleable.CustomSeekBar_progressTextPaddingBottom)) {
|
||||
mProgressTextPaddingBottom = ta.getFloat(R.styleable.CustomSeekBar_progressTextPaddingBottom, mProgressTextPaddingBottom)
|
||||
mProgressTextPaddingBottom = mProgressTextPaddingBottom.dip2px().toFloat()
|
||||
}
|
||||
ta.recycle()
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
val thumbHeight = if (thumb == null) 0 else thumb.intrinsicHeight
|
||||
val measureText = measureText("0")
|
||||
val dh = thumbHeight + measureText.second + mProgressTextPaddingBottom
|
||||
setMeasuredDimension(
|
||||
View.getDefaultSize(0, widthMeasureSpec),
|
||||
View.resolveSizeAndState(dh.toInt(), heightMeasureSpec, 0)
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressLint("DrawAllocation")
|
||||
override fun onDraw(canvas: Canvas?) {
|
||||
canvas?.save()
|
||||
//由于滑块和进度都是居中绘制,所以这里需要向下移动
|
||||
canvas?.translate(0f, mProgressTextPaddingBottom)
|
||||
super.onDraw(canvas)
|
||||
canvas?.restore()
|
||||
|
||||
val paint = Paint()
|
||||
paint.isAntiAlias = true
|
||||
paint.textSize = mProgressTextSize.sp2px().toFloat()
|
||||
paint.color = mProgressTextColor
|
||||
val textString = "${progress * 100 / max}%"
|
||||
val pair = measureText(textString)
|
||||
val percent = progress.toFloat() / max
|
||||
val progressWidth = width - paddingLeft - paddingRight
|
||||
val offsetX = progressWidth * percent + paddingLeft - pair.first / 2
|
||||
canvas?.drawText(
|
||||
textString,
|
||||
offsetX,
|
||||
pair.second.toFloat() - paint.fontMetrics.descent,
|
||||
paint
|
||||
)
|
||||
}
|
||||
|
||||
private fun measureText(str: String): Pair<Int, Int> {
|
||||
val paint = Paint()
|
||||
paint.textSize = mProgressTextSize.sp2px().toFloat()
|
||||
val rect = Rect()
|
||||
paint.getTextBounds(str, 0, str.length, rect)
|
||||
val w: Int = rect.width()
|
||||
val h: Int = rect.height()
|
||||
return Pair(w, h + paint.fontMetrics.descent.toInt())
|
||||
}
|
||||
}
|
||||
@ -39,6 +39,7 @@ public class DownloadProgressBar extends ProgressBar {
|
||||
RESERVABLE,
|
||||
RESERVED,
|
||||
H5_GAME,
|
||||
UPDATING,
|
||||
|
||||
XAPK_UNZIPPING,
|
||||
XAPK_SUCCESS,
|
||||
@ -212,17 +213,21 @@ public class DownloadProgressBar extends ProgressBar {
|
||||
break;
|
||||
case RESERVABLE:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.button_reserve));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.all_white);
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
|
||||
break;
|
||||
case UPDATING:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.download_button_updating_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
|
||||
break;
|
||||
case RESERVED:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.game_item_btn_pause_dn));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.all_white);
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
|
||||
break;
|
||||
case XAPK_FAILURE:
|
||||
case XAPK_SUCCESS:
|
||||
case XAPK_UNZIPPING:
|
||||
setProgressDrawable(getResources().getDrawable(R.drawable.progressbar_xapk_detail_style));
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.all_white);
|
||||
mDefaultColor = ContextCompat.getColor(getContext(), R.color.white);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ class GameIconView : ConstraintLayout {
|
||||
private var mCornerRadius = 10
|
||||
private var mBorderColor = 0
|
||||
private var mBorderWidth = 1
|
||||
private var mFadeDuration = -1
|
||||
|
||||
constructor(context: Context) : super(context, null)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs, 0) {
|
||||
@ -36,6 +37,7 @@ class GameIconView : ConstraintLayout {
|
||||
mCornerRadius = ta.getDimensionPixelSize(R.styleable.GameIconView_gameIconCornerRadius, DisplayUtils.dip2px(10F))
|
||||
mBorderColor = ta.getColor(R.styleable.GameIconView_gameIconBorderColor, 0)
|
||||
mBorderWidth = ta.getDimensionPixelSize(R.styleable.GameIconView_gameIconBorderWidth, 1)
|
||||
mFadeDuration = ta.getInt(R.styleable.GameIconView_gameIconFadeDuration, -1)
|
||||
ta.recycle()
|
||||
|
||||
val roundingParams = RoundingParams.fromCornersRadius(mCornerRadius.toFloat())
|
||||
@ -45,6 +47,10 @@ class GameIconView : ConstraintLayout {
|
||||
}
|
||||
gameIconIv.hierarchy.roundingParams = roundingParams
|
||||
gameIconDecoratorIv.hierarchy.roundingParams = roundingParams
|
||||
|
||||
if (mFadeDuration != -1) {
|
||||
gameIconIv.hierarchy.fadeDuration = mFadeDuration
|
||||
}
|
||||
}
|
||||
|
||||
fun displayGameIcon(game: GameEntity) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user