Compare commits
1052 Commits
feature-ci
...
v5.29.2-93
| Author | SHA1 | Date | |
|---|---|---|---|
| f33595c4c4 | |||
| f6f2db4b6f | |||
| c57a9f44a2 | |||
| 2fb90cb5d4 | |||
| ab984d133a | |||
| 7440998d5f | |||
| 1e6351a11c | |||
| 78d9bde4c7 | |||
| 351e1d2eba | |||
| 0a067eb9dd | |||
| a97a0d64a4 | |||
| 627190ddb7 | |||
| f1139add2a | |||
| ba59291932 | |||
| d3a8bafe8b | |||
| 4cfc98ec5a | |||
| 86b7924a55 | |||
| 37a6dae3b5 | |||
| 4cbd4fe629 | |||
| 44df5dc061 | |||
| 9f144a638b | |||
| 18276c5941 | |||
| 385d197e31 | |||
| 2542311341 | |||
| f4d001a821 | |||
| bbca9c17e7 | |||
| d84cca5ab9 | |||
| 99d1185333 | |||
| 9f6611f877 | |||
| 24e6f93eae | |||
| 9a75e242e6 | |||
| 3a15f9af33 | |||
| 6920d682b2 | |||
| b0493502e4 | |||
| 723202d4ce | |||
| 6e0628b478 | |||
| 7f14555886 | |||
| c2477d2a3f | |||
| 8ff4945cfa | |||
| fcc65fdbfe | |||
| d4b0ecce98 | |||
| 848ca0b5c6 | |||
| 4f0c81420e | |||
| 0c437d32bd | |||
| 25d9771a3c | |||
| 668b54ac6d | |||
| 92b0f8fe73 | |||
| f689dfce07 | |||
| 42d5d46e53 | |||
| cdccc35703 | |||
| d3e2fea019 | |||
| f343841233 | |||
| f62083eff2 | |||
| 8594e998c2 | |||
| 6865706b0f | |||
| bfb8b46ce8 | |||
| b6d8ca4d84 | |||
| 455e1f0432 | |||
| ba27c09096 | |||
| 15276cc4b3 | |||
| 130a7cdf2a | |||
| 164ec0c368 | |||
| 756bc66f26 | |||
| e589bce5c6 | |||
| 991bd22511 | |||
| df1ab5221d | |||
| 70916fd0f7 | |||
| 226d6c4f2c | |||
| 896adc9d36 | |||
| 0e33abebdd | |||
| c8ed126605 | |||
| b510a329b6 | |||
| 2de1ba4e1d | |||
| e4a0f0e68b | |||
| c064f9d3a6 | |||
| 759401d9ae | |||
| e56209d15e | |||
| c466ff1f21 | |||
| e09cf299f0 | |||
| 25352ba609 | |||
| 3cd065cb6e | |||
| 5a483bb5db | |||
| 3b380c6fe3 | |||
| 919a98ffe6 | |||
| eff84218a8 | |||
| 7c9c363422 | |||
| add6448f44 | |||
| efccfaaa7f | |||
| a61057ae10 | |||
| 9472cafe48 | |||
| be83e1a2b4 | |||
| e48d7745b4 | |||
| 8b1a38214c | |||
| 2acde0af00 | |||
| daab20424e | |||
| 63f2adade2 | |||
| 201c1207f9 | |||
| 75d86b5a91 | |||
| f30d647936 | |||
| c7dd449899 | |||
| 0e9f7feff9 | |||
| 3697cd720e | |||
| 07a3c06804 | |||
| 2fce492689 | |||
| d87d12e1ec | |||
| a595730c50 | |||
| 7976355e34 | |||
| a9097793ac | |||
| 86e4ddd3f7 | |||
| b9abf2009d | |||
| a7dfd6c16c | |||
| 07dcb4aca2 | |||
| 48123ff991 | |||
| 8312d8e5fe | |||
| 98b4901d55 | |||
| a6a411f2e3 | |||
| 59976dcccd | |||
| e22a3ddcdb | |||
| ecfd133ce2 | |||
| d13ef56eb8 | |||
| 66f2d1df99 | |||
| 8555673d71 | |||
| cfe4c243e6 | |||
| c999ddf914 | |||
| f9004bf884 | |||
| 7794ef4acf | |||
| 1ef9c1fc23 | |||
| 1b1b753feb | |||
| 2561767b9a | |||
| 8bda0e178e | |||
| f634d60605 | |||
| 1dcc7654e8 | |||
| 3579b9d808 | |||
| c74663c082 | |||
| 848d352c60 | |||
| 5176766b29 | |||
| 0a90a7ddd9 | |||
| 27ca5073d7 | |||
| e3eb8178a3 | |||
| 10104812d6 | |||
| 12cb9a4883 | |||
| a30cc8c273 | |||
| 0f0620586b | |||
| b9e86dd67a | |||
| 9ce793d47e | |||
| 43cb18d6e0 | |||
| 1e87610899 | |||
| d04d486425 | |||
| 843aa4d1c8 | |||
| 1745ac91b7 | |||
| 20bc4a0dc8 | |||
| 1105f1b92a | |||
| 53f00f00d3 | |||
| b66827e216 | |||
| 485c34d402 | |||
| 330bcd72d7 | |||
| b04231772b | |||
| ec1bbdc7d5 | |||
| c685a02653 | |||
| 6594bf14df | |||
| 5a4f19dd8a | |||
| b54be8cb79 | |||
| 655380d547 | |||
| da3948228f | |||
| 5c03119c32 | |||
| 2a496b680b | |||
| db535cf281 | |||
| c199582efc | |||
| b53677a118 | |||
| 76ba3a5938 | |||
| db596a6c75 | |||
| 043f3c5d17 | |||
| 68006dda38 | |||
| b5cab193be | |||
| 6f2692296c | |||
| 0bb7a53046 | |||
| 25fe362912 | |||
| 6749d94c34 | |||
| 51f5ea1cd9 | |||
| 50a6d5e204 | |||
| 044e5646ec | |||
| 0ebf3d191d | |||
| bb81d91fd5 | |||
| 7442da80e0 | |||
| 96c28907ec | |||
| e9e7c2043e | |||
| eb5c55f046 | |||
| 8f2a1ecaa1 | |||
| 8dbe9c5772 | |||
| 6c911e09d3 | |||
| df557099ec | |||
| fedc91d37e | |||
| 27484a8306 | |||
| 42193d222a | |||
| 0a433566b1 | |||
| ff02ccd839 | |||
| d1cc0853d4 | |||
| 51eb814a42 | |||
| 684dbcfd87 | |||
| 6534c17cc0 | |||
| 749a76a09e | |||
| 0f59f79495 | |||
| af66a967b5 | |||
| 4f8b961e2c | |||
| 58a7f7c3fa | |||
| ae8267d96d | |||
| e20af462b7 | |||
| 9a9095bcf0 | |||
| 225f2becf3 | |||
| e2773ed8c7 | |||
| c77e5ca56b | |||
| e78c23ca4f | |||
| a502fb64cb | |||
| 724fe8142c | |||
| dee5a0822d | |||
| e826346ca9 | |||
| 06b43cde77 | |||
| ae5edad87b | |||
| c8916f5f33 | |||
| 04cca95435 | |||
| 1bd3d8b044 | |||
| 4e79466cca | |||
| b790d71aa5 | |||
| 88093d0a8e | |||
| 26adcc48f8 | |||
| e94e86d901 | |||
| 73355a4103 | |||
| 794377fdad | |||
| 1bff098369 | |||
| 45c7638dee | |||
| 4c57092300 | |||
| 1ddf9a667e | |||
| 84972e7ba7 | |||
| 03692ad753 | |||
| 5c91023a68 | |||
| 2eae71bc96 | |||
| bb138fa25f | |||
| c5024e670a | |||
| fe5c92e988 | |||
| 909477ec7f | |||
| a5da376f62 | |||
| 9b31bf4164 | |||
| c670ab722f | |||
| fd4f3c25e7 | |||
| a14ea3708a | |||
| c003240f16 | |||
| 891e3d93fb | |||
| af5ec74b9e | |||
| d2c4483455 | |||
| 3a156aa8c1 | |||
| 60bd3ee9b2 | |||
| dacda1a858 | |||
| d084cb1c34 | |||
| 411bf3561f | |||
| 265b5f6b57 | |||
| b4bd6f250b | |||
| 0f3ae5f085 | |||
| 3ab6cc202e | |||
| 610c006aeb | |||
| ffa81bc4c1 | |||
| 67477ac20a | |||
| 7a154bc130 | |||
| 7cd6f2b0f4 | |||
| a6a16e4694 | |||
| 8f8352dc12 | |||
| 1bbbe575f2 | |||
| 5975d9850f | |||
| ef001b0a77 | |||
| fd49ecbc8a | |||
| 8db2519f61 | |||
| 6b2902a73b | |||
| d683969eda | |||
| f8527da9df | |||
| df7618bbda | |||
| 246983a097 | |||
| f50d901171 | |||
| 71db870bd2 | |||
| b4c550f71b | |||
| 91bde61054 | |||
| ca6146ad9a | |||
| c647320abc | |||
| d7940121ee | |||
| ef9c473301 | |||
| 2c82437449 | |||
| 311e5e4225 | |||
| 91864e3681 | |||
| afd738454e | |||
| 134cb327ec | |||
| f50ce741ae | |||
| 5e66db7435 | |||
| e7c74d3f39 | |||
| d0fa02b221 | |||
| 70e4378ef0 | |||
| f8ee943678 | |||
| 918aa17fbd | |||
| 0a7a3d9878 | |||
| b6a823e793 | |||
| 4547ba969e | |||
| 9a95a4623d | |||
| 206bc1bfcc | |||
| 4045e42a7b | |||
| 0a4af78ac8 | |||
| 15f283d330 | |||
| 97bafee09e | |||
| e32745d9d7 | |||
| c37a54ac89 | |||
| 607d514ae9 | |||
| 62ee0b4a6e | |||
| 11ff054520 | |||
| d38e1d1637 | |||
| 0d3456cf97 | |||
| e96fc0f3b4 | |||
| a7875b21c9 | |||
| e53154c810 | |||
| e1d89725bc | |||
| 1d3ec9eff6 | |||
| 0403743533 | |||
| 1f25b932d5 | |||
| d3545bc766 | |||
| b2b858c403 | |||
| debbe08262 | |||
| 4e746a2b16 | |||
| b86e372e5b | |||
| f65e76a94a | |||
| 05c8de827e | |||
| 78eb10fa3c | |||
| 23dfb7378b | |||
| f56529aa5b | |||
| 0e2e175194 | |||
| 9050a04c3a | |||
| 57df50b0a2 | |||
| 4ff21914c1 | |||
| 0dec30ff56 | |||
| 4bdfe6e190 | |||
| 55813cdaae | |||
| 8668b2b4ec | |||
| b758658ea6 | |||
| 4ca9c32762 | |||
| af8fdd5d65 | |||
| 36dd4f5a82 | |||
| c7161e3483 | |||
| bffaaffc56 | |||
| 3257dd4c53 | |||
| 6793945606 | |||
| 52be14a4ef | |||
| e2cb5a31cf | |||
| d807b7973b | |||
| 1fb0d13646 | |||
| 68a3eadfeb | |||
| a2d904c634 | |||
| 56cd1bdad7 | |||
| 999e1a3ad8 | |||
| 8b4f71bc75 | |||
| be937703b8 | |||
| aa069b7a21 | |||
| f89914746a | |||
| fb0db2feee | |||
| 250dba9198 | |||
| 4c531b40b0 | |||
| 875a84b5ae | |||
| 77b9b731e2 | |||
| bd11481c2d | |||
| a3f1b09da1 | |||
| 1798dfb64d | |||
| 8e5814d389 | |||
| 14c01cf171 | |||
| c800dac1ec | |||
| 88448b7b8d | |||
| 77a1e5fea7 | |||
| ef0a212b85 | |||
| 2ee4ad6752 | |||
| 9173a73ed0 | |||
| 5d8e208ef8 | |||
| 309111c422 | |||
| 3c3a228500 | |||
| 33a5e2061f | |||
| b62b1f399c | |||
| c4449db90a | |||
| 6edd9f2204 | |||
| 8508b9ece2 | |||
| 20d5ef7a6e | |||
| ff70d7a48a | |||
| 4bc2374cb4 | |||
| 73d7a38886 | |||
| 8efa858a01 | |||
| 53e2297976 | |||
| 9cd5e342ac | |||
| 26dfb79ece | |||
| e1f70ce788 | |||
| 7bc36814b7 | |||
| b29651ecfb | |||
| 74aad0e7e0 | |||
| 52a5faacfe | |||
| 5cee489ba6 | |||
| f76c3e3638 | |||
| fe5b93c35a | |||
| 74c3e7a10d | |||
| deb2b07644 | |||
| 386a7f82d9 | |||
| c6b433d09c | |||
| c556a127f5 | |||
| 94983c4b7f | |||
| 119cdf4f91 | |||
| bdfd88a4c3 | |||
| 2697fd57b4 | |||
| bde7685dc6 | |||
| 6acaa95098 | |||
| 610f116b82 | |||
| fe616ed87b | |||
| 06e238b2d5 | |||
| a4c323b5e0 | |||
| fdfb03348e | |||
| 91ba665c4c | |||
| ba65c5e23a | |||
| f05b20ed98 | |||
| 74d3e8b2d4 | |||
| 74364cd452 | |||
| dc2a023fbb | |||
| 47560daec6 | |||
| 657b900418 | |||
| d826c3dcce | |||
| 935d61f910 | |||
| 0a412feefb | |||
| 31111a1cc8 | |||
| cf901ef840 | |||
| 8d70716f15 | |||
| 7cf086874a | |||
| d1698f0c2d | |||
| f80bcbcfb9 | |||
| 0f2fcdba68 | |||
| 548156c159 | |||
| ea08a52750 | |||
| 4c51ca7670 | |||
| 2ea9d46e12 | |||
| 65445859d3 | |||
| 8c9927b9cb | |||
| 5477a4a4cc | |||
| d1277aa1aa | |||
| 2381550e08 | |||
| 3ff4a9b6cf | |||
| 174f47edb1 | |||
| 96fbe30924 | |||
| 954c7e427a | |||
| e466eb6683 | |||
| 01437e9d8a | |||
| eac553ba46 | |||
| e57017f5f2 | |||
| 6506a18d6f | |||
| ed79b230aa | |||
| ac56650ce5 | |||
| 81d5a8a12c | |||
| 192ae916de | |||
| 5047ae5f9c | |||
| f5a30a7dde | |||
| e9c22ef577 | |||
| 8292d8512d | |||
| a606633755 | |||
| 9788b632d6 | |||
| 0e988b2b49 | |||
| 0a8211d40b | |||
| 1b3c2da6d3 | |||
| 48209b05e7 | |||
| 2da42d48e6 | |||
| f6b1813e88 | |||
| c16407e360 | |||
| b7ca5c54a3 | |||
| d42a915ef5 | |||
| 91c1e8fcef | |||
| 9abd0de3fe | |||
| 25cb0de6c0 | |||
| 41804a9a05 | |||
| 4db1147c4f | |||
| 48f9d5e159 | |||
| ccaf82a20b | |||
| 7802082797 | |||
| c293a4485e | |||
| eb7f2b418b | |||
| bbdecd6627 | |||
| f88aa52d09 | |||
| dd77243a2f | |||
| 9ead786c4c | |||
| f367eabddc | |||
| 16ced738ac | |||
| d607c04c33 | |||
| da40da432f | |||
| 6a03b63e65 | |||
| 81400a37f1 | |||
| 228a786f6c | |||
| 224c17c582 | |||
| 64a35316cb | |||
| 8c889001bf | |||
| 224689ad9c | |||
| 78207eb0cb | |||
| c3b9b52f5d | |||
| 63b1e510fa | |||
| bb7b5cde09 | |||
| 9a2a60cd5d | |||
| 690c2e53d9 | |||
| 5a72c12233 | |||
| 74f41404ef | |||
| 586af43050 | |||
| 454f0cad26 | |||
| 50510b808f | |||
| d46ef9f068 | |||
| 293561d807 | |||
| 4c64137e9a | |||
| d7090125c7 | |||
| c2058290f4 | |||
| 0b2f845021 | |||
| c77934cc75 | |||
| 57e57c19d0 | |||
| 475b03d591 | |||
| a97091bf49 | |||
| 7a12c4ab1d | |||
| 4f732c3921 | |||
| 531deacc3d | |||
| b219e60f13 | |||
| 387fc37b19 | |||
| 1b88c3e0a3 | |||
| af1c7ff2c9 | |||
| 976f315ba8 | |||
| 216c13054b | |||
| 9643c3cb9c | |||
| 6a6d0641a2 | |||
| 3fd4d330d2 | |||
| f811759bf4 | |||
| 6efc5bb4fa | |||
| 754d7f58c0 | |||
| f0266504de | |||
| 84e7ee6347 | |||
| dc39f9f207 | |||
| 65c46c2eb4 | |||
| 923f212424 | |||
| 092bdd4812 | |||
| 40e30058f9 | |||
| 432f8dc090 | |||
| ea68931461 | |||
| 648e6c9dc4 | |||
| 4d15361b37 | |||
| c1660a9816 | |||
| e6a2f0528a | |||
| 71f2c937db | |||
| 2a8ae9a022 | |||
| 3f28fcc211 | |||
| dd850bdbbc | |||
| 6ae8b520ac | |||
| 6c7baf54f3 | |||
| d956081d61 | |||
| fe75be35fb | |||
| 9080f82b80 | |||
| 15d6fd98b5 | |||
| d1d22de559 | |||
| 8daf5a8feb | |||
| ac86821871 | |||
| 1d10fc52b9 | |||
| 1c1a1f3db0 | |||
| 788cada5c9 | |||
| 285c87568b | |||
| 8a749ad730 | |||
| 1b19760562 | |||
| 2f69074418 | |||
| 684e7a63db | |||
| 89e588fb9e | |||
| d81b3002cb | |||
| 4048554c6e | |||
| 5fe976f8d0 | |||
| 208c21c4ea | |||
| 55c8fd9271 | |||
| 664f35090d | |||
| aaec370afa | |||
| af09f28fdd | |||
| 00b92d2aec | |||
| 4c4dafde62 | |||
| d481741c1a | |||
| f6c4e58498 | |||
| b59c061df3 | |||
| 846c532eeb | |||
| 2a3b9ebc21 | |||
| 808c7a46fc | |||
| ed6e495ecc | |||
| a90d694a48 | |||
| 73595d5a78 | |||
| 9be57f617e | |||
| 3e021e3721 | |||
| 0896051458 | |||
| b12f08367a | |||
| 03babbfdee | |||
| 8d2b83566c | |||
| fe3c0a2084 | |||
| b26ac93f58 | |||
| 7285baadbf | |||
| 32cf945b4d | |||
| 207813376b | |||
| 7129751c44 | |||
| deda82b02e | |||
| 98a54ad85d | |||
| fc0a36e4b8 | |||
| a3a68d7550 | |||
| 572400a3c7 | |||
| 8b42390175 | |||
| ad71193089 | |||
| f631810acc | |||
| 6c9ac11175 | |||
| 5ba2ec0129 | |||
| e6677c781d | |||
| 86fb3e02a2 | |||
| 97790e9416 | |||
| ae800c2046 | |||
| 75de02669a | |||
| 9f15983512 | |||
| c1eb1cde87 | |||
| 1f9cee2823 | |||
| 67e0181fa5 | |||
| dfa2d9b568 | |||
| 402e3be226 | |||
| 2db297e7c9 | |||
| 43b634f17e | |||
| 3dce109b87 | |||
| 683981d5a1 | |||
| 9c9b23e1f2 | |||
| 629c274b20 | |||
| 2548e36e65 | |||
| 974e35962f | |||
| b05f3de5b2 | |||
| 9437d64b0f | |||
| a9787ebc5a | |||
| 329ca952d4 | |||
| 6cebded553 | |||
| 6b77c71b09 | |||
| 386315247a | |||
| 31d819573b | |||
| 060ef0e2e1 | |||
| 3797caaee6 | |||
| cfe262eee2 | |||
| 5d15f9097b | |||
| a9093dfe37 | |||
| c4ab306f0d | |||
| b9daf3075a | |||
| 843ac6b432 | |||
| e5d6de8bf4 | |||
| 7fd2a4ce67 | |||
| 7cc38a8d56 | |||
| fb9e0c19a5 | |||
| f3a2db619a | |||
| dc4fc254f6 | |||
| 9f451af564 | |||
| 6f62b597b7 | |||
| b6f73a1e61 | |||
| 814d212f53 | |||
| 4f07be4528 | |||
| 6eaf16e039 | |||
| 89a7325264 | |||
| 0cdceaf0ed | |||
| c0eb8c7263 | |||
| 4581acb5d4 | |||
| 9c1d64ffe6 | |||
| 6de711d127 | |||
| 17a5445f25 | |||
| 7062d5d8d4 | |||
| 38347243f3 | |||
| bf11c964a3 | |||
| d76e3beb63 | |||
| e6d8ee779d | |||
| 744b60d0de | |||
| 6bbca7e62d | |||
| 39983bdc02 | |||
| a72a12c516 | |||
| 4fa5234231 | |||
| 26f5a03c98 | |||
| cff85a9990 | |||
| cf82938182 | |||
| 103b551f88 | |||
| a7fb23fda9 | |||
| 0735458c8b | |||
| 7559e87117 | |||
| beb282503d | |||
| 4fc185a033 | |||
| 5a54a85fe1 | |||
| d19e7f97d1 | |||
| fbb9fb885b | |||
| 2547f21174 | |||
| 0056680f4a | |||
| 1eb81d994d | |||
| 24949b9688 | |||
| 65de350da2 | |||
| d02e8fbfa6 | |||
| 48e8d4b631 | |||
| 517c3c90d5 | |||
| 5ee773c5b8 | |||
| e4e92e0efc | |||
| 1d0bf46597 | |||
| 98c0fb39b4 | |||
| db037e4162 | |||
| 2d3af55875 | |||
| 2fdb613ecc | |||
| 7ad634c78e | |||
| 6950c9af09 | |||
| 851f79c58f | |||
| 7ef2d9b193 | |||
| 7298d772bb | |||
| 7a6afa9f6c | |||
| 310b800149 | |||
| 4126f06107 | |||
| 3e3f276cc4 | |||
| a3ff7d19a7 | |||
| bd5902d924 | |||
| 7022cf97c8 | |||
| 0452116830 | |||
| 5dfbe5c571 | |||
| b8adfc7a4b | |||
| 87de104da6 | |||
| b97a68828d | |||
| b84f456943 | |||
| 18e96d1c0c | |||
| 07abad8e04 | |||
| ad8f06f899 | |||
| eb1b04caea | |||
| 84493b312e | |||
| fe4ad76e2a | |||
| e9efbbc44a | |||
| 7cc7bb54d0 | |||
| 4adcadbc21 | |||
| 38a5893b4d | |||
| 2c303002f3 | |||
| 316778e8a5 | |||
| 210f731b59 | |||
| 42b7a4abf9 | |||
| 6a12a0236e | |||
| 9e6816440b | |||
| d37d4c37bf | |||
| 128fea4446 | |||
| 7e6e85469c | |||
| d9c1108dfe | |||
| 86b79d6240 | |||
| acd308eb00 | |||
| c0937b7393 | |||
| 7a04e1b8f4 | |||
| b666368bb2 | |||
| 62b9e8a76c | |||
| 76b3607c7f | |||
| 619ca32a4a | |||
| 2bd9b7cfe2 | |||
| c93978c773 | |||
| d0991d1b1b | |||
| 60b3c25162 | |||
| 3cf6dba418 | |||
| 8ac408b5c8 | |||
| 76a18782d8 | |||
| 404c3e1968 | |||
| 11482d2318 | |||
| b9ea681431 | |||
| 2fb956cd3b | |||
| b18d268f73 | |||
| 34b3eb1299 | |||
| 2e4c341bb2 | |||
| bfed223640 | |||
| 5bf74b5631 | |||
| fd16bc33ef | |||
| 04e36554bd | |||
| 2a0322e566 | |||
| b9de58d9dd | |||
| 9fba8efac4 | |||
| 3e5e768be1 | |||
| 6b54e584fd | |||
| 05e57ed12f | |||
| d1c50f90c3 | |||
| b33efeab8c | |||
| 1051d40fab | |||
| 2b6e0fd159 | |||
| 33f0e1d2c5 | |||
| 762309e2c1 | |||
| 744a3331f7 | |||
| 9384009bfa | |||
| 13cbfd60e5 | |||
| cd4d16feb0 | |||
| 0a92ba7653 | |||
| 6fdd2c860a | |||
| 47355a3db6 | |||
| 3cd8d4d4dc | |||
| 738c1b7283 | |||
| 01df2f7a17 | |||
| e774d1c636 | |||
| 8978e006e4 | |||
| e6cf1a2425 | |||
| 0d15bc1ba4 | |||
| 62f6aa1a71 | |||
| ce811ea2e9 | |||
| 730b1651f6 | |||
| b18ff30077 | |||
| 756a215db9 | |||
| 91f3a92a2f | |||
| 2cae0ade4b | |||
| 1853c683d7 | |||
| 4506ad4367 | |||
| 393f0942ad | |||
| a57f8ed305 | |||
| a22deaff04 | |||
| 8c9201c401 | |||
| 6fcfc2f4be | |||
| 0ffbba06fc | |||
| 1c8502608f | |||
| baf33ca5db | |||
| 5f4ebea65e | |||
| 10eed8844d | |||
| 2cbe13b8f8 | |||
| b61558438e | |||
| bc847a500e | |||
| 13d90793c4 | |||
| 85ab438e5f | |||
| 948adaa5ec | |||
| 88dc6584e7 | |||
| 7ed06b6c06 | |||
| aa7bc499b2 | |||
| 71abfe6a0d | |||
| 126064c7f1 | |||
| d311d70bd1 | |||
| 90de69b338 | |||
| a16c52980f | |||
| a63e9ed08e | |||
| 21a1573f2c | |||
| 9b0c9aceb8 | |||
| e9c00b4a32 | |||
| c05a82543a | |||
| cafbc0efb0 | |||
| cac6875044 | |||
| e3d5923ff3 | |||
| e5e21e8695 | |||
| 4f2917e1ac | |||
| 0a3fd9a99e | |||
| 782bbd95b2 | |||
| e2106dd7ca | |||
| aad3186a5e | |||
| 311e2292be | |||
| 842999ec9d | |||
| d4b3bc059a | |||
| 8a47e867c7 | |||
| fcba306373 | |||
| 2067b8dea3 | |||
| bc3bfb16c2 | |||
| 38e3b8471f | |||
| 2aaac4faaf | |||
| 19ed5b963d | |||
| 77c725068b | |||
| c05b3bdca6 | |||
| 1f630ae652 | |||
| 26883ee136 | |||
| e48d090eb3 | |||
| d9cffafba1 | |||
| 868dbcd32c | |||
| d392247abd | |||
| 14ba1585e4 | |||
| 1c591c6e45 | |||
| c27b6421a7 | |||
| 71f69bc528 | |||
| 53c374064a | |||
| 457897397a | |||
| 90fedcbd2f | |||
| 7cb059f1e8 | |||
| 8b8895603b | |||
| 78ecde06b1 | |||
| 1de8b02fdb | |||
| bd8115a2d9 | |||
| f2b163ee42 | |||
| 44d98090ca | |||
| d7e9b82ef7 | |||
| f11fb23bf2 | |||
| aecc9cecdd | |||
| 9345b70c0b | |||
| 168e0fff08 | |||
| 1af6776356 | |||
| 8340dcb3a0 | |||
| 863b6b7970 | |||
| fb109bab4f | |||
| fc9bbde996 | |||
| 1c47720561 | |||
| 8f0bd4e4b5 | |||
| 4427523ed9 | |||
| 8281d36d69 | |||
| 15b2073771 | |||
| c481d99205 | |||
| 27c4cbd38b | |||
| 32cb10853c | |||
| d937fa1953 | |||
| dc2bcb4699 | |||
| f514037c48 | |||
| fcae6fa36c | |||
| a2594dd700 | |||
| 8f9fd3a24e | |||
| b7da892475 | |||
| 9a68db252e | |||
| 5e04e62939 | |||
| 403991acc9 | |||
| bc21fbcb1a | |||
| f0dc5a9c83 | |||
| a170284a3b | |||
| bd1d300341 | |||
| ef29af1aaa | |||
| eaf1696a93 | |||
| 5ec05a4cb8 | |||
| 277acd08eb | |||
| 9738269f56 | |||
| 13dff229e9 | |||
| 8de7e990ac | |||
| 97433cd0bd | |||
| 3306db8f68 | |||
| aabc70d9bb | |||
| aff9e036cb | |||
| e2988cdba6 | |||
| 42c674c1d8 | |||
| dd0962df27 | |||
| c158be5714 | |||
| ee6ec82d27 | |||
| 317cce1f56 | |||
| f29f5089fd | |||
| f5b71fdcb2 | |||
| 79c0e61a24 | |||
| bfeadf8c75 | |||
| b118309d4e | |||
| 5aab516058 | |||
| 3ef4214313 | |||
| dcca1b9ff9 | |||
| 905b6395d7 | |||
| 7bdc7a946d | |||
| 55a92847c7 | |||
| 0889abef9e | |||
| b858365c1d | |||
| 92d2f7e701 | |||
| 0967df5751 | |||
| d6e5b88d95 | |||
| b08e653b99 | |||
| f539e45e18 | |||
| 6a6ff5b12a | |||
| b8ba5f85c9 | |||
| 67ed3cb919 | |||
| c973bd6b5e | |||
| 61e9bcb89d | |||
| 2d3f18a302 | |||
| 401d36a74e | |||
| bee52ba0bd | |||
| 6d2e0853ff | |||
| 3b23f086c8 | |||
| d50e4e044b | |||
| 84f56681d0 | |||
| 7fbb3eec86 | |||
| ef11044b50 | |||
| 26395038bd | |||
| 68b0691618 | |||
| f5a4e4ca06 | |||
| c75eacaf45 | |||
| aa5ecb8e6c | |||
| 00dda64279 | |||
| 2bd3be0088 | |||
| 3bff64af27 | |||
| 32210875da | |||
| db9d7d9d22 | |||
| 1f211356fd | |||
| 81b5b6b369 | |||
| 98e263f99a | |||
| 81b74e7077 | |||
| 083a893582 | |||
| 405d4b709f | |||
| 36942aab5a | |||
| e61b21ca49 | |||
| b9e7f4145a | |||
| 517b474a1e | |||
| dfac1e93b7 | |||
| d848081f62 | |||
| 2bac0feb2c | |||
| a602055f98 | |||
| 28ba14e9ec | |||
| c36fb04f81 | |||
| 7d26a66bc3 | |||
| 9451f9bae3 | |||
| ac18a678ff | |||
| bd2871788f | |||
| beeece1d0e | |||
| 1e9e39eea9 | |||
| 9162b0f67d | |||
| 46dd84aaf9 | |||
| e5e0d99abb | |||
| 6f34b16bba | |||
| 5b2512f16f | |||
| 9a1e0f1ae2 | |||
| a03b6b643f | |||
| 8b2cb8b40c | |||
| c2402bd4d2 | |||
| b724cde6ca | |||
| fd3058e0be | |||
| 03431ef3a3 | |||
| 23e2a79bee | |||
| 3aa14c9541 | |||
| 39fcc5ed63 | |||
| 577be922a6 | |||
| 19d128e98a | |||
| a8acf1d6c8 | |||
| ce0a301348 | |||
| 2567e520da | |||
| 2394cf837e | |||
| bf692569e6 | |||
| 090102ec5d | |||
| 61e9966de8 | |||
| fe26504f43 | |||
| e4d2036cc2 | |||
| 2627a4c39c | |||
| a44d454f13 | |||
| 0600daadde | |||
| f29b1a6124 | |||
| 1892d10040 | |||
| 9a8df13870 | |||
| 4eabeae5d5 | |||
| c4b1be9925 | |||
| b2a6393afd | |||
| b5c15940a1 | |||
| 3f6f55b265 | |||
| ba666da059 | |||
| 8b1f251c80 | |||
| 01aadbd64c | |||
| 6256b31cd9 | |||
| 8e4d1e7e6e | |||
| fa29e00864 | |||
| 1b412bf081 | |||
| 0d82b9ec71 | |||
| 1055d0c728 | |||
| a53183d405 | |||
| 11874c3984 | |||
| 47464b2864 | |||
| a2ed4987ed | |||
| 4392f9f20b | |||
| 8e43d0cae3 | |||
| f83f67553c | |||
| 14893acf4b | |||
| 1cbed03788 | |||
| 0eff89acfc | |||
| 560b6046ab | |||
| e898886659 | |||
| b1abadc145 | |||
| 05da2c3da4 | |||
| e83ece5520 | |||
| 08a86c778d | |||
| 58119a0bdb | |||
| 8d9c57e972 | |||
| b216d33d6b | |||
| 4fe062ea40 | |||
| 7d678085d5 | |||
| acae755461 | |||
| f29d3b4e29 | |||
| e1907fcea8 | |||
| 76564b2414 | |||
| c72d34b4f7 | |||
| 8145f389a9 | |||
| 45a8f9683e | |||
| 572cbba819 |
182
.gitlab-ci.yml
182
.gitlab-ci.yml
@ -1,43 +1,155 @@
|
||||
stages:
|
||||
- analysis
|
||||
- sendmail
|
||||
# commit_sha 文件记录上一次成功流水线的commit sha,用于定时计划检测是否有新代码提交,有就执行流水线,没有就终止流水线
|
||||
cache:
|
||||
# 不同的分支采用不同的 cache,防止分支之间相互影响
|
||||
key: "${CI_COMMIT_REF_SLUG}_commit_sha"
|
||||
paths:
|
||||
- commit_sha
|
||||
policy: pull
|
||||
|
||||
## 代码检查
|
||||
sonarqube_analysis:
|
||||
# 将打包&发送apk包邮件job 和代码分析job 并行执行
|
||||
stages:
|
||||
- build&analyze
|
||||
- oss-upload&send-email
|
||||
- ci_sonar_mail
|
||||
|
||||
# 阻止了 合并请求 或 push(分支和标签)的流水线。 最后的 when: always 规则运行所有其他流水线类型,包括定时计划流水线。
|
||||
workflow:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "push"'
|
||||
when: always
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
when: never
|
||||
- when: always
|
||||
|
||||
before_script:
|
||||
# 检查是否存在 commit_sha 文件
|
||||
- if [ -f commit_sha ]; then cat commit_sha; else echo "0000000" > commit_sha; fi
|
||||
- export BEFORE_COMMIT_SHA=$(cat commit_sha)
|
||||
# 比较commit sha ,若与上一次成功流水线的commit sha 相同,则退出流水线
|
||||
- if [ "$CI_COMMIT_SHA" == "$BEFORE_COMMIT_SHA" ] && [ "$CI_PIPELINE_SOURCE" != "web" ]; then exit 137; fi
|
||||
|
||||
# 使用 .post 阶段使作业在流水线的末尾运行。.post 始终是流水线的最后阶段。
|
||||
change_commit:
|
||||
tags:
|
||||
- offline-test
|
||||
stage: .post
|
||||
# 此job 跳过拉取git代码
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
# 更新 commit_sha
|
||||
- if [ "$CI_COMMIT_SHA" != "$BEFORE_COMMIT_SHA" ]; then echo $CI_COMMIT_SHA > commit_sha; fi
|
||||
cache:
|
||||
# 不同的分支采用不同的 cache,防止分支之间相互影响
|
||||
key: "${CI_COMMIT_REF_SLUG}_commit_sha"
|
||||
paths:
|
||||
- commit_sha
|
||||
policy: pull-push
|
||||
allow_failure:
|
||||
exit_codes: 137
|
||||
|
||||
android_build:
|
||||
tags:
|
||||
# - local-runner
|
||||
- offline-test
|
||||
stage: analysis
|
||||
image: sonarsource/sonar-scanner-cli:latest
|
||||
dependencies: [] #禁止传递来的artifact
|
||||
stage: build&analyze
|
||||
image: hub.shanqu.cc/library/ci-android:jdk11-sdk31-33
|
||||
resource_group: android_build
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
KUBERNETES_CPU_LIMIT: "10"
|
||||
script:
|
||||
## 获取项目的一级组和二级组和项目名作为projectKey,例如projectKey=platform-backend-eci-monitor
|
||||
- group=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
|
||||
- sonar-scanner
|
||||
-Dsonar.host.url=http://sonarqube-server.sonarqube:9000/
|
||||
-Dsonar.login=be43de7264ce4c4766eb0c020373c3e74e6df257
|
||||
-Dsonar.jacoco.reportPaths=target/jacoco.exec
|
||||
-Dsonar.projectKey=$group
|
||||
-Dsonar.projectName=$CI_PROJECT_PATH
|
||||
-Dsonar.sourceEncoding=UTF-8
|
||||
-Dsonar.exclusions=**/vendor/**,**/errcode/**
|
||||
-Dsonar.gitlab.project_id=$CI_PROJECT_ID
|
||||
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
|
||||
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
|
||||
-Dsonar.gitlab.merge_request_discussion=true
|
||||
-Dsonar.java.binaries=. # 如果不使用Maven或Gradle进行分析,则必须手动提供测试二进制文件
|
||||
- export GRADLE_USER_HOME=/home/gitlab-runner/ci-build-cache/$CI_PROJECT_PATH/.gradle
|
||||
- chmod +x ./gradlew
|
||||
- ./scripts/jenkins_build.sh -c
|
||||
#设置打包后的产物,用于job之间共享
|
||||
artifacts:
|
||||
paths:
|
||||
- app/build/tmp/*.apk
|
||||
expire_in: 48 hrs # 指定附件上载后保存的时间24h,默认永久在Gitlab保存
|
||||
allow_failure:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
|
||||
- dev-5.29.0
|
||||
|
||||
# 代码检查
|
||||
sonarqube_analysis:
|
||||
tags:
|
||||
- offline-test
|
||||
stage: build&analyze
|
||||
image: sonarsource/sonar-scanner-cli:latest
|
||||
dependencies: [] #禁止传递来的artifact
|
||||
script:
|
||||
## 获取项目的一级组和二级组和项目名作为projectKey,例如projectKey=platform-backend-eci-monitor
|
||||
- group=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
|
||||
- sonar-scanner
|
||||
-Dsonar.host.url=http://sonarqube-server.sonarqube:9000/
|
||||
-Dsonar.login=be43de7264ce4c4766eb0c020373c3e74e6df257
|
||||
-Dsonar.jacoco.reportPaths=target/jacoco.exec
|
||||
-Dsonar.projectKey=$group
|
||||
-Dsonar.projectName=$CI_PROJECT_PATH
|
||||
-Dsonar.sourceEncoding=UTF-8
|
||||
-Dsonar.exclusions=**/vendor/**,**/errcode/**
|
||||
-Dsonar.gitlab.project_id=$CI_PROJECT_ID
|
||||
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
|
||||
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
|
||||
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
|
||||
-Dsonar.gitlab.merge_request_discussion=true
|
||||
-Dsonar.java.binaries=.
|
||||
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
|
||||
allow_failure:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
|
||||
## 发送简易检测结果报告
|
||||
send_sonar_report:
|
||||
tags:
|
||||
- offline-test
|
||||
stage: sendmail
|
||||
image: hub.shanqu.cc/library/docker:latest
|
||||
dependencies: [] #禁止传递来的artifact
|
||||
script:
|
||||
- group=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
|
||||
- docker run -e PROJECTKEY=$group -e EMAIL=$GITLAB_USER_EMAIL --name send-email --rm hub.shanqu.cc/platform/send-sonar-report:latest
|
||||
only:
|
||||
- dev
|
||||
tags:
|
||||
- offline-test
|
||||
stage: ci_sonar_mail
|
||||
image: hub.shanqu.cc/library/docker:latest
|
||||
# 此job 跳过拉取git代码
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
- group=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
|
||||
- docker run -e PROJECTKEY=$group -e EMAIL=$GITLAB_USER_EMAIL -e BRANCH=$CI_COMMIT_REF_NAME --name send-email --rm hub.shanqu.cc/platform/send-sonar-report:latest
|
||||
allow_failure:
|
||||
exit_codes: 137
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
|
||||
oss-upload&send-email:
|
||||
tags:
|
||||
- rancher-k8s
|
||||
stage: oss-upload&send-email
|
||||
image: hub.shanqu.cc/devops/android-apk-oss-upload:latest
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
VAULT_ADDR: https://vault.shanqu.cc # 固定值
|
||||
VAULT_SECRET_PATH: prod/devops/android-apk-oss-upload # 固定值
|
||||
VAULT_ROLE: android-apk-oss-upload # 固定值
|
||||
ENDPOINT: "oss-cn-shenzhen-internal.aliyuncs.com" # 固定值
|
||||
BUCKET: "shanqu" # 固定值
|
||||
FILE_PATH: "app/build/tmp/" # APK 存放路径
|
||||
Email_To_List: $EMAIL_TO_LIST # 邮件接受人列表
|
||||
Email_Title: "光环助手 $CI_COMMIT_BRANCH" # 邮件标题
|
||||
PIPELINE_ID: $CI_PIPELINE_ID # 流水线id
|
||||
COMMIT_BRANCH: $CI_COMMIT_BRANCH # 提交分支
|
||||
MAIL_MESSAGE: "[$CI_COMMIT_AUTHOR] $CI_COMMIT_MESSAGE"
|
||||
needs:
|
||||
- job: android_build
|
||||
artifacts: true
|
||||
script:
|
||||
### 绑定上传参数 ###
|
||||
- export OSS_PATH="release/dev/${CI_PROJECT_NAME}/$(date "+%Y/%m/%d")"
|
||||
### 开启上传 ###
|
||||
- /usr/local/bin/python /upload.py
|
||||
### 发送邮件
|
||||
- /usr/local/bin/python /ci-android-mail.py
|
||||
only:
|
||||
- dev
|
||||
- dev-5.29.0
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -1,13 +1,13 @@
|
||||
[submodule "libraries/LGLibrary"]
|
||||
path = libraries/LGLibrary
|
||||
url = git@git.shanqu.cc:android/common-library.git
|
||||
url = ../../../android/common-library.git
|
||||
branch = master
|
||||
[submodule "vspace-bridge"]
|
||||
path = vspace-bridge
|
||||
url = git@git.shanqu.cc:cwzs/android/vspace-bridge.git
|
||||
url = ../../../cwzs/android/vspace-bridge.git
|
||||
[submodule "module_common/src/debug/assets/assistant-android-mock"]
|
||||
path = module_common/src/debug/assets/assistant-android-mock
|
||||
url = git@git.shanqu.cc:halo/android/assistant-android-mock.git
|
||||
url = ../../../halo/android/assistant-android-mock.git
|
||||
[submodule "ndownload"]
|
||||
path = ndownload
|
||||
url = git@git.shanqu.cc:android/ndownload.git
|
||||
url = ../../../android/ndownload.git
|
||||
|
||||
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM openjdk:11-jdk
|
||||
WORKDIR /project
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
#配置SDK环境变量
|
||||
ENV ANDROID_SDK_ROOT /usr/lib/sdk
|
||||
ENV ANDROID_HOME /usr/lib/sdk
|
||||
ENV PATH $ANDROID_SDK_ROOT:$PATH
|
||||
ENV PATH=$PATH:${ANDROID_HOME}/cmdline-tools/cmdline-tools/bin/
|
||||
ENV GRADLE_USER_HOME /project/.gradle
|
||||
RUN source ~/.bashrc
|
||||
RUN sed -i "s@http://\(deb\|security\).debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list \
|
||||
&& apt-get --quiet update --yes \
|
||||
&& apt-get --quiet install --yes lib32stdc++6 lib32z1 libncurses5 util-linux bash tzdata librdkafka-dev pkgconf \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY .gradle /project/.gradle
|
||||
@ -9,6 +9,14 @@ import groovy.xml.XmlUtil
|
||||
|
||||
android {
|
||||
|
||||
String CONFIG_ID = ""
|
||||
String FIRST_LAUNCH = ""
|
||||
String SDK_VERSION = ""
|
||||
String SDK_APP_ID = ""
|
||||
String SDK_APP_NAME = ""
|
||||
boolean USE_DEFAULT_CHANNEL_SDK = true
|
||||
int ACTIVATE_REPORTING_RATIO = 100
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
dataBinding true
|
||||
@ -67,9 +75,26 @@ android {
|
||||
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
|
||||
|
||||
/**
|
||||
* All third-party appid/appkey
|
||||
*/
|
||||
String CORE_EVENT_GAME_CATEGORY = ""
|
||||
|
||||
// 推广用的关键事件游戏类型
|
||||
buildConfigField "String", "CORE_EVENT_GAME_CATEGORY", "\"${CORE_EVENT_GAME_CATEGORY}\""
|
||||
|
||||
// 推广用的配置 id
|
||||
buildConfigField "String", "CONFIG_ID", "\"${CONFIG_ID}\""
|
||||
|
||||
// 推广用的 SDK 版本 (仅记录使用)
|
||||
buildConfigField "String", "SDK_VERSION", "\"${SDK_VERSION}\""
|
||||
buildConfigField "String", "SDK_APP_ID", "\"${SDK_APP_ID}\""
|
||||
buildConfigField "String", "SDK_APP_NAME", "\"${SDK_APP_NAME}\""
|
||||
buildConfigField "boolean", "USE_DEFAULT_CHANNEL_SDK", "${USE_DEFAULT_CHANNEL_SDK}"
|
||||
|
||||
// 首次启动的跳转配置
|
||||
buildConfigField "String", "FIRST_LAUNCH", "\"${FIRST_LAUNCH}\""
|
||||
|
||||
buildConfigField "int", "ACTIVATE_REPORTING_RATIO", "${ACTIVATE_REPORTING_RATIO}"
|
||||
|
||||
// All third-party appid/appkey
|
||||
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
|
||||
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
|
||||
buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
@ -127,7 +152,7 @@ android {
|
||||
variantFilter { variant ->
|
||||
def names = variant.flavors*.name
|
||||
def isDebugType = variant.buildType.name == "debug"
|
||||
if ((names.contains("tea") || name.contains("kuaishou")) && isDebugType) {
|
||||
if ((names.contains("tea") || name.contains("kuaishou") || name.contains("gdt")) && isDebugType) {
|
||||
setIgnore(true)
|
||||
}
|
||||
}
|
||||
@ -147,10 +172,13 @@ android {
|
||||
kuaishou {
|
||||
java.srcDirs = ['src/main/java', 'src/kuaishou/java']
|
||||
}
|
||||
gdt {
|
||||
java.srcDirs = ['src/main/java', 'src/gdt/java']
|
||||
}
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
// internal test dev host
|
||||
// internal, 内部测试包使用的 flavor,接口包含包括测试和正式环境
|
||||
internal {
|
||||
dimension "env"
|
||||
versionNameSuffix "-debug"
|
||||
@ -162,7 +190,7 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
|
||||
}
|
||||
|
||||
// publish release host
|
||||
// publish, 发布时候使用的 flavor,接口仅包含正式环境
|
||||
publish {
|
||||
dimension "env"
|
||||
|
||||
@ -194,6 +222,16 @@ android {
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
}
|
||||
|
||||
gdt {
|
||||
dimension "env"
|
||||
|
||||
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
|
||||
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
|
||||
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
|
||||
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +247,7 @@ dependencies {
|
||||
|
||||
teaImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/tea/libs')
|
||||
kuaishouImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/kuaishou/libs')
|
||||
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
|
||||
testImplementation 'junit:junit:4.12'
|
||||
|
||||
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
|
||||
@ -216,8 +255,7 @@ dependencies {
|
||||
|
||||
// debugImplementation "com.gu.android:toolargetool:${toolargetool}" // 需要使用调试时才启用
|
||||
debugImplementation "com.github.nichbar:WhatTheStack:${whatTheStack}"
|
||||
debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
|
||||
|
||||
// debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
|
||||
|
||||
implementation "androidx.multidex:multidex:${multiDex}"
|
||||
implementation "androidx.fragment:fragment-ktx:${fragment}"
|
||||
@ -257,6 +295,7 @@ dependencies {
|
||||
implementation "com.llew.huawei:verifier:${verifier}"
|
||||
|
||||
teaImplementation "com.bytedance.applog:RangersAppLog-Lite-cn:${bytedanceApplog}"
|
||||
teaImplementation "com.bytedance.applog:RangersAppLog-All-convert:${bytedanceApplog}"
|
||||
|
||||
implementation "net.lingala.zip4j:zip4j:${zip4j}"
|
||||
|
||||
@ -271,7 +310,8 @@ dependencies {
|
||||
|
||||
implementation "com.lg:gid:${gid}"
|
||||
|
||||
compileOnly "com.github.axen1314.lancet:lancet-base:${lancet_version}"
|
||||
implementation "com.lg:shortcut:${shortcut}"
|
||||
|
||||
kapt "com.alibaba:arouter-compiler:$arouterVersion"
|
||||
|
||||
implementation project(':ndownload')
|
||||
@ -289,17 +329,23 @@ dependencies {
|
||||
// implementation(project(':module_setting_compose')) {
|
||||
// exclude group: 'androidx.swiperefreshlayout'
|
||||
// }
|
||||
implementation(project(':module_core_feature')){
|
||||
implementation(project(':module_core_feature')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
implementation(project(':module_feedback')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
// 默认不接入光能模块,提高编译速度
|
||||
// debugImplementation(project(':module_energy')) {
|
||||
// exclude group: 'androidx.swiperefreshlayout'
|
||||
// }
|
||||
implementation(project(':module_sensors_data')) {
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
}
|
||||
// implementation(project(':feature:vpn'))
|
||||
implementation(project(':feature:pkg'))
|
||||
implementation(project(':feature:oaid'))
|
||||
implementation(project(':feature:floating-window'))
|
||||
// implementation(project(':feature:beizi_startup_ad'))
|
||||
implementation(project(':feature:xapk-installer'))
|
||||
}
|
||||
|
||||
File propFile = file('sign.properties')
|
||||
if (propFile.exists()) {
|
||||
Properties props = new Properties()
|
||||
@ -439,7 +485,12 @@ andResGuard {
|
||||
"R.drawable.suggest_add_pic_icon",
|
||||
"R.drawable.icon_pic_add",
|
||||
"R.drawable.ask_search_input_delete",
|
||||
"R.drawable.suggest_pic_delete"
|
||||
"R.drawable.suggest_pic_delete",
|
||||
"R.id.cardIv",
|
||||
"R.id.cardMask",
|
||||
"R.id.cardGradientMask",
|
||||
"R.id.gameIconIv",
|
||||
"R.id.titleContainer"
|
||||
]
|
||||
compressFilePattern = [
|
||||
"*.png",
|
||||
|
||||
@ -20,11 +20,13 @@
|
||||
-keep class com.gh.gamecenter.db.info.* {*;}
|
||||
-keep class com.gh.gamecenter.entity.** {<fields>;}
|
||||
-keep class com.gh.gamecenter.qa.entity.** {<fields>;}
|
||||
-keep class com.gh.download.DownloadDataSimpleEntity {<fields>;}
|
||||
-keep class com.gh.gamecenter.floatingwindow.FloatingWindowEntity {<fields>;}
|
||||
-keep class com.gh.gamecenter.BR
|
||||
-keep class com.gh.gamecenter.retrofit.* {*;}
|
||||
-keep class com.gh.gamecenter.eventbus.* {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.GameCollectionStackLayout {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.GameCollectionStackAnimation {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.carousel.GameCollectionStackLayout {*;}
|
||||
-keep class com.gh.gamecenter.home.gamecollection.carousel.GameCollectionStackAnimation {*;}
|
||||
|
||||
# Prevent R8 from leaving Data object members always null
|
||||
-keepclassmembers,allowobfuscation class * {
|
||||
@ -62,6 +64,16 @@
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
### RecyclerView.jumpToPositionForSmoothScroller
|
||||
-keep class androidx.recyclerview.widget.RecyclerView {
|
||||
void jumpToPositionForSmoothScroller(int);
|
||||
}
|
||||
|
||||
### ViewBinding 反射相关
|
||||
-keep class * implements androidx.viewbinding.ViewBinding {
|
||||
public static *** inflate(android.view.LayoutInflater, android.view.ViewGroup, boolean);
|
||||
}
|
||||
|
||||
### TEA
|
||||
-keep class com.gh.gamecenter.TeaHelper { *; }
|
||||
|
||||
@ -69,4 +81,14 @@
|
||||
-keep class com.lzf.easyfloat.* {*;}
|
||||
|
||||
### dokit
|
||||
-keep class com.didichuxing.** {*;}
|
||||
-keep class com.didichuxing.** {*;}
|
||||
|
||||
### 广点通SDK
|
||||
-dontwarn com.qq.gdt.action.**
|
||||
-keep class com.qq.gdt.action.** {*;}
|
||||
-keep public class com.tencent.turingfd.sdk.**
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
|
||||
@ -26,11 +26,15 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
return channel
|
||||
}
|
||||
|
||||
override fun init(application: Application, activity: Activity) {
|
||||
override fun init(application: Application, activity: Activity, activateRatio: Int) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override fun logEvent(content: String) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override fun logCoreEvent() {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
37
app/src/gdt/java/com/gh/gamecenter/GdtHelper.kt
Normal file
37
app/src/gdt/java/com/gh/gamecenter/GdtHelper.kt
Normal file
@ -0,0 +1,37 @@
|
||||
package com.gh.gamecenter
|
||||
|
||||
import android.app.Application
|
||||
import com.lightgame.utils.Utils
|
||||
import com.qq.gdt.action.ActionParam
|
||||
import com.qq.gdt.action.ActionType
|
||||
import com.qq.gdt.action.GDTAction
|
||||
import org.json.JSONObject
|
||||
|
||||
object GdtHelper {
|
||||
private const val USER_ACTION_SET_ID = "1201041887"
|
||||
private const val APP_SECRET_ID = "c29cc5c48cf540c43b4b97363bb09216"
|
||||
|
||||
private const val KS_USER_ACTION_SET_ID = "1201032128"
|
||||
private const val KS_APP_SECRET_ID = "9bdbbb81d4e0bd333a2a581f9ee36986"
|
||||
|
||||
@JvmStatic
|
||||
fun init(application: Application, channel: String) {
|
||||
if (channel == "KS_GDT_GHZS_MC01") {
|
||||
GDTAction.init(application, KS_USER_ACTION_SET_ID, KS_APP_SECRET_ID, channel)
|
||||
} else {
|
||||
GDTAction.init(application, USER_ACTION_SET_ID, APP_SECRET_ID, channel)
|
||||
}
|
||||
Utils.log("init GdtHelper")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logAction(type: String) {
|
||||
when (type) {
|
||||
"EVENT_ACTIVE" -> GDTAction.logAction(ActionType.START_APP)
|
||||
"active_register" -> GDTAction.logAction(ActionType.REGISTER)
|
||||
"EVENT_NEXTDAY_STAY" -> GDTAction.logAction(ActionType.START_APP, JSONObject().apply {
|
||||
put(ActionParam.Key.LENGTH_OF_STAY, 1)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.gh.gamecenter.provider
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.GdtHelper
|
||||
import com.gh.gamecenter.core.provider.IFlavorProvider
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.leon.channel.helper.ChannelReaderUtil
|
||||
|
||||
class FlavorProviderImp : IFlavorProvider {
|
||||
|
||||
override fun init(application: Application, activity: Activity, activateRatio: Int) {
|
||||
GdtHelper.init(application, getChannelStr(application))
|
||||
|
||||
if (HaloApp.getInstance().isBrandNewInstall) {
|
||||
logEvent("EVENT_ACTIVE")
|
||||
SPUtils.setLong("TIME_OF_BRAND_NEW_INSTALL", System.currentTimeMillis() / 1000)
|
||||
} else {
|
||||
val shouldSendRetentionLogEvent =
|
||||
SPUtils.getBoolean("SHOULD_SEND_RETENTION_EVENT", true)
|
||||
val installTimeNotToday =
|
||||
!TimeUtils.isToday(SPUtils.getLong("TIME_OF_BRAND_NEW_INSTALL", System.currentTimeMillis() / 1000))
|
||||
if (shouldSendRetentionLogEvent && installTimeNotToday) {
|
||||
logEvent("EVENT_NEXTDAY_STAY")
|
||||
SPUtils.setBoolean("SHOULD_SEND_RETENTION_EVENT", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getChannelStr(application: Application): String {
|
||||
var channel = ChannelReaderUtil.getChannel(application)
|
||||
if (channel == null || TextUtils.isEmpty(channel.trim())) {
|
||||
channel = GDT_DEFAULT_CHANNEL
|
||||
}
|
||||
return channel
|
||||
}
|
||||
|
||||
override fun logEvent(content: String) {
|
||||
GdtHelper.logAction(content)
|
||||
}
|
||||
|
||||
override fun logCoreEvent() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val GDT_DEFAULT_CHANNEL = "GDT_GHZS_01"
|
||||
}
|
||||
}
|
||||
BIN
app/src/gdt/libs/GDTActionSDK.min.1.8.7.aar
Normal file
BIN
app/src/gdt/libs/GDTActionSDK.min.1.8.7.aar
Normal file
Binary file not shown.
10
app/src/internal/res/xml/network_security_config.xml
Normal file
10
app/src/internal/res/xml/network_security_config.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<!-- Trust user added CAs while debuggable only -->
|
||||
<certificates src="user" />
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
@ -5,15 +5,15 @@ import com.kwai.monitor.log.TurboAgent
|
||||
import com.kwai.monitor.log.TurboConfig
|
||||
|
||||
object KuaishouHelper {
|
||||
private const val APP_ID = "80655"
|
||||
private const val APP_NAME = "guanghuanzhushou_1"
|
||||
private val mAppId by lazy { BuildConfig.SDK_APP_ID.ifEmpty { "81537" } }
|
||||
private val mAppName by lazy { BuildConfig.SDK_APP_NAME.ifEmpty { "guanghuanzhushou_1" } }
|
||||
|
||||
@JvmStatic
|
||||
fun init(context: Context, channel: String) {
|
||||
TurboAgent.init(
|
||||
TurboConfig.TurboConfigBuilder.create(context)
|
||||
.setAppId(APP_ID)
|
||||
.setAppName(APP_NAME)
|
||||
.setAppId(mAppId)
|
||||
.setAppName(mAppName)
|
||||
.setAppChannel(channel)
|
||||
.build()
|
||||
)
|
||||
|
||||
@ -3,16 +3,20 @@ package com.gh.gamecenter.provider
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.KuaishouHelper
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.provider.IFlavorProvider
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.TimeUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.kwai.monitor.payload.TurboHelper
|
||||
import com.leon.channel.helper.ChannelReaderUtil
|
||||
|
||||
class FlavorProviderImp : IFlavorProvider {
|
||||
|
||||
override fun init(application: Application, activity: Activity) {
|
||||
override fun init(application: Application, activity: Activity, activateRatio: Int) {
|
||||
KuaishouHelper.init(application, getChannelStr(application))
|
||||
|
||||
if (HaloApp.getInstance().isBrandNewInstall) {
|
||||
@ -31,7 +35,11 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
}
|
||||
|
||||
override fun getChannelStr(application: Application): String {
|
||||
var channel = ChannelReaderUtil.getChannel(application)
|
||||
var channel = if (BuildConfig.USE_DEFAULT_CHANNEL_SDK) {
|
||||
ChannelReaderUtil.getChannel(application)
|
||||
} else {
|
||||
TurboHelper.getChannel(application)
|
||||
}
|
||||
if (channel == null || TextUtils.isEmpty(channel.trim())) {
|
||||
channel = KUAISHOU_CHANNEL
|
||||
}
|
||||
@ -42,6 +50,15 @@ class FlavorProviderImp : IFlavorProvider {
|
||||
KuaishouHelper.onEvent(content)
|
||||
}
|
||||
|
||||
override fun logCoreEvent() {
|
||||
logEvent("EVENT_KEY_PATH_OPTIMIZATION")
|
||||
if (BuildConfig.ACTIVATE_REPORTING_RATIO == 1) {
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast("关键行为 EVENT_KEY_PATH_OPTIMIZATION")
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KUAISHOU_CHANNEL = "KS-GHZS-01"
|
||||
}
|
||||
|
||||
BIN
app/src/kuaishou/libs/channelsdk-0.2.2.aar
Normal file
BIN
app/src/kuaishou/libs/channelsdk-0.2.2.aar
Normal file
Binary file not shown.
Binary file not shown.
BIN
app/src/kuaishou/libs/monitorsdk-1.0.13.aar
Normal file
BIN
app/src/kuaishou/libs/monitorsdk-1.0.13.aar
Normal file
Binary file not shown.
@ -46,7 +46,8 @@
|
||||
<!-- 如果有视频相关的广告且使用textureView播放,请务必添加,否则黑屏 -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.shuyu.gsyvideoplayer,
|
||||
<uses-sdk tools:overrideLibrary="
|
||||
com.shuyu.gsyvideoplayer,
|
||||
com.shuyu.gsyvideoplayer.lib,
|
||||
com.haroldadmin.whatthestack,
|
||||
com.shuyu.gsyvideoplayer.armv7a,
|
||||
@ -76,7 +77,7 @@
|
||||
androidx.compose.animation.core,
|
||||
androidx.constraintlayout.compose,
|
||||
androidx.compose.ui.test.manifest,
|
||||
androidx.compose.ui.tooling.preview"/>
|
||||
androidx.compose.ui.tooling.preview" />
|
||||
|
||||
<!-- 去掉 SDK 一些流氓权限 -->
|
||||
<uses-permission
|
||||
@ -105,11 +106,16 @@
|
||||
android:icon="@mipmap/logo"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:resizeableActivity="true"
|
||||
android:theme="@style/AppCompatTheme.APP"
|
||||
tools:replace="android:name,android:allowBackup"
|
||||
tools:targetApi="n">
|
||||
|
||||
<meta-data
|
||||
android:name="EasyGoClient"
|
||||
android:value="true" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.sentry.auto-init"
|
||||
android:value="false" />
|
||||
@ -119,6 +125,8 @@
|
||||
android:name="io.sentry.breadcrumbs.system-events"
|
||||
android:value="false" />
|
||||
|
||||
<service android:name="com.gh.ndownload.NDownloadService" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.SplashScreenActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
@ -135,10 +143,15 @@
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MainActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/AppCompatTheme.APP"
|
||||
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
|
||||
android:windowSoftInputMode="stateAlwaysHidden|adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.DownloadManagerActivity"
|
||||
@ -619,8 +632,8 @@
|
||||
<!-- android:theme="@android:style/Theme.Translucent" />-->
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name="com.gh.gamecenter.SkipActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.AppCompat.Light.Fullscreen.Transparent">
|
||||
<intent-filter>
|
||||
<data android:scheme="ghzhushou" />
|
||||
@ -639,6 +652,19 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- 光环助手授权登陆页面 -->
|
||||
<activity
|
||||
android:name=".authorization.AuthorizationActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<data android:scheme="ghzhushou_authorization" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.teenagermode.TeenagerModeActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -730,6 +756,10 @@
|
||||
android:name=".servers.gametest2.GameServerTestV2Activity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
|
||||
<!-- <activity-->
|
||||
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
|
||||
@ -767,9 +797,9 @@
|
||||
<service
|
||||
android:name=".aidl.CommunicationService"
|
||||
android:enabled="true"
|
||||
android:exported="true" >
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.gh.gamecenter.aidl.CommunicationService"/>
|
||||
<action android:name="com.gh.gamecenter.aidl.CommunicationService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
@ -800,6 +830,11 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name="com.gh.common.xapk.XapkInstallReceiver"
|
||||
android:theme="@style/Theme.Transparent"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver
|
||||
android:name="com.gh.gamecenter.receiver.ActivitySkipReceiver"
|
||||
android:exported="true">
|
||||
|
||||
27
app/src/main/assets/easygo.json
Normal file
27
app/src/main/assets/easygo.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"easyGoVersion": "1.0",
|
||||
"client": "com.gh.gamecenter",
|
||||
"logicEntities": [
|
||||
{
|
||||
"head": {
|
||||
"function": "magicwindow",
|
||||
"required": "true"
|
||||
},
|
||||
"body": {
|
||||
"mode":"1",
|
||||
"activityPairs":[
|
||||
{"from":"com.gh.gamecenter.MainActivity","to":"*"}
|
||||
],
|
||||
"defaultDualActivities": {
|
||||
"mainPages": "com.gh.gamecenter.MainActivity"
|
||||
},
|
||||
"UX": {
|
||||
"supportRotationUxCompat": "false",
|
||||
"isDraggable": "true"
|
||||
},
|
||||
"transActivities":[
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
{"v":"5.5.9","fr":60,"ip":0,"op":90,"w":1080,"h":202,"nm":"click","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"椭圆形","sr":1,"ks":{"o":{"a":0,"k":20,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[204,1455,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":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","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":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"椭圆形","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[10]},{"t":70,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[204,1455,0],"ix":2},"a":{"a":0,"k":[0,0,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":39,"s":[100,100,100]},{"t":49,"s":[110,110,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[36,36],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","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":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"圆环","refId":"comp_0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.531],"y":[0]},"t":28,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":38,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.526],"y":[0]},"t":48,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.446],"y":[0]},"t":63,"s":[50]},{"t":82,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[125.951,79.658,0],"ix":2},"a":{"a":0,"k":[205.951,1458.658,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.601,0.601,0.333],"y":[0,0,0]},"t":28,"s":[50,50,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.528,0.528,0.333],"y":[0,0,0]},"t":38,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.526,0.526,0.333],"y":[0,0,0]},"t":48,"s":[120,120,100]},{"t":63,"s":[100,100,100]}],"ix":6}},"ao":0,"w":1080,"h":1920,"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"点击手","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.596],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.515],"y":[0]},"t":63,"s":[100]},{"t":83,"s":[0]}],"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.507],"y":[0]},"t":10,"s":[6]},{"t":30,"s":[2]}],"ix":10},"p":{"a":0,"k":[178.982,123.325,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.489,0.489,0.333],"y":[0,0,0]},"t":10,"s":[100,100,100]},{"t":30,"s":[90,90,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.33,-8.3],[3.89,0.27],[-4.4,-1.68],[-4.33,-0.67],[-4.08,9.32],[3.33,5.44],[3.39,4.6],[0.87,-3.7],[3.6,-0.86],[1.03,-0.21],[2.34,-0.53],[0.96,1.15],[4.22,5.48],[-1.18,-4.56]],"o":[[1.11,1.71],[-3.89,-0.27],[6.42,2.5],[4.33,0.66],[1.63,-5.32],[-3.34,-5.45],[-1.68,-2.1],[-0.71,3.14],[-3.43,0.95],[-0.57,0.08],[-3.86,1.12],[-3.23,-3.94],[-1.89,-2.28],[2.42,4.64]],"v":[[-5.387,9.698],[-10.717,8.498],[-12.327,15.628],[5.813,21.748],[23.313,11.778],[20.273,-1.202],[11.563,-13.962],[5.393,-12.362],[1.083,-13.722],[-2.087,-9.742],[-5.707,-11.752],[-8.777,-7.572],[-18.297,-20.542],[-23.827,-17.832]],"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":"路径备份 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]}
|
||||
@ -1 +0,0 @@
|
||||
{"v":"5.6.4","fr":25,"ip":0,"op":35,"w":1080,"h":214,"nm":"点赞","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"椭圆形 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.588],"y":[0]},"t":17,"s":[15]},{"t":20,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[468.04,73.68,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.659,0.659,0.333],"y":[0,0,0]},"t":10,"s":[50,50,100]},{"t":19,"s":[150,150,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","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":10,"op":1510,"st":10,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"椭圆形 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.588],"y":[0]},"t":27,"s":[15]},{"t":30,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[468.04,73.68,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.659,0.659,0.333],"y":[0,0,0]},"t":20,"s":[50,50,100]},{"t":28,"s":[140,140,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24,24],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","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":20,"op":1520,"st":20,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"路径备份 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.602],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.663],"y":[0]},"t":24,"s":[100]},{"t":29,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[531.02,129.675,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.514,0.514,0.333],"y":[0,0,0]},"t":5,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.533,0.533,0.333],"y":[0,0,0]},"t":10,"s":[90,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.586,0.586,0.333],"y":[0,0,0]},"t":15,"s":[95,95,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.499,0.499,0.333],"y":[0,0,0]},"t":19,"s":[90,90,100]},{"t":24,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-5.33,-8.3],[3.89,0.27],[-4.4,-1.68],[-4.33,-0.67],[-4.08,9.32],[3.33,5.44],[3.39,4.6],[0.87,-3.7],[3.6,-0.86],[1.03,-0.21],[2.34,-0.53],[0.96,1.15],[4.22,5.48],[-1.18,-4.56]],"o":[[1.11,1.71],[-3.89,-0.27],[6.42,2.5],[4.33,0.66],[1.63,-5.32],[-3.34,-5.45],[-1.68,-2.1],[-0.71,3.14],[-3.43,0.95],[-0.57,0.08],[-3.86,1.12],[-3.23,-3.94],[-1.89,-2.28],[2.42,4.64]],"v":[[-5.387,9.698],[-10.717,8.498],[-12.327,15.628],[5.813,21.748],[23.313,11.778],[20.273,-1.202],[11.563,-13.962],[5.393,-12.362],[1.083,-13.722],[-2.087,-9.742],[-5.707,-11.752],[-8.777,-7.572],[-18.297,-20.542],[-23.827,-17.832]],"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":"路径备份 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1500,"st":0,"bm":0}],"markers":[]}
|
||||
1
app/src/main/assets/lottie/icon_fab_change.json
Normal file
1
app/src/main/assets/lottie/icon_fab_change.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":144,"h":144,"nm":"icon_change","ddd":0,"assets":[{"id":"comp_0","nm":"icon_change_detail","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"stroke1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[37.04,52.994,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.533,-0.143],[0.143,-0.533],[1.487,-1.304],[1.961,-0.258],[1.774,0.875],[0.709,0.661],[0,0],[0,0.445],[0,0],[-0.276,0],[0,0],[-0.013,0],[0,0],[0.315,-0.315],[0,0],[-0.682,-0.336],[-1.569,0.207],[-1.19,1.043],[-0.41,1.528]],"o":[[0.533,0.143],[-0.512,1.91],[-1.487,1.304],[-1.961,0.258],[-0.879,-0.433],[0,0],[-0.315,0.315],[0,0],[0,-0.276],[0,0],[0.013,0],[0,0],[0.445,0],[0,0],[0.555,0.508],[1.419,0.7],[1.569,-0.207],[1.19,-1.043],[0.143,-0.533]],"v":[[8.605,-4.301],[9.312,-3.076],[6.247,1.854],[0.958,4.25],[-4.77,3.304],[-7.163,1.652],[-8.493,2.982],[-9.347,2.628],[-9.347,-1.665],[-8.847,-2.165],[-8.161,-2.165],[-8.122,-2.165],[-4.554,-2.165],[-4.2,-1.311],[-5.748,0.237],[-3.885,1.51],[0.697,2.267],[4.928,0.35],[7.381,-3.594]],"c":true},"ix":2},"nm":"stroke1","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,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.8,1,0.6],"ix":9}},"s":{"a":0,"k":[-5.347,-4.665],"ix":5},"e":{"a":0,"k":[8.653,-4.665],"ix":6},"t":1,"nm":"color1","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":"stroke1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"stroke2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34.96,19.006,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.961,0.258],[-1.774,-0.875],[-0.709,-0.661],[0,0],[0,-0.445],[0,0],[0.276,0],[0,0],[0.012,0],[0,0],[-0.315,0.315],[0,0],[0.682,0.336],[1.569,-0.207],[1.19,-1.043],[0.41,-1.528],[0.533,0.143],[-0.143,0.533],[-1.487,1.304]],"o":[[1.961,-0.258],[0.879,0.433],[0,0],[0.315,-0.315],[0,0],[0,0.276],[0,0],[-0.012,0],[0,0],[-0.445,0],[0,0],[-0.555,-0.508],[-1.419,-0.7],[-1.569,0.207],[-1.19,1.043],[-0.143,0.533],[-0.533,-0.143],[0.512,-1.91],[1.487,-1.304]],"v":[[-0.958,-4.25],[4.77,-3.304],[7.163,-1.652],[8.493,-2.982],[9.347,-2.628],[9.347,1.665],[8.847,2.165],[8.16,2.165],[8.123,2.165],[4.554,2.165],[4.2,1.311],[5.748,-0.237],[3.885,-1.51],[-0.697,-2.267],[-4.928,-0.35],[-7.381,3.594],[-8.605,4.301],[-9.312,3.076],[-6.247,-1.854]],"c":true},"ix":2},"nm":"stroke2","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,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.8,1,0.6],"ix":9}},"s":{"a":0,"k":[5.347,4.665],"ix":5},"e":{"a":0,"k":[-8.653,4.665],"ix":6},"t":1,"nm":"color2","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":"stroke2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"icon_change_detail","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[72,72,0],"ix":2,"l":2},"a":{"a":0,"k":[36,36,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":72,"h":72,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}
|
||||
1
app/src/main/assets/lottie/icon_title_change_dark.json
Normal file
1
app/src/main/assets/lottie/icon_title_change_dark.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":72,"h":72,"nm":"icon_title_change","ddd":0,"assets":[{"id":"comp_0","nm":"arrow","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"arrow_e_dark","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.25,30,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.701,0.456],[-1.627,-0.674],[-0.705,-0.667],[0,0],[-0.552,0],[0,-0.552],[0,0],[0.552,0],[0,0],[0.012,0],[0,0],[0,0.552],[-0.552,0],[0,0],[0.615,0.255],[1.276,-0.342],[0.804,-1.048],[0,-1.321],[-0.804,-1.048],[-1.276,-0.342],[-1.22,0.505],[-0.66,1.144],[-0.478,-0.276],[0.276,-0.478],[1.627,-0.674],[1.701,0.456],[1.072,1.397],[0,1.761],[-1.072,1.397]],"o":[[1.701,-0.456],[0.909,0.376],[0,0],[0,-0.552],[0.552,0],[0,0],[0,0.552],[0,0],[-0.012,0],[0,0],[-0.552,0],[0,-0.552],[0,0],[-0.493,-0.435],[-1.22,-0.505],[-1.276,0.342],[-0.804,1.048],[0,1.321],[0.804,1.048],[1.276,0.342],[1.22,-0.505],[0.276,-0.478],[0.478,0.276],[-0.881,1.525],[-1.627,0.674],[-1.701,-0.456],[-1.072,-1.397],[0,-1.761],[1.072,-1.397]],"v":[[-1.821,-7.727],[3.311,-7.391],[5.75,-5.809],[5.75,-6.5],[6.75,-7.5],[7.75,-6.5],[7.75,-3.5],[6.75,-2.5],[6.331,-2.5],[6.295,-2.5],[3.75,-2.5],[2.75,-3.5],[3.75,-4.5],[4.219,-4.5],[2.546,-5.543],[-1.303,-5.796],[-4.51,-3.653],[-5.75,0],[-4.51,3.653],[-1.303,5.796],[2.546,5.543],[5.446,3],[6.812,2.634],[7.178,4],[3.311,7.391],[-1.821,7.727],[-6.097,4.87],[-7.75,0],[-6.097,-4.87]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.158117651939,0.532358944416,0.878431379795,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":"arrow_e_dark","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"arrow","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[36,36,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":60,"h":60,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}
|
||||
1
app/src/main/assets/lottie/icon_title_change_light.json
Normal file
1
app/src/main/assets/lottie/icon_title_change_light.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.9.1","fr":60,"ip":0,"op":60,"w":72,"h":72,"nm":"icon_title_change","ddd":0,"assets":[{"id":"comp_0","nm":"arrow","fr":60,"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"arrow_e_light","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29.25,30,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.701,0.456],[-1.627,-0.674],[-0.705,-0.667],[0,0],[-0.552,0],[0,-0.552],[0,0],[0.552,0],[0,0],[0.012,0],[0,0],[0,0.552],[-0.552,0],[0,0],[0.615,0.255],[1.276,-0.342],[0.804,-1.048],[0,-1.321],[-0.804,-1.048],[-1.276,-0.342],[-1.22,0.505],[-0.66,1.144],[-0.478,-0.276],[0.276,-0.478],[1.627,-0.674],[1.701,0.456],[1.072,1.397],[0,1.761],[-1.072,1.397]],"o":[[1.701,-0.456],[0.909,0.376],[0,0],[0,-0.552],[0.552,0],[0,0],[0,0.552],[0,0],[-0.012,0],[0,0],[-0.552,0],[0,-0.552],[0,0],[-0.493,-0.435],[-1.22,-0.505],[-1.276,0.342],[-0.804,1.048],[0,1.321],[0.804,1.048],[1.276,0.342],[1.22,-0.505],[0.276,-0.478],[0.478,0.276],[-0.881,1.525],[-1.627,0.674],[-1.701,-0.456],[-1.072,-1.397],[0,-1.761],[1.072,-1.397]],"v":[[-1.821,-7.727],[3.311,-7.391],[5.75,-5.809],[5.75,-6.5],[6.75,-7.5],[7.75,-6.5],[7.75,-3.5],[6.75,-2.5],[6.331,-2.5],[6.295,-2.5],[3.75,-2.5],[2.75,-3.5],[3.75,-4.5],[4.219,-4.5],[2.546,-5.543],[-1.303,-5.796],[-4.51,-3.653],[-5.75,0],[-4.51,3.653],[-1.303,5.796],[2.546,5.543],[5.446,3],[6.812,2.634],[7.178,4],[3.311,7.391],[-1.821,7.727],[-6.097,4.87],[-7.75,0],[-6.097,-4.87]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.141176477075,0.588235318661,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":"arrow_e_light","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"arrow","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.5],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"t":36,"s":[360]}],"ix":10},"p":{"a":0,"k":[36,36,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":60,"h":60,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]}
|
||||
@ -1 +0,0 @@
|
||||
{"v":"5.5.9","fr":60,"ip":0,"op":120,"w":1080,"h":586,"nm":"上滑","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"手","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.642],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":6,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.558],"y":[0]},"t":60,"s":[100]},{"t":71,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.479,"y":0},"t":3,"s":[611,475,0],"to":[0,-62.75,0],"ti":[0,62.75,0]},{"t":40,"s":[611,98.5,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[90,90,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-7.78,-12.06],[5.68,0.39],[-6.42,-2.45],[-6.32,-0.97],[-5.95,13.55],[4.87,7.91],[4.94,6.69],[1.26,-5.37],[5.25,-1.25],[1.5,-0.3],[3.4,-0.77],[1.4,1.68],[6.15,7.98],[-1.73,-6.64]],"o":[[1.62,2.49],[-5.68,-0.39],[9.37,3.63],[6.31,0.98],[2.39,-7.74],[-4.87,-7.92],[-2.45,-3.05],[-1.05,4.57],[-4.99,1.39],[-0.83,0.13],[-5.63,1.63],[-4.71,-5.72],[-2.75,-3.31],[3.52,6.76]],"v":[[-7.86,14.26],[-15.64,12.52],[-17.99,22.89],[8.47,31.78],[33.98,17.29],[29.55,-1.59],[16.85,-20.15],[7.86,-17.83],[1.56,-19.8],[-3.05,-14.02],[-8.33,-16.94],[-12.44,-11.045],[-26.761,-30.19],[-34.75,-25.78]],"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":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"矩形","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.715],"y":[0]},"t":57,"s":[100]},{"t":67,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[525,228.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.491,"y":0},"t":3,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[24.328,180.5],[-22,180.5],[-22,204.5],[24.328,204.5]],"c":true}]},{"t":40,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[24.328,-207.5],[-22,-207.5],[-22,204.5],[24.328,204.5]],"c":true}]}],"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"蒙版 1"}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[6,137],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":2,"ix":4},"nm":"矩形路径 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,1,1,0.5,1,1,1,1,1,1,1,0,1,0.5,0.5,1,0],"ix":9}},"s":{"a":0,"k":[0,-68.5],"ix":5},"e":{"a":0,"k":[0,68.5],"ix":6},"t":1,"nm":"Gradient Fill 1","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},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":33,"ix":3},"m":1,"ix":2,"nm":"修剪路径 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":3,"op":123,"st":3,"bm":0}],"markers":[]}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.base
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
@ -17,6 +18,8 @@ import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.common.entity.ErrorEntity
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.entity.ForumDetailEntity
|
||||
import com.gh.gamecenter.entity.LocalVideoEntity
|
||||
import com.gh.gamecenter.entity.QuoteCountEntity
|
||||
import com.gh.gamecenter.qa.BbsType
|
||||
@ -28,7 +31,9 @@ import com.google.gson.JsonObject
|
||||
import com.lightgame.utils.Utils
|
||||
import com.zhihu.matisse.Matisse
|
||||
import com.zhihu.matisse.internal.utils.PathUtils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
import java.io.File
|
||||
@ -38,6 +43,7 @@ import kotlin.collections.set
|
||||
// TODO: 移动到module_bbs模块
|
||||
abstract class BaseRichEditorViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val mApi: ApiService = RetrofitManager.getInstance().api
|
||||
val mNewApi: ApiService = RetrofitManager.getInstance().newApi
|
||||
val processDialog = MediatorLiveData<WaitingDialogFragment.WaitingDialogData>()
|
||||
val chooseImagesUpload = MutableLiveData<LinkedHashMap<String, String>>()
|
||||
val chooseImagesUploadSuccess = MutableLiveData<LinkedHashMap<String, String>>()
|
||||
@ -55,6 +61,8 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
|
||||
var id = ""//视频标记
|
||||
var videoId = ""//更改封面视频id
|
||||
val quoteCountEntity = QuoteCountEntity()//数据上报用
|
||||
val sectionListLiveData = MutableLiveData<List<ForumDetailEntity.Section>>()
|
||||
var isModerator = false
|
||||
|
||||
fun setUploadVideoListener(uploadVideoListener: UploadVideoListener) {
|
||||
this.mUploadVideoListener = uploadVideoListener
|
||||
@ -408,6 +416,30 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
|
||||
return true
|
||||
}
|
||||
|
||||
fun getForumSections(bbsId: String) {
|
||||
mNewApi.getForumSections(bbsId)
|
||||
.compose(observableToMain())
|
||||
.subscribe(object : Response<List<ForumDetailEntity.Section>>() {
|
||||
override fun onResponse(response: List<ForumDetailEntity.Section>?) {
|
||||
response?.run {
|
||||
sectionListLiveData.postValue(this)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getModeratorsInfo(bbsId: String) {
|
||||
mApi.getModeratorsInfo(bbsId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<JsonObject>() {
|
||||
override fun onSuccess(data: JsonObject) {
|
||||
isModerator = data["is_moderators"].asBoolean
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun getVideoType(): String {
|
||||
return when (type) {
|
||||
BbsType.GAME_BBS.value -> {
|
||||
|
||||
@ -5,9 +5,13 @@ import android.app.Application
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.common.util.FloatingBackViewManager
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.SingletonWebActivity
|
||||
import com.gh.gamecenter.SkipActivity
|
||||
import com.gh.gamecenter.SplashScreenActivity
|
||||
import com.gh.gamecenter.authorization.AuthorizationActivity
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.utils.PackageFlavorHelper
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
@ -26,11 +30,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
// 判断是否需要显示或隐藏返回小浮窗
|
||||
if (FloatingBackViewManager.getType().isNotEmpty()) {
|
||||
if ((activity::class.java.name == "EnergyCenterActivity")
|
||||
&& FloatingBackViewManager.getType() == FloatingBackViewManager.TYPE_TASK
|
||||
) {
|
||||
FloatingBackViewManager.disableBackView()
|
||||
} else if (activity is SingletonWebActivity
|
||||
if (activity is SingletonWebActivity
|
||||
&& FloatingBackViewManager.getType() == FloatingBackViewManager.TYPE_ACTIVITY
|
||||
) {
|
||||
FloatingBackViewManager.disableBackView()
|
||||
@ -55,9 +55,15 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
|
||||
DarkModeSwitchHelper.showDarkModeSwitchFloatingView(activity)
|
||||
}
|
||||
|
||||
if (activity is AppCompatActivity && activity !is SplashScreenActivity) {
|
||||
if (activity is AppCompatActivity
|
||||
&& activity !is SplashScreenActivity
|
||||
&& activity !is SkipActivity
|
||||
&& activity !is AuthorizationActivity
|
||||
) {
|
||||
VHelper.showFeedbackDialogIfLastSuccessfulLaunchedGameExitUnexpectedly(activity)
|
||||
}
|
||||
|
||||
XapkInstaller.updateCurrentInstallStatus()
|
||||
}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
package com.gh.base
|
||||
|
||||
import android.app.Activity
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
object GlobalActivityManager {
|
||||
private var mCurrentActivityWeakRef: WeakReference<Activity>? = null
|
||||
|
||||
var currentActivity: Activity?
|
||||
get() = mCurrentActivityWeakRef?.get()
|
||||
set(activity) {
|
||||
mCurrentActivityWeakRef = WeakReference<Activity>(activity)
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.download.DownloadManager
|
||||
@ -32,10 +33,13 @@ import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.energy.EnergyBridge
|
||||
import com.gh.gamecenter.entity.SensorsEvent
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.eventbus.EBPackage
|
||||
import com.gh.gamecenter.feature.entity.Badge
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.login.user.LoginTag
|
||||
import com.gh.gamecenter.login.user.UserManager
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
@ -50,21 +54,31 @@ import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus.*
|
||||
import com.lightgame.utils.Utils
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import org.json.JSONObject
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.*
|
||||
|
||||
class DefaultJsApi(var context: Context, val entrance: String = "", private var mFragment: Fragment? = null) {
|
||||
class DefaultJsApi(
|
||||
var context: Context,
|
||||
val entrance: String = "",
|
||||
private var mFragment: Fragment? = null,
|
||||
private var mBbsId: String? = "",
|
||||
) {
|
||||
|
||||
private var mLoginHandler: CompletionHandler<Any>? = null
|
||||
private var mDownloadWatcher: DataWatcher? = null
|
||||
private var mDownloadUrlSet: HashSet<String>? = null
|
||||
private var mDownloadHandler: CompletionHandler<Any>? = null
|
||||
private var mDownloadWatcher: DataWatcher? = null // 下载观察者
|
||||
private var mDownloadUrlSet: HashSet<String>? = null // 下载的 url 集合
|
||||
private var mDownloadHandler: CompletionHandler<Any>? = null // 下载信息回调
|
||||
private var mExposureEvent: ExposureEvent? = null // 活动曝光实体
|
||||
|
||||
init {
|
||||
if (mFragment != null) {
|
||||
EventBus.getDefault().register(this)
|
||||
autoUnregisterDownloadObserverIfNeeded(mFragment)
|
||||
}
|
||||
}
|
||||
@ -84,6 +98,19 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
// do nothing, mta is deprecated
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun logSensorsEvent(event: Any) {
|
||||
val sensorsEvent = event.toString().toObject() ?: SensorsEvent()
|
||||
val trackEvent = JSONObject()
|
||||
tryCatchInRelease {
|
||||
sensorsEvent.kv.split(",").forEach {
|
||||
val kv = it.split(":")
|
||||
trackEvent.put(kv[0], kv[1])
|
||||
}
|
||||
}
|
||||
SensorsBridge.trackEvent(sensorsEvent.name, trackEvent)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getUserInfo(msg: Any): String {
|
||||
return UserManager.getInstance().userInfoEntity?.toJson() ?: ""
|
||||
@ -146,7 +173,6 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
|
||||
WechatBindHelper.bindWechat(wechatLoginInfoMap, object : BiCallback<Boolean, Boolean> {
|
||||
override fun onFirst(first: Boolean) {
|
||||
EnergyBridge.postEnergyTask("bind_wechat")
|
||||
handler.complete(true)
|
||||
}
|
||||
|
||||
@ -187,11 +213,11 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
runOnUiThread {
|
||||
// 若畅玩列表中安装了,优先启动畅玩游戏
|
||||
if (VHelper.isInstalled(packageName)) {
|
||||
if (!VHelper.showDialogIfVSpaceIsNeeded(context)) {
|
||||
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "", "", "")) {
|
||||
VHelper.launch(context, packageName)
|
||||
}
|
||||
} else {
|
||||
PackageUtils.launchApplicationByPackageName(context, packageName)
|
||||
PackageLauncher.launchApp(context, packageName = packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,6 +267,24 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为论坛详情的专区
|
||||
*/
|
||||
@JavascriptInterface
|
||||
fun isForumZone(msg: Any): Boolean {
|
||||
return !mBbsId.isNullOrEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开论坛搜索页
|
||||
*/
|
||||
@JavascriptInterface
|
||||
fun openForumSearch(msg: Any) {
|
||||
runOnUiThread {
|
||||
DirectUtils.directToForumOrUserSearch(context, mBbsId ?: "", entrance.ifBlank { "内部网页" })
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun exitWebView(msg: Any) {
|
||||
runOnUiThread { (context as Activity).finish() }
|
||||
@ -249,7 +293,6 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
@JavascriptInterface
|
||||
fun updateRegulationTestStatus(msg: Any) {
|
||||
if (msg.toString().toLowerCase(Locale.getDefault()) == "pass") {
|
||||
EnergyBridge.postEnergyTask("finish_etiquette_exam")
|
||||
SPUtils.setString(Constants.SP_REGULATION_TEST_PASS_STATUS, "pass")
|
||||
}
|
||||
}
|
||||
@ -325,17 +368,17 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
|
||||
@JavascriptInterface
|
||||
fun postWearBadgeTask(msg: Any) {
|
||||
EnergyBridge.postEnergyTask("wear_badge")
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun startEnergyCenter(msg: Any) {
|
||||
context.startActivity(EnergyBridge.getEnergyCenterIntent(context))
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun startEnergyHouse(msg: Any) {
|
||||
context.startActivity(EnergyBridge.getEnergyHouseIntent(context, null))
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -585,6 +628,26 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun logExposure(event: Any) {
|
||||
val simpleExposureEvent = event.toString().toObject() ?: SimpleExposureEvent()
|
||||
if (simpleExposureEvent.id.isNotEmpty()) {
|
||||
val exposureSource = ExposureSource("游戏活动", "${simpleExposureEvent.title}+${simpleExposureEvent.id}")
|
||||
mExposureEvent = ExposureEvent.createEvent(
|
||||
gameEntity = null,
|
||||
source = arrayListOf(exposureSource),
|
||||
)
|
||||
ExposureManager.log(mExposureEvent!!)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ExposureEvent,可能为空
|
||||
*/
|
||||
fun getExposureEvent(): ExposureEvent? {
|
||||
return mExposureEvent
|
||||
}
|
||||
|
||||
private fun autoUnregisterDownloadObserverIfNeeded(fragment: Fragment?) {
|
||||
fragment?.parentFragmentManager?.registerFragmentLifecycleCallbacks(
|
||||
object : FragmentManager.FragmentLifecycleCallbacks() {
|
||||
@ -596,6 +659,8 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
if (mDownloadWatcher != null) {
|
||||
DownloadManager.getInstance().removeObserver(mDownloadWatcher)
|
||||
}
|
||||
|
||||
EventBus.getDefault().unregister(this@DefaultJsApi)
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,6 +683,14 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(status: EBDownloadStatus) {
|
||||
// 将下载任务删除事件回调给网页
|
||||
if (mDownloadHandler != null && "delete" == status.status) {
|
||||
mDownloadHandler?.setProgressData(SimpleDownloadEntity(status.url, 0F, "UNKNOWN").toJson())
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
internal class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
|
||||
|
||||
@ -627,6 +700,9 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
|
||||
@Keep
|
||||
internal class TextShareEvent(var text: String = "", var type: String = "")
|
||||
|
||||
@Keep
|
||||
internal class SimpleExposureEvent(var title: String = "", var id: String = "")
|
||||
|
||||
@Keep
|
||||
internal class InviteFriendsEvent(
|
||||
var type: String = "",
|
||||
|
||||
@ -5,9 +5,8 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.util.Base64
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.DirectUtils.directToFeedback
|
||||
import com.gh.common.util.DirectUtils.directToGameDetailVideoStreaming
|
||||
import com.gh.common.util.DirectUtils.directToGameServerCalendar
|
||||
@ -15,22 +14,31 @@ import com.gh.common.util.DirectUtils.directToGameVideo
|
||||
import com.gh.common.util.DirectUtils.directToLegacyVideoDetail
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.DirectUtils.directToQa
|
||||
import com.gh.gamecenter.*
|
||||
import com.gh.gamecenter.core.utils.GsonUtils.gson
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.LibaoDetailActivity
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.NewsDetailActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.EnvHelper
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.GsonUtils.gson
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.entity.ActivityLabelEntity
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.entity.VideoLinkEntity
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity
|
||||
import com.gh.gamecenter.qa.BbsType
|
||||
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
|
||||
@ -44,14 +52,21 @@ object DefaultUrlHandler {
|
||||
|
||||
@JvmStatic
|
||||
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
|
||||
return interceptUrl(context, url, entrance, false)
|
||||
return interceptUrl(context, url, null, entrance, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并拦截部分内部处理的 url
|
||||
* @param traceEvent 供一些页面用于登记曝光来源的实体
|
||||
* @param bringAppToFront 是否需要在不匹配 host 的时候把 APP 调回到前台 (如微信调起)
|
||||
*
|
||||
* @return 是否已拦截处理
|
||||
*/
|
||||
@JvmStatic
|
||||
fun interceptUrl(context: Context, url: String, entrance: String, bringAppToFront: Boolean = false): Boolean {
|
||||
fun interceptUrl(context: Context, url: String,
|
||||
traceEvent: ExposureEvent? = null,
|
||||
entrance: String,
|
||||
bringAppToFront: Boolean = false): Boolean {
|
||||
val uri = Uri.parse(url)
|
||||
if ("ghzhushou" == uri.scheme) {
|
||||
Utils.log("url = $url")
|
||||
@ -75,6 +90,7 @@ object DefaultUrlHandler {
|
||||
id = id,
|
||||
tab = uri.getQueryParameter("to"),
|
||||
autoDownload = uri.getQueryParameter("auto_download") == "true",
|
||||
traceEvent = traceEvent,
|
||||
entrance = entrance
|
||||
)
|
||||
|
||||
@ -83,6 +99,7 @@ object DefaultUrlHandler {
|
||||
id,
|
||||
uri.getQueryParameter("name"),
|
||||
false,
|
||||
null,
|
||||
entrance
|
||||
)
|
||||
|
||||
@ -401,10 +418,11 @@ object DefaultUrlHandler {
|
||||
val packageMd5 = uri.getQueryParameter(EntranceConsts.KEY_PACKAGE_MD5)
|
||||
val isQaFeedback = uri.getQueryParameter(EntranceConsts.KEY_IS_QA_FEEDBACK) == "true"
|
||||
val content = if (TextUtils.isEmpty(gameId) || TextUtils.isEmpty(packageMd5)) String.format(
|
||||
"%s-%s-V%s,",
|
||||
"%s—V%s—%s(V%s),",
|
||||
uri.getQueryParameter(EntranceConsts.KEY_GAME_NAME),
|
||||
uri.getQueryParameter(EntranceConsts.KEY_VERSION),
|
||||
if (TextUtils.isEmpty(platformName)) platform else platformName,
|
||||
uri.getQueryParameter(EntranceConsts.KEY_VERSION)
|
||||
uri.getQueryParameter(EntranceConsts.KEY_PLATFORM_VERSION),
|
||||
) else String.format(
|
||||
"%s-%s-V%s\n游戏ID:%s\n游戏包MD5:%s\n",
|
||||
uri.getQueryParameter(EntranceConsts.KEY_GAME_NAME),
|
||||
@ -459,7 +477,7 @@ object DefaultUrlHandler {
|
||||
}
|
||||
|
||||
EntranceConsts.HOST_GAME_COLLECTION_DETAIL -> {
|
||||
DirectUtils.directToGameCollectionDetail(context, id, entrance)
|
||||
DirectUtils.directToGameCollectionDetail(context, id, entrance, traceEvent = traceEvent)
|
||||
}
|
||||
|
||||
EntranceConsts.HOST_GAME_COLLECTION_SQUARE -> {
|
||||
|
||||
@ -18,10 +18,10 @@ import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
object FixedRateJobHelper {
|
||||
private const val CHECKER_PERIOD: Long = 15 * 1000L
|
||||
private const val TIME_PERIOD: Long = 600 * 1000L
|
||||
private const val LOGHUB_PERIOD: Long = 120 * 1000L
|
||||
private const val EXPOSURE_PERIOD: Long = 300 * 1000L
|
||||
private const val REGION_SETTING_PERIOD: Long = 30 * 1000L
|
||||
private const val TIME_PERIOD: Long = 10 * 60 * 1000L
|
||||
private const val LOGHUB_PERIOD: Long = 2 * 60 * 1000L
|
||||
private const val EXPOSURE_PERIOD: Long = 1 * 60 * 1000L
|
||||
private const val REGION_SETTING_PERIOD: Long = 60 * 1000L
|
||||
private const val VIDEO_RECORD_PERIOD: Long = 60 * 1000L
|
||||
|
||||
private const val DOWNLOAD_HEARTBEAT_PERIOD: Long = 60 * 1000L
|
||||
@ -35,9 +35,11 @@ object FixedRateJobHelper {
|
||||
@JvmStatic
|
||||
fun begin() {
|
||||
doOnMainProcessOnly {
|
||||
// 时间检查,每15秒检查一次
|
||||
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
|
||||
val elapsedTime = mExecuteCount * CHECKER_PERIOD
|
||||
// 时间校对,10分钟一次
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % TIME_PERIOD == 0L) {
|
||||
if (elapsedTime % TIME_PERIOD == 0L) {
|
||||
RetrofitManager.getInstance().api.time
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Response<TimeEntity>() {
|
||||
@ -51,14 +53,12 @@ object FixedRateJobHelper {
|
||||
}
|
||||
|
||||
// 提交曝光数据
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % EXPOSURE_PERIOD == 0L) {
|
||||
runOnUiThread {
|
||||
ExposureManager.commitSavedExposureEvents(true)
|
||||
}
|
||||
if (elapsedTime % EXPOSURE_PERIOD == 0L) {
|
||||
ExposureManager.commitSavedExposureEvents(true)
|
||||
}
|
||||
|
||||
// 分片检测下载进度
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
|
||||
if (elapsedTime % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
|
||||
tryCatchInRelease {
|
||||
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
|
||||
DownloadDataHelper.uploadDownloadHeartbeat(upload)
|
||||
@ -66,30 +66,29 @@ object FixedRateJobHelper {
|
||||
}
|
||||
|
||||
// 提交普通 loghub 数据
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % LOGHUB_PERIOD == 0L) {
|
||||
if (elapsedTime % LOGHUB_PERIOD == 0L) {
|
||||
runOnUiThread {
|
||||
LoghubUtils.commitSavedLoghubEvents(true)
|
||||
}
|
||||
}
|
||||
|
||||
// 更新游戏屏蔽信息
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % REGION_SETTING_PERIOD == 0L) {
|
||||
if (elapsedTime % REGION_SETTING_PERIOD == 0L) {
|
||||
if (HaloApp.getInstance().isRunningForeground) {
|
||||
RegionSettingHelper.getRegionSetting()
|
||||
}
|
||||
}
|
||||
|
||||
// 提交视频浏览记录数据
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % VIDEO_RECORD_PERIOD == 0L) {
|
||||
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
|
||||
VideoRecordUtils.commitVideoRecord()
|
||||
}
|
||||
|
||||
// 获取启动广告
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % STARTUP_AD == 0L) {
|
||||
// 获取启动广告 (第一次不需要获取)
|
||||
if (elapsedTime % STARTUP_AD == 0L && mExecuteCount != 0) {
|
||||
AdHelper.getSettingAdCache()
|
||||
}
|
||||
|
||||
// ExposureUtils.logADownloadCompleteExposureEvent(GameEntity(id = mExecuteCount.toString(), name = "测试曝光上传"), platform = "", trace = null, downloadType = ExposureUtils.DownloadType.DOWNLOAD)
|
||||
mExecuteCount++
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
@ -8,14 +9,15 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
class BrowserInstallHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
BrowserInstallHelper.showBrowserInstallHintDialog(context, gameEntity.isVGame(), object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
BrowserInstallHelper.showBrowserInstallHintDialog(
|
||||
context,
|
||||
gameEntity.isVGame() || gameEntity.isSplitXApk()
|
||||
) {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@ class CheckDownloadHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(context: Context, gameEntity: GameEntity) {
|
||||
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
|
||||
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
||||
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package com.gh.common.chain
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
|
||||
class UnsupportedFeatureHandler : ChainHandler() {
|
||||
|
||||
override fun handleRequest(
|
||||
context: Context, gameEntity: GameEntity
|
||||
) {
|
||||
if (shouldShowUnsupportedFeatureDialog()) {
|
||||
DialogHelper.showUnsupportedFeatureDialog(context)
|
||||
} else {
|
||||
if (hasNext()) {
|
||||
getNext()?.handleRequest(context, gameEntity)
|
||||
} else {
|
||||
processEndCallback?.invoke(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO 检查某个版本是否支持指定的功能
|
||||
*/
|
||||
private fun shouldShowUnsupportedFeatureDialog(): Boolean = false
|
||||
}
|
||||
@ -21,6 +21,7 @@ import com.gh.gamecenter.common.utils.DarkModeUtils;
|
||||
import com.gh.gamecenter.common.utils.EnvHelper;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
import com.gh.gamecenter.core.utils.SPUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.entity.GameGuidePopupEntity;
|
||||
import com.gh.gamecenter.entity.NewApiSettingsEntity;
|
||||
import com.gh.gamecenter.entity.NewSettingsEntity;
|
||||
@ -76,8 +77,6 @@ public class Config {
|
||||
|
||||
public static final String FIX_DOWNLOAD_KEY = "isFixDownload";
|
||||
public static final String FIX_PLUGIN_KEY = "isFixPlugin";
|
||||
public static final String FIX_ARTICLE_KEY = "isFixArticle";
|
||||
public static final String FIX_COMMUNITY_KEY = "isFixCommunity";
|
||||
|
||||
public static final int VIDEO_PAGE_SIZE = 21; // 视频列表大多都是一行3个
|
||||
|
||||
@ -124,17 +123,18 @@ public class Config {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否启用畅玩游戏
|
||||
* VPN 开关选项是否开启
|
||||
*/
|
||||
public static boolean isVGameEnabled() {
|
||||
if (getSettings() == null) {
|
||||
public static boolean isVpnOptionEnabled() {
|
||||
if (mNewApiSettingsEntity == null
|
||||
|| mNewApiSettingsEntity.getInstall() == null
|
||||
|| mNewApiSettingsEntity.getInstall().getVpnRequired() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !"off".equals(getSettings().getGameSmooth());
|
||||
return mNewApiSettingsEntity.getInstall().getVpnRequired().getShouldShowVpnOption();
|
||||
}
|
||||
|
||||
|
||||
public static boolean isShowPlugin(String gameId) {
|
||||
SharedPreferences preferences = getPreferences();
|
||||
boolean isFixPlugin = preferences.getBoolean(FIX_PLUGIN_KEY, false);
|
||||
@ -205,9 +205,6 @@ public class Config {
|
||||
|
||||
// 加载完设置后刷新下
|
||||
PackageHelper.initList();
|
||||
|
||||
// 初始化畅玩相关的东西
|
||||
VHelper.init(HaloApp.getInstance(), false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -218,6 +215,8 @@ public class Config {
|
||||
if (!TextUtils.isEmpty(json)) {
|
||||
mSettingsEntity = GsonUtils.fromJson(json, SettingsEntity.class);
|
||||
}
|
||||
|
||||
mSettingsEntity.setGameSmooth("off");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -306,6 +305,26 @@ public class Config {
|
||||
return mVSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求网络数据,尝试刷新畅玩相关配置
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
public static void refreshVSettingEntity() {
|
||||
RetrofitManager.getInstance()
|
||||
.getVApi().getSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new BiResponse<VSetting>() {
|
||||
@Override
|
||||
public void onSuccess(VSetting data) {
|
||||
mVSetting = data;
|
||||
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
|
||||
|
||||
VHelper.init(HaloApp.getInstance());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GameGuidePopupEntity getGameGuidePopupEntity() {
|
||||
return mGameGuidePopupEntity;
|
||||
@ -343,6 +362,10 @@ public class Config {
|
||||
@SuppressLint("CheckResult")
|
||||
public static void getGhzsSettings() {
|
||||
String channel = HaloApp.getInstance().getChannel();
|
||||
|
||||
// 把请求提前,避免请求过多阻塞,首页显示广告时老是用到上一次的缓存
|
||||
getNewSettings(channel);
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.getApi().getSettings(PackageUtils.getGhVersionName(), channel)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@ -379,39 +402,7 @@ public class Config {
|
||||
}
|
||||
});
|
||||
|
||||
if (mVSetting == null) {
|
||||
RetrofitManager.getInstance()
|
||||
.getVApi().getSettings(BuildConfig.VERSION_NAME)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(new BiResponse<VSetting>() {
|
||||
@Override
|
||||
public void onSuccess(VSetting data) {
|
||||
mVSetting = data;
|
||||
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mNewApiSettingsEntity == null) {
|
||||
RetrofitManager.getInstance()
|
||||
.getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new BiResponse<NewApiSettingsEntity>() {
|
||||
@Override
|
||||
public void onSuccess(NewApiSettingsEntity data) {
|
||||
mNewApiSettingsEntity = data;
|
||||
mNightModeSetting = data.getNightMode();
|
||||
mNewSimulatorEntity = data.getSimulator();
|
||||
if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
|
||||
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
|
||||
DarkModeUtils.INSTANCE.initDarkMode();
|
||||
}
|
||||
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
|
||||
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
refreshVSettingEntity();
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
|
||||
@ -444,4 +435,34 @@ public class Config {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private static void getNewSettings(String channel) {
|
||||
if (mNewApiSettingsEntity == null) {
|
||||
|
||||
String filterString = UrlFilterUtils.getFilterQuery(
|
||||
"manufacturer", Build.MANUFACTURER,
|
||||
"model", Build.MODEL,
|
||||
"android_sdk_version", String.valueOf(Build.VERSION.SDK_INT));
|
||||
|
||||
RetrofitManager.getInstance()
|
||||
.getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel, filterString)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new BiResponse<NewApiSettingsEntity>() {
|
||||
@Override
|
||||
public void onSuccess(NewApiSettingsEntity data) {
|
||||
mNewApiSettingsEntity = data;
|
||||
mNightModeSetting = data.getNightMode();
|
||||
mNewSimulatorEntity = data.getSimulator();
|
||||
if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
|
||||
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
|
||||
DarkModeUtils.INSTANCE.initDarkMode();
|
||||
}
|
||||
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
|
||||
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.databind;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
@ -24,14 +25,15 @@ import com.gh.common.chain.CertificationHandler;
|
||||
import com.gh.common.chain.ChainBuilder;
|
||||
import com.gh.common.chain.ChainHandler;
|
||||
import com.gh.common.chain.CheckDownloadHandler;
|
||||
import com.gh.common.chain.CheckStoragePermissionHandler;
|
||||
import com.gh.common.chain.DownloadDialogHelperHandler;
|
||||
import com.gh.common.chain.GamePermissionHandler;
|
||||
import com.gh.common.chain.OverseaDownloadHandler;
|
||||
import com.gh.common.chain.PackageCheckHandler;
|
||||
import com.gh.common.chain.UnsupportedFeatureHandler;
|
||||
import com.gh.common.chain.ValidateVSpaceHandler;
|
||||
import com.gh.common.chain.VersionNumberHandler;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent;
|
||||
import com.gh.common.filter.RegionSetting;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
@ -45,38 +47,41 @@ import com.gh.common.util.GameViewUtils;
|
||||
import com.gh.common.util.LogUtils;
|
||||
import com.gh.common.util.NewsUtils;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.PackageLauncher;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils;
|
||||
import com.gh.common.util.ReservationHelper;
|
||||
import com.gh.gamecenter.feature.view.DownloadButton;
|
||||
import com.gh.gamecenter.feature.view.GameIconView;
|
||||
import com.gh.gamecenter.common.view.NoEllipsizeSpaceTextView;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.download.server.BrowserInstallHelper;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
import com.gh.gamecenter.common.baselist.LoadStatus;
|
||||
import com.gh.gamecenter.common.callback.OnViewClickListener;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.common.utils.DarkModeUtils;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.DarkModeUtils;
|
||||
import com.gh.gamecenter.common.view.DrawableView;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.core.utils.NumberUtils;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation;
|
||||
import com.gh.gamecenter.feature.entity.ServerCalendarEntity;
|
||||
import com.gh.gamecenter.feature.entity.TagStyleEntity;
|
||||
import com.gh.gamecenter.feature.entity.TestEntity;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent;
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils;
|
||||
import com.gh.gamecenter.feature.view.DownloadButton;
|
||||
import com.gh.gamecenter.feature.view.GameIconView;
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
|
||||
import com.gh.vspace.VDownloadManagerActivity;
|
||||
import com.gh.vspace.VHelper;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
@ -398,8 +403,10 @@ public class BindingAdapters {
|
||||
}
|
||||
|
||||
ChainBuilder builder = new ChainBuilder();
|
||||
builder.addHandler(new ValidateVSpaceHandler());
|
||||
builder.addHandler(new UnsupportedFeatureHandler());
|
||||
builder.addHandler(new GamePermissionHandler());
|
||||
builder.addHandler(new CheckStoragePermissionHandler());
|
||||
builder.addHandler(new ValidateVSpaceHandler());
|
||||
builder.addHandler(new BrowserInstallHandler());
|
||||
builder.addHandler(new PackageCheckHandler());
|
||||
builder.addHandler(new DownloadDialogHelperHandler());
|
||||
@ -409,7 +416,7 @@ public class BindingAdapters {
|
||||
builder.addHandler(new CheckDownloadHandler());
|
||||
|
||||
builder.setProcessEndCallback(o -> {
|
||||
download(progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
|
||||
download(v.getContext(), progressBar, gameEntity, traceEvent, (boolean) o, entrance, location);
|
||||
return null;
|
||||
});
|
||||
final ChainHandler chainHandler = builder.buildHandlerChain();
|
||||
@ -418,6 +425,7 @@ public class BindingAdapters {
|
||||
}
|
||||
} else {
|
||||
ChainBuilder builder = new ChainBuilder();
|
||||
builder.addHandler(new UnsupportedFeatureHandler());
|
||||
builder.addHandler(new GamePermissionHandler());
|
||||
builder.addHandler(new CertificationHandler());
|
||||
builder.addHandler(new VersionNumberHandler());
|
||||
@ -446,7 +454,7 @@ public class BindingAdapters {
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
download(v.getContext(), progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -456,11 +464,11 @@ public class BindingAdapters {
|
||||
}
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
VHelper.installOrLaunch((AppCompatActivity) v.getContext(), gameEntity, null);
|
||||
return;
|
||||
}
|
||||
|
||||
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
PackageLauncher.launchApp(v.getContext(), gameEntity, gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
@ -474,10 +482,9 @@ public class BindingAdapters {
|
||||
case INSTALL_NORMAL:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity);
|
||||
String packageName = gameEntity.getApk().get(0).getPackageName();
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch(v.getContext(), packageName);
|
||||
VHelper.installOrLaunch(v.getContext(), gameEntity, null);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -489,7 +496,7 @@ public class BindingAdapters {
|
||||
case RESERVABLE:
|
||||
GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> {
|
||||
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
|
||||
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), () -> {
|
||||
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), gameEntity.getName(), () -> {
|
||||
LogUtils.logReservation(gameEntity, traceEvent);
|
||||
updateReservation(progressBar, gameEntity);
|
||||
});
|
||||
@ -594,9 +601,11 @@ public class BindingAdapters {
|
||||
case pause:
|
||||
case timeout:
|
||||
case neterror:
|
||||
case diskisfull:
|
||||
case diskioerror:
|
||||
case waiting:
|
||||
progressBar.setText(R.string.downloading);
|
||||
if (downloadEntity.isPluggable() && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN);
|
||||
} else {
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
|
||||
@ -605,7 +614,7 @@ public class BindingAdapters {
|
||||
case done:
|
||||
progressBar.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_PLUGIN);
|
||||
} else {
|
||||
progressBar.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
|
||||
@ -671,12 +680,16 @@ public class BindingAdapters {
|
||||
|
||||
|
||||
// 开始下载
|
||||
private static void download(DownloadButton progressBar,
|
||||
private static void download(Context context,
|
||||
DownloadButton progressBar,
|
||||
GameEntity gameEntity,
|
||||
ExposureEvent traceEvent,
|
||||
boolean isSubscribe,
|
||||
String entrance,
|
||||
String location) {
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
|
||||
}
|
||||
String str = progressBar.getText().toString();
|
||||
String method;
|
||||
if (str.contains("更新")) {
|
||||
@ -785,7 +798,7 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setGameName(NoEllipsizeSpaceTextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
|
||||
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
|
||||
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
|
||||
String gameName;
|
||||
if (isShowPlatform && game.getApk().size() > 0) {
|
||||
|
||||
@ -22,6 +22,7 @@ import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.ShellActivity
|
||||
import com.gh.gamecenter.common.callback.ConfirmListener
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.feature.entity.AuthDialogEntity
|
||||
@ -35,7 +36,7 @@ import com.lightgame.utils.AppManager
|
||||
class CertificationDialog(
|
||||
context: Context,
|
||||
private val authDialogEntity: AuthDialogEntity,
|
||||
val gameId: String,
|
||||
val gameEntity: GameEntity,
|
||||
val listener: ConfirmListener
|
||||
) :
|
||||
Dialog(context, R.style.GhAlertDialog) {
|
||||
@ -69,9 +70,11 @@ class CertificationDialog(
|
||||
actionRightTv.text = "去实名认证"
|
||||
noRemindAgainCb.visibility = View.GONE
|
||||
actionLeftTv.setOnClickListener {
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
|
||||
dismiss()
|
||||
}
|
||||
actionRightTv.setOnClickListener {
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
gotoAuthPage()
|
||||
} else {
|
||||
@ -84,6 +87,7 @@ class CertificationDialog(
|
||||
actionRightTv.text = "继续下载"
|
||||
noRemindAgainCb.visibility = View.GONE
|
||||
actionLeftTv.setOnClickListener {
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
gotoAuthPage()
|
||||
} else {
|
||||
@ -91,6 +95,7 @@ class CertificationDialog(
|
||||
}
|
||||
}
|
||||
actionRightTv.setOnClickListener {
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
|
||||
listener.onConfirm()
|
||||
dismiss()
|
||||
}
|
||||
@ -100,8 +105,9 @@ class CertificationDialog(
|
||||
actionRightTv.text = "继续下载"
|
||||
noRemindAgainCb.visibility = View.VISIBLE
|
||||
actionLeftTv.setOnClickListener {
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
|
||||
if (noRemindAgainCb.isChecked) {
|
||||
SPUtils.setBoolean(gameId, true)
|
||||
SPUtils.setBoolean(gameEntity.id, true)
|
||||
}
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
gotoAuthPage()
|
||||
@ -110,14 +116,25 @@ class CertificationDialog(
|
||||
}
|
||||
}
|
||||
actionRightTv.setOnClickListener {
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
|
||||
if (noRemindAgainCb.isChecked) {
|
||||
SPUtils.getBoolean(gameId, true)
|
||||
SPUtils.getBoolean(gameEntity.id, true)
|
||||
}
|
||||
listener.onConfirm()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SensorsBridge.trackEvent(
|
||||
"VerificationDialogShow",
|
||||
"game_id",
|
||||
gameEntity.id,
|
||||
"game_name",
|
||||
gameEntity.name ?: "",
|
||||
"game_type",
|
||||
gameEntity.categoryChinese
|
||||
)
|
||||
}
|
||||
|
||||
//跳转登录页面
|
||||
@ -145,7 +162,7 @@ class CertificationDialog(
|
||||
context,
|
||||
ShellActivity.Type.REAL_NAME_INFO,
|
||||
).apply {
|
||||
putExtra(EntranceConsts.KEY_GAME_ID, gameId)
|
||||
putExtra(EntranceConsts.KEY_GAME_ID, gameEntity.id)
|
||||
}, object : Callback {
|
||||
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
@ -194,7 +211,7 @@ class CertificationDialog(
|
||||
}
|
||||
val isCloseAuthDialog = SPUtils.getBoolean(game.id, false)
|
||||
if (authDialog != null && (authDialog.level != AuthDialogLevel.OPTIONAL_HINT.value || !isCloseAuthDialog)) {
|
||||
val dialog = CertificationDialog(context, authDialog, game.id, listener)
|
||||
val dialog = CertificationDialog(context, authDialog, game, listener)
|
||||
dialog.show()
|
||||
} else {
|
||||
listener.onConfirm()
|
||||
|
||||
@ -13,6 +13,7 @@ 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.NewFlatLogUtils
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
|
||||
@ -31,6 +32,8 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
|
||||
lateinit var mView: View
|
||||
var isXapk = false
|
||||
var url: String = ""
|
||||
var gameId: String = ""
|
||||
var gameName: String = ""
|
||||
var mCallBack: ((isFromPermissionGrantedCallback: Boolean) -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
@ -50,6 +53,8 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
|
||||
switchLottie.setAnimation("lottie/install_permission_switch.json")
|
||||
switchLottie.playAnimation()
|
||||
|
||||
if (isXapk) NewFlatLogUtils.logXApkInstallPermissionDialogShowed(gameId, gameName)
|
||||
|
||||
val randomNumber = if (isXapk) 1 else Random.nextInt(2)
|
||||
closeTv.goneIf(randomNumber == 0)
|
||||
closeIv.goneIf(randomNumber != 0)
|
||||
@ -60,14 +65,17 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
|
||||
|
||||
closeTv.setOnClickListener {
|
||||
if (isXapk) {
|
||||
NewFlatLogUtils.logXApkInstallPermissionDialogClick("尝试解压", false, gameId, gameName)
|
||||
mCallBack?.invoke(false)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
closeIv.setOnClickListener {
|
||||
if (isXapk) NewFlatLogUtils.logXApkInstallPermissionDialogClick("关闭", false, gameId, gameName)
|
||||
dismiss()
|
||||
}
|
||||
activateTv.setOnClickListener {
|
||||
NewFlatLogUtils.logXApkInstallPermissionDialogClick("立即开启", false, gameId, gameName)
|
||||
PermissionHelper.toInstallPermissionSetting(requireActivity())
|
||||
if (isXapk) {
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, requireActivity().javaClass.name)
|
||||
@ -79,6 +87,8 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISSION_CODE) {
|
||||
NewFlatLogUtils.logXApkInstallPermissionDialogClick("立即开启", true, gameId, gameName)
|
||||
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, "")
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, "")
|
||||
@ -124,6 +134,8 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
|
||||
installPermissionDialogFragment.mCallBack = callBack
|
||||
installPermissionDialogFragment.isXapk = isXapk
|
||||
installPermissionDialogFragment.url = downloadEntity.url
|
||||
installPermissionDialogFragment.gameId = downloadEntity.gameId
|
||||
installPermissionDialogFragment.gameName = downloadEntity.name
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(installPermissionDialogFragment)
|
||||
transaction.commit()
|
||||
@ -132,6 +144,8 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
|
||||
this.mCallBack = callBack
|
||||
this.isXapk = isXapk
|
||||
this.url = downloadEntity.url
|
||||
this.gameId = downloadEntity.gameId
|
||||
this.gameName = downloadEntity.name
|
||||
}
|
||||
installPermissionDialogFragment.show(
|
||||
activity.supportFragmentManager,
|
||||
|
||||
@ -4,6 +4,8 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.LayoutManager
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import io.reactivex.functions.Consumer
|
||||
|
||||
@ -18,7 +20,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
Consumer(Throwable::printStackTrace)
|
||||
)
|
||||
}
|
||||
var layoutManager: LinearLayoutManager? = null
|
||||
var layoutManager: LayoutManager? = null
|
||||
var visibleState: ExposureThrottleBus.VisibleState? = null
|
||||
|
||||
init {
|
||||
@ -47,12 +49,28 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
|
||||
if (layoutManager == null) layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
layoutManager = recyclerView.layoutManager
|
||||
|
||||
layoutManager?.run {
|
||||
visibleState =
|
||||
ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
if (layoutManager != null) {
|
||||
if (layoutManager is LinearLayoutManager) {
|
||||
(layoutManager as LinearLayoutManager).run {
|
||||
visibleState =
|
||||
ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
}
|
||||
} else if (layoutManager is StaggeredGridLayoutManager) {
|
||||
(recyclerView.layoutManager as StaggeredGridLayoutManager).run {
|
||||
val firstVisibleItemArray = IntArray(2)
|
||||
val lastVisibleItemArray = IntArray(2)
|
||||
|
||||
findFirstVisibleItemPositions(firstVisibleItemArray)
|
||||
findLastVisibleItemPositions(lastVisibleItemArray)
|
||||
|
||||
visibleState =
|
||||
ExposureThrottleBus.VisibleState(firstVisibleItemArray.first(), lastVisibleItemArray.first())
|
||||
throttleBus.postVisibleState(visibleState!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.common.loghub.LoghubHelper
|
||||
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
|
||||
import com.gh.gamecenter.common.utils.toJson
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
@ -30,19 +31,7 @@ object ExposureManager {
|
||||
* Log a single exposure event.
|
||||
*/
|
||||
fun log(event: ExposureEvent) {
|
||||
if (!exposureCache.contains(event.id)) {
|
||||
exposureSet.add(event)
|
||||
exposureCache.add(event.id)
|
||||
} else {
|
||||
Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a collection of exposure event.
|
||||
*/
|
||||
fun log(eventList: List<ExposureEvent>) {
|
||||
for (event in eventList) {
|
||||
AppExecutor.logExecutor.execute {
|
||||
if (!exposureCache.contains(event.id)) {
|
||||
exposureSet.add(event)
|
||||
exposureCache.add(event.id)
|
||||
@ -50,29 +39,47 @@ object ExposureManager {
|
||||
Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})")
|
||||
}
|
||||
}
|
||||
commitSavedExposureEvents()
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a collection of exposure event.
|
||||
*/
|
||||
fun log(eventList: List<ExposureEvent>) {
|
||||
AppExecutor.logExecutor.execute {
|
||||
for (event in eventList) {
|
||||
if (event != null && !exposureCache.contains(event.id)) {
|
||||
exposureSet.add(event)
|
||||
exposureCache.add(event.id)
|
||||
} else {
|
||||
Utils.log("Exposure", "遇到重复曝光事件,自动过滤 (${event.id} - ${event.payload.gameName})")
|
||||
}
|
||||
}
|
||||
commitSavedExposureEvents()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param forcedUpload Ignore all restrictions.
|
||||
*/
|
||||
fun commitSavedExposureEvents(forcedUpload: Boolean = false) {
|
||||
if (exposureSet.size < STORE_SIZE && !forcedUpload || exposureSet.size == 0) return
|
||||
AppExecutor.logExecutor.execute {
|
||||
if (exposureSet.size < STORE_SIZE && !forcedUpload || exposureSet.size == 0) return@execute
|
||||
|
||||
uploadExposures(exposureSet.toList(), forcedUpload)
|
||||
uploadExposures(exposureSet, forcedUpload)
|
||||
|
||||
Utils.log("Exposure", "提交了${exposureSet.size}条曝光记录")
|
||||
exposureSet.clear()
|
||||
Utils.log("Exposure", "提交了${exposureSet.size}条曝光记录")
|
||||
exposureSet.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun eliminateMultipleBrackets(jsonWithMultipleBracket: String): String {
|
||||
return jsonWithMultipleBracket.replace("[[", "[").replace("]]", "]")
|
||||
}
|
||||
|
||||
private fun uploadExposures(eventList: List<ExposureEvent>, forced: Boolean) {
|
||||
eventList.forEach {
|
||||
private fun uploadExposures(eventSet: HashSet<ExposureEvent>, forced: Boolean) {
|
||||
eventSet.forEach {
|
||||
LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced)
|
||||
it.recycle()
|
||||
// it.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +95,6 @@ object ExposureManager {
|
||||
eliminateMultipleBrackets(event.eTrace?.toJson() ?: "")
|
||||
} else ""
|
||||
)
|
||||
logTime = event.time.toLong()
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.gh.common.exposure
|
||||
import android.text.TextUtils
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.common.util.RealNameHelper
|
||||
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
|
||||
import com.gh.gamecenter.common.utils.toObject
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity
|
||||
@ -30,6 +31,9 @@ object ExposureUtils {
|
||||
} else {
|
||||
entity.id
|
||||
}
|
||||
|
||||
traceEvent ?: gameEntity.exposureEvent
|
||||
|
||||
gameEntity.gameVersion = entity.getApk().elementAtOrNull(0)?.version
|
||||
?: gameEntity.gameVersion
|
||||
gameEntity.platform = platform
|
||||
@ -39,9 +43,12 @@ object ExposureUtils {
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
event = ExposureType.DOWNLOAD
|
||||
)
|
||||
).apply {
|
||||
this.payload.certification = RealNameHelper.getCertificationStatus()
|
||||
}
|
||||
if (!TextUtils.isEmpty(entity.id)) {
|
||||
ExposureManager.log(exposureEvent)
|
||||
ExposureManager.commitSavedExposureEvents(forcedUpload = true)
|
||||
}
|
||||
return exposureEvent
|
||||
}
|
||||
@ -75,7 +82,9 @@ object ExposureUtils {
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
event = ExposureType.DOWNLOAD_COMPLETE
|
||||
)
|
||||
).apply {
|
||||
this.payload.certification = RealNameHelper.getCertificationStatus()
|
||||
}
|
||||
exposureEvent.payload.host = host
|
||||
exposureEvent.payload.path = path
|
||||
exposureEvent.payload.speed = speed
|
||||
|
||||
@ -8,6 +8,8 @@ import com.google.gson.annotations.SerializedName
|
||||
class RegionSetting(
|
||||
@SerializedName("game_mirror")
|
||||
var mirrorGameIdSet: HashSet<String>,
|
||||
@SerializedName("game_mirror2")
|
||||
var mirrorGameIdSet2: HashSet<String>?,
|
||||
@SerializedName("game_block")
|
||||
var filterGameIdSet: HashSet<String>,
|
||||
@SerializedName("channel_control")
|
||||
|
||||
@ -18,9 +18,13 @@ import io.reactivex.schedulers.Schedulers
|
||||
|
||||
object RegionSettingHelper {
|
||||
|
||||
// 是否是初始化调用
|
||||
private var mIsInit = true
|
||||
|
||||
private var mChannelControl: RegionSetting.ChannelControl? = null
|
||||
private var mFilterGameIdSet: HashSet<String>? = hashSetOf()
|
||||
private var mDisplayMirrorIfoGameIdSet: HashSet<String>? = hashSetOf()
|
||||
private var mDisplayMirrorGameIdSet: HashSet<String>? = hashSetOf()
|
||||
private var mDisplayMirrorGameIdSet2: HashSet<String>? = hashSetOf()
|
||||
private var mGameH5DownloadList: List<RegionSetting.GameH5Download>? = listOf()
|
||||
private var mGameSpecialDownloadInfoList: List<RegionSetting.GameSpecialDownloadInfo>? = listOf()
|
||||
private var mIpInfo: IpInfo? = null
|
||||
@ -28,8 +32,23 @@ object RegionSettingHelper {
|
||||
private const val SP_SETTING = "region_setting"
|
||||
const val SP_SETTING_FAILURE = "region_setting_failure"
|
||||
|
||||
@JvmStatic
|
||||
fun shouldThisGameDisplayMirrorInfo(gameId: String): Boolean {
|
||||
return mDisplayMirrorIfoGameIdSet?.contains(gameId) ?: false
|
||||
return mDisplayMirrorGameIdSet?.contains(gameId) == true
|
||||
|| mDisplayMirrorGameIdSet2?.contains(gameId) == true
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取镜像数据的位置,是归属镜像 1 还是镜像 2
|
||||
*/
|
||||
fun getMirrorPosition(gameId: String): Int {
|
||||
return if (mDisplayMirrorGameIdSet?.contains(gameId) == true) {
|
||||
1
|
||||
} else if (mDisplayMirrorGameIdSet2?.contains(gameId) == true) {
|
||||
2
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -95,6 +114,15 @@ object RegionSettingHelper {
|
||||
@JvmStatic
|
||||
fun getRegionSetting() {
|
||||
debounceActionWithInterval(R.string.app_name, 5000) {
|
||||
|
||||
// 初始启动时先使用历史数据
|
||||
if (mIsInit) {
|
||||
SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
|
||||
updateSettingsInMemory(it)
|
||||
}
|
||||
mIsInit = false
|
||||
}
|
||||
|
||||
// 使用默认的 Schdulers.io() 可能会触发 OOM
|
||||
RetrofitManager.getInstance()
|
||||
.api
|
||||
@ -118,7 +146,8 @@ object RegionSettingHelper {
|
||||
|
||||
private fun updateSettingsInMemory(data: RegionSetting) {
|
||||
mFilterGameIdSet = data.filterGameIdSet
|
||||
mDisplayMirrorIfoGameIdSet = data.mirrorGameIdSet
|
||||
mDisplayMirrorGameIdSet = data.mirrorGameIdSet
|
||||
mDisplayMirrorGameIdSet2 = data.mirrorGameIdSet2
|
||||
mChannelControl = data.channelControl
|
||||
mGameH5DownloadList = data.gameH5DownloadList
|
||||
mGameSpecialDownloadInfoList = data.gameSpecialDownloadInfoList
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IAppProvider
|
||||
@ -69,4 +70,12 @@ class AppProviderImpl : IAppProvider {
|
||||
override fun getFlavorProvider(): IFlavorProvider {
|
||||
return HaloApp.getInstance().flavorProvider
|
||||
}
|
||||
|
||||
override fun getFlavor(): String {
|
||||
return BuildConfig.FLAVOR
|
||||
}
|
||||
|
||||
override fun getIsBrandNewInstall(): Boolean {
|
||||
return HaloApp.getInstance().isBrandNewInstall
|
||||
}
|
||||
}
|
||||
@ -2,17 +2,17 @@ package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.databind.BindingAdapters
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.view.NoEllipsizeSpaceTextView
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.provider.IBindingAdaptersProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.bindingAdapters, name = "BindingAdapters暴露服务")
|
||||
class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
|
||||
override fun setGameName(
|
||||
view: NoEllipsizeSpaceTextView,
|
||||
view: TextView,
|
||||
game: GameEntity,
|
||||
isShowPlatform: Boolean,
|
||||
isShowSuffix: Boolean
|
||||
|
||||
@ -15,7 +15,7 @@ class DefaultUrlHandlerProviderImpl : IDefaultUrlHandlerProvider {
|
||||
entrance: String,
|
||||
bringAppToFront: Boolean
|
||||
): Boolean {
|
||||
return DefaultUrlHandler.interceptUrl(context, url, entrance, bringAppToFront)
|
||||
return DefaultUrlHandler.interceptUrl(context, url, null, entrance, bringAppToFront)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
|
||||
@ -0,0 +1,119 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.provider.IDownloadButtonClickedProvider
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
@Route(path = RouteConsts.provider.downloadButtonClickedHandler, name = "DownloadButton点击事件暴露服务")
|
||||
class DownloadButtonClickedProviderImpl : IDownloadButtonClickedProvider {
|
||||
override fun onClicked(downloadButton: DownloadButton) {
|
||||
var gameId = ""
|
||||
var gameName = ""
|
||||
var gameCategory = ""
|
||||
var gameTypeInChinese = ""
|
||||
var downloadStatus = ""
|
||||
var downloadStatusInChinese = ""
|
||||
var gameSchemaType = ""
|
||||
var packageName = ""
|
||||
|
||||
val boundedObject = downloadButton.getObject()
|
||||
|
||||
Utils.log("DownloadButtonClickedProviderImpl", "$downloadButton onClicked ${boundedObject?.javaClass}")
|
||||
|
||||
if (boundedObject != null) {
|
||||
when (boundedObject) {
|
||||
is GameEntity -> {
|
||||
gameId = boundedObject.id
|
||||
gameName = boundedObject.name ?: ""
|
||||
gameCategory = boundedObject.category ?: ""
|
||||
downloadStatus = if (boundedObject.isVGame()) {
|
||||
"畅玩"
|
||||
} else if (boundedObject.downloadStatus == "demo") {
|
||||
"试玩"
|
||||
} else {
|
||||
"下载"
|
||||
}
|
||||
gameTypeInChinese = boundedObject.categoryChinese
|
||||
downloadStatusInChinese = boundedObject.downloadStatusChinese
|
||||
gameSchemaType = boundedObject.gameBitChinese
|
||||
packageName = boundedObject.getUniquePackageName() ?: ""
|
||||
}
|
||||
|
||||
is GameUpdateEntity -> {
|
||||
gameId = boundedObject.id
|
||||
gameName = boundedObject.name ?: ""
|
||||
// 下载管理-更新页面,把下载状态都置为下载
|
||||
downloadStatus = "下载"
|
||||
gameTypeInChinese = boundedObject.categoryChinese
|
||||
downloadStatusInChinese = boundedObject.downloadStatusChinese
|
||||
packageName = boundedObject.packageName
|
||||
}
|
||||
|
||||
is DownloadEntity -> {
|
||||
gameId = boundedObject.gameId
|
||||
gameName = boundedObject.name ?: ""
|
||||
gameCategory = boundedObject.getGameCategory()
|
||||
downloadStatus = if (boundedObject.isVGame()) "畅玩" else "下载"
|
||||
packageName = boundedObject.packageName
|
||||
}
|
||||
}
|
||||
|
||||
// 上报 UI 状态为启动的点击事件 (样式为启动,或者文案包含启动都算能启动)
|
||||
if (downloadButton.buttonStyle == DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
|
||||
|| downloadButton.text.contains("启动")) {
|
||||
|
||||
// boundedObject 里找不到游戏类型时,尝试从已安装列表中获取
|
||||
if (gameCategory.isEmpty() && packageName.isNotEmpty()) {
|
||||
gameCategory = PackageRepository.gameInstalled.find { it.packageName == packageName }?.category ?: ""
|
||||
}
|
||||
|
||||
NewFlatLogUtils.logGameLaunchButtonClicked(
|
||||
gameId = gameId,
|
||||
gameName = gameName,
|
||||
location = downloadButton.getWidgetBusinessName(),
|
||||
gameCategory = gameCategory,
|
||||
downloadStatus = downloadStatus
|
||||
)
|
||||
}
|
||||
|
||||
// 预约状态不上报
|
||||
if (downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVABLE
|
||||
&& downloadButton.buttonStyle != DownloadButton.ButtonStyle.RESERVED
|
||||
) {
|
||||
|
||||
// 上报神策点击事件
|
||||
SensorsBridge.trackEvent(
|
||||
"DownLoadbuttonClick",
|
||||
"game_id", gameId,
|
||||
"game_name", gameName,
|
||||
"game_type", gameTypeInChinese,
|
||||
"download_status", downloadStatusInChinese,
|
||||
"button_name", downloadButton.text,
|
||||
"game_schema_type", gameSchemaType,
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
|
||||
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
|
||||
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
|
||||
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
|
||||
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
|
||||
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,6 +5,7 @@ import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.ErrorHelper
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IErrorHelperProvider
|
||||
import com.gh.gamecenter.login.user.LoginTag
|
||||
import retrofit2.HttpException
|
||||
|
||||
@Route(path = RouteConsts.provider.errorHelper, name = "ErrorHelper暴露服务")
|
||||
@ -18,8 +19,13 @@ class ErrorHelperProviderImpl : IErrorHelperProvider {
|
||||
ErrorHelper.handleError(context, errorString, showHighPriorityHint)
|
||||
}
|
||||
|
||||
override fun handleLoginError(context: Context, httpException: HttpException?) {
|
||||
ErrorHelper.handleLoginError(context, httpException)
|
||||
override fun handleLoginError(
|
||||
context: Context,
|
||||
httpException: HttpException?,
|
||||
loginTagChinese: String,
|
||||
isCertificate: Boolean
|
||||
) {
|
||||
ErrorHelper.handleLoginError(context, httpException, loginTagChinese, isCertificate)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.provider.IExposureManagerProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.exposureManager, name = "ExposureManager暴露服务")
|
||||
class ExposureManagerProviderImpl: IExposureManagerProvider {
|
||||
override fun logExposure(exposureEvent: ExposureEvent) {
|
||||
ExposureManager.log(exposureEvent)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import android.content.Context
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.gh.common.util.FloatingBackViewManager
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.core.provider.IFloatingBackViewManagerProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.floatingBackViewManager, name = "FloatingViewBackManager暴露服务")
|
||||
class FloatingBackViewManagerProviderImpl : IFloatingBackViewManagerProvider {
|
||||
|
||||
override fun enableBackViewForTaskType() {
|
||||
FloatingBackViewManager.enableBackView(FloatingBackViewManager.TYPE_TASK)
|
||||
}
|
||||
|
||||
override fun init(context: Context?) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
@ -22,7 +22,7 @@ class GameDetailProviderImpl : IGameDetailProvider {
|
||||
context: Context,
|
||||
gameEntity: GameEntity?,
|
||||
entrance: String,
|
||||
defaultTab: Int,
|
||||
defaultTab: String,
|
||||
isSkipGameComment: Boolean,
|
||||
scrollToLibao: Boolean,
|
||||
scrollToServer: Boolean,
|
||||
|
||||
@ -7,7 +7,8 @@ import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.entity.SuggestType
|
||||
import com.gh.gamecenter.common.provider.ILinkDirectUtilsProvider
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.provider.ILinkDirectUtilsProvider
|
||||
|
||||
@Route(path = RouteConsts.provider.linkDirectUtils, name = "DirectUtils暴露服务,主要是暴露directToLinkPage方法")
|
||||
class LinkDirectUtilsProviderImpl : ILinkDirectUtilsProvider {
|
||||
@ -21,6 +22,16 @@ class LinkDirectUtilsProviderImpl : ILinkDirectUtilsProvider {
|
||||
DirectUtils.directToLinkPage(context, linkEntity, entrance, path)
|
||||
}
|
||||
|
||||
override fun directToLinkPage(
|
||||
context: Context,
|
||||
linkEntity: LinkEntity,
|
||||
entrance: String,
|
||||
path: String,
|
||||
exposureEvent: ExposureEvent?
|
||||
) {
|
||||
DirectUtils.directToLinkPage(context, linkEntity, entrance, path, exposureEvent)
|
||||
}
|
||||
|
||||
override fun directToSuggestion(context: Context, type: SuggestType, requestCode: Int?) {
|
||||
DirectUtils.directToSuggestion(context, type, requestCode)
|
||||
}
|
||||
|
||||
@ -14,6 +14,10 @@ class RegionSettingHelperProviderImpl : IRegionSettingHelperProvider {
|
||||
return RegionSettingHelper.shouldThisGameDisplayMirrorInfo(gameId)
|
||||
}
|
||||
|
||||
override fun getMirrorPosition(gameId: String): Int {
|
||||
return RegionSettingHelper.getMirrorPosition(gameId)
|
||||
}
|
||||
|
||||
override fun shouldThisGameShowSpecialDownload(gameId: String): Boolean {
|
||||
return RegionSettingHelper.shouldThisGameShowSpecialDownload(gameId)
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import com.gh.gamecenter.manager.UpdateManager
|
||||
|
||||
@Route(path = RouteConsts.provider.updateManager, name = "UpdateManager暴露服务")
|
||||
class UpdateManagerProviderImpl: IUpdateManagerProvider {
|
||||
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler) {
|
||||
override fun checkUpdate(context: Context, isAutoCheck: Boolean, handler: Handler?) {
|
||||
UpdateManager.getInstance(context).checkUpdate(isAutoCheck, handler)
|
||||
}
|
||||
|
||||
|
||||
@ -22,8 +22,12 @@ import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity
|
||||
import com.gh.gamecenter.feature.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.entity.TrackableEntity
|
||||
import com.gh.ndownload.NDataChanger
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.*
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import java.lang.ref.WeakReference
|
||||
import java.text.DecimalFormat
|
||||
@ -95,6 +99,12 @@ class SimulatorDownloadManager private constructor() {
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
}
|
||||
DownloadStatus.diskisfull == downloadEntity.status -> {
|
||||
ToastUtils.showToast("存储空间已满,下载任务已暂停")
|
||||
}
|
||||
DownloadStatus.diskioerror == downloadEntity.status -> {
|
||||
ToastUtils.showToast("下载 IO 出现异常,下载任务已暂停")
|
||||
}
|
||||
DownloadStatus.neterror == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络不稳定,下载任务已暂停")
|
||||
}
|
||||
@ -290,13 +300,17 @@ class SimulatorDownloadManager private constructor() {
|
||||
HaloApp.put(simulator.name, simulator)
|
||||
if (entity != null) {
|
||||
when (entity.status) {
|
||||
DownloadStatus.pause, DownloadStatus.subscribe,
|
||||
DownloadStatus.neterror, DownloadStatus.timeout -> {
|
||||
DownloadStatus.pause,
|
||||
DownloadStatus.subscribe,
|
||||
DownloadStatus.neterror,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.diskioerror,
|
||||
DownloadStatus.diskisfull -> {
|
||||
DownloadManager.getInstance().addObserver(dataWatcher)
|
||||
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, true) }, 200)
|
||||
downloadDialog?.show()
|
||||
}
|
||||
DownloadStatus.done -> DataChanger.notifyDataChanged(entity)
|
||||
DownloadStatus.done -> NDataChanger.notifyDataChanged(entity)
|
||||
|
||||
else -> createDownload(apkEntity, simulator)
|
||||
}
|
||||
|
||||
@ -10,15 +10,13 @@ import com.gh.download.simple.AutoUnregisteredSimpleDownloadListener
|
||||
import com.gh.download.simple.DownloadListener
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.roundTo
|
||||
import com.gh.gamecenter.common.utils.toResString
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.databinding.DialogArchiveLoadingBinding
|
||||
import com.gh.gamecenter.entity.ArchiveEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.vspace.VArchiveHelper
|
||||
import com.gh.vspace.VHelper
|
||||
@ -40,6 +38,7 @@ object ArchiveDownloadButtonHelper {
|
||||
packageName: String,
|
||||
archiveEntity: ArchiveEntity,
|
||||
downloadBtn: TextView,
|
||||
gameEntity: GameEntity?,
|
||||
downloadCompletedListener: (() -> Unit)? = null
|
||||
) {
|
||||
downloadBtn.text = if (VArchiveHelper.isArchiveDownloaded(archiveEntity.md5)) {
|
||||
@ -50,7 +49,7 @@ object ArchiveDownloadButtonHelper {
|
||||
downloadBtn.setOnClickListener {
|
||||
when {
|
||||
// 检查是否已安装畅玩助手
|
||||
!VHelper.isVSpaceInstalled(context) -> showVspaceTipDialog(context)
|
||||
!VHelper.isVSpaceInstalled(context) -> showVSpaceTipDialog(context, gameEntity)
|
||||
// 检查是否已安装游戏
|
||||
!VHelper.isInstalled(packageName) -> {
|
||||
// 检查游戏是否在安装中
|
||||
@ -65,7 +64,8 @@ object ArchiveDownloadButtonHelper {
|
||||
context,
|
||||
entrance,
|
||||
packageName,
|
||||
archiveEntity
|
||||
archiveEntity,
|
||||
gameEntity
|
||||
)
|
||||
// 检查完毕下载存档
|
||||
else -> downloadArchive(
|
||||
@ -75,13 +75,14 @@ object ArchiveDownloadButtonHelper {
|
||||
packageName,
|
||||
archiveEntity,
|
||||
downloadBtn,
|
||||
gameEntity,
|
||||
downloadCompletedListener
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showVspaceTipDialog(context: Context) {
|
||||
private fun showVSpaceTipDialog(context: Context, gameEntity: GameEntity?) {
|
||||
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogShow()
|
||||
DialogHelper.showDialog(
|
||||
context,
|
||||
@ -91,7 +92,7 @@ object ArchiveDownloadButtonHelper {
|
||||
R.string.cancel.toResString(),
|
||||
{
|
||||
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogClick(R.string.archive_vspace_dialog_confirm.toResString())
|
||||
VHelper.showVspaceDialog(context)
|
||||
VHelper.showVSpaceDialog(context, gameEntity)
|
||||
},
|
||||
{
|
||||
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogClick(R.string.cancel.toResString())
|
||||
@ -124,7 +125,8 @@ object ArchiveDownloadButtonHelper {
|
||||
context: Context,
|
||||
entrance: String,
|
||||
packageName: String,
|
||||
archiveEntity: ArchiveEntity
|
||||
archiveEntity: ArchiveEntity,
|
||||
gameEntity: GameEntity?
|
||||
) {
|
||||
VArchiveHelper.getArchiveFile(archiveEntity.md5)?.run {
|
||||
|
||||
@ -144,7 +146,14 @@ object ArchiveDownloadButtonHelper {
|
||||
}
|
||||
}
|
||||
|
||||
NewFlatLogUtils.logCloudArchiveDownloadOrApply(archiveEntity.name, entrance)
|
||||
NewFlatLogUtils.logCloudArchiveDownloadOrApply(
|
||||
archiveEntity.name,
|
||||
entrance,
|
||||
gameEntity?.id ?: "",
|
||||
gameEntity?.name ?: "",
|
||||
archiveEntity.id,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
private fun downloadArchive(
|
||||
@ -154,6 +163,7 @@ object ArchiveDownloadButtonHelper {
|
||||
packageName: String,
|
||||
archiveEntity: ArchiveEntity,
|
||||
downloadBtn: TextView,
|
||||
gameEntity: GameEntity?,
|
||||
downloadCompletedListener: (() -> Unit)? = null
|
||||
) {
|
||||
// 执行下载
|
||||
@ -187,7 +197,7 @@ object ArchiveDownloadButtonHelper {
|
||||
DownloadStatus.COMPLETED -> {
|
||||
dismissArchiveLoadingDialog(archiveLoadingDialog)
|
||||
downloadBtn.text = R.string.archive_apply.toResString()
|
||||
showApplyArchiveTipDialog(context, entrance, packageName, archiveEntity)
|
||||
showApplyArchiveTipDialog(context, entrance, packageName, archiveEntity, gameEntity)
|
||||
downloadCompletedListener?.invoke()
|
||||
}
|
||||
else -> {
|
||||
@ -202,7 +212,22 @@ object ArchiveDownloadButtonHelper {
|
||||
|
||||
})
|
||||
|
||||
NewFlatLogUtils.logCloudArchiveDownloadOrApply(archiveEntity.name, entrance)
|
||||
NewFlatLogUtils.logCloudArchiveDownloadOrApply(
|
||||
archiveEntity.name,
|
||||
entrance,
|
||||
gameEntity?.id ?: "",
|
||||
gameEntity?.name ?: "",
|
||||
archiveEntity.id,
|
||||
true
|
||||
)
|
||||
|
||||
SensorsBridge.trackEvent(
|
||||
"CloudSaveDownload",
|
||||
"cloud_save_name", archiveEntity.name,
|
||||
"game_id", gameEntity?.id ?: "",
|
||||
"game_name", gameEntity?.name ?: "",
|
||||
"source_entrance", entrance
|
||||
)
|
||||
}
|
||||
|
||||
private fun showArchiveLoadingDialog(
|
||||
@ -226,7 +251,8 @@ object ArchiveDownloadButtonHelper {
|
||||
context: Context,
|
||||
entrance: String,
|
||||
packageName: String,
|
||||
archiveEntity: ArchiveEntity
|
||||
archiveEntity: ArchiveEntity,
|
||||
gameEntity: GameEntity?
|
||||
) {
|
||||
DialogHelper.showDialog(
|
||||
context,
|
||||
@ -235,14 +261,33 @@ object ArchiveDownloadButtonHelper {
|
||||
R.string.archive_apply.toResString(),
|
||||
R.string.cancel.toResString(),
|
||||
{
|
||||
applyArchive(context, entrance, packageName, archiveEntity)
|
||||
applyArchive(context, entrance, packageName, archiveEntity, gameEntity)
|
||||
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "使用")
|
||||
SensorsBridge.trackEvent(
|
||||
"CloudSaveOverwriteDialogClick",
|
||||
"game_id", gameEntity?.id ?: "",
|
||||
"game_name", gameEntity?.name ?: "",
|
||||
"button_name", "使用"
|
||||
)
|
||||
},
|
||||
{
|
||||
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "取消")
|
||||
SensorsBridge.trackEvent(
|
||||
"CloudSaveOverwriteDialogClick",
|
||||
"game_id", gameEntity?.id ?: "",
|
||||
"game_name", gameEntity?.name ?: "",
|
||||
"button_name", "取消"
|
||||
)
|
||||
},
|
||||
{ NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "取消") },
|
||||
extraConfig = DialogHelper.Config(centerTitle = true)
|
||||
)
|
||||
|
||||
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_show")
|
||||
SensorsBridge.trackEvent(
|
||||
"CloudSaveOverwriteDialogShow",
|
||||
"game_id", gameEntity?.id ?: "",
|
||||
"game_name", gameEntity?.name ?: ""
|
||||
)
|
||||
}
|
||||
|
||||
private fun dismissArchiveLoadingDialog(archiveLoadingDialog: Dialog) {
|
||||
|
||||
@ -3,11 +3,15 @@ package com.gh.common.util;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@ -19,6 +23,7 @@ import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
|
||||
import com.gh.gamecenter.common.callback.SimpleCallback;
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
@ -45,6 +50,7 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
@ -102,17 +108,27 @@ public class CommentUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void showReportDialog(final CommentEntity commentEntity,
|
||||
final Context context,
|
||||
final boolean showConversation,
|
||||
final String patch) {
|
||||
final Dialog dialog = new Dialog(context);
|
||||
|
||||
LinearLayout container = new LinearLayout(context);
|
||||
container.setOrientation(LinearLayout.VERTICAL);
|
||||
container.setBackgroundColor(ContextCompat.getColor(context, R.color.background_white));
|
||||
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
|
||||
public static void showMorePopupWindow(
|
||||
final View anchor,
|
||||
final CommentEntity commentEntity,
|
||||
final boolean showConversation,
|
||||
final String patch,
|
||||
final OnCommentDeleteListener onCommentDeleteListener
|
||||
) {
|
||||
Context context = anchor.getContext();
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
View contentView = inflater.inflate(R.layout.layout_popup_container, null);
|
||||
PopupWindow popupWindow = new PopupWindow(
|
||||
contentView,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
popupWindow.setBackgroundDrawable(new ColorDrawable(0));
|
||||
popupWindow.setTouchable(true);
|
||||
popupWindow.setFocusable(true);
|
||||
popupWindow.setOutsideTouchable(true);
|
||||
|
||||
LinearLayout container = contentView.findViewById(R.id.container);
|
||||
List<String> dialogType = new ArrayList<>();
|
||||
dialogType.add("复制");
|
||||
dialogType.add("投诉");
|
||||
@ -121,21 +137,23 @@ public class CommentUtils {
|
||||
dialogType.add("查看对话");
|
||||
}
|
||||
|
||||
String commentUserId = commentEntity.getUser().getId();
|
||||
String userId = UserManager.getInstance().getUserId();
|
||||
MeEntity me = commentEntity.getMe();
|
||||
boolean isCommentedByUser = Objects.equals(commentUserId, userId);
|
||||
boolean isContentAuthorOrModerator = me != null && (me.isModerator() || me.isContentAuthor());
|
||||
if (isCommentedByUser || isContentAuthorOrModerator) {
|
||||
dialogType.add("删除");
|
||||
}
|
||||
|
||||
for (String s : dialogType) {
|
||||
final TextView reportTv = new TextView(context);
|
||||
View itemView = inflater.inflate(R.layout.layout_popup_option_item, container, false);
|
||||
TextView reportTv = itemView.findViewById(R.id.hint_text);
|
||||
reportTv.setText(s);
|
||||
reportTv.setTextSize(17);
|
||||
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
|
||||
reportTv.setBackgroundResource(R.drawable.textview_white_style);
|
||||
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
|
||||
reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
reportTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
|
||||
0, DisplayUtils.dip2px(context, 12));
|
||||
container.addView(reportTv);
|
||||
container.addView(itemView);
|
||||
|
||||
reportTv.setOnClickListener(v -> {
|
||||
dialog.cancel();
|
||||
popupWindow.dismiss();
|
||||
switch (reportTv.getText().toString()) {
|
||||
case "复制":
|
||||
copyText(commentEntity.getContent(), context);
|
||||
@ -143,19 +161,30 @@ public class CommentUtils {
|
||||
case "投诉":
|
||||
CheckLoginUtils.checkLogin(context, patch + "-投诉",
|
||||
() -> showReportTypeDialog(commentEntity, context));
|
||||
|
||||
break;
|
||||
case "查看对话":
|
||||
context.startActivity(CommentDetailActivity.getIntent(context, commentEntity.getId(), null));
|
||||
break;
|
||||
case "删除":
|
||||
DialogHelper.INSTANCE.showDialog(
|
||||
context,
|
||||
"提示",
|
||||
"删除评论后,评论下所有的回复都将被删除",
|
||||
"删除",
|
||||
"取消",
|
||||
() -> {
|
||||
deleteComment(context, commentEntity, onCommentDeleteListener);
|
||||
return null;
|
||||
},
|
||||
null,
|
||||
new DialogHelper.Config("", false, true, true, false, -1)
|
||||
);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(container);
|
||||
dialog.show();
|
||||
|
||||
ExtensionsKt.showAutoOrientation(popupWindow, anchor, 0, 0);
|
||||
}
|
||||
|
||||
private static void showReportTypeDialog(final CommentEntity commentEntity, final Context context) {
|
||||
@ -430,6 +459,28 @@ public class CommentUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static void deleteComment(
|
||||
final Context context,
|
||||
final CommentEntity commentEntity,
|
||||
final OnCommentDeleteListener listener
|
||||
) {
|
||||
Dialog dialog = DialogUtils.showWaitDialog(
|
||||
context,
|
||||
context.getString(R.string.post_dialog_hint)
|
||||
);
|
||||
RetrofitManager.getInstance().getApi()
|
||||
.deleteComment(commentEntity.getId())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doFinally(dialog::cancel)
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(@Nullable ResponseBody response) {
|
||||
listener.onCommentDelete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 设置评论item 用户相关的view(点赞/头像/用户名)
|
||||
public static void setCommentUserView(Context mContext, CommentViewHolder holder, CommentEntity entity) {
|
||||
@ -540,4 +591,8 @@ public class CommentUtils {
|
||||
public interface OnVoteListener {
|
||||
void onVote();
|
||||
}
|
||||
|
||||
public interface OnCommentDeleteListener {
|
||||
void onCommentDelete();
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,12 +9,14 @@ import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.gh.base.GlobalActivityManager;
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
@ -30,6 +32,8 @@ import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.sentry.Sentry;
|
||||
import io.sentry.android.core.SentryAndroid;
|
||||
@ -53,8 +57,7 @@ public class DataUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化 Sentry 约占用 90ms,这里切换到子线程初始化
|
||||
AppExecutor.getIoExecutor().execute(() -> initSentry(context, channel));
|
||||
initSentry(context, channel);
|
||||
}
|
||||
|
||||
private static void initSentry(Context context, String channel) {
|
||||
@ -114,6 +117,13 @@ public class DataUtils {
|
||||
String originalGid = HaloApp.getInstance().getGid();
|
||||
HaloApp.getInstance().setGid(gid);
|
||||
|
||||
// gid 变更时上报 gid 变更日志
|
||||
if (!TextUtils.isEmpty(originalGid) && !originalGid.equals(gid)) {
|
||||
NewFlatLogUtils.logGidChanged(originalGid, gid);
|
||||
}
|
||||
|
||||
SensorsBridge.setGid(gid);
|
||||
|
||||
// 避免重复调用
|
||||
if (!TextUtils.isEmpty(gid) && !gid.equals(originalGid)) {
|
||||
GameSubstituteRepositoryHelper.updateSubstitutableGames();
|
||||
@ -160,16 +170,29 @@ public class DataUtils {
|
||||
IdCardEntity idCardEntity = data.getIdCard();
|
||||
|
||||
if (idCardEntity != null) {
|
||||
values.put(GhContentProvider.KEY_IS_CERTIFICATED, !TextUtils.isEmpty(data.getIdCard().getId())); // 是否认证
|
||||
values.put(GhContentProvider.KEY_IS_ADULT,
|
||||
data.getIdCard().getMinor() == null
|
||||
|| !data.getIdCard().getMinor()
|
||||
);
|
||||
boolean isCertificated = !TextUtils.isEmpty(data.getIdCard().getId());
|
||||
boolean isAdult = data.getIdCard().getMinor() == null || !data.getIdCard().getMinor();
|
||||
|
||||
values.put(GhContentProvider.KEY_IS_CERTIFICATED, isCertificated); // 是否认证
|
||||
values.put(GhContentProvider.KEY_IS_ADULT, isAdult); // 是否成年
|
||||
|
||||
if (!isCertificated) {
|
||||
RealNameHelper.updateCertificationStatus(0);
|
||||
} else {
|
||||
if (isAdult) {
|
||||
RealNameHelper.updateCertificationStatus(2);
|
||||
} else {
|
||||
RealNameHelper.updateCertificationStatus(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
values.put(GhContentProvider.KEY_IS_CERTIFICATED, false);
|
||||
values.put(GhContentProvider.KEY_IS_ADULT, false);
|
||||
RealNameHelper.updateCertificationStatus(0);
|
||||
}
|
||||
|
||||
EventBus.getDefault().post(new EBReuse(Constants.EB_REALNAME_RESULT));
|
||||
|
||||
// new GhContentProvider().localInsert( HaloApp.getInstance().getApplication(),values);
|
||||
try {
|
||||
// Unknown URL content://com.gh.gamecenter.provider/certification
|
||||
|
||||
@ -24,6 +24,8 @@ import com.gh.vspace.VHelper;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/06/17.
|
||||
* 详情下载工具类
|
||||
@ -42,9 +44,7 @@ public class DetailDownloadUtils {
|
||||
viewHolder.mMultiVersionDownloadTv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (viewHolder.gameEntity != null
|
||||
&& Config.isShowDownload(viewHolder.gameEntity.getId())
|
||||
&& !"光环助手".equals(viewHolder.gameEntity.getName())) {
|
||||
if (viewHolder.gameEntity != null && Config.isShowDownload(viewHolder.gameEntity.getId()) && !"光环助手".equals(viewHolder.gameEntity.getName())) {
|
||||
viewHolder.downloadBottom.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
viewHolder.downloadBottom.setVisibility(View.GONE);
|
||||
@ -114,7 +114,7 @@ public class DetailDownloadUtils {
|
||||
if (downloadEntity == null && viewHolder.gameEntity.isVGame()) {
|
||||
String packageName = viewHolder.gameEntity.getUniquePackageName();
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
downloadEntity = VHelper.getDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName);
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +214,7 @@ public class DetailDownloadUtils {
|
||||
if (downloadEntity == null && viewHolder.gameEntity.isVGame()) {
|
||||
String packageName = viewHolder.gameEntity.getUniquePackageName();
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
downloadEntity = VHelper.getDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName);
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(viewHolder.gameEntity.getId(), packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,6 +233,13 @@ public class DetailDownloadUtils {
|
||||
DownloadEntity downloadEntity = viewHolder.downloadEntity;
|
||||
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
|
||||
|
||||
if (XapkUnzipStatus.SUCCESS.name().equals(xapkStatus) && XapkInstaller.INSTANCE.isInstalling(downloadEntity.getPath())) {
|
||||
viewHolder.mDownloadPb.setText("游戏安装中");
|
||||
viewHolder.mDownloadPb.setProgress(100);
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
|
||||
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
|
||||
viewHolder.mDownloadPb.setText("游戏解压中 " + percent + "%");
|
||||
@ -262,11 +269,13 @@ public class DetailDownloadUtils {
|
||||
case downloading:
|
||||
case redirected:
|
||||
case pause:
|
||||
case diskisfull:
|
||||
case diskioerror:
|
||||
case overflow:
|
||||
String downloadingText = "游戏加载中 " + downloadEntity.getPercent() + "%";
|
||||
String resumeText = "继续加载 " + downloadEntity.getPercent() + "%";
|
||||
viewHolder.mDownloadPb.setText((downloadEntity.getStatus() == DownloadStatus.downloading || downloadEntity.getStatus() == DownloadStatus.redirected) ? downloadingText : resumeText);
|
||||
if (downloadEntity.isPluggable() && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
|
||||
@ -284,7 +293,7 @@ public class DetailDownloadUtils {
|
||||
viewHolder.mDownloadPb.setText(R.string.launch);
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.LAUNCH_OR_OPEN);
|
||||
} else {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
|
||||
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
@ -305,13 +314,12 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL)) {
|
||||
if (SPUtils.getBoolean(Constants.SP_USE_BROWSER_TO_INSTALL) && !Objects.equals(Constants.XAPK_APKS_FORMAT, downloadEntity.getFormat())) {
|
||||
viewHolder.mDownloadPb.setText(R.string.browser_install_install);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
}
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_NORMAL);
|
||||
@ -348,6 +356,8 @@ public class DetailDownloadUtils {
|
||||
case timeout:
|
||||
case neterror:
|
||||
case subscribe:
|
||||
case diskisfull:
|
||||
case diskioerror:
|
||||
case pause:
|
||||
viewHolder.mDownloadPb.setText("继续加载 " + viewHolder.downloadEntity.getPercent() + "%");
|
||||
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);
|
||||
|
||||
@ -41,6 +41,7 @@ import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.filter.RegionSetting;
|
||||
import com.gh.common.xapk.XapkDialogHelper;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.ShellActivity;
|
||||
import com.gh.gamecenter.adapter.ReportReasonAdapter;
|
||||
@ -56,6 +57,7 @@ import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.NetworkUtils;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.common.view.CustomLinkMovementMethod;
|
||||
import com.gh.gamecenter.common.view.DrawableView;
|
||||
import com.gh.gamecenter.common.view.FixLinearLayoutManager;
|
||||
@ -119,7 +121,7 @@ public class DialogUtils {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static void checkDownload(Context context, String size, CheckDownloadCallBack callBack) {
|
||||
public static void checkDownload(Context context, String size, String gameId, String gameName, CheckDownloadCallBack callBack) {
|
||||
if (!NetworkUtils.isNetworkConnected(context)) {
|
||||
showNoConnectionDownloadDialog(context, () -> {
|
||||
},
|
||||
@ -134,7 +136,9 @@ public class DialogUtils {
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
|
||||
showDownloadDialog(context,
|
||||
() -> callBack.onResponse(false),
|
||||
() -> callBack.onResponse(true));
|
||||
() -> callBack.onResponse(true),
|
||||
gameId,
|
||||
gameName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,9 +167,11 @@ public class DialogUtils {
|
||||
DialogHelper.showDialog(context, "下载提示", "网络异常,请检查手机网络状态", "知道了", "WiFi自动下载", listener::onConfirm, cancelListener::onCancel, false, "", "");
|
||||
}
|
||||
|
||||
public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener) {
|
||||
public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener, String gameId, String gameName) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
NewFlatLogUtils.logDownloadMobileDataDialogShow(gameId, gameName);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_download_traffic, null);
|
||||
@ -175,6 +181,7 @@ public class DialogUtils {
|
||||
|
||||
Context finalContext = context;
|
||||
allowOnce.setOnClickListener(v -> {
|
||||
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "允许一次");
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
Utils.toast(finalContext, "已使用移动网络下载,请注意流量消耗");
|
||||
}, 500);
|
||||
@ -183,11 +190,13 @@ public class DialogUtils {
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
|
||||
});
|
||||
wifiAuto.setOnClickListener(v -> {
|
||||
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "WiFi自动下载");
|
||||
cancelListener.onCancel();
|
||||
dialog.dismiss();
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
|
||||
});
|
||||
allowAlways.setOnClickListener(v -> {
|
||||
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "总是允许");
|
||||
SPUtils.setBoolean(getTrafficDownloadHintKey(), false);
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
// 显示了弹窗以后,即便下面这个 toast 放在 listener.onConfirm 后调用也是显示 listener.onConfirm 里的 toast
|
||||
@ -199,6 +208,8 @@ public class DialogUtils {
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
|
||||
});
|
||||
|
||||
dialog.setOnCancelListener(downloadDialog -> NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "关闭弹窗"));
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
@ -910,6 +921,8 @@ public class DialogUtils {
|
||||
public static void showRegulationTestDialog(Context context, @NonNull ConfirmListener confirmListener, @NonNull CancelListener cancelListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
SensorsBridge.trackEvent("EtiquetteTestDialogShow");
|
||||
|
||||
final Dialog dialog = new TrackableDialog(
|
||||
context,
|
||||
R.style.GhAlertDialog,
|
||||
@ -935,6 +948,7 @@ public class DialogUtils {
|
||||
cancelListener.onCancel();
|
||||
|
||||
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "跳过");
|
||||
SensorsBridge.trackEvent("EtiquetteTestDialogClick", "button_name", "跳过");
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
@ -943,6 +957,7 @@ public class DialogUtils {
|
||||
Util_System_Keyboard.hideSoftKeyboard((Activity) finalContext1);
|
||||
|
||||
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "确定");
|
||||
SensorsBridge.trackEvent("EtiquetteTestDialogClick", "button_name", "进入考试");
|
||||
confirmListener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
@ -958,33 +973,7 @@ public class DialogUtils {
|
||||
}
|
||||
|
||||
public static void showUnzipFailureDialog(Context context, DownloadEntity downloadEntity) {
|
||||
final Context activityContext = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(activityContext, R.style.GhAlertDialog);
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawableResource(android.R.color.transparent);
|
||||
}
|
||||
|
||||
View contentView = LayoutInflater.from(activityContext).inflate(R.layout.dialog_unzip_failure, null);
|
||||
|
||||
View cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
View confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
String hint = "《" + downloadEntity.getName() + "》游戏安装包解压失败,问题反馈:";
|
||||
HelpAndFeedbackBridge.startSuggestionActivity(activityContext, SuggestType.normal, null, hint);
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
XapkDialogHelper.INSTANCE.showUnzipFailureDialog(context, downloadEntity, false);
|
||||
}
|
||||
|
||||
public static void showNoticeDialog(Context context, String title, String content, @NonNull ConfirmListener listener) {
|
||||
@ -1025,7 +1014,7 @@ public class DialogUtils {
|
||||
SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
|
||||
ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);
|
||||
|
||||
ImageUtils.display(badgeView, badge.getIcon());
|
||||
ImageUtils.display(badgeView, badge.getMIcon());
|
||||
titleTv.setText(badge.getName());
|
||||
|
||||
// 领取条件文本超过一行就不显示
|
||||
@ -1079,6 +1068,8 @@ public class DialogUtils {
|
||||
|
||||
if ("self".equals(badge.getReceive().getType())) {
|
||||
receiveTv.setText(R.string.receive_badge);
|
||||
} else if ("auto".equals(badge.getReceive().getType())) {
|
||||
receiveTv.setText(R.string.view_badge);
|
||||
} else {
|
||||
receiveTv.setText(R.string.apply_badge);
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts.*
|
||||
import com.gh.gamecenter.common.constant.RouteConsts
|
||||
import com.gh.gamecenter.common.entity.*
|
||||
import com.gh.gamecenter.common.entity.Display
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
@ -36,6 +37,7 @@ import com.gh.gamecenter.discovery.DiscoveryActivity
|
||||
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.feature.entity.GameDetailServer
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.MeEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
@ -43,11 +45,13 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
|
||||
import com.gh.gamecenter.feature.exposure.ExposureType
|
||||
import com.gh.gamecenter.forum.detail.ForumDetailActivity
|
||||
import com.gh.gamecenter.forum.home.CommunityHomeFragment
|
||||
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity
|
||||
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailActivity
|
||||
import com.gh.gamecenter.game.upload.GameSubmissionActivity
|
||||
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
|
||||
import com.gh.gamecenter.gamecollection.hotlist.GameCollectionHotListActivity
|
||||
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment
|
||||
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
|
||||
@ -87,6 +91,7 @@ import org.greenrobot.eventbus.EventBus
|
||||
import retrofit2.HttpException
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@ -186,7 +191,9 @@ object DirectUtils {
|
||||
"game_list",
|
||||
"game_list_detail",
|
||||
"bbs_video",
|
||||
"explore_column"
|
||||
"explore_column",
|
||||
"game_explore",
|
||||
"column_test_v2"
|
||||
)
|
||||
|
||||
fun directToLinkPage(
|
||||
@ -214,8 +221,9 @@ object DirectUtils {
|
||||
)
|
||||
} else {
|
||||
directToGameDetail(
|
||||
context, linkEntity.link
|
||||
?: "", BaseActivity.mergeEntranceAndPath(entrance, path)
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
entrance = BaseActivity.mergeEntranceAndPath(entrance, path)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -306,13 +314,14 @@ object DirectUtils {
|
||||
name = linkEntity.name,
|
||||
display = linkEntity.display ?: Display()
|
||||
),
|
||||
entrance
|
||||
entrance,
|
||||
exposureEvent
|
||||
)
|
||||
}
|
||||
|
||||
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
|
||||
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance, "", exposureEvent)
|
||||
|
||||
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path)
|
||||
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path, exposureEvent)
|
||||
|
||||
"top_game_comment" -> directToAmway(context, null, entrance, path)
|
||||
|
||||
@ -332,7 +341,7 @@ object DirectUtils {
|
||||
|
||||
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, false, "", entrance)
|
||||
|
||||
"qa", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
|
||||
"qa", "qa_content", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
|
||||
|
||||
"qa_collection", "Q&A合集" -> directToQaCollection(
|
||||
context, linkEntity.text
|
||||
@ -348,6 +357,13 @@ object DirectUtils {
|
||||
|
||||
"bbs_detail" -> directForumDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
"bbs_section" -> directForumDetailSection(
|
||||
context,
|
||||
linkEntity.community?.id,
|
||||
linkEntity.link ?: "",
|
||||
entrance
|
||||
)
|
||||
|
||||
"mobile_bind" -> {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
context.startActivity(SettingBridge.getBindPhoneNormalIntent(context, false))
|
||||
@ -427,11 +443,28 @@ object DirectUtils {
|
||||
|
||||
"game_list" -> directToGameCollectionSquare(context, entrance, "", "", "")
|
||||
|
||||
"game_list_detail" -> directToGameCollectionDetail(context, linkEntity.link ?: "", entrance)
|
||||
"game_list_detail" -> directToGameCollectionDetail(
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
entrance,
|
||||
traceEvent = exposureEvent
|
||||
)
|
||||
|
||||
"explore_column" -> context.startActivity(DiscoveryActivity.getIntent(context, entrance))
|
||||
"explore_column", "game_explore" -> context.startActivity(
|
||||
DiscoveryActivity.getIntent(
|
||||
context,
|
||||
entrance,
|
||||
exposureEvent
|
||||
)
|
||||
)
|
||||
|
||||
"column_test_v2" -> context.startActivity(GameServerTestV2Activity.getIntent(context, entrance))
|
||||
"column_test_v2" -> context.startActivity(
|
||||
GameServerTestV2Activity.getIntent(
|
||||
context,
|
||||
entrance,
|
||||
exposureEvent
|
||||
)
|
||||
)
|
||||
|
||||
"" -> {
|
||||
// do nothing
|
||||
@ -483,7 +516,8 @@ object DirectUtils {
|
||||
id: String,
|
||||
position: Int = -1,
|
||||
entrance: String,
|
||||
columnName: String = ""
|
||||
columnName: String = "",
|
||||
exposureEvent: ExposureEvent? = null
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
@ -492,6 +526,9 @@ object DirectUtils {
|
||||
bundle.putString(KEY_COLLECTION_ID, id)
|
||||
bundle.putString(KEY_COLUMNNAME, columnName)
|
||||
bundle.putInt(KEY_POSITION, position)
|
||||
if (exposureEvent != null) {
|
||||
bundle.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST ,ArrayList(exposureEvent.source))
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -544,6 +581,9 @@ object DirectUtils {
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
|
||||
bundle.putString(KEY_NEWSID, id)
|
||||
if (entrance?.contains("隐私政策") == true) {
|
||||
bundle.putBoolean(KEY_HIDE_USELESS_INFO, true)
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -646,10 +686,10 @@ object DirectUtils {
|
||||
bundle.putString(KEY_GAMEID, id)
|
||||
if (!TextUtils.isEmpty(tab)) {
|
||||
when (tab) {
|
||||
"comment" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_RATING)
|
||||
"desc" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_DESC)
|
||||
"forum" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_BBS)
|
||||
"zone" -> bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_TRENDES)
|
||||
"comment" -> bundle.putString(KEY_TARGET, GameDetailFragment.TAB_RATING)
|
||||
"desc" -> bundle.putString(KEY_TARGET, GameDetailFragment.TAB_DESC)
|
||||
"forum" -> bundle.putString(KEY_TARGET, GameDetailFragment.TAB_BBS)
|
||||
"zone" -> bundle.putString(KEY_TARGET, GameDetailFragment.TAB_TRENDS)
|
||||
}
|
||||
}
|
||||
if (traceEvent != null) {
|
||||
@ -689,7 +729,7 @@ object DirectUtils {
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_GAMEID, id)
|
||||
bundle.putBoolean(KEY_OPEN_VIDEO_STREAMING, true)
|
||||
bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_DESC)
|
||||
bundle.putString(KEY_TARGET, GameDetailFragment.TAB_DESC)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -697,14 +737,14 @@ object DirectUtils {
|
||||
fun directToGameDetail(
|
||||
context: Context,
|
||||
id: String,
|
||||
defaultTab: Int = GameDetailFragment.INDEX_DESC,
|
||||
defaultTab: String = GameDetailFragment.TAB_DESC,
|
||||
entrance: String? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_GAMEID, id)
|
||||
bundle.putInt(KEY_TARGET, defaultTab)
|
||||
bundle.putString(KEY_TARGET, defaultTab)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -767,8 +807,11 @@ object DirectUtils {
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 畅玩助手反馈跳转
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToFeedbackCompat(
|
||||
fun directToVGameFeedback(
|
||||
context: Context,
|
||||
content: String? = null,
|
||||
hintType: String? = null,
|
||||
@ -783,14 +826,14 @@ object DirectUtils {
|
||||
if (isQaFeedback) {
|
||||
bundle.putBoolean(KEY_IS_QA_FEEDBACK, true)
|
||||
bundle.putString(KEY_QA_CONTENT_ID, qaContentId)
|
||||
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.normal)
|
||||
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.cwzsQuestion)
|
||||
} else {
|
||||
bundle.putString(KEY_CONTENT, content)
|
||||
if (TextUtils.isEmpty(hintType)) {
|
||||
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.gameQuestion)
|
||||
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
|
||||
} else {
|
||||
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.normal)
|
||||
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.cwzsQuestion)
|
||||
bundle.putString(KEY_SUGGEST_HINT_TYPE, hintType)
|
||||
}
|
||||
}
|
||||
@ -1338,11 +1381,17 @@ object DirectUtils {
|
||||
* 跳转到板块
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBlock(context: Context, blockData: SubjectRecommendEntity, entrance: String) {
|
||||
fun directToBlock(
|
||||
context: Context,
|
||||
blockData: SubjectRecommendEntity,
|
||||
entrance: String,
|
||||
exposureEvent: ExposureEvent? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, BlockActivity::class.java.name)
|
||||
bundle.putParcelable(KEY_BLOCK_DATA, blockData)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1350,10 +1399,11 @@ object DirectUtils {
|
||||
* 跳转到开服表
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameServers(context: Context, entrance: String, path: String) {
|
||||
fun directToGameServers(context: Context, entrance: String, path: String, exposureEvent: ExposureEvent? = null) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameServersActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, ToolBarActivity.mergeEntranceAndPath(entrance, path))
|
||||
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1381,7 +1431,7 @@ object DirectUtils {
|
||||
response?.apply {
|
||||
if (zone.status == "on") {
|
||||
if (zone.style == "link") {
|
||||
directToGameDetail(context, gameId, GameDetailFragment.INDEX_TRENDES, entrance)
|
||||
directToGameDetail(context, gameId, GameDetailFragment.TAB_TRENDS, entrance)
|
||||
} else {
|
||||
directToWebView(context, url, entrance)
|
||||
}
|
||||
@ -1414,6 +1464,21 @@ object DirectUtils {
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directForumDetailSection(
|
||||
context: Context,
|
||||
bbsId: String? = "",
|
||||
sectionId: String = "",
|
||||
entrance: String? = null
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, ForumDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_BBS_ID, bbsId)
|
||||
bundle.putString(KEY_BBS_SECTION_ID, sectionId)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 到首页-首页 tab
|
||||
*/
|
||||
@ -1788,7 +1853,8 @@ object DirectUtils {
|
||||
collectionId: String,
|
||||
blockId: String = "",
|
||||
blockName: String = "",
|
||||
entrance: String = ""
|
||||
entrance: String = "",
|
||||
exposureEvent: ExposureEvent? = null
|
||||
) {
|
||||
if (collectionId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
@ -1797,6 +1863,7 @@ object DirectUtils {
|
||||
bundle.putString(KEY_BLOCK_NAME, blockName)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_COLLECTION_ID, collectionId)
|
||||
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1817,7 +1884,9 @@ object DirectUtils {
|
||||
entrance: String = "",
|
||||
forumName: String = "",
|
||||
gameCollectionTitle: String = "",
|
||||
gameCollectionId: String = ""
|
||||
gameCollectionId: String = "",
|
||||
collectionName: String = "",
|
||||
collectionId: String = ""
|
||||
) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameCollectionSquareActivity::class.java.name)
|
||||
@ -1825,6 +1894,19 @@ object DirectUtils {
|
||||
bundle.putString(KEY_FORUM_NAME, forumName)
|
||||
bundle.putString(KEY_GAME_COLLECTION_TITLE, gameCollectionTitle)
|
||||
bundle.putString(KEY_GAME_COLLECTION_ID, gameCollectionId)
|
||||
bundle.putString(KEY_COLLECTION_ID, collectionId)
|
||||
bundle.putString(KEY_COLLECTION_NAME, collectionName)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至游戏单热榜
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameCollectionHotList(context: Context, entrance: String = "") {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameCollectionHotListActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1832,13 +1914,25 @@ object DirectUtils {
|
||||
* 跳转至游戏单详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameCollectionDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
|
||||
fun directToGameCollectionDetail(
|
||||
context: Context,
|
||||
id: String,
|
||||
entrance: String? = null,
|
||||
path: String? = null,
|
||||
traceEvent: ExposureEvent? = null,
|
||||
) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
val exposureSourceList = traceEvent?.source
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
bundle.putString(KEY_TO, GameCollectionDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_GAME_COLLECTION_ID, id)
|
||||
if (exposureSourceList is ArrayList) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
} else if (exposureSourceList != null) {
|
||||
bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureSourceList))
|
||||
}
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -1880,6 +1974,15 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到论坛搜索页
|
||||
* @param bbsId, 为空时搜索全范围的内容,不为空时搜索该 bbsId 对应的内容
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToForumOrUserSearch(context: Context, bbsId: String, entrance: String) {
|
||||
context.startActivity(ForumOrUserSearchActivity.getIntent(context, bbsId, entrance))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToVGameDownload(context: Context, switchToDownloadingTab: Boolean = false) {
|
||||
val bundle = Bundle()
|
||||
|
||||
@ -29,7 +29,7 @@ object DownloadDialogHelper {
|
||||
|
||||
private fun retrieveAvailableDialog(gameEntity: GameEntity, apkEntity: ApkEntity): GameEntity.Dialog? {
|
||||
val downloadDialog = if (gameEntity.shouldUseMirrorInfo()) {
|
||||
gameEntity.mirrorData?.downloadDialog
|
||||
gameEntity.obtainMirrorData()?.downloadDialog
|
||||
} else {
|
||||
gameEntity.downloadDialog
|
||||
}
|
||||
|
||||
@ -10,19 +10,19 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.gh.common.chain.*
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.dialog.DeviceRemindDialog
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.common.history.HistoryHelper
|
||||
import com.gh.common.repository.ReservationRepository
|
||||
import com.gh.common.simulator.NewSimulatorGameManager
|
||||
import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.common.xapk.XapkInstaller.cancelUnzipTask
|
||||
import com.gh.common.xapk.XapkInstaller.isInstalling
|
||||
import com.gh.common.xapk.XapkUnzipStatus
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.download.dialog.DownloadDialog
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
|
||||
@ -31,10 +31,12 @@ import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.energy.EnergyBridge
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.feature.view.DownloadButton
|
||||
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
|
||||
import com.gh.gamecenter.manager.PackagesManager
|
||||
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
|
||||
@ -163,6 +165,8 @@ object DownloadItemUtils {
|
||||
briefStyle: String? = null,
|
||||
isShowRecommendStar: Boolean = false
|
||||
) {
|
||||
holder.gameDownloadBtn.putObject(gameEntity)
|
||||
|
||||
// 显示预约
|
||||
if (gameEntity.isReservable) {
|
||||
holder.multiVersionDownloadTv?.visibility = View.GONE
|
||||
@ -244,9 +248,11 @@ object DownloadItemUtils {
|
||||
context.getString(R.string.check)
|
||||
}
|
||||
isClickable = true
|
||||
buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
} else {
|
||||
if ("dialog" == offStatus) {
|
||||
text = context.getString(R.string.check)
|
||||
buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
} else if ("updating" == offStatus) {
|
||||
text = context.getString(R.string.updating)
|
||||
buttonStyle = DownloadButton.ButtonStyle.UPDATING
|
||||
@ -261,18 +267,17 @@ object DownloadItemUtils {
|
||||
}
|
||||
}
|
||||
} else if (gameEntity.getApk().size == 1) {
|
||||
// 优先从下载管理获取 downloadEntity
|
||||
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
|
||||
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在,代表游戏已下载并成功安装
|
||||
if (downloadEntity == null && gameEntity.isVGame()) {
|
||||
downloadEntity = VHelper.getDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
|
||||
}
|
||||
|
||||
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
|
||||
if (downloadEntity == null) {
|
||||
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
if (entryMap.isNotEmpty()) {
|
||||
downloadEntity = entryMap[apkEntity.getPlatform()]
|
||||
}
|
||||
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
@ -295,6 +300,25 @@ object DownloadItemUtils {
|
||||
DownloadButton.ButtonStyle.LAUNCH_OR_OPEN
|
||||
}
|
||||
} else {
|
||||
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {
|
||||
progress = 100
|
||||
setText(R.string.installing)
|
||||
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
return
|
||||
}
|
||||
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
|
||||
val percent = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_PERCENT]
|
||||
progress = (java.lang.Float.valueOf(percent) * 10).toInt()
|
||||
text = "$percent%"
|
||||
buttonStyle = DownloadButton.ButtonStyle.XAPK_UNZIPPING
|
||||
return
|
||||
} else if (XapkUnzipStatus.FAILURE.name == xapkStatus) {
|
||||
setText(R.string.install)
|
||||
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
return
|
||||
}
|
||||
|
||||
buttonStyle = DownloadButton.ButtonStyle.INSTALL_NORMAL
|
||||
setText(R.string.install)
|
||||
}
|
||||
@ -305,17 +329,22 @@ object DownloadItemUtils {
|
||||
DownloadButton.ButtonStyle.NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
DownloadStatus.pause,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror,
|
||||
DownloadStatus.subscribe,
|
||||
DownloadStatus.diskisfull,
|
||||
DownloadStatus.diskioerror,
|
||||
DownloadStatus.overflow -> {
|
||||
buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
setText(R.string.resume)
|
||||
}
|
||||
|
||||
DownloadStatus.cancel -> {
|
||||
GameUtils.setDownloadBtnStatus(context, gameEntity, downloadBtn, pluginLocation)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// do nothing
|
||||
}
|
||||
@ -392,7 +421,7 @@ object DownloadItemUtils {
|
||||
}
|
||||
|
||||
// 更改进度条和提示文本的状态
|
||||
fun changeStatus(
|
||||
private fun changeStatus(
|
||||
context: Context,
|
||||
holder: GameViewHolder,
|
||||
downloadEntity: DownloadEntity,
|
||||
@ -417,6 +446,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.text = downloadEntity.percent.toString() + "%"
|
||||
}
|
||||
}
|
||||
|
||||
DownloadStatus.waiting -> {
|
||||
if (isMultiVersion) {
|
||||
holder.gameDownloadTips?.visibility = View.VISIBLE
|
||||
@ -425,9 +455,12 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.WAITING
|
||||
holder.gameDownloadBtn.text = context.getString(R.string.waiting)
|
||||
}
|
||||
|
||||
DownloadStatus.pause,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror,
|
||||
DownloadStatus.diskioerror,
|
||||
DownloadStatus.diskisfull,
|
||||
DownloadStatus.subscribe,
|
||||
DownloadStatus.overflow -> {
|
||||
if (isMultiVersion) {
|
||||
@ -437,6 +470,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
|
||||
holder.gameDownloadBtn.text = context.getString(R.string.resume)
|
||||
}
|
||||
|
||||
DownloadStatus.done -> {
|
||||
if (isMultiVersion) {
|
||||
holder.gameDownloadTips?.visibility = View.VISIBLE
|
||||
@ -456,6 +490,7 @@ object DownloadItemUtils {
|
||||
holder.gameDownloadBtn.progress = 1000
|
||||
holder.gameDownloadBtn.setText(R.string.hundred_percent)
|
||||
}
|
||||
|
||||
else -> {
|
||||
holder.gameDownloadTips?.visibility = View.GONE
|
||||
}
|
||||
@ -586,6 +621,9 @@ object DownloadItemUtils {
|
||||
refreshCallback: EmptyCallback?,
|
||||
allStateClickCallback: EmptyCallback?
|
||||
) {
|
||||
// 为 downloadButton 添加游戏实体,供点击的时候上报用
|
||||
downloadBtn.putObject(gameEntity)
|
||||
|
||||
val gamePermissionDialogFragment = (context as AppCompatActivity).supportFragmentManager.findFragmentByTag(
|
||||
GamePermissionDialogFragment::class.java.name
|
||||
) as GamePermissionDialogFragment?
|
||||
@ -638,16 +676,25 @@ object DownloadItemUtils {
|
||||
if (gameEntity.isReservable) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
|
||||
downloadBtn.setOnClickListener {
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmentGame",
|
||||
"game_name",
|
||||
gameEntity.name ?: "",
|
||||
"game_id",
|
||||
gameEntity.id
|
||||
)
|
||||
allStateClickCallback?.onCallback()
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
clickCallback?.onCallback()
|
||||
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
LogUtils.logReservation(gameEntity, traceEvent)
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
})
|
||||
ReservationHelper.reserve(
|
||||
context,
|
||||
gameEntity.id,
|
||||
gameEntity.name ?: ""
|
||||
) {
|
||||
LogUtils.logReservation(gameEntity, traceEvent)
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -696,7 +743,6 @@ object DownloadItemUtils {
|
||||
if (gameEntity.getApk().size == 0 && gameEntity.h5Link != null) {
|
||||
downloadBtn.setOnClickListener {
|
||||
allStateClickCallback?.onCallback()
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.name)
|
||||
val linkEntity = gameEntity.h5Link
|
||||
val isPlay = "play" == linkEntity!!.type // 是否为开始玩
|
||||
if (isPlay) {
|
||||
@ -773,6 +819,7 @@ object DownloadItemUtils {
|
||||
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
|
||||
if (str == context.getString(R.string.download)) {
|
||||
ChainBuilder().apply {
|
||||
addHandler(UnsupportedFeatureHandler())
|
||||
addHandler(UpdateNewSimulatorHandler())
|
||||
addHandler(GamePermissionHandler())
|
||||
addHandler(BrowserInstallHandler())
|
||||
@ -790,6 +837,7 @@ object DownloadItemUtils {
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
|
||||
} else if (str == context.getString(R.string.attempt)) {
|
||||
ChainBuilder().apply {
|
||||
addHandler(UnsupportedFeatureHandler())
|
||||
addHandler(UpdateNewSimulatorHandler())
|
||||
addHandler(GamePermissionHandler())
|
||||
addHandler(BrowserInstallHandler())
|
||||
@ -808,12 +856,14 @@ object DownloadItemUtils {
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
|
||||
} else if (str == context.getString(R.string.smooth)) {
|
||||
ChainBuilder().apply {
|
||||
addHandler(UnsupportedFeatureHandler())
|
||||
addHandler(GamePermissionHandler())
|
||||
addHandler(PackageCheckHandler())
|
||||
addHandler(DownloadDialogHelperHandler())
|
||||
addHandler(CertificationHandler())
|
||||
addHandler(VersionNumberHandler())
|
||||
addHandler(OverseaDownloadHandler())
|
||||
addHandler(CheckStoragePermissionHandler())
|
||||
addHandler(ValidateVSpaceHandler())
|
||||
addHandler(CheckDownloadHandler())
|
||||
}
|
||||
@ -823,9 +873,6 @@ object DownloadItemUtils {
|
||||
.buildHandlerChain()
|
||||
?.handleRequest(context, gameEntity)
|
||||
} else if (str.contains("化")) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "插件化", gameEntity.name)
|
||||
}
|
||||
if (gameEntity.pluggableCollection != null) {
|
||||
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
|
||||
} else {
|
||||
@ -862,12 +909,11 @@ object DownloadItemUtils {
|
||||
}
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "")
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
|
||||
} else {
|
||||
install(context, gameEntity, position, adapter, refreshCallback)
|
||||
}
|
||||
} else if (str == context.getString(R.string.launch)) {
|
||||
EnergyBridge.postEnergyTask("play_game", gameEntity.id, gameEntity.getApk()[0].packageName)
|
||||
//启动模拟器游戏
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
|
||||
@ -888,40 +934,43 @@ object DownloadItemUtils {
|
||||
}
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "")
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
|
||||
return
|
||||
}
|
||||
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
|
||||
}
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
|
||||
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
|
||||
} else if (str == context.getString(R.string.update)) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.name)
|
||||
}
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.updateOrReDownload(gameEntity)
|
||||
return
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
if (downloadEntity == null && gameEntity.getApk().size == 1) {
|
||||
val entryMap: ArrayMap<String, DownloadEntity> = gameEntity.getEntryMap()
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
if (entryMap.isNotEmpty()) {
|
||||
downloadEntity = entryMap[apkEntity.getPlatform()]
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apk.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshot(gameEntity)
|
||||
|
||||
// 找不到时,若类型为畅玩,尝试从畅玩数据库的快照中获取 downloadEntity。若存在,代表游戏已下载并成功安装
|
||||
if (downloadEntity == null && gameEntity.isVGame()) {
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.id, gameEntity.getUniquePackageName())
|
||||
}
|
||||
|
||||
// 还是找不到时,尝试从 gameEntity 里找已绑定的 downloadEntity
|
||||
if (downloadEntity == null) {
|
||||
downloadEntity = gameEntity.getEntryMap().getOrDefault(gameEntity.getUniquePlatform(), null)
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
if (XapkUnzipStatus.SUCCESS.name == xapkStatus && isInstalling(downloadEntity.path)) {// 安装过程中避免重复点击
|
||||
return
|
||||
}
|
||||
if (XapkUnzipStatus.UNZIPPING.name == xapkStatus) {
|
||||
cancelUnzipTask(downloadEntity)
|
||||
return
|
||||
@ -930,9 +979,11 @@ object DownloadItemUtils {
|
||||
context.getString(R.string.resume) -> {
|
||||
DownloadManager.getInstance().resume(downloadEntity, true)
|
||||
}
|
||||
|
||||
context.getString(R.string.waiting) -> {
|
||||
Utils.toast(context, "最多只能同时下载三个任务,请稍等")
|
||||
}
|
||||
|
||||
else -> {
|
||||
DownloadManager.getInstance().pause(downloadEntity.url)
|
||||
}
|
||||
@ -953,7 +1004,7 @@ object DownloadItemUtils {
|
||||
) {
|
||||
if (gameEntity.getApk().isEmpty()) return
|
||||
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size)
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
@ -964,7 +1015,13 @@ object DownloadItemUtils {
|
||||
isSubscribe,
|
||||
traceEvent
|
||||
)
|
||||
Utils.toast(context, gameEntity.name + "已加入下载队列")
|
||||
ToastUtils.toast(gameEntity.name + "已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
if (downloadBtn is DownloadButton) {
|
||||
downloadBtn.text = "0%"
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_NORMAL
|
||||
@ -985,10 +1042,16 @@ object DownloadItemUtils {
|
||||
isSubscribe: Boolean,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size)
|
||||
val msg = FileUtils.isCanDownload(context, gameEntity.getApk()[0].size ?: "")
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
||||
Utils.toast(context, gameEntity.name + "已加入下载队列")
|
||||
ToastUtils.toast(gameEntity.name + "已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
if (downloadBtn is DownloadButton) {
|
||||
downloadBtn.setText(R.string.downloading)
|
||||
downloadBtn.buttonStyle = DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN
|
||||
@ -1018,9 +1081,11 @@ object DownloadItemUtils {
|
||||
adapter?.notifyItemChanged(position)
|
||||
refreshCallback?.onCallback()
|
||||
}
|
||||
|
||||
PackageUtils.isCanPluggable(apkEntity) -> {
|
||||
DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
|
||||
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
|
||||
}
|
||||
|
||||
else -> {
|
||||
PackageInstaller.install(context, downloadEntity)
|
||||
}
|
||||
|
||||
@ -98,18 +98,20 @@ object DownloadNotificationHelper {
|
||||
DownloadStatus.waiting -> builder.setContentText("等待中")
|
||||
DownloadStatus.subscribe,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.diskisfull,
|
||||
DownloadStatus.diskioerror,
|
||||
DownloadStatus.neterror -> builder.setContentText("已暂停,连接WiFi自动下载")
|
||||
else -> builder.setContentText("暂停中")
|
||||
}
|
||||
builder.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
|
||||
}
|
||||
|
||||
when {
|
||||
entity.status == DownloadStatus.done -> {
|
||||
when (entity.status) {
|
||||
DownloadStatus.done -> {
|
||||
builder.setSortKey("A")
|
||||
builder.setOngoing(true) // 垃圾华为 sortKey 不起效 priority 也不起效,要将下载完成任务的通知置顶只能设置为 ongoing,喷了
|
||||
}
|
||||
entity.status == DownloadStatus.downloading -> builder.setSortKey("B")
|
||||
DownloadStatus.downloading -> builder.setSortKey("B")
|
||||
else -> builder.setSortKey("C")
|
||||
}
|
||||
|
||||
|
||||
@ -8,33 +8,28 @@ import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.callback.ConfirmListener
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.entity.SuggestType
|
||||
import com.gh.gamecenter.common.eventbus.EBShowDialog
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.energy.EnergyBridge
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.feature.utils.PlatformUtils
|
||||
import com.gh.gamecenter.help.HelpAndFeedbackBridge
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.pkg.PkgHelper
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.*
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.json.JSONObject
|
||||
|
||||
object DownloadObserver {
|
||||
|
||||
@ -44,7 +39,10 @@ object DownloadObserver {
|
||||
// TODO 修复因为更改内存对象造成的双重下载完成事件问题,具体触发代码见 DownloadDao.updateSnapshotList
|
||||
private var mDoneDebouncePair: Pair<String, Long>? = null
|
||||
|
||||
private const val TEA_EVENT_DOWNLOAD_COMPLETE = "game_addiction"
|
||||
private const val TAG = "DownloadObserver"
|
||||
private const val CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED = "CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED"
|
||||
|
||||
private val mRetryableHashMap = hashMapOf<String, Boolean>()
|
||||
|
||||
// 如果在WIFI状态下,下载自动暂停,则再重试一遍
|
||||
@JvmStatic
|
||||
@ -75,35 +73,48 @@ object DownloadObserver {
|
||||
|
||||
val currentActivity = AppManager.getInstance().currentActivity() ?: return
|
||||
|
||||
DialogHelper.showDialog(currentActivity, "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
|
||||
HelpAndFeedbackBridge.startSuggestionActivity(
|
||||
currentActivity,
|
||||
SuggestType.gameQuestion, "notfound",
|
||||
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
|
||||
SimpleGameEntity(gameId, downloadEntity.name, "")
|
||||
)
|
||||
}, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
|
||||
DialogHelper.showDialog(
|
||||
currentActivity,
|
||||
"下载失败",
|
||||
"下载链接已失效,建议提交反馈",
|
||||
"立即反馈",
|
||||
"取消",
|
||||
{
|
||||
HelpAndFeedbackBridge.startSuggestionActivity(
|
||||
currentActivity,
|
||||
SuggestType.gameQuestion, "notfound",
|
||||
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
|
||||
SimpleGameEntity(gameId, downloadEntity.name, "")
|
||||
)
|
||||
},
|
||||
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
|
||||
)
|
||||
return
|
||||
} else if (DownloadStatus.neterror == downloadEntity.status || DownloadStatus.timeout == downloadEntity.status) {
|
||||
if (downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD].isNullOrEmpty()
|
||||
} else if (DownloadStatus.neterror == downloadEntity.status
|
||||
|| DownloadStatus.timeout == downloadEntity.status
|
||||
|| DownloadStatus.diskioerror == downloadEntity.status
|
||||
|| DownloadStatus.diskisfull == downloadEntity.status
|
||||
) {
|
||||
if (mRetryableHashMap[downloadEntity.url] == true
|
||||
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
|
||||
) {
|
||||
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = downloadEntity.progress.toString()
|
||||
downloadManager.updateDownloadEntity(downloadEntity)
|
||||
downloadManager.resumeDownload(downloadEntity.url)
|
||||
debugOnly {
|
||||
Utils.log("DownloadObserver", "下载重试->" + downloadEntity.toJson())
|
||||
}
|
||||
mRetryableHashMap[downloadEntity.url] = false
|
||||
Utils.log(TAG, "下载重试->" + downloadEntity.toJson())
|
||||
} else {
|
||||
Utils.toast(mApplication, "网络不稳定,下载任务已暂停")
|
||||
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
|
||||
|
||||
debugOnly {
|
||||
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
|
||||
if (DownloadStatus.diskisfull == downloadEntity.status) {
|
||||
ToastUtils.toast("磁盘已满,请清理空间后重试下载")
|
||||
} else if (DownloadStatus.diskioerror == downloadEntity.status) {
|
||||
ToastUtils.toast("磁盘 IO 异常,请稍后重试")
|
||||
} else {
|
||||
ToastUtils.toast("网络不稳定,下载任务已暂停")
|
||||
}
|
||||
|
||||
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
|
||||
Utils.log(TAG, "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
} else if (DownloadStatus.redirected == downloadEntity.status) {
|
||||
debugOnly { Utils.log("重定向完毕") }
|
||||
Utils.log(TAG, "重定向完毕")
|
||||
DownloadDataHelper.uploadRedirectEvent(downloadEntity)
|
||||
} else if (DownloadStatus.unqualified == downloadEntity.status) {
|
||||
// 未成年
|
||||
@ -148,40 +159,35 @@ object DownloadObserver {
|
||||
if (DownloadStatus.done == downloadEntity.status) {
|
||||
if (mDoneDebouncePair?.first != downloadEntity.url) {
|
||||
mDoneDebouncePair = Pair(downloadEntity.url, System.currentTimeMillis())
|
||||
performDownloadCompleteAction(downloadEntity, gameId, downloadManager)
|
||||
performDownloadCompleteAction(downloadEntity, downloadManager)
|
||||
} else {
|
||||
if (mDoneDebouncePair?.second == 0L
|
||||
|| System.currentTimeMillis() - (mDoneDebouncePair?.second ?: 0) > 500
|
||||
) {
|
||||
performDownloadCompleteAction(downloadEntity, gameId, downloadManager)
|
||||
performDownloadCompleteAction(downloadEntity, downloadManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.done) {
|
||||
mRetryableHashMap.remove(downloadEntity.url)
|
||||
|
||||
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", downloadEntity.packageName, ""))
|
||||
}
|
||||
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
// 如果已下载大小发生变化,表示成功恢复下载,则重置重试标记
|
||||
if (downloadEntity.status == DownloadStatus.downloading &&
|
||||
downloadEntity.progress.toString() != downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD]
|
||||
) {
|
||||
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = ""
|
||||
downloadManager.updateDownloadEntity(downloadEntity)
|
||||
if (downloadEntity.status == DownloadStatus.downloading) {
|
||||
mRetryableHashMap[downloadEntity.url] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加观察者
|
||||
DownloadManager.getInstance().addObserver(dataWatcher)
|
||||
|
||||
}
|
||||
|
||||
private fun performDownloadCompleteAction(
|
||||
downloadEntity: DownloadEntity,
|
||||
gameId: String,
|
||||
downloadManager: DownloadManager
|
||||
) {
|
||||
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
|
||||
@ -199,14 +205,10 @@ object DownloadObserver {
|
||||
} else {
|
||||
statDoneEvent(downloadEntity)
|
||||
|
||||
if (!SPUtils.getBoolean(TEA_EVENT_DOWNLOAD_COMPLETE)) {
|
||||
HaloApp.getInstance().flavorProvider.logEvent(TEA_EVENT_DOWNLOAD_COMPLETE)
|
||||
SPUtils.setBoolean(TEA_EVENT_DOWNLOAD_COMPLETE, true)
|
||||
}
|
||||
logCoreEventIfNeeded(downloadEntity.getGameCategory())
|
||||
|
||||
GameActivityDownloadHelper.clear()
|
||||
|
||||
EnergyBridge.postEnergyTask("download_game", downloadEntity.gameId, downloadEntity.packageName)
|
||||
val platform = PlatformUtils.getInstance(mApplication)
|
||||
.getPlatformName(downloadEntity.platform)
|
||||
if (platform != null) {
|
||||
@ -216,25 +218,24 @@ object DownloadObserver {
|
||||
EventBus.getDefault().post(
|
||||
EBShowDialog(
|
||||
BaseActivity.PLUGGABLE,
|
||||
downloadEntity.path
|
||||
downloadEntity.path,
|
||||
downloadEntity.pluginDesc
|
||||
)
|
||||
)
|
||||
|
||||
downloadEntity.isPlugin -> Utils.toast(
|
||||
mApplication,
|
||||
downloadEntity.name + " - " + platform + " - 下载完成"
|
||||
)
|
||||
|
||||
else -> {
|
||||
if (downloadEntity.isVGame()) {
|
||||
VHelper.showFloatingWindow(downloadEntity.packageName)
|
||||
} else {
|
||||
if (!downloadEntity.isVGame()) {
|
||||
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (downloadEntity.isVGame()) {
|
||||
VHelper.showFloatingWindow(downloadEntity.packageName)
|
||||
} else {
|
||||
if (!downloadEntity.isVGame()) {
|
||||
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
|
||||
}
|
||||
}
|
||||
@ -244,15 +245,10 @@ object DownloadObserver {
|
||||
val gameName = downloadEntity.getMetaExtra(Constants.GAME_NAME)
|
||||
if (simulatorJson.isEmpty()) return
|
||||
var simulator = GsonUtils.fromJson(simulatorJson, SimulatorEntity::class.java)
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(
|
||||
HaloApp.getInstance().application,
|
||||
simulator.apk?.packageName
|
||||
)
|
||||
val isInstalledNewSimulator =
|
||||
SimulatorGameManager.isNewSimulatorInstalled(HaloApp.getInstance().application)
|
||||
val isInstalledOldSimulator =
|
||||
SimulatorGameManager.isOldSimulatorInstalled(HaloApp.getInstance().application)
|
||||
// if (!isInstalled && !isInstalledNewSimulator) {
|
||||
val currentActivity = AppManager.getInstance().currentActivity()
|
||||
?: return
|
||||
val newSimulator = Config.getNewSimulatorEntitySetting()
|
||||
@ -263,14 +259,13 @@ object DownloadObserver {
|
||||
currentActivity, simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, downloadEntity.gameId, gameName, null
|
||||
)
|
||||
// }
|
||||
SimulatorGameManager.recordDownloadSimulatorGame(downloadEntity.gameId, simulator.type)
|
||||
SimulatorGameManager.postPlayedGame(downloadEntity.gameId, downloadEntity.packageName)
|
||||
} else {
|
||||
val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
// 是否是自动安装
|
||||
val isAutoInstall = SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true)
|
||||
if (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall) {
|
||||
if (downloadType != Constants.VSPACE_32_DOWNLOAD_ONLY && (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall)) {
|
||||
if (FileUtils.isEmptyFile(downloadEntity.path)) {
|
||||
Utils.toast(mApplication, R.string.install_failure_hint)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
@ -290,7 +285,8 @@ object DownloadObserver {
|
||||
EventBus.getDefault().post(
|
||||
EBShowDialog(
|
||||
BaseActivity.PLUGGABLE,
|
||||
downloadEntity.path
|
||||
downloadEntity.path,
|
||||
downloadEntity.pluginDesc
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@ -306,9 +302,6 @@ object DownloadObserver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 统计下载完成
|
||||
uploadData(gameId, downloadEntity.platform)
|
||||
}
|
||||
|
||||
// 下载过程分析统计
|
||||
@ -371,17 +364,41 @@ object DownloadObserver {
|
||||
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
|
||||
}
|
||||
|
||||
if (downloadEntity.isVGame()) {
|
||||
SensorsBridge.trackEvent(
|
||||
"HaloFunGameDownloadDone",
|
||||
"game_name", downloadEntity.name,
|
||||
"game_id", downloadEntity.gameId,
|
||||
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位"
|
||||
)
|
||||
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
|
||||
SensorsBridge.trackEvent(
|
||||
"HaloFunDownloadDone",
|
||||
"space_schema_type",
|
||||
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
|
||||
)
|
||||
} else if (downloadEntity.gameId != Constants.GHZS_GAME_ID && downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD) {
|
||||
SensorsBridge.trackEvent(
|
||||
"DownloadProcessFinish",
|
||||
"game_id", downloadEntity.gameId,
|
||||
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
|
||||
"game_type", downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: "",
|
||||
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
|
||||
"page_name", getCurrentPageEntity().pageName,
|
||||
"page_id", getCurrentPageEntity().pageId,
|
||||
"page_business_id", getCurrentPageEntity().pageBusinessId,
|
||||
"last_page_name", getLastPageEntity().pageName,
|
||||
"last_page_id", getLastPageEntity().pageId,
|
||||
"last_page_business_id", getLastPageEntity().pageBusinessId
|
||||
)
|
||||
}
|
||||
|
||||
var downloadSpeed = 0L
|
||||
val elapsedTimeString = downloadEntity.meta[DownloadConfig.KEY_DOWNLOAD_ELAPSED_TIME]
|
||||
if (elapsedTimeString != null) {
|
||||
var elapsedTime = elapsedTimeString.toLong()
|
||||
if (elapsedTime == 0L) {
|
||||
elapsedTime = 1L
|
||||
SentryHelper.onEvent(
|
||||
"DOWNLOAD_ELAPSED_TIME",
|
||||
"elapsedTime is zero",
|
||||
downloadEntity.gameId + ":" + downloadEntity.size
|
||||
)
|
||||
}
|
||||
downloadSpeed = downloadEntity.size / elapsedTime
|
||||
}
|
||||
@ -393,7 +410,9 @@ object DownloadObserver {
|
||||
id = downloadEntity.gameId,
|
||||
mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR),
|
||||
gameVersion = downloadEntity.versionName ?: "",
|
||||
isPlatformRecommend = isPlatformRecommend
|
||||
isPlatformRecommend = isPlatformRecommend,
|
||||
adIconActive = downloadEntity.meta[Constants.AD_ICON_ACTIVE].toBoolean(),
|
||||
isAdData = downloadEntity.meta[Constants.IS_AD_DATA].toBoolean()
|
||||
),
|
||||
downloadEntity.platform,
|
||||
downloadEntity.exposureTrace,
|
||||
@ -418,19 +437,21 @@ object DownloadObserver {
|
||||
DataLogUtils.uploadHijack(mApplication, downloadEntity)
|
||||
}
|
||||
|
||||
// 统计下载
|
||||
private fun uploadData(id: String, platform: String?) {
|
||||
val params = HashMap<String, String>()
|
||||
params["game"] = id
|
||||
params["platform"] = platform ?: ""
|
||||
val body = RequestBody.create(
|
||||
MediaType.parse("application/json"),
|
||||
JSONObject(params as Map<*, *>).toString()
|
||||
)
|
||||
RetrofitManager.getInstance().api.postDownload(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(Response())
|
||||
/**
|
||||
* 根据预设的游戏类型上报关键事件(下载完成事件)
|
||||
*/
|
||||
private fun logCoreEventIfNeeded(gameCategory: String) {
|
||||
val category = PkgHelper.getCoreEventGameCategory()
|
||||
val categoryMatched = if (category == "standard" || category.isNullOrEmpty()) {
|
||||
true
|
||||
} else {
|
||||
gameCategory == category
|
||||
}
|
||||
|
||||
if (!SPUtils.getBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED) && categoryMatched) {
|
||||
HaloApp.getInstance().flavorProvider.logCoreEvent()
|
||||
SPUtils.setBoolean(CORE_EVENT_DOWNLOAD_COMPLETE_LOGGED, true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,11 +15,10 @@ import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
|
||||
import com.gh.gamecenter.common.avoidcallback.Callback
|
||||
import com.gh.gamecenter.common.callback.ConfirmListener
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.toObject
|
||||
import com.gh.gamecenter.common.entity.ErrorEntity
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.login.user.LoginTag
|
||||
import com.halo.assistant.fragment.user.UserInfoEditFragment
|
||||
import com.halo.assistant.fragment.user.VerifyPhoneFragment
|
||||
import com.lightgame.utils.AppManager
|
||||
@ -403,23 +402,50 @@ object ErrorHelper {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handleLoginError(context: Context, httpException: HttpException?) {
|
||||
fun handleLoginError(
|
||||
context: Context,
|
||||
httpException: HttpException?,
|
||||
loginTagChinese: String,
|
||||
isCertificate: Boolean
|
||||
) {
|
||||
try {
|
||||
var errorReason = ""
|
||||
val errorEntity: ErrorEntity? =
|
||||
httpException?.response()?.errorBody()?.string()?.toObject()
|
||||
when {
|
||||
errorEntity?.code == 403099 -> Utils.toast(context, "当前账号正在注销,禁止登录")
|
||||
errorEntity?.code == 403099 -> {
|
||||
errorReason = "当前账号正在注销,禁止登录"
|
||||
Utils.toast(context, errorReason)
|
||||
}
|
||||
|
||||
// 用户禁止登录
|
||||
errorEntity?.code == 403401 -> Utils.toast(context, "您的账号存在违规,不允许登录")
|
||||
errorEntity?.code == 403401 -> {
|
||||
errorReason = "您的账号存在违规,不允许登录"
|
||||
Utils.toast(context, errorReason)
|
||||
}
|
||||
|
||||
// 设备禁止登录
|
||||
errorEntity?.code == 403404 -> Utils.toast(context, "您的设备存在违规,不允许登录")
|
||||
errorEntity?.code == 403404 -> {
|
||||
errorReason = "您的设备存在违规,不允许登录"
|
||||
Utils.toast(context, errorReason)
|
||||
}
|
||||
|
||||
errorEntity?.toast?.isNotEmpty() == true -> Utils.toast(context, errorEntity.toast)
|
||||
errorEntity?.toast?.isNotEmpty() == true -> {
|
||||
Utils.toast(context, errorEntity.toast)
|
||||
errorReason = errorEntity.toast!!
|
||||
}
|
||||
|
||||
else -> Utils.toast(context, R.string.login_failure)
|
||||
}
|
||||
if (!isCertificate) SensorsBridge.trackEvent(
|
||||
"LoginResult",
|
||||
"login_type",
|
||||
loginTagChinese,
|
||||
"login_result",
|
||||
"失败",
|
||||
"defeated_reason",
|
||||
errorReason
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Utils.toast(context, R.string.login_failure)
|
||||
|
||||
@ -7,7 +7,6 @@ import android.view.View
|
||||
import android.widget.TextView
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.energy.EnergyBridge
|
||||
import com.lightgame.utils.Util_System_Keyboard
|
||||
import com.lzf.easyfloat.EasyFloat
|
||||
import com.lzf.easyfloat.enums.ShowPattern
|
||||
@ -22,7 +21,6 @@ import com.lzf.easyfloat.enums.SidePattern
|
||||
object FloatingBackViewManager {
|
||||
|
||||
const val TYPE_ACTIVITY = "type_activity"
|
||||
const val TYPE_TASK = "type_task"
|
||||
|
||||
private const val FLOATING_BACK_VIEW = "floating_back_view"
|
||||
|
||||
@ -56,10 +54,6 @@ object FloatingBackViewManager {
|
||||
titleView?.text = "返回活动"
|
||||
|
||||
DirectUtils.directToWebView(activity, mActivityUrl, ("返回活动浮窗"))
|
||||
} else if (mType == TYPE_TASK) {
|
||||
titleView?.text = "返回任务"
|
||||
|
||||
activity.startActivity(EnergyBridge.getEnergyCenterIntent(activity))
|
||||
}
|
||||
|
||||
disableBackView()
|
||||
@ -111,11 +105,4 @@ object FloatingBackViewManager {
|
||||
mActivityUrl = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回小浮窗类型是否为活动
|
||||
*/
|
||||
fun isTypeActivity(): Boolean {
|
||||
return mType == TYPE_ACTIVITY
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,6 +15,7 @@ import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.download.dialog.DownloadDialog
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
@ -26,12 +27,12 @@ import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.observableToMain
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.runOnUiThread
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.core.utils.MtaHelper
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.energy.EnergyBridge
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PluginLocation
|
||||
@ -138,7 +139,7 @@ object GameActivityDownloadHelper {
|
||||
) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
|
||||
CheckLoginUtils.checkLogin(context, entrance) {
|
||||
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
|
||||
ReservationHelper.reserve(context, gameEntity.id, gameEntity.name ?: "", object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
LogUtils.logReservation(gameEntity, traceEvent)
|
||||
clear()
|
||||
@ -184,6 +185,12 @@ object GameActivityDownloadHelper {
|
||||
str != context.getString(R.string.launch)
|
||||
) {
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
when {
|
||||
str == context.getString(R.string.download) || str == context.getString(R.string.attempt) -> {
|
||||
@ -206,6 +213,12 @@ object GameActivityDownloadHelper {
|
||||
}
|
||||
else -> {
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,7 +235,7 @@ object GameActivityDownloadHelper {
|
||||
) {
|
||||
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity) {
|
||||
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
||||
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
|
||||
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
|
||||
}
|
||||
}
|
||||
@ -242,7 +255,12 @@ object GameActivityDownloadHelper {
|
||||
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
|
||||
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity) {
|
||||
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apk.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe: Boolean ->
|
||||
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
|
||||
}
|
||||
}
|
||||
@ -263,7 +281,7 @@ object GameActivityDownloadHelper {
|
||||
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
|
||||
} else {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity) {
|
||||
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
||||
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
|
||||
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
}
|
||||
@ -299,7 +317,7 @@ object GameActivityDownloadHelper {
|
||||
}
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "")
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
|
||||
} else {
|
||||
downloadEntity?.run {
|
||||
install(context, gameEntity, apk, this)
|
||||
@ -316,7 +334,6 @@ object GameActivityDownloadHelper {
|
||||
location: String,
|
||||
traceEvent: ExposureEvent
|
||||
) {
|
||||
EnergyBridge.postEnergyTask("play_game", gameEntity.id, gameEntity.getApk()[0].packageName)
|
||||
//启动模拟器游戏
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
if (NewSimulatorGameManager.shouldShowUpdateNewSimulatorAlert(context)) {
|
||||
@ -338,14 +355,14 @@ object GameActivityDownloadHelper {
|
||||
}
|
||||
|
||||
if (gameEntity.isVGame()) {
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity.getUniquePackageName() ?: "")
|
||||
VHelper.installOrLaunch((context as AppCompatActivity), gameEntity)
|
||||
return
|
||||
}
|
||||
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.name)
|
||||
}
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk()[0].packageName)
|
||||
PackageLauncher.launchApp(context, gameEntity, gameEntity.getApk()[0].packageName)
|
||||
}
|
||||
|
||||
// 处理更新状态
|
||||
@ -357,7 +374,7 @@ object GameActivityDownloadHelper {
|
||||
location: String,
|
||||
traceEvent: ExposureEvent
|
||||
) {
|
||||
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
||||
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
|
||||
update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
|
||||
}
|
||||
}
|
||||
@ -421,6 +438,12 @@ object GameActivityDownloadHelper {
|
||||
), entrance, location, isSubscribe, traceEvent
|
||||
)
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast(msg)
|
||||
}
|
||||
@ -440,6 +463,12 @@ object GameActivityDownloadHelper {
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast(msg)
|
||||
}
|
||||
@ -460,7 +489,7 @@ object GameActivityDownloadHelper {
|
||||
gameEntity.getEntryMap().remove(apkEntity.getPlatform())
|
||||
}
|
||||
PackageUtils.isCanPluggable(apkEntity) -> {
|
||||
DialogHelper.showPluginDialog(context) { PackageInstaller.uninstall(context, path) }
|
||||
DialogHelper.showPluginDialog(context, gameEntity.pluginDesc) { PackageInstaller.uninstall(context, path) }
|
||||
}
|
||||
else -> {
|
||||
PackageInstaller.install(context, downloadEntity)
|
||||
@ -480,6 +509,12 @@ object GameActivityDownloadHelper {
|
||||
) {
|
||||
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
|
||||
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
||||
if (BrowserInstallHelper.shouldAutoSwitchAssistantInstall(gameEntity)) {
|
||||
val toast = context.getString(R.string.unsupported_browser_install_hint)
|
||||
AppExecutor.uiExecutor.executeWithDelay({
|
||||
ToastUtils.toast(toast)
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
|
||||
@ -8,6 +8,7 @@ import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.feature.view.DownloadButton;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
@ -107,7 +108,7 @@ public class GameUtils {
|
||||
|
||||
// 在下载管理找不到下载实体,并且为畅玩游戏的时候到畅玩数据库里找
|
||||
if (downloadEntity == null && gameEntity.isVGame()) {
|
||||
downloadEntity = VHelper.getDownloadEntitySnapshot(gameEntity.getId(), apkEntity.getPackageName());
|
||||
downloadEntity = VHelper.getVDownloadEntitySnapshot(gameEntity.getId(), apkEntity.getPackageName());
|
||||
}
|
||||
|
||||
if (downloadEntity != null) {
|
||||
@ -180,7 +181,8 @@ public class GameUtils {
|
||||
if (gameEntity.isVGame()) {
|
||||
return context.getString(R.string.smooth);
|
||||
} else {
|
||||
if ("smooth".equals(gameEntity.getDownloadStatus())) {
|
||||
if (Constants.V_GAME.equals(gameEntity.getDownloadStatus())
|
||||
|| Constants.V_GAME_32.equals(gameEntity.getDownloadStatus())) {
|
||||
GameEntity.GameCategory gameCategory = gameEntity.getGameCategory();
|
||||
if (gameCategory.equals(GameEntity.GameCategory.ONLINE_GAME)
|
||||
|| gameCategory.equals(GameEntity.GameCategory.INTERNATIONAL_ONLINE_GAME)) {
|
||||
|
||||
@ -33,94 +33,6 @@ object IntegralLogHelper {
|
||||
log(json, "score", false)
|
||||
}
|
||||
|
||||
fun logTask(event: String, location: String, jobId: String, jobName: String, jobType: String) {
|
||||
val json = JSONObject().apply {
|
||||
tryWithDefaultCatch {
|
||||
put("meta", LogUtils.getMetaObject())
|
||||
put("event", event)
|
||||
put("location", location)
|
||||
put("timestamp", System.currentTimeMillis() / 1000)
|
||||
put("launch_id", launchId)
|
||||
put("session_id", sessionId)
|
||||
put("job_id", jobId)
|
||||
put("job_name", jobName)
|
||||
put("job_type", jobType)
|
||||
}
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("LogUtils->$json")
|
||||
}
|
||||
log(json, "score", false)
|
||||
}
|
||||
|
||||
fun logCommodityCategory(
|
||||
event: String,
|
||||
location: String,
|
||||
entrance: String,
|
||||
categoryId: String,
|
||||
categoryName: String
|
||||
) {
|
||||
val json = JSONObject().apply {
|
||||
tryWithDefaultCatch {
|
||||
put("meta", LogUtils.getMetaObject())
|
||||
put("event", event)
|
||||
put("location", location)
|
||||
put("timestamp", System.currentTimeMillis() / 1000)
|
||||
put("launch_id", launchId)
|
||||
put("session_id", sessionId)
|
||||
put("entrance", entrance)
|
||||
put("goods_species_id", categoryId)
|
||||
put("goods_species_name", categoryName)
|
||||
}
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("LogUtils->$json")
|
||||
}
|
||||
log(json, "score", false)
|
||||
}
|
||||
|
||||
fun logCommodity(event: String, location: String, commodityId: String, categoryId: String, categoryName: String) {
|
||||
val json = JSONObject().apply {
|
||||
tryWithDefaultCatch {
|
||||
put("meta", LogUtils.getMetaObject())
|
||||
put("event", event)
|
||||
put("location", location)
|
||||
put("timestamp", System.currentTimeMillis() / 1000)
|
||||
put("launch_id", launchId)
|
||||
put("session_id", sessionId)
|
||||
put("goods_id", commodityId)
|
||||
put("goods_species_id", categoryId)
|
||||
put("goods_species_name", categoryName)
|
||||
}
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("LogUtils->$json")
|
||||
}
|
||||
log(json, "score", false)
|
||||
}
|
||||
|
||||
fun logEnergyRange(event: String, location: String, range: String) {
|
||||
val json = JSONObject().apply {
|
||||
tryWithDefaultCatch {
|
||||
put("meta", LogUtils.getMetaObject())
|
||||
put("event", event)
|
||||
put("location", location)
|
||||
put("timestamp", System.currentTimeMillis() / 1000)
|
||||
put("launch_id", launchId)
|
||||
put("session_id", sessionId)
|
||||
put("energy_range", range)
|
||||
}
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("LogUtils->$json")
|
||||
}
|
||||
log(json, "score", false)
|
||||
}
|
||||
|
||||
fun logPendent(event: String, location: String, pendentId: String, pendentType: String? = null) {
|
||||
val json = JSONObject().apply {
|
||||
tryWithDefaultCatch {
|
||||
|
||||
@ -18,6 +18,7 @@ import com.gh.gamecenter.adapter.LibaoDetailAdapter;
|
||||
import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.NotificationHelper;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.utils.ToastUtils;
|
||||
import com.gh.gamecenter.core.utils.UrlFilterUtils;
|
||||
import com.gh.gamecenter.feature.entity.ApkEntity;
|
||||
@ -305,7 +306,7 @@ public class LibaoUtils {
|
||||
|
||||
public static void initLibaoBtn(final Context context, final TextView libaoBtn, final LibaoEntity libaoEntity,
|
||||
final boolean isInstallRequired, final LibaoDetailAdapter adapter, boolean shouldUpdateStatus,
|
||||
final String entrance, final OnLibaoStatusChangeListener listener) {
|
||||
final String entrance, final String sourceEntrance, final OnLibaoStatusChangeListener listener) {
|
||||
setLiBaoBtnStatusRound(libaoBtn, libaoEntity, shouldUpdateStatus, context);
|
||||
String status = libaoEntity.getStatus();
|
||||
|
||||
@ -318,6 +319,32 @@ public class LibaoUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// 类型为复制的,不需要登录也可以直接复制
|
||||
if ("copy".equals(libaoEntity.getReceiveMethod())) {
|
||||
if ("finish".equals(libaoEntity.getStatus())) {
|
||||
libaoBtn.setText(R.string.libao_finish);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_round_gray);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
libaoBtn.setOnClickListener(v -> ToastUtils.toast("兑换码领取已结束"));
|
||||
} else {
|
||||
libaoBtn.setText(R.string.libao_copy);
|
||||
libaoBtn.setTextColor(ExtensionsKt.toColor(R.color.white, context));
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
libaoBtn.setOnClickListener(v -> {
|
||||
LogUtils.uploadReceiveGift(
|
||||
"game_gift_code_successful",
|
||||
libaoEntity.getId(),
|
||||
libaoEntity.getName(),
|
||||
"游戏详情",
|
||||
libaoEntity.getGame().getId(),
|
||||
libaoEntity.getGame().getName()
|
||||
);
|
||||
ExtensionsKt.copyTextAndToast(libaoEntity.getCode(), libaoEntity.getToast());
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
libaoBtn.setOnClickListener(v -> {
|
||||
String btnStatus = libaoBtn.getText().toString();
|
||||
// 领取限制
|
||||
@ -380,13 +407,29 @@ public class LibaoUtils {
|
||||
if ("repeatLing".equals(status)) {
|
||||
ToastUtils.showToast("礼包每天0点刷新,明日0点后可再领一个");
|
||||
} else {
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance, listener);
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance, sourceEntrance, listener);
|
||||
}
|
||||
SensorsBridge.trackEvent("GameGiftDraw",
|
||||
"gift_type", "普通礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
break;
|
||||
case "再淘":
|
||||
case "再淘一个":
|
||||
case "淘号":
|
||||
libaoTao(context, libaoBtn, libaoEntity, isInstallRequired, adapter, status, entrance, listener);
|
||||
libaoTao(context, libaoBtn, libaoEntity, isInstallRequired, adapter, status, entrance, sourceEntrance, listener);
|
||||
SensorsBridge.trackEvent("GameGiftDraw",
|
||||
"gift_type", "淘号礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -394,7 +437,7 @@ public class LibaoUtils {
|
||||
}
|
||||
|
||||
private static void libaoTao(Context context, TextView libaoBtn, LibaoEntity libaoEntity, boolean isInstallRequired, LibaoDetailAdapter adapter,
|
||||
String status, String entrance, final OnLibaoStatusChangeListener listener) {
|
||||
String status, String entrance, String sourceEntrance, final OnLibaoStatusChangeListener listener) {
|
||||
if ("repeatTao".equals(status)) {
|
||||
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
|
||||
return;
|
||||
@ -449,6 +492,16 @@ public class LibaoUtils {
|
||||
des = "您已领取过相同的礼包,可能无法成功兑换";
|
||||
}
|
||||
ToastUtils.showToast(des);
|
||||
|
||||
SensorsBridge.trackEvent("GameGiftDrawResult",
|
||||
"draw_result", "成功",
|
||||
"gift_type", "淘号礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -507,12 +560,22 @@ public class LibaoUtils {
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "发生异常");
|
||||
|
||||
SensorsBridge.trackEvent("GameGiftDrawResult",
|
||||
"draw_result", "失败",
|
||||
"gift_type", "淘号礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void libaoLing(final Context context, TextView libaoBtn, final LibaoEntity libaoEntity, final LibaoDetailAdapter adapter,
|
||||
final boolean isInstallRequired, String captchaCode, final String entrance, final OnLibaoStatusChangeListener listener) {
|
||||
final boolean isInstallRequired, String captchaCode, final String entrance, final String sourceEntrance, final OnLibaoStatusChangeListener listener) {
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
if (libaoBtn != null) {
|
||||
@ -543,6 +606,15 @@ public class LibaoUtils {
|
||||
}
|
||||
if (TextUtils.isEmpty(libaoCode)) {
|
||||
Utils.toast(context, "领取异常");
|
||||
SensorsBridge.trackEvent("GameGiftDrawResult",
|
||||
"draw_result", "失败",
|
||||
"gift_type", "普通礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
return;
|
||||
}
|
||||
libaoEntity.setAvailable(libaoEntity.getAvailable() - 1);
|
||||
@ -570,6 +642,15 @@ public class LibaoUtils {
|
||||
}
|
||||
return null;
|
||||
});
|
||||
SensorsBridge.trackEvent("GameGiftDrawResult",
|
||||
"draw_result", "成功",
|
||||
"gift_type", "普通礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -615,7 +696,7 @@ public class LibaoUtils {
|
||||
}, false, "", "");
|
||||
libaoEntity.setStatus("used_up");
|
||||
if (libaoBtn != null) {
|
||||
initLibaoBtn(context, libaoBtn, libaoEntity, isInstallRequired, adapter, false, entrance, listener);
|
||||
initLibaoBtn(context, libaoBtn, libaoEntity, isInstallRequired, adapter, false, entrance, sourceEntrance, listener);
|
||||
}
|
||||
break;
|
||||
case "maintaining":
|
||||
@ -633,13 +714,22 @@ public class LibaoUtils {
|
||||
} else if (exception.code() == 412) {
|
||||
// 需要验证
|
||||
GeetestUtils.getInstance().showDialog(context, captcha ->
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, captcha, entrance, listener));
|
||||
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, captcha, entrance, sourceEntrance, listener));
|
||||
return;
|
||||
} else if (exception.code() == 401) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "发生异常");
|
||||
SensorsBridge.trackEvent("GameGiftDrawResult",
|
||||
"draw_result", "失败",
|
||||
"gift_type", "普通礼包",
|
||||
"game_name", libaoEntity.getGame().getName(),
|
||||
"game_id", libaoEntity.getGame().getId(),
|
||||
"gift_id", libaoEntity.getId(),
|
||||
"gift_name", libaoEntity.getName(),
|
||||
"source_entrance", sourceEntrance
|
||||
);
|
||||
}
|
||||
}, captchaCode);
|
||||
}
|
||||
@ -696,7 +786,7 @@ public class LibaoUtils {
|
||||
, "关闭", "启动游戏"
|
||||
, () -> {
|
||||
if (LibaoUtils.isAppInstalled(context, libaoEntity.getPackageName())) {
|
||||
PackageUtils.launchApplicationByPackageName(context, libaoEntity.getPackageName());
|
||||
PackageLauncher.launchApp(context, null, libaoEntity.getPackageName());
|
||||
} else {
|
||||
Utils.toast(context, "请安装游戏:" + libaoEntity.getGame().getName()
|
||||
+ PlatformUtils.getInstance(context).getPlatformName(libaoEntity.getPlatform()) + "版");
|
||||
|
||||
@ -415,13 +415,19 @@ public class LogUtils {
|
||||
LoghubUtils.log(object, "video_streaming", false);
|
||||
}
|
||||
|
||||
public static void uploadWelcomeDialog(String action, String dialogId, String linkTitle) {
|
||||
public static void uploadWelcomeDialog(String action,
|
||||
String dialogId,
|
||||
String linkId,
|
||||
String linkType,
|
||||
String linkTitle) {
|
||||
ExposureEntity payload = new ExposureEntity();
|
||||
payload.setWelcomeDialogId(dialogId);
|
||||
payload.setWelcomeDialogLinkTitle(linkTitle);
|
||||
|
||||
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
|
||||
entity.setEvent("dialog");
|
||||
entity.setLinkId(linkId);
|
||||
entity.setLinkType(linkType);
|
||||
entity.setAction(action);
|
||||
entity.setMeta(MetaUtil.INSTANCE.getMeta());
|
||||
entity.setPayload(payload);
|
||||
@ -562,16 +568,19 @@ public class LogUtils {
|
||||
}
|
||||
|
||||
public static void uploadSearchGame(String event, String location, String key, String searchType) {
|
||||
uploadSearchClick(event, location, key, searchType, "", "", false, false);
|
||||
uploadSearchClick(event, location, key, searchType, "", "", 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mirrorDataPosition 镜像的归类,不是镜像是为 -1 ,使用镜像 1 时为 1,使用镜像 2 时为 2
|
||||
*/
|
||||
public static void uploadSearchClick(String event,
|
||||
String location,
|
||||
String key,
|
||||
String searchType,
|
||||
String gameId,
|
||||
String gameName,
|
||||
Boolean isMirrorData,
|
||||
int mirrorDataPosition,
|
||||
Boolean isAdData) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
@ -585,7 +594,13 @@ public class LogUtils {
|
||||
payload.put("search_type", searchType); //搜索类型, 有四种取值 默认搜索/历史搜索/自动搜索/主动搜索
|
||||
payload.put(KEY_GAME_ID, gameId); //event为search_click才取值
|
||||
payload.put(KEY_GAME_NAME, gameName); //event为search_click才取值
|
||||
payload.put("is_mirror_data", isMirrorData);
|
||||
|
||||
// 是否使用镜像
|
||||
if (mirrorDataPosition == 1) {
|
||||
payload.put("is_mirror_data", true);
|
||||
} else if (mirrorDataPosition == 2) {
|
||||
payload.put("is_mirror2_data", true);
|
||||
}
|
||||
payload.put("is_ad_data", isAdData);
|
||||
object.put(KEY_PAY_LOAD, payload);
|
||||
} catch (JSONException e) {
|
||||
@ -1028,7 +1043,7 @@ public class LogUtils {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payloadObject = new JSONObject();
|
||||
try {
|
||||
object.put(KEY_EVENT, event);//game_gift_get_successful领取礼包、game_gift_dig_successful淘号
|
||||
object.put(KEY_EVENT, event);//game_gift_get_successful领取礼包、game_gift_dig_successful淘号、game_gift_code_successful复制礼包
|
||||
payloadObject.put("gift_id", giftId);
|
||||
payloadObject.put("gift_name", giftName);
|
||||
payloadObject.put("location", location);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -137,7 +137,7 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
// 游戏详情点击顶部标签
|
||||
fun logGameDetailTagClick(gameId: String, gameName: String, tagId: String, tagName: String) {
|
||||
fun logGameDetailTagClick(gameId: String, gameName: String, tagId: String, tagName: String, isTop: Boolean) {
|
||||
val json = json {
|
||||
KEY_EVENT to "game_type_tag_click_jump"
|
||||
KEY_META to LogUtils.getMetaObject()
|
||||
@ -145,6 +145,7 @@ object NewLogUtils {
|
||||
KEY_GAME_NAME to gameName
|
||||
"type_tag_id" to tagId
|
||||
"type_tag_name" to tagName
|
||||
"is_top_type_tag" to isTop
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
}
|
||||
log(json, LOG_STORE_EVENT)
|
||||
@ -1343,8 +1344,9 @@ object NewLogUtils {
|
||||
gameName: String,
|
||||
tagId: String,
|
||||
tagName: String,
|
||||
linkType: String,
|
||||
linkTitle: String
|
||||
linkId: String = "",
|
||||
linkType: String = "",
|
||||
linkTitle: String = ""
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "search_click_tag"
|
||||
@ -1354,6 +1356,7 @@ object NewLogUtils {
|
||||
KEY_GAME_NAME to gameName
|
||||
"tag_id" to tagId
|
||||
"tag" to tagName
|
||||
"link_id" to linkId
|
||||
"link_type" to linkType
|
||||
"link_title" to linkTitle
|
||||
KEY_META to LogUtils.getMetaObject()
|
||||
@ -1654,13 +1657,22 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//进入游戏单广场
|
||||
fun logEnterGameCollectionSquare(entrance: String, forumName: String = "", title: String = "", id: String = "") {
|
||||
fun logEnterGameCollectionSquare(
|
||||
entrance: String,
|
||||
forumName: String = "",
|
||||
gameCollectionTitle: String = "",
|
||||
gameCollectionId: String = "",
|
||||
collectionName: String = "",
|
||||
collectionId: String = ""
|
||||
) {
|
||||
val json = json {
|
||||
KEY_EVENT to "enter_game_collect_square"
|
||||
KEY_ENTRANCE to entrance
|
||||
"forum_name" to forumName
|
||||
"game_collect_title" to title
|
||||
"game_collect_id" to id
|
||||
"game_collect_title" to gameCollectionTitle
|
||||
"game_collect_id" to gameCollectionId
|
||||
"game_list_collection_name" to collectionName
|
||||
"game_list_collection_id" to collectionId
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1668,9 +1680,10 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//进入选择标签
|
||||
fun logEnterGameCollectionTag() {
|
||||
fun logEnterGameCollectionTag(source: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "enter_game_collect_tag_location"
|
||||
"source" to source
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1678,11 +1691,12 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//筛选游戏单标签
|
||||
fun logFilterGameCollectionTag(tagCategory: String, tagName: String) {
|
||||
fun logFilterGameCollectionTag(tagCategory: String, tagName: String, source: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "filter_game_collect_tag"
|
||||
"filter_tag_category" to tagCategory
|
||||
"filter_tag_name" to tagName
|
||||
"source" to source
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
@ -1690,9 +1704,10 @@ object NewLogUtils {
|
||||
}
|
||||
|
||||
//点击安利墙卡片
|
||||
fun logClickGameCollectionAmway() {
|
||||
fun logClickGameCollectionAmway(tabName: String) {
|
||||
val json = json {
|
||||
KEY_EVENT to "click_game_collect_recommend_card"
|
||||
"tab_name" to tabName
|
||||
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
|
||||
parseAndPutMeta().invoke(this)
|
||||
}
|
||||
|
||||
@ -1,37 +1,32 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.FileProvider
|
||||
import com.gh.common.dialog.InstallPermissionDialogFragment
|
||||
import com.gh.common.xapk.XapkInstallReceiver
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.getExtension
|
||||
import com.gh.gamecenter.common.utils.getMetaExtra
|
||||
import com.gh.gamecenter.common.utils.toRequestBody
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.gamecenter.core.utils.MD5Utils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.vpn.VpnHelper
|
||||
import com.gh.vspace.VHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
import java.io.File
|
||||
|
||||
object PackageInstaller {
|
||||
@ -64,15 +59,17 @@ object PackageInstaller {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO 此处可能遇到 activity 是 WXEntryActivity
|
||||
// TODO 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装!
|
||||
// 已知问题
|
||||
// 1. 此处可能遇到 activity 是 WXEntryActivity,因为 WXEntryActivity 不是 AppCompatActivity 调不起弹窗
|
||||
// 2. 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装
|
||||
if (currentActivity is AppCompatActivity && !currentActivity.isFinishing) {
|
||||
InstallPermissionDialogFragment.show(currentActivity, downloadEntity) { isFromPermissionGrantedCallback ->
|
||||
// 取消状态栏下载完成的通知,若存在
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
|
||||
if (isFromPermissionGrantedCallback && Build.VERSION.SDK_INT >= 31) {
|
||||
// 安卓12后的设备,需要重启应用来继续解压 XAPK 文件
|
||||
if (isFromPermissionGrantedCallback && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val pm = context.packageManager
|
||||
val intent = pm.getLaunchIntentForPackage(context.packageName)
|
||||
val mainIntent = Intent.makeRestartActivityTask(intent!!.component)
|
||||
@ -82,7 +79,7 @@ object PackageInstaller {
|
||||
if (isXapk) {
|
||||
XapkInstaller.install(context, downloadEntity, showUnzipToast)
|
||||
} else {
|
||||
install(context, downloadEntity.isPlugin, downloadEntity.path)
|
||||
install(context, downloadEntity.isPlugin, downloadEntity.path, downloadEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,9 +91,11 @@ object PackageInstaller {
|
||||
*
|
||||
* 除非特殊情况,请勿使用此方法进行应用安装操作
|
||||
* 除非你已经确定该文件一定是Apk
|
||||
*
|
||||
* @param downloadEntity 仅用来记录日志用,非必须可为空
|
||||
*/
|
||||
@JvmStatic
|
||||
fun install(context: Context, isPluggin: Boolean = false, pkgPath: String?) {
|
||||
fun install(context: Context, isPluggin: Boolean = false, pkgPath: String?, downloadEntity: DownloadEntity? = null) {
|
||||
if (pkgPath.isNullOrEmpty()) {
|
||||
ToastUtils.toast("下载文件异常")
|
||||
return
|
||||
@ -112,23 +111,16 @@ object PackageInstaller {
|
||||
}
|
||||
|
||||
if (PackageUtils.isCanLaunchSetup(context, pkgPath)) {
|
||||
// val app = HaloApp.getInstance()
|
||||
val currentActivity = CurrentActivityHolder.getCurrentActivity()
|
||||
|
||||
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
|
||||
|
||||
// val downloadEntity =
|
||||
// DownloadManager.getInstance().allDownloadEntity.firstOrNull {
|
||||
// it.path == pkgPath
|
||||
// }
|
||||
// if (downloadEntity != null) {
|
||||
// showCertificateDialogIfNeededBeforeInstall(app, downloadEntity, pkgPath)
|
||||
// } else {
|
||||
val installIntent = getInstallIntent(context, pkgPath)
|
||||
context.startActivity(installIntent)
|
||||
// }
|
||||
if (VpnHelper.shouldUseVpn() && currentActivity is AppCompatActivity) {
|
||||
turnOnVpnThenInstall(currentActivity, pkgPath, downloadEntity)
|
||||
} else {
|
||||
install(context, pkgPath)
|
||||
}
|
||||
} else {
|
||||
if (isPluggin) {
|
||||
DialogHelper.showPluginDialog(context) {
|
||||
DialogHelper.showPluginDialog(context, downloadEntity?.pluginDesc) {
|
||||
uninstall(context, pkgPath)
|
||||
}
|
||||
} else {
|
||||
@ -143,47 +135,39 @@ object PackageInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun showCertificateDialogIfNeededBeforeInstall(context: Context, downloadEntity: DownloadEntity, pkgPath: String) {
|
||||
val isOverwrite = LunchType.UPDATE.name == SPUtils.getString(Constants.SP_INSTALL_TYPE)
|
||||
val hashMap = hashMapOf(Pair("url", downloadEntity.url), Pair("overwrite", isOverwrite))
|
||||
RetrofitManager.getInstance().api.postCertificationCheck(hashMap.toRequestBody())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
val installIntent = getInstallIntent(context, pkgPath)
|
||||
context.startActivity(installIntent)
|
||||
}
|
||||
/**
|
||||
* 最终执行安装的方法
|
||||
*/
|
||||
private fun install(context: Context, pkgPath: String) {
|
||||
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
|
||||
val installIntent = getInstallIntent(context, pkgPath)
|
||||
context.startActivity(installIntent)
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
super.onFailure(exception)
|
||||
fun installMultiple(
|
||||
context: Context,
|
||||
pkgPath: String,
|
||||
sessionId: Int = -1
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
return
|
||||
}
|
||||
val installer = context.packageManager.packageInstaller
|
||||
val session = installer.openSession(sessionId)
|
||||
// 监听安装回调的组件,可以是Activity、Service或者是BroadcastReceiver
|
||||
val intent = Intent(context, XapkInstallReceiver::class.java)
|
||||
.also {
|
||||
it.putExtra(XapkInstallReceiver.KEY_PACKAGE_PATH, pkgPath)
|
||||
}
|
||||
|
||||
if (exception is HttpException) {
|
||||
val resultString =
|
||||
(exception as HttpException).response().errorBody()
|
||||
?.string()
|
||||
// 未实名
|
||||
when {
|
||||
resultString?.contains("403117") == true -> {
|
||||
RealNameHelper.showRealNameUncertificatedDialog(
|
||||
downloadEntity
|
||||
)
|
||||
}
|
||||
resultString?.contains("403118") == true -> {
|
||||
RealNameHelper.showRealNameUnqualifiedDialog(
|
||||
downloadEntity
|
||||
)
|
||||
}
|
||||
resultString?.contains("400004") == true -> {
|
||||
ToastUtils.toast("安装服务异常,缺少参数")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ToastUtils.toast("安装服务异常,${exception.localizedMessage}请稍候再试")
|
||||
}
|
||||
}
|
||||
})
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_CANCEL_CURRENT
|
||||
}
|
||||
val pendingIntent = PendingIntent.getActivity(context, sessionId, intent, flags)
|
||||
// 提交数据流并执行安装
|
||||
session.commit(pendingIntent.intentSender)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,7 +244,8 @@ object PackageInstaller {
|
||||
}
|
||||
|
||||
private fun getFileSuffixByFormat(format: String?): String {
|
||||
return if (format == XapkInstaller.XAPK_EXTENSION_NAME) {
|
||||
return if (format == Constants.XAPK_FORMAT
|
||||
|| format == Constants.XAPK_APKS_FORMAT) {
|
||||
XapkInstaller.XAPK_EXTENSION_NAME
|
||||
} else {
|
||||
"apk"
|
||||
@ -271,4 +256,81 @@ object PackageInstaller {
|
||||
fun createDownloadId(gameName: String?): String {
|
||||
return MD5Utils.getContentMD5(gameName + "_" + System.currentTimeMillis())
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 VPN 然后安装应用 (若没有授权会先提醒授权 VPN ,若拒绝授权会回落到直接执行安装)
|
||||
*/
|
||||
private fun turnOnVpnThenInstall(currentActivity: AppCompatActivity,
|
||||
pkgPath: String,
|
||||
downloadEntity: DownloadEntity?) {
|
||||
if (VpnHelper.isVpnPermissionGranted(currentActivity) == true) {
|
||||
VpnHelper.startVpn(currentActivity) { shouldShowVpnError ->
|
||||
if (shouldShowVpnError) {
|
||||
ToastUtils.toast("安装防护功能启动失败")
|
||||
}
|
||||
install(currentActivity, pkgPath)
|
||||
}
|
||||
} else {
|
||||
val isTheFirstTimeToShowVpnHintDialog = VpnHelper.isTheFistTimeToShowVpnHintDialog()
|
||||
|
||||
downloadEntity?.let {
|
||||
NewFlatLogUtils.logVpnHintDialogShow(it.gameId, it.name)
|
||||
}
|
||||
|
||||
// 将 VPN 提示弹窗标记为已读(已读后的下一次显示"不再提醒"按钮)
|
||||
VpnHelper.setVpnHintDialogShowed()
|
||||
if (!VpnHelper.shouldShowVpnHintDialog()) {
|
||||
VpnHelper.startVpn(currentActivity) { shouldShowVpnError ->
|
||||
if (shouldShowVpnError) {
|
||||
ToastUtils.toast("安装防护功能启动失败")
|
||||
}
|
||||
install(currentActivity, pkgPath)
|
||||
}
|
||||
} else {
|
||||
DialogHelper.showGuideDialog(
|
||||
context = currentActivity,
|
||||
title = "开启安装防护",
|
||||
content = "建议您开启安装防护功能,该功能有助于帮助您更快的完成安装,避免因提示和置换导致的重复下载等问题,安装防护功能需要获取您的VPN权限",
|
||||
confirmText = "立即授权开启防护",
|
||||
cancelText = "不再提醒",
|
||||
confirmClickCallback = {
|
||||
VpnHelper.ignoreVpnHintDialog()
|
||||
VpnHelper.startVpn(currentActivity) { shouldShowVpnError ->
|
||||
if (shouldShowVpnError) {
|
||||
ToastUtils.toast("安装防护功能启动失败")
|
||||
}
|
||||
install(currentActivity, pkgPath)
|
||||
}
|
||||
|
||||
downloadEntity?.let {
|
||||
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "立即授权")
|
||||
}
|
||||
},
|
||||
cancelClickCallback = {
|
||||
VpnHelper.ignoreVpnFunction()
|
||||
install(currentActivity, pkgPath)
|
||||
downloadEntity?.let {
|
||||
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "不再提醒")
|
||||
}
|
||||
},
|
||||
extraConfig = DialogHelper.Config(
|
||||
showCloseIcon = true,
|
||||
showAlternativeCancelStyle = !isTheFirstTimeToShowVpnHintDialog
|
||||
),
|
||||
uiModificationCallback = { binding, dialog ->
|
||||
binding.cancelTv.visibility = View.GONE
|
||||
binding.closeContainer.setOnClickListener {
|
||||
install(currentActivity, pkgPath)
|
||||
dialog.dismiss()
|
||||
|
||||
downloadEntity?.let {
|
||||
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "关闭按钮")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
54
app/src/main/java/com/gh/common/util/PackageLauncher.kt
Normal file
54
app/src/main/java/com/gh/common/util/PackageLauncher.kt
Normal file
@ -0,0 +1,54 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.entity.GameInstall
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository
|
||||
|
||||
object PackageLauncher {
|
||||
|
||||
/*
|
||||
* 启动应用
|
||||
*/
|
||||
@JvmStatic
|
||||
fun launchApp(
|
||||
context: Context,
|
||||
gameEntity: GameEntity? = null,
|
||||
packageName: String?
|
||||
) {
|
||||
|
||||
if (packageName.isNullOrEmpty()) {
|
||||
ToastUtils.toast("启动失败")
|
||||
return
|
||||
}
|
||||
|
||||
// 获取 GameInstall 实体,用于记录启动日志用
|
||||
val gameInstall = if (gameEntity != null) {
|
||||
GameInstall.transformGameInstall(gameEntity, packageName)
|
||||
} else {
|
||||
PackageRepository.gameInstalled.find { it.packageName == packageName }
|
||||
}
|
||||
|
||||
if (gameInstall != null) {
|
||||
NewFlatLogUtils.logGameLaunch(
|
||||
gameId = gameInstall.id ?: "unknown",
|
||||
gameName = gameInstall.name ?: "unknown",
|
||||
gameCategory = gameInstall.category ?: "unknown",
|
||||
downloadStatus = if (gameInstall.downloadStatus == "demo") "试玩" else "下载"
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
val intent = context.applicationContext.packageManager.getLaunchIntentForPackage(packageName)
|
||||
if (intent != null) {
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
ToastUtils.toast("启动失败")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.toast( "启动失败")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -23,6 +23,7 @@ import androidx.webkit.WebViewCompat;
|
||||
import com.android.apksig.ApkVerifier;
|
||||
import com.android.apksig.internal.apk.ApkSigningBlockUtilsLite;
|
||||
import com.g00fy2.versioncompare.Version;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
@ -37,6 +38,7 @@ import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.gh.vspace.VHelper;
|
||||
import com.gh.vspace.db.VGameEntity;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lg.vspace.VirtualAppManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import net.dongliu.apk.parser.ApkFile;
|
||||
@ -139,6 +141,11 @@ public class PackageUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// 镜像游戏,使用镜像 Apk 替换掉原来的 ApkNormal
|
||||
if (RegionSettingHelper.shouldThisGameDisplayMirrorInfo(gameEntity.getId())) {
|
||||
gameEntity.setApkNormal(gameEntity.getApk());
|
||||
}
|
||||
|
||||
// 非插件游戏更新
|
||||
for (ApkEntity apkEntity : gameEntity.getApkNormal()) {
|
||||
|
||||
@ -548,9 +555,32 @@ public class PackageUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据包名,判断是否已安装该游戏
|
||||
* 不区分是否有桌面图标
|
||||
*/
|
||||
public static boolean isInstalledFromAllPackage(Context context, String packageName) {
|
||||
ArrayList<String> allPackageName = getAllPackageName(context);
|
||||
return allPackageName.contains(packageName);
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
context.getPackageManager().getPackageInfo(
|
||||
packageName,
|
||||
PackageManager.PackageInfoFlags.of(0)
|
||||
);
|
||||
} else {
|
||||
context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
ArrayList<String> allPackageName = getAllPackageName(context);
|
||||
boolean isInstalled = allPackageName.contains(packageName);
|
||||
|
||||
if (isInstalled) {
|
||||
// 能进这里说明上面的 try {} 结果有问题,记录一下
|
||||
SentryHelper.INSTANCE.onEvent("CHECK_INSTALLED_CONFLICT", "packageName", packageName);
|
||||
}
|
||||
|
||||
return isInstalled;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -716,9 +746,11 @@ public class PackageUtils {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* 启动应用
|
||||
* 请使用 PackageLauncher.launchApp()
|
||||
*/
|
||||
@Deprecated
|
||||
public static void launchApplicationByPackageName(Context context, String packageName) {
|
||||
try {
|
||||
Intent intent = context.getApplicationContext().getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
|
||||
@ -3,8 +3,10 @@ package com.gh.common.util
|
||||
import com.gh.gamecenter.core.utils.CurrentActivityHolder
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.ShellActivity
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.common.utils.getMetaExtra
|
||||
import com.lightgame.download.DownloadEntity
|
||||
@ -14,6 +16,9 @@ object RealNameHelper {
|
||||
|
||||
var pendingInstallPkgPath = ""
|
||||
|
||||
// 0表示未实名,1表示未成年,2表示成年
|
||||
private var mCertificationStatus: Int = 0
|
||||
|
||||
/**
|
||||
* 弹未成年人不能下载游戏弹窗
|
||||
*/
|
||||
@ -54,6 +59,15 @@ object RealNameHelper {
|
||||
val isForced = downloadEntity.getMetaExtra("force_real_name") != "false"
|
||||
|
||||
NewLogUtils.logCertificationTrigger(downloadEntity.gameId, downloadEntity.name)
|
||||
SensorsBridge.trackEvent(
|
||||
"VerificationDialogShow",
|
||||
"game_id",
|
||||
downloadEntity.gameId,
|
||||
"game_name",
|
||||
downloadEntity.name ?: "",
|
||||
"game_type",
|
||||
downloadEntity.meta[Constants.GAME_CATEGORY_IN_CHINESE] ?: ""
|
||||
)
|
||||
|
||||
val contentText = if (downloadEntity.status == DownloadStatus.done) {
|
||||
"为保护未成年身心健康成长\n" + "根据相关政策要求,该游戏不对未成年人开放\n" + "如需完成安装,请前往实名认证"
|
||||
@ -88,9 +102,11 @@ object RealNameHelper {
|
||||
pendingInstallPkgPath = downloadEntity.path
|
||||
}
|
||||
NewLogUtils.logCertificationHintDialogOptionsClicked("前往实名认证")
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", "前往实名认证")
|
||||
},
|
||||
cancelClickCallback = {
|
||||
NewLogUtils.logCertificationHintDialogOptionsClicked("取消")
|
||||
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", "取消")
|
||||
if (!isForced) {
|
||||
DownloadManager.getInstance()
|
||||
.resumeAllInvisiblePendingTask()
|
||||
@ -111,7 +127,21 @@ object RealNameHelper {
|
||||
DownloadManager.getInstance()
|
||||
.addInvisiblePendingTask(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实名状态 0表示未实名,1表示未成年,2表示成年
|
||||
*/
|
||||
fun getCertificationStatus(): Int {
|
||||
return mCertificationStatus
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新实名状态 0表示未实名,1表示未成年,2表示成年
|
||||
*/
|
||||
@JvmStatic
|
||||
fun updateCertificationStatus(newCertificationStatus: Int) {
|
||||
mCertificationStatus = newCertificationStatus
|
||||
}
|
||||
|
||||
}
|
||||
@ -69,7 +69,7 @@ object ReservationHelper {
|
||||
|
||||
@JvmStatic
|
||||
@SuppressLint("CheckResult")
|
||||
fun reserve(context: Context, gameId: String, callback: EmptyCallback) {
|
||||
fun reserve(context: Context, gameId: String, gameName: String, callback: EmptyCallback) {
|
||||
val requestMap = hashMapOf<String, String>()
|
||||
requestMap["game_id"] = gameId
|
||||
RetrofitManager.getInstance().api
|
||||
@ -78,6 +78,16 @@ object ReservationHelper {
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmentGameResult",
|
||||
"game_name",
|
||||
gameName,
|
||||
"game_id",
|
||||
gameId,
|
||||
"result",
|
||||
"成功"
|
||||
)
|
||||
|
||||
ReservationRepository.addReservationToMemoryAndRefresh(gameId)
|
||||
callback.onCallback()
|
||||
val wechatConfig = SPUtils.getString(Constants.SP_WECHAT_CONFIG).toObject<WechatConfigEntity>()
|
||||
@ -88,14 +98,22 @@ object ReservationHelper {
|
||||
DialogUtils.showReserveSuccessDialog(context)
|
||||
} else {
|
||||
NewLogUtils.logReserveWechatRemindPopShow(wechatConfig)
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogShow")
|
||||
DialogUtils.showReserveSuccess2WechatBindDialog(context, object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
|
||||
context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmenWechatRemindConfigPageShow",
|
||||
"source_entrance",
|
||||
"设置微信提醒弹窗"
|
||||
)
|
||||
}
|
||||
}, object : CancelListener {
|
||||
override fun onCancel() {
|
||||
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "关闭弹窗")
|
||||
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -103,6 +121,15 @@ object ReservationHelper {
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
SensorsBridge.trackEvent(
|
||||
"AppointmentGameResult",
|
||||
"game_name",
|
||||
gameName,
|
||||
"game_id",
|
||||
gameId,
|
||||
"result",
|
||||
"失败"
|
||||
)
|
||||
ToastUtils.showToast(exception.message ?: "")
|
||||
}
|
||||
})
|
||||
|
||||
29
app/src/main/java/com/gh/common/util/SensorsLogUtils.kt
Normal file
29
app/src/main/java/com/gh/common/util/SensorsLogUtils.kt
Normal file
@ -0,0 +1,29 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Message
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge
|
||||
|
||||
object SensorsLogUtils {
|
||||
private const val KEY_EVENT_NAME = "event_name"
|
||||
private val mLogHandler = LogHandler()
|
||||
|
||||
fun trackEventDelay(key: Int, eventName: String, delay: Long) {
|
||||
mLogHandler.sendMessageDelayed(Message().apply {
|
||||
what = key
|
||||
data.putString(KEY_EVENT_NAME, eventName)
|
||||
}, delay)
|
||||
}
|
||||
|
||||
fun removeTrackEvent(key: Int) {
|
||||
mLogHandler.removeMessages(key)
|
||||
}
|
||||
|
||||
class LogHandler : Handler(Looper.getMainLooper()) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
super.handleMessage(msg)
|
||||
SensorsBridge.trackEvent(msg.data.getString(KEY_EVENT_NAME) ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
135
app/src/main/java/com/gh/common/util/TextViewExt.kt
Normal file
135
app/src/main/java/com/gh/common/util/TextViewExt.kt
Normal file
@ -0,0 +1,135 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.TextPaint
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.ClickableSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.text.style.UnderlineSpan
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
/**
|
||||
* @author : liujiarui
|
||||
* date : 2023/3/22
|
||||
* description : 文本颜色事件控制
|
||||
*/
|
||||
//作用域进行限制
|
||||
@DslMarker
|
||||
@Target(AnnotationTarget.TYPE)
|
||||
annotation class TextSpanDsl
|
||||
|
||||
interface DslSpannableStringBuilder {
|
||||
//增加一段文字
|
||||
fun addText(text: String, method: (@TextSpanDsl DslSpanBuilder.() -> Unit)? = null)
|
||||
fun addText(@StringRes stringRes: Int, method: (@TextSpanDsl DslSpanBuilder.() -> Unit)? = null)
|
||||
}
|
||||
|
||||
interface DslSpanBuilder {
|
||||
//设置文字颜色文本
|
||||
fun setColor(color: String)
|
||||
|
||||
//设置文字颜色int
|
||||
fun setColor(color: ColorInt)
|
||||
|
||||
//设置文字颜色id
|
||||
fun setColor(color: ColorResId)
|
||||
|
||||
//设置点击事件
|
||||
fun onClick(useUnderLine: Boolean = false, onClick: (View) -> Unit)
|
||||
}
|
||||
|
||||
//为 TextView 创建扩展函数,其参数为接口的扩展函数
|
||||
fun TextView.buildSpannableString(init: @TextSpanDsl DslSpannableStringBuilder.() -> Unit) {
|
||||
//具体实现类
|
||||
val spanStringBuilderImpl = DslSpannableStringBuilderImpl(context)
|
||||
spanStringBuilderImpl.init()
|
||||
movementMethod = LinkMovementMethod.getInstance()
|
||||
//通过实现类返回SpannableStringBuilder
|
||||
text = spanStringBuilderImpl.build()
|
||||
}
|
||||
|
||||
class DslSpannableStringBuilderImpl(val context: Context) : DslSpannableStringBuilder {
|
||||
private val builder = SpannableStringBuilder()
|
||||
|
||||
//记录上次添加文字后最后的索引值
|
||||
private var lastIndex: Int = 0
|
||||
var isClickable = false
|
||||
|
||||
override fun addText(text: String, method: (@TextSpanDsl DslSpanBuilder.() -> Unit)?) {
|
||||
val start = lastIndex
|
||||
builder.append(text)
|
||||
lastIndex += text.length
|
||||
val spanBuilder = DslSpanBuilderImpl(context)
|
||||
method?.let { spanBuilder.it() }
|
||||
spanBuilder.apply {
|
||||
onClickSpan?.let {
|
||||
builder.setSpan(it, start, lastIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
isClickable = true
|
||||
}
|
||||
if (!useUnderLine) {
|
||||
val noUnderlineSpan = NoUnderlineSpan()
|
||||
builder.setSpan(noUnderlineSpan, start, lastIndex, Spanned.SPAN_MARK_MARK)
|
||||
}
|
||||
foregroundColorSpan?.let {
|
||||
builder.setSpan(it, start, lastIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun addText(stringRes: Int, method: (@TextSpanDsl DslSpanBuilder.() -> Unit)?) {
|
||||
val text = context.getString(stringRes)
|
||||
addText(text, method)
|
||||
}
|
||||
|
||||
fun build(): SpannableStringBuilder {
|
||||
return builder
|
||||
}
|
||||
}
|
||||
|
||||
class DslSpanBuilderImpl(val context: Context) : DslSpanBuilder {
|
||||
var foregroundColorSpan: ForegroundColorSpan? = null
|
||||
var onClickSpan: ClickableSpan? = null
|
||||
var useUnderLine = true
|
||||
|
||||
override fun setColor(color: String) {
|
||||
foregroundColorSpan = ForegroundColorSpan(Color.parseColor(color))
|
||||
}
|
||||
|
||||
override fun setColor(color: ColorInt) {
|
||||
foregroundColorSpan = ForegroundColorSpan(color.color)
|
||||
}
|
||||
|
||||
override fun setColor(color: ColorResId) {
|
||||
val c = ContextCompat.getColor(context, color.colorResId)
|
||||
foregroundColorSpan = ForegroundColorSpan(c)
|
||||
}
|
||||
|
||||
override fun onClick(useUnderLine: Boolean, onClick: (View) -> Unit) {
|
||||
onClickSpan = object : ClickableSpan() {
|
||||
override fun onClick(widget: View) {
|
||||
onClick(widget)
|
||||
}
|
||||
}
|
||||
this.useUnderLine = useUnderLine
|
||||
}
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class ColorInt(val color: Int)
|
||||
|
||||
@JvmInline
|
||||
value class ColorResId(val colorResId: Int)
|
||||
|
||||
class NoUnderlineSpan : UnderlineSpan() {
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
ds.color = ds.linkColor
|
||||
ds.isUnderlineText = false
|
||||
}
|
||||
}
|
||||
@ -12,10 +12,7 @@ import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.utils.DarkModeUtils
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.common.utils.sp2px
|
||||
import com.gh.gamecenter.common.utils.toColor
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils
|
||||
import com.gh.gamecenter.feature.entity.TagStyleEntity
|
||||
import kotlin.math.ceil
|
||||
@ -41,12 +38,12 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
gravity = Gravity.CENTER_VERTICAL
|
||||
|
||||
val ta = context.obtainStyledAttributes(attrs, R.styleable.FlexLinearLayout)
|
||||
mItemHeight = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemHeight, 20f.dip2px())
|
||||
mPadding = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemPadding, 5f.dip2px())
|
||||
mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4f.dip2px())
|
||||
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10f.sp2px().toFloat())
|
||||
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18f.dip2px())
|
||||
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5f.dip2px())
|
||||
mItemHeight = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemHeight, 20F.dip2px())
|
||||
mPadding = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemPadding, 5F.dip2px())
|
||||
mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4F.dip2px())
|
||||
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10F.sp2px().toFloat())
|
||||
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18F.dip2px())
|
||||
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5F.dip2px())
|
||||
|
||||
ta.recycle()
|
||||
}
|
||||
@ -95,7 +92,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
layoutParams = params
|
||||
setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_game_detail_label_more))
|
||||
if (DarkModeUtils.isDarkModeOn(context)) setColorFilter(R.color.text_title.toColor(context))
|
||||
background = createBackgroundDrawable()
|
||||
background = createNormalBackgroundDrawable()
|
||||
scaleType = ImageView.ScaleType.CENTER
|
||||
}
|
||||
imageView.setOnClickListener {
|
||||
@ -111,27 +108,33 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
|
||||
includeFontPadding = false
|
||||
textSize = DisplayUtils.px2sp(context, mTextSize).toFloat()
|
||||
gravity = Gravity.CENTER
|
||||
setTextColor(R.color.text_title.toColor(context))
|
||||
|
||||
val params = LayoutParams(LayoutParams.WRAP_CONTENT, mItemHeight)
|
||||
params.setMargins(0, 0, mMargin, 0)
|
||||
setPadding(mPadding, 0, mPadding, 0)
|
||||
layoutParams = params
|
||||
|
||||
val gradientDrawable = createBackgroundDrawable()
|
||||
background = gradientDrawable
|
||||
setTextColor(if (tag.isTop) "#${tag.color}".hexStringToIntColor() else R.color.text_title.toColor(context))
|
||||
background = if (tag.isTop) createTopBackgroundDrawable(tag) else createNormalBackgroundDrawable()
|
||||
setOnClickListener {
|
||||
onClickListener?.onItemClickListener(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createBackgroundDrawable(): GradientDrawable {
|
||||
private fun createNormalBackgroundDrawable(): GradientDrawable {
|
||||
val gradientDrawable = GradientDrawable()
|
||||
val isDarkModeOn = DarkModeUtils.isDarkModeOn(context)
|
||||
gradientDrawable.setColor(Color.TRANSPARENT)
|
||||
gradientDrawable.setStroke(mStrokeWidth, Color.parseColor(if (isDarkModeOn) "#33FFFFFF" else "#CCCCCC"))
|
||||
gradientDrawable.cornerRadius = DisplayUtils.dip2px(2f).toFloat()
|
||||
gradientDrawable.cornerRadius = 2F.dip2px().toFloat()
|
||||
return gradientDrawable
|
||||
}
|
||||
|
||||
private fun createTopBackgroundDrawable(tag: TagStyleEntity): GradientDrawable {
|
||||
val gradientDrawable = GradientDrawable()
|
||||
gradientDrawable.setColor("#${tag.background}".hexStringToIntColor())
|
||||
gradientDrawable.cornerRadius = 2F.dip2px().toFloat()
|
||||
return gradientDrawable
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import com.gh.gamecenter.common.utils.DialogHelper;
|
||||
import com.gh.gamecenter.common.utils.EnvHelper;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.NetworkUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
@ -139,6 +140,7 @@ public class RichEditor extends WebView {
|
||||
setVerticalScrollBarEnabled(false);
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
getSettings().setJavaScriptEnabled(true);
|
||||
getSettings().setDomStorageEnabled(true);
|
||||
setWebChromeClient(new WebChromeClient()); // 不要重写这个方法否则无法加载
|
||||
setWebViewClient(createWebViewClient());
|
||||
|
||||
@ -573,6 +575,13 @@ public class RichEditor extends WebView {
|
||||
exec("javascript:RE.formatBlock();");
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用 JS 方法,告诉网页端该 url 对应视频播放的进度
|
||||
*/
|
||||
public void onVideoPlayedCallback(String url, int position) {
|
||||
exec("javascript:RE.onVideoPlayedCallback('" + url + "', '" + position + "')");
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return HtmlUtils.stripHtml(mContents);
|
||||
}
|
||||
@ -586,7 +595,7 @@ public class RichEditor extends WebView {
|
||||
return String.format("#%06X", (0xFFFFFF & color));
|
||||
}
|
||||
|
||||
protected void exec(final String trigger) {
|
||||
public void exec(final String trigger) {
|
||||
if (isReady) {
|
||||
load(trigger);
|
||||
} else {
|
||||
@ -708,7 +717,9 @@ public class RichEditor extends WebView {
|
||||
|
||||
@JavascriptInterface
|
||||
public void onPageFinished() {
|
||||
mPageFinishedListener.onPageFinished();
|
||||
if (mPageFinishedListener != null) {
|
||||
mPageFinishedListener.onPageFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -721,6 +732,16 @@ public class RichEditor extends WebView {
|
||||
return PackageUtils.getGhVersionCode();
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public boolean isNetworkConnected() {
|
||||
return NetworkUtils.isNetworkConnected(HaloApp.getInstance());
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
public boolean isWifiConnected() {
|
||||
return NetworkUtils.isWifiConnected(HaloApp.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示toast
|
||||
*
|
||||
|
||||
131
app/src/main/java/com/gh/common/xapk/XapkDialogHelper.kt
Normal file
131
app/src/main/java/com/gh/common/xapk/XapkDialogHelper.kt
Normal file
@ -0,0 +1,131 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.activityresult.ActResultRequest
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.entity.SimpleGameEntity
|
||||
import com.gh.gamecenter.common.entity.SuggestType
|
||||
import com.gh.gamecenter.common.utils.DialogHelper
|
||||
import com.gh.gamecenter.common.utils.PermissionHelper
|
||||
import com.gh.gamecenter.common.utils.dip2px
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.help.HelpAndFeedbackBridge
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
object XapkDialogHelper {
|
||||
|
||||
private var mUnzipFailureDialogRef: WeakReference<Dialog>? = null
|
||||
|
||||
fun showUnzipFailureDialog(context: Context, downloadEntity: DownloadEntity, isManualAction: Boolean) {
|
||||
val trigger = if (isManualAction) "手动触发" else "自动触发"
|
||||
NewFlatLogUtils.logXApkUnzipFailedDialogShowed(trigger, downloadEntity.gameId, downloadEntity.name)
|
||||
|
||||
val previousShowedDialog = mUnzipFailureDialogRef?.get()
|
||||
|
||||
if (previousShowedDialog != null
|
||||
&& previousShowedDialog.isShowing
|
||||
&& context == previousShowedDialog.ownerActivity) {
|
||||
// 上一个解压失败弹窗还在显示,当前 activity 不用再显示新的弹窗了
|
||||
return
|
||||
}
|
||||
|
||||
val dialog = DialogHelper.showGuideDialog(
|
||||
context = context,
|
||||
title = "",
|
||||
content = "未授权允许未知来源安装、数据包格式、设备兼容性…等均可能导致解压失败。\n如果开启权限后仍未能解决,请提交反馈帮助我们改进。",
|
||||
confirmText = "开启权限",
|
||||
cancelText = "提交反馈",
|
||||
confirmClickCallback = {
|
||||
if (context is AppCompatActivity) {
|
||||
val intent = PermissionHelper.getToInstallPermissionSettingIntent(context)
|
||||
|
||||
NewFlatLogUtils.logXApkUnzipFailedDialogClick(
|
||||
"开启权限",
|
||||
false,
|
||||
downloadEntity.gameId,
|
||||
downloadEntity.name
|
||||
)
|
||||
|
||||
// 记录应用重启前需要重解压的信息
|
||||
SPUtils.setString(Constants.SP_XAPK_UNZIP_ACTIVITY, context.javaClass.name)
|
||||
SPUtils.setString(Constants.SP_XAPK_URL, downloadEntity.url)
|
||||
|
||||
ActResultRequest(context).startForResult(intent) { resultCode, _ ->
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
NewFlatLogUtils.logXApkUnzipFailedDialogClick(
|
||||
"开启权限",
|
||||
true,
|
||||
downloadEntity.gameId,
|
||||
downloadEntity.name
|
||||
)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
val pm = context.packageManager
|
||||
val restartIntent = pm.getLaunchIntentForPackage(context.packageName)
|
||||
val mainIntent = Intent.makeRestartActivityTask(restartIntent!!.component)
|
||||
context.startActivity(mainIntent)
|
||||
Runtime.getRuntime().exit(0)
|
||||
} else {
|
||||
XapkInstaller.install(context, downloadEntity, true)
|
||||
}
|
||||
} else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
Utils.log("授予未知应用安装权限失败")
|
||||
}
|
||||
}
|
||||
} else if (context is Activity) {
|
||||
PermissionHelper.toInstallPermissionSetting(context)
|
||||
}
|
||||
},
|
||||
cancelClickCallback = {
|
||||
val hint = "《" + downloadEntity.name + "》游戏安装包解压失败,问题反馈:"
|
||||
HelpAndFeedbackBridge.startSuggestionActivity(
|
||||
context,
|
||||
SuggestType.normal,
|
||||
null,
|
||||
hint,
|
||||
SimpleGameEntity(downloadEntity.gameId, downloadEntity.name, downloadEntity.icon)
|
||||
)
|
||||
NewFlatLogUtils.logXApkUnzipFailedDialogClick(
|
||||
"提交反馈",
|
||||
false,
|
||||
downloadEntity.gameId,
|
||||
downloadEntity.name
|
||||
)
|
||||
},
|
||||
uiModificationCallback = { binding, dialog ->
|
||||
binding.headIv.setBackgroundResource(R.drawable.dialog_unzip_failure_head_background)
|
||||
binding.titleTv.visibility = View.GONE
|
||||
// VectorDrawable 的动态颜色设置只在支持 Vector 的系统版本上生效,为了能方便复用资源不支持的就用默认颜色,又不是不能用!
|
||||
binding.closeIv.setColorFilter(Color.WHITE)
|
||||
binding.contentTv.setLineSpacing(5.0F.dip2px().toFloat(), 1.0F)
|
||||
binding.closeContainer.setOnClickListener {
|
||||
NewFlatLogUtils.logXApkUnzipFailedDialogClick(
|
||||
"关闭",
|
||||
false,
|
||||
downloadEntity.gameId,
|
||||
downloadEntity.name
|
||||
)
|
||||
dialog.dismiss()
|
||||
}
|
||||
},
|
||||
extraConfig = DialogHelper.Config(showCloseIcon = true)
|
||||
)
|
||||
|
||||
if (context is Activity) {
|
||||
dialog?.setOwnerActivity(context)
|
||||
}
|
||||
mUnzipFailureDialogRef = WeakReference(dialog)
|
||||
}
|
||||
|
||||
}
|
||||
64
app/src/main/java/com/gh/common/xapk/XapkInstallReceiver.kt
Normal file
64
app/src/main/java/com/gh/common/xapk/XapkInstallReceiver.kt
Normal file
@ -0,0 +1,64 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
class XapkInstallReceiver : Activity() {
|
||||
|
||||
companion object {
|
||||
const val KEY_PACKAGE_PATH = "package_path"
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
overridePendingTransition(0, 0)
|
||||
handleIntent(this, intent)
|
||||
|
||||
}
|
||||
|
||||
private fun handleIntent(context: Context, intent: Intent) {
|
||||
when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val installIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
if (installIntent != null) {
|
||||
try {
|
||||
context.startActivity(installIntent)
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION)
|
||||
} catch (e: Exception) {
|
||||
// OPPO低版本会出现CONFIRM_PERMISSIONS的权限异常,这个问题无解,直接取消安装
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE,
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED,
|
||||
PackageInstaller.STATUS_FAILURE_BLOCKED,
|
||||
PackageInstaller.STATUS_FAILURE_CONFLICT,
|
||||
PackageInstaller.STATUS_FAILURE_INCOMPATIBLE,
|
||||
PackageInstaller.STATUS_FAILURE_INVALID,
|
||||
PackageInstaller.STATUS_FAILURE_STORAGE -> {
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
finish()
|
||||
}
|
||||
else -> {
|
||||
updatePendingSessionInfoStatus(intent, XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updatePendingSessionInfoStatus(intent: Intent, status: Int) {
|
||||
val installPackagePath = intent.getStringExtra(KEY_PACKAGE_PATH)
|
||||
if (!installPackagePath.isNullOrEmpty()) {
|
||||
val pendingSessionInfo = XapkInstaller.getPendingSessionInfo(installPackagePath)
|
||||
pendingSessionInfo?.updateStatus(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,35 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.common.utils.debugOnly
|
||||
import com.gh.gamecenter.common.utils.getExtension
|
||||
import com.gh.gamecenter.common.utils.throwExceptionInDebug
|
||||
import com.gh.gamecenter.common.utils.tryCatchInRelease
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.AppExecutor
|
||||
import com.gh.gamecenter.core.utils.SentryHelper
|
||||
import com.gh.gamecenter.core.utils.ToastUtils
|
||||
import com.gh.gamecenter.xapk.XApkUnZipper
|
||||
import com.gh.gamecenter.xapk.core.XApkFile
|
||||
import com.gh.gamecenter.xapk.core.XApkUnZipCallback
|
||||
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
|
||||
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
|
||||
import com.gh.gamecenter.xapk.io.NonSplitApksOutput
|
||||
import com.gh.gamecenter.xapk.io.OBBFileOutput
|
||||
import com.gh.gamecenter.xapk.io.SplitApksOutput
|
||||
import com.gh.gamecenter.xapk.io.XApkFileOutput
|
||||
import com.gh.gamecenter.xapk.pi.IPackageInstaller
|
||||
import com.gh.ndownload.NDataChanger
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataChanger
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import java.text.DecimalFormat
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -25,10 +41,11 @@ import java.util.*
|
||||
* obb文件直接解压至根目录即可,无需操作文件
|
||||
* apk文件这解压的gh-files文件夹中
|
||||
*/
|
||||
object XapkInstaller : IXapkUnzipListener {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
|
||||
private const val XAPK_PACKAGE_PATH_TAG = "xapk_package_path"
|
||||
|
||||
// private const val XAPK_DATA_PATH_TAG = "xapk_data_path"
|
||||
const val XAPK_EXTENSION_NAME = "xapk"
|
||||
|
||||
// 通过解压过程存放于 DownloadEntity meta
|
||||
@ -38,10 +55,19 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
const val XAPK_DATA_EXTENSION_NAME = "obb"
|
||||
const val PACKAGE_EXTENSION_NAME = "apk"
|
||||
|
||||
private const val GUIDE_TYPE_MIUI_OPTIMIZATION = "miui_optimization"
|
||||
private const val MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE = "MIUI优化关闭提示弹窗"
|
||||
|
||||
private var mContext = HaloApp.getInstance().application.applicationContext
|
||||
|
||||
// 是否需要开启特定线程处理
|
||||
private val mXapkUnzipThreadMap = Collections.synchronizedMap(HashMap<String, XapkUnzipThread>())
|
||||
private val mXApkUnZipper = XApkUnZipper(this)
|
||||
.also {
|
||||
it.registerCallback(this)
|
||||
}
|
||||
|
||||
private val mDownloadEntityMap = Collections.synchronizedMap(HashMap<String, DownloadEntity>())
|
||||
|
||||
private val mPendingSessionInfoMap = HashMap<String, XapkPendingSessionInfo>()
|
||||
|
||||
// 按并行解压
|
||||
@JvmStatic
|
||||
@ -50,6 +76,38 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
|
||||
val filePath = downloadEntity.path
|
||||
if (XAPK_EXTENSION_NAME == filePath.getExtension()) {
|
||||
if (MiuiUtils.isMiui() && !MiuiUtils.isMiuiOptimizationDisabled() && downloadEntity.format == Constants.XAPK_APKS_FORMAT) {// 小米手机开启miui以后,需要引导用户关闭miui优化
|
||||
DialogHelper.showMiuiOptimizationWarning(
|
||||
context,
|
||||
onHintClick = {
|
||||
val guides = Config.getNewApiSettingsEntity()?.install
|
||||
val miuiOptimizationGuide = guides?.guides?.findLast {
|
||||
it.type == GUIDE_TYPE_MIUI_OPTIMIZATION
|
||||
}
|
||||
if (miuiOptimizationGuide != null) {
|
||||
DirectUtils.directToLinkPage(
|
||||
context,
|
||||
miuiOptimizationGuide.link,
|
||||
MIUI_OPTIMIZATION_WARNING_DIALOG_ENTRANCE,
|
||||
""
|
||||
)
|
||||
}
|
||||
},
|
||||
onConfirmClick = {
|
||||
if (SystemUtils.isDevelopmentSettingsEnabled(context)) {
|
||||
context.startActivity(
|
||||
Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
)
|
||||
it.dismiss()
|
||||
} else {
|
||||
ToastUtils.showToast(context.getString(R.string.miui_open_adb_hint))
|
||||
}
|
||||
}
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
unzipXapkFile(downloadEntity)
|
||||
if (showUnzipToast) {
|
||||
Utils.toast(mContext, "解压过程请勿退出光环助手!")
|
||||
@ -61,78 +119,71 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
}
|
||||
|
||||
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
|
||||
if (mXapkUnzipThreadMap[downloadEntity.path] == null) {
|
||||
val xapkUnzipThread = XapkUnzipThread(downloadEntity, this)
|
||||
xapkUnzipThread.start()
|
||||
mXapkUnzipThreadMap[downloadEntity.path] = xapkUnzipThread
|
||||
} else {
|
||||
debugOnly {
|
||||
Utils.log("unzip", "重复解压,该文件解压已在队列中")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProgress(downloadEntity: DownloadEntity, unzipPath: String, unzipSize: Long, unzipProgress: Long) {
|
||||
AppExecutor.uiExecutor.execute {
|
||||
val df = DecimalFormat("#.0")
|
||||
var percent = 0.0
|
||||
tryCatchInRelease {
|
||||
percent = df.format((unzipProgress / unzipSize.toFloat()) * 100).toDouble()
|
||||
}
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = percent.toString()
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
|
||||
DataChanger.notifyDataChanged(downloadEntity)
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onProgress->" + (unzipProgress / unzipSize.toFloat()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNext(downloadEntity: DownloadEntity, unzipPath: String) {
|
||||
if (PACKAGE_EXTENSION_NAME == unzipPath.getExtension()) {
|
||||
downloadEntity.meta[XAPK_PACKAGE_PATH_TAG] = unzipPath
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onNext->$unzipPath")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消解压回调
|
||||
*
|
||||
* 取消后的表现与下载完成一致
|
||||
*/
|
||||
override fun onCancel(downloadEntity: DownloadEntity) {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
DataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(downloadEntity: DownloadEntity, exception: Exception) {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
DataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
mXApkUnZipper.unzip(
|
||||
XApkUnZipEntry(
|
||||
downloadEntity.path,
|
||||
File(downloadEntity.path)
|
||||
)
|
||||
)
|
||||
mDownloadEntityMap[downloadEntity.path] = downloadEntity
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cancelUnzipTask(downloadEntity: DownloadEntity) {
|
||||
mXApkUnZipper.cancel(downloadEntity.path)
|
||||
}
|
||||
|
||||
override fun onProgress(apk: XApkFile, progress: Float) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = String.format("%.2f", progress * 100)
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onProgress->$progress")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(apk: XApkFile, installer: IPackageInstaller) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压成功")
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
|
||||
}
|
||||
|
||||
installer.install(mContext)
|
||||
}
|
||||
|
||||
override fun onError(apk: XApkFile, exception: Throwable) {
|
||||
val downloadEntity = mDownloadEntityMap[apk.file.path] ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
)
|
||||
}
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
@ -140,38 +191,158 @@ object XapkInstaller : IXapkUnzipListener {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSuccess(downloadEntity: DownloadEntity) {
|
||||
mXapkUnzipThreadMap.remove(downloadEntity.path)
|
||||
|
||||
AppExecutor.uiExecutor.execute {
|
||||
val pkgPath = downloadEntity.meta[XAPK_PACKAGE_PATH_TAG]
|
||||
|
||||
if (pkgPath == null) {
|
||||
Utils.toast(mContext, "下载出错,请重新下载!")
|
||||
|
||||
return@execute
|
||||
}
|
||||
|
||||
PackageInstaller.install(mContext, downloadEntity.isPlugin, pkgPath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
|
||||
DataChanger.notifyDataChanged(downloadEntity)
|
||||
override fun onCancel(apk: XApkFile) {
|
||||
val downloadEntity = mDownloadEntityMap.remove(apk.file.path) ?: return
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
}
|
||||
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onSuccess->${downloadEntity.path}")
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun cancelUnzipTask(downloadEntity: DownloadEntity) {
|
||||
val xapkUnzipThread = mXapkUnzipThreadMap[downloadEntity.path]
|
||||
if (xapkUnzipThread != null) {
|
||||
xapkUnzipThread.canceled = true
|
||||
override fun onNext(apk: XApkFile, fileName: String) {
|
||||
debugOnly {
|
||||
Utils.log("unzip", "onNext->$fileName")
|
||||
}
|
||||
}
|
||||
|
||||
fun getPendingSessionInfo(packagePath: String): XapkPendingSessionInfo? = mPendingSessionInfoMap[packagePath]
|
||||
|
||||
fun isInstalling(packagePath: String): Boolean = mPendingSessionInfoMap.containsKey(packagePath)
|
||||
|
||||
/**
|
||||
* 通知XAPK安装完成
|
||||
*/
|
||||
fun onInstalled(packagePath: String) {
|
||||
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
|
||||
|
||||
mPendingSessionInfoMap.remove(packagePath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.INSTALLED.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装成功")
|
||||
}
|
||||
}
|
||||
|
||||
fun onInstallCanceled(packagePath: String) {
|
||||
|
||||
val downloadEntity = mDownloadEntityMap.remove(packagePath) ?: return
|
||||
|
||||
mPendingSessionInfoMap.remove(packagePath)
|
||||
|
||||
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
|
||||
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
|
||||
|
||||
AppExecutor.ioExecutor.execute {
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk安装取消")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前XAPK安装状态, 主要针对以下出现安装结果回调异常的情况:
|
||||
* 1. 用户触碰安装弹窗(原生Android系统)区域外导致安装取消
|
||||
*/
|
||||
fun updateCurrentInstallStatus() {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || mPendingSessionInfoMap.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
||||
val updateList = mutableListOf<XapkPendingSessionInfo>()
|
||||
|
||||
for (pendingSessionInfoEntry in mPendingSessionInfoMap) {
|
||||
|
||||
val pendingSessionInfo = pendingSessionInfoEntry.value
|
||||
|
||||
if (pendingSessionInfo.getStatus() == XapkPendingSessionInfo.STATUS_PENDING_USER_ACTION) {// 用户触摸安装弹窗外部区域取消安装后,更新安装状态
|
||||
val installer = mContext.packageManager.packageInstaller
|
||||
val sessionId = pendingSessionInfo.sessionId
|
||||
if (sessionId != -1) {
|
||||
val sessionInfo = installer.getSessionInfo(sessionId)
|
||||
// 表示用户点击了安装弹窗外部区域
|
||||
if (sessionInfo == null) {
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
} else if (sessionInfo.progress <= 0.8F) {
|
||||
AppExecutor.ioExecutor.execute {
|
||||
installer.abandonSession(sessionInfo.sessionId)
|
||||
}
|
||||
pendingSessionInfo.updateStatus(XapkPendingSessionInfo.STATUS_INSTALL_CANCELED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installStatus = pendingSessionInfo.getStatus()
|
||||
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED
|
||||
|| installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS
|
||||
) {
|
||||
updateList.add(pendingSessionInfo)
|
||||
}
|
||||
}
|
||||
|
||||
for (pendingSessionInfo in updateList) {
|
||||
val downloadEntity = mDownloadEntityMap[pendingSessionInfo.path] ?: continue
|
||||
val installStatus = pendingSessionInfo.getStatus()
|
||||
if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_SUCCESS) {
|
||||
onInstalled(downloadEntity.path)
|
||||
} else if (installStatus == XapkPendingSessionInfo.STATUS_INSTALL_CANCELED) {
|
||||
onInstallCanceled(downloadEntity.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOBBOutput(apk: XApkFile): XApkFileOutput<Unit> {
|
||||
return OBBFileOutput()
|
||||
}
|
||||
|
||||
override fun onCreateApkOutput(apk: XApkFile): XApkFileOutput<IPackageInstaller> {
|
||||
val isMultiApks = apk.manifest.isMultiApks
|
||||
return if (isMultiApks) {
|
||||
SplitApksOutput(mContext.applicationContext) {
|
||||
SplitApksInstaller(apk, it)
|
||||
}
|
||||
} else {
|
||||
onCancel(downloadEntity) // 刷新页面
|
||||
NonSplitApksOutput {
|
||||
NonSplitApkInstaller(apk, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SplitApksInstaller(
|
||||
private val xApkFile: XApkFile,
|
||||
private val sessionId: Int,
|
||||
) : IPackageInstaller {
|
||||
|
||||
override fun install(context: Context) {
|
||||
val applicationContext = context.applicationContext
|
||||
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
|
||||
|
||||
mPendingSessionInfoMap[downloadEntity.path] = XapkPendingSessionInfo(downloadEntity.path, sessionId)
|
||||
AppExecutor.ioExecutor.execute {// 有可能卡顿造成anr
|
||||
PackageInstaller.installMultiple(applicationContext, downloadEntity.path, sessionId)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NonSplitApkInstaller(
|
||||
private val xApkFile: XApkFile,
|
||||
private val file: File
|
||||
) : IPackageInstaller {
|
||||
|
||||
override fun install(context: Context) {
|
||||
val downloadEntity = mDownloadEntityMap[xApkFile.file.path] ?: return
|
||||
PackageInstaller.install(
|
||||
context,
|
||||
downloadEntity.isPlugin,
|
||||
file.absolutePath,
|
||||
downloadEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,5 +351,6 @@ enum class XapkUnzipStatus(status: String) {
|
||||
UNZIPPING("unzipping"),
|
||||
SUCCESS("success"),
|
||||
CANCEL("cancel"),
|
||||
INSTALLED("installed"),
|
||||
FAILURE("failure");
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.gh.common.xapk
|
||||
|
||||
class XapkPendingSessionInfo(
|
||||
val path: String,
|
||||
val sessionId: Int = -1
|
||||
) {
|
||||
companion object {
|
||||
const val STATUS_INIT = -1
|
||||
const val STATUS_PENDING_USER_ACTION = 0
|
||||
const val STATUS_INSTALL_SUCCESS = 1
|
||||
const val STATUS_INSTALL_CANCELED = 2
|
||||
}
|
||||
|
||||
private var status = STATUS_INIT
|
||||
|
||||
internal fun updateStatus(status: Int) {
|
||||
this.status = status
|
||||
}
|
||||
|
||||
fun getStatus(): Int = status
|
||||
}
|
||||
@ -3,18 +3,16 @@ package com.gh.download
|
||||
import android.content.pm.PackageInfo
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.common.util.RealNameHelper
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.exposure.meta.MetaUtil
|
||||
import com.gh.gamecenter.common.exposure.meta.MetaUtil.getMeta
|
||||
import com.gh.gamecenter.common.loghub.LoghubUtils
|
||||
import com.gh.gamecenter.common.utils.DeviceUtils
|
||||
import com.gh.gamecenter.common.utils.getExtension
|
||||
import com.gh.gamecenter.common.utils.getMetaExtra
|
||||
import com.gh.gamecenter.common.utils.isSimulatorGame
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.utils.SentryHelper
|
||||
import com.gh.ndownload.NDataChanger
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DataChanger
|
||||
import com.lightgame.download.DownloadConfig
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus
|
||||
@ -25,9 +23,6 @@ import org.json.JSONObject
|
||||
object DownloadDataHelper {
|
||||
private const val TAG = "DownloadDataHelper"
|
||||
|
||||
private const val DOWNLOAD_SPEED_TIME = "download_speed_time"
|
||||
private const val DOWNLOAD_SPEED_SIZE = "download_speed_size"
|
||||
|
||||
const val DOWNLOAD_RESUME_WAY = "download_resume_way"
|
||||
const val DOWNLOAD_RESUME_MANUAL = "manual"
|
||||
const val DOWNLOAD_RESUME_AUTO = "auto"
|
||||
@ -36,8 +31,6 @@ object DownloadDataHelper {
|
||||
const val DOWNLOAD_CANCEL_MANUAL = "manual"
|
||||
const val DOWNLOAD_CANCEL_AUTO = "auto"
|
||||
|
||||
const val DOWNLOAD_FIRST_START = "download_first_start"
|
||||
|
||||
const val DOWNLOAD_THREAD_SIZE = "download_thread_size" // 线程数量,0为传统单线程模式; 1为多线程的单线程; >1为多线程的实际线程数量
|
||||
|
||||
private val mDownloadSpeedMap = HashMap<String, MutableList<Long>>()
|
||||
@ -64,6 +57,7 @@ object DownloadDataHelper {
|
||||
|| status == DownloadStatus.neterror
|
||||
|| status == DownloadStatus.timeout
|
||||
|| status == DownloadStatus.diskisfull
|
||||
|| status == DownloadStatus.diskioerror
|
||||
) {
|
||||
"暂停下载-连上WiFi自动下载"
|
||||
} else if (status == DownloadStatus.done) {
|
||||
@ -127,7 +121,9 @@ object DownloadDataHelper {
|
||||
payloadObject.put("gameName", downloadEntity.name)
|
||||
payloadObject.put("platform", downloadEntity.platform)
|
||||
payloadObject.put("package", downloadEntity.packageName)
|
||||
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
|
||||
payloadObject.put("filename", getFileName(downloadEntity))
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@ -139,26 +135,28 @@ object DownloadDataHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun uploadDownloadEvent(downloadEntity: DownloadEntity) {
|
||||
val downloadSimpleEntity = DownloadDataSimpleHelper.getDownloadDataSimpleEntity(downloadEntity.url)
|
||||
|
||||
if (downloadEntity.status != DownloadStatus.downloading) {
|
||||
uploadDownloadStatusEvent(downloadEntity)
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.downloading) {
|
||||
val startupTime = downloadEntity.meta[DownloadEntity.DOWNLOAD_STARTUP_TIME_KEY]
|
||||
val startupTime =
|
||||
downloadSimpleEntity?.downloadStartUpTime
|
||||
if (startupTime != null) {
|
||||
uploadDownloadStartupTimeEvent(downloadEntity, startupTime.toInt())
|
||||
downloadEntity.meta.remove(DownloadEntity.DOWNLOAD_STARTUP_TIME_KEY)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
uploadDownloadStartupTimeEvent(downloadEntity, startupTime)
|
||||
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadStartUpTime = null)
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.downloading || downloadEntity.status == DownloadStatus.done) {
|
||||
val time = downloadEntity.meta[DOWNLOAD_SPEED_TIME]
|
||||
val size = downloadEntity.meta[DOWNLOAD_SPEED_SIZE]
|
||||
val time = downloadSimpleEntity?.downloadSpeedTime
|
||||
val size = downloadSimpleEntity?.downloadSpeedSize
|
||||
if (downloadEntity.speed == 0L || time == null || size == null) {
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_TIME] = System.currentTimeMillis().toString()
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_SIZE] = downloadEntity.progress.toString()
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val currentProgress = downloadEntity.progress
|
||||
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadSpeedTime = currentTime, downloadSpeedSize = currentProgress)
|
||||
} else {
|
||||
val offset = System.currentTimeMillis() - time.toLong()
|
||||
if (offset > 5000) {
|
||||
@ -179,15 +177,15 @@ object DownloadDataHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_TIME] = System.currentTimeMillis().toString()
|
||||
downloadEntity.meta[DOWNLOAD_SPEED_SIZE] = downloadEntity.progress.toString()
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
val currentTime = System.currentTimeMillis()
|
||||
val currentProgress = downloadEntity.progress
|
||||
DownloadDataSimpleHelper.updateDownloadDataSimpleEntity(downloadEntity.url, downloadSpeedTime = currentTime, downloadSpeedSize = currentProgress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadDownloadStartupTimeEvent(downloadEntity: DownloadEntity, startupTime: Int) {
|
||||
private fun uploadDownloadStartupTimeEvent(downloadEntity: DownloadEntity, startupTime: Long) {
|
||||
val jsonObject = JSONObject()
|
||||
|
||||
try {
|
||||
@ -202,15 +200,21 @@ object DownloadDataHelper {
|
||||
|
||||
// payload
|
||||
val payloadObject = JSONObject()
|
||||
val parallel = downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt()
|
||||
|
||||
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
|
||||
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
|
||||
payloadObject.put("game_id", downloadEntity.gameId)
|
||||
payloadObject.put("gameName", downloadEntity.name)
|
||||
payloadObject.put("platform", downloadEntity.platform)
|
||||
payloadObject.put("package", downloadEntity.packageName)
|
||||
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
|
||||
payloadObject.put("filename", getFileName(downloadEntity))
|
||||
payloadObject.put("launch_ms", startupTime)
|
||||
payloadObject.put("parallel", downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt() ?: 0)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
if (parallel != null) {
|
||||
payloadObject.put("parallel", parallel)
|
||||
}
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@ -220,11 +224,11 @@ object DownloadDataHelper {
|
||||
LoghubUtils.log(jsonObject, "download_debug", false)
|
||||
}
|
||||
|
||||
private fun uploadDownloadStatusEvent(downloadEntity: DownloadEntity) {
|
||||
fun uploadDownloadStatusEvent(downloadEntity: DownloadEntity, extraStatus: String? = null) {
|
||||
val jsonObject = JSONObject()
|
||||
|
||||
try {
|
||||
val statusAlias = getDownloadStatusAlias(downloadEntity)
|
||||
val statusAlias = extraStatus ?: getDownloadStatusAlias(downloadEntity)
|
||||
jsonObject.put("event", statusAlias)
|
||||
jsonObject.put("msg", downloadEntity.error)
|
||||
jsonObject.put("status", downloadEntity.status.status)
|
||||
@ -234,16 +238,21 @@ object DownloadDataHelper {
|
||||
|
||||
// payload
|
||||
val payloadObject = JSONObject()
|
||||
val parallel = downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt()
|
||||
val sizeInMB = downloadEntity.size / 1024 / 1024
|
||||
|
||||
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
|
||||
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
|
||||
payloadObject.put("game_id", downloadEntity.gameId)
|
||||
payloadObject.put("gameName", downloadEntity.name)
|
||||
payloadObject.put("platform", downloadEntity.platform)
|
||||
payloadObject.put("package", downloadEntity.packageName)
|
||||
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
|
||||
payloadObject.put("filename", getFileName(downloadEntity))
|
||||
payloadObject.put("total_size", sizeInMB)
|
||||
payloadObject.put("parallel", downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt() ?: 0)
|
||||
if (parallel != null) {
|
||||
payloadObject.put("parallel", parallel)
|
||||
}
|
||||
|
||||
if (statusAlias == "下载完成") {
|
||||
val elapsedTimeString = downloadEntity.meta[DownloadConfig.KEY_DOWNLOAD_ELAPSED_TIME]
|
||||
@ -252,23 +261,16 @@ object DownloadDataHelper {
|
||||
// 下载时间统计时间为零时,手动改成 1000ms,如果文件大小大于 50M 时上报 sentry
|
||||
if (elapsedTime == 0L) {
|
||||
elapsedTime = 1000L
|
||||
if (sizeInMB > 50) {
|
||||
SentryHelper.onEvent(
|
||||
"DOWNLOAD_ELAPSED_TIME",
|
||||
"elapsedTime is zero",
|
||||
downloadEntity.gameId + ":" + sizeInMB
|
||||
)
|
||||
}
|
||||
}
|
||||
val speed = downloadEntity.size / elapsedTime
|
||||
payloadObject.put("speed", speed)
|
||||
}
|
||||
} else {
|
||||
payloadObject.put("task_num", DataChanger.downloadingTasks.size)
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
}
|
||||
payloadObject.put("completed_size", downloadEntity.progress / 1024 / 1024)
|
||||
if (downloadEntity.status == DownloadStatus.resume) {
|
||||
if (downloadEntity.meta[DOWNLOAD_FIRST_START] == "YES") {
|
||||
if (DownloadDataSimpleHelper.getDownloadDataSimpleEntity(downloadEntity.url)?.isFirstTimeDownload == true) {
|
||||
payloadObject.put("is_first_start", true)
|
||||
} else {
|
||||
payloadObject.put("is_first_start", false)
|
||||
@ -276,8 +278,7 @@ object DownloadDataHelper {
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.resume || downloadEntity.status == DownloadStatus.add) {
|
||||
downloadEntity.meta[DOWNLOAD_FIRST_START] = "NO"
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
DownloadDataSimpleHelper.updateDownloadSimpleEntityFirstTimeDownload(downloadEntity.url, false)
|
||||
}
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
@ -301,18 +302,23 @@ object DownloadDataHelper {
|
||||
|
||||
// payload
|
||||
val payloadObject = JSONObject()
|
||||
val parallel = downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt()
|
||||
|
||||
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
|
||||
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
|
||||
payloadObject.put("game_id", downloadEntity.gameId)
|
||||
payloadObject.put("gameName", downloadEntity.name)
|
||||
payloadObject.put("platform", downloadEntity.platform)
|
||||
payloadObject.put("package", downloadEntity.packageName)
|
||||
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
|
||||
payloadObject.put("filename", getFileName(downloadEntity))
|
||||
payloadObject.put("speed_progress", JSONArray(averageSpeedList))
|
||||
payloadObject.put("is_finished", downloadEntity.status == DownloadStatus.done)
|
||||
payloadObject.put("completed_size", downloadEntity.progress / 1024 / 1024)
|
||||
payloadObject.put("parallel", downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt() ?: 0)
|
||||
payloadObject.put("task_num", DataChanger.downloadingTasks.size)
|
||||
if (parallel != null) {
|
||||
payloadObject.put("parallel", parallel)
|
||||
}
|
||||
payloadObject.put("task_num", NDataChanger.downloadingTaskUrlSet.size)
|
||||
jsonObject.put("payload", payloadObject)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@ -325,7 +331,7 @@ object DownloadDataHelper {
|
||||
/**
|
||||
* 分片检测下载进度,每隔15秒内记录一次,60秒上传一次
|
||||
*
|
||||
* 请见:https://gitlab.ghzs.com/stats/stats-issues/-/issues/188#note_66919
|
||||
* 请见:https://git.shanqu.cc/stats/stats-issues/-/issues/188#note_66919
|
||||
*/
|
||||
fun uploadDownloadHeartbeat(upload: Boolean) {
|
||||
val allDownloadEntity = DownloadManager.getInstance().allDownloadEntity
|
||||
@ -335,7 +341,8 @@ object DownloadDataHelper {
|
||||
* 在后台唤醒的情况下 下载状态可能无法修正
|
||||
* see [DownloadManager.initDownloadService]
|
||||
*/
|
||||
if (downloadEntity.status == DownloadStatus.downloading && DataChanger.downloadingTasks[downloadEntity.url] != null) {
|
||||
if (downloadEntity.status == DownloadStatus.downloading
|
||||
&& NDataChanger.downloadingTaskUrlSet.contains(downloadEntity.url)) {
|
||||
var sheet = mDownloadHeartbeatSheet[downloadEntity.url]
|
||||
if (sheet == null) {
|
||||
sheet = JSONObject()
|
||||
@ -344,6 +351,7 @@ object DownloadDataHelper {
|
||||
sheet.put("game_id", downloadEntity.gameId)
|
||||
sheet.put("platform", downloadEntity.platform)
|
||||
sheet.put("package", downloadEntity.packageName)
|
||||
sheet.put("certification", RealNameHelper.getCertificationStatus())
|
||||
sheet.put("filename", getFileName(downloadEntity))
|
||||
sheet.put("total_size", downloadEntity.size / 1024 / 1024)
|
||||
sheet.put("current_progress_size", downloadEntity.progress / 1024)
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
package com.gh.download
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.gh.gamecenter.common.HaloApp
|
||||
import com.gh.gamecenter.common.utils.toJsonIgnoredNull
|
||||
import com.gh.gamecenter.common.utils.toObject
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
|
||||
/**
|
||||
* 用来简单保存/获取下载时一些额外信息的辅助类,避免下载时反复修改原始下载实体的糟糕操作
|
||||
* 使用 SP 来实现,只适用于相对较为低频的调用
|
||||
*/
|
||||
object DownloadDataSimpleHelper {
|
||||
|
||||
private val mSp: SharedPreferences by lazy {
|
||||
HaloApp.getInstance().getSharedPreferences("DownloadDataSimpleDao", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
fun getDownloadDataSimpleEntity(url: String): DownloadDataSimpleEntity? {
|
||||
return mSp.getString(url, "")?.toObject()
|
||||
}
|
||||
|
||||
fun updateDownloadDataSimpleEntity(
|
||||
url: String,
|
||||
downloadStartUpTime: Long? = null,
|
||||
downloadSpeedTime: Long? = null,
|
||||
downloadSpeedSize: Long? = null,
|
||||
) {
|
||||
val entity = getDownloadDataSimpleEntity(url) ?: DownloadDataSimpleEntity()
|
||||
entity.downloadStartUpTime = downloadStartUpTime
|
||||
|
||||
entity.downloadSpeedTime = downloadSpeedTime
|
||||
entity.downloadSpeedSize = downloadSpeedSize
|
||||
|
||||
SPUtils.setString(mSp, url, entity.toJsonIgnoredNull())
|
||||
}
|
||||
|
||||
fun updateDownloadSimpleEntityFirstTimeDownload(url: String, isFirstTimeDownload: Boolean) {
|
||||
val entity = getDownloadDataSimpleEntity(url) ?: DownloadDataSimpleEntity()
|
||||
|
||||
entity.isFirstTimeDownload = isFirstTimeDownload
|
||||
|
||||
SPUtils.setString(mSp, url, entity.toJsonIgnoredNull())
|
||||
}
|
||||
|
||||
fun removeDownloadSimpleEntity(url: String) {
|
||||
SPUtils.remove(mSp, url)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DownloadDataSimpleEntity(
|
||||
var downloadStartUpTime: Long? = null,
|
||||
|
||||
var downloadSpeedTime: Long? = null,
|
||||
var downloadSpeedSize: Long? = null,
|
||||
|
||||
var isFirstTimeDownload: Boolean? = true
|
||||
)
|
||||
@ -15,7 +15,9 @@ import androidx.collection.ArrayMap;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.SensorsBridge;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent;
|
||||
@ -47,18 +49,18 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.gh.gamecenter.login.user.UserManager;
|
||||
import com.gh.gamecenter.packagehelper.PackageRepository;
|
||||
import com.gh.vspace.VHelper;
|
||||
import com.gh.ndownload.NDataChanger;
|
||||
import com.gh.ndownload.NDownloadBridge;
|
||||
import com.gh.ndownload.NDownloadService;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.ConnectionUtils;
|
||||
import com.lightgame.download.DataChanger;
|
||||
import com.lightgame.download.DataWatcher;
|
||||
import com.lightgame.download.DownloadConfig;
|
||||
import com.lightgame.download.DownloadDao;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.DownloadService;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
import com.lightgame.download.DownloadStatusListener;
|
||||
import com.lightgame.download.DownloadStatusManager;
|
||||
import com.lightgame.download.DownloadTask;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.download.HttpDnsManager;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -89,9 +91,9 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
private final Map<String, ConcurrentHashMap<String, DownloadEntity>> gameMap;
|
||||
|
||||
private final ArrayMap<String, DownloadStatus> statusMap;
|
||||
private final ArrayMap<String, DownloadEntity> downloadingMap;
|
||||
private final ConcurrentHashMap<String, DownloadEntity> downloadingMap;
|
||||
|
||||
private ArrayList<DownloadEntity> mInvisiblePendingTaskList; // 用户不可见的 pending 任务
|
||||
private final ArrayList<DownloadEntity> mInvisiblePendingTaskList; // 用户不可见的 pending 任务
|
||||
private final DownloadDao mDownloadDao;
|
||||
private final DownloadedGameIdAndPackageNameDao mDownloadedGameIdAndPackageNameDao;
|
||||
|
||||
@ -167,8 +169,6 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
|
||||
mUpdateMarks = SPUtils.getStringSet(UPDATE_IS_READ_MARK);
|
||||
|
||||
DownloadStatusManager.getInstance().registerTaskStatusListener(this);
|
||||
|
||||
// 只有下载模块需要这坨东西,因此移动到这里初始化
|
||||
ConnectionUtils.initHttpsUrlConnection(mContext);
|
||||
|
||||
@ -178,7 +178,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
platformMap = new ArrayMap<>();
|
||||
gameMap = new ConcurrentHashMap<>();
|
||||
statusMap = new ArrayMap<>();
|
||||
downloadingMap = new ArrayMap<>();
|
||||
downloadingMap = new ConcurrentHashMap<>();
|
||||
// mDownloadSnapshotList = new ArrayList<>();
|
||||
mInvisiblePendingTaskList = new ArrayList<>();
|
||||
|
||||
@ -224,10 +224,6 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayMap<String, DownloadEntity> getDownloadingMap() {
|
||||
return downloadingMap;
|
||||
}
|
||||
|
||||
public static DownloadManager getInstance() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
@ -287,6 +283,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
|
||||
String path;
|
||||
String downloadId = PackageInstaller.createDownloadId(gameEntity.getName());
|
||||
String gameCategory = gameEntity.getCategory();
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
path = SimulatorGameManager.getPathByType(gameEntity.getSimulatorType()) + "/" + gameEntity.getName() + "." + apkEntity.getFormat();
|
||||
|
||||
@ -312,6 +309,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
downloadEntity.setUrl(apkEntity.getUrl());
|
||||
downloadEntity.setName(gameEntity.getName());
|
||||
downloadEntity.setPath(path);
|
||||
downloadEntity.setPluginDesc(gameEntity.getPluginDesc());
|
||||
downloadEntity.setETag(apkEntity.getEtag());
|
||||
downloadEntity.setIcon(gameEntity.getIcon());
|
||||
downloadEntity.setPlatform(apkEntity.getPlatform());
|
||||
@ -319,6 +317,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
downloadEntity.setGameId(gameEntity.getId());
|
||||
downloadEntity.setEntrance(entrance);
|
||||
downloadEntity.setLocation(location);
|
||||
downloadEntity.setFormat(apkEntity.getFormat());
|
||||
downloadEntity.setVersionName(apkEntity.getVersion());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_MD5, apkEntity.getMd5());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.DOWNLOAD_ID, downloadId);
|
||||
@ -326,6 +325,11 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_PLATFORM_RECOMMEND, apkEntity.getRecommend() != null ? "true" : "false");
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_NAME, gameEntity.getName());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_CATEGORY_IN_CHINESE, gameEntity.getCategoryChinese());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.AD_ICON_ACTIVE, String.valueOf(gameEntity.getAdIconActive()));
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_AD_DATA, String.valueOf(gameEntity.isAdData()));
|
||||
ExtensionsKt.putGameCategory(downloadEntity, gameCategory != null ? gameCategory : "");
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.APK_SIZE, apkEntity.getSize());
|
||||
if (gameEntity.getIconFloat() != null) {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT, gameEntity.getIconFloat().getUpperLeftText());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR, gameEntity.getIconFloat().getUpperLeftColor());
|
||||
@ -340,6 +344,26 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true");
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME);
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200");
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, VHelper.KEY_REQUIRED_G_APPS, gameEntity.getGAppsSwitch());
|
||||
ExtensionsKt.addMetaExtra(downloadEntity, VHelper.KEY_BIT, apkEntity.getBit());
|
||||
|
||||
SensorsBridge.trackEvent("HaloFunGameDownloadClick",
|
||||
"game_name", gameEntity.getName(),
|
||||
"game_id", gameEntity.getId(),
|
||||
"game_schema_type", gameEntity.getGameBitChinese());
|
||||
} else {
|
||||
SensorsBridge.trackEvent("DownloadProcessBegin",
|
||||
"game_id", gameEntity.getId(),
|
||||
"game_name", gameEntity.getName(),
|
||||
"game_type", gameEntity.getCategoryChinese(),
|
||||
"game_schema_type", gameEntity.getGameBitChinese(),
|
||||
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
|
||||
"page_id", GlobalActivityManager.getCurrentPageEntity().getPageId(),
|
||||
"page_business_id", GlobalActivityManager.getCurrentPageEntity().getPageBusinessId(),
|
||||
"last_page_name", GlobalActivityManager.getLastPageEntity().getPageName(),
|
||||
"last_page_id", GlobalActivityManager.getLastPageEntity().getPageId(),
|
||||
"last_page_business_id", GlobalActivityManager.getLastPageEntity().getPageBusinessId()
|
||||
);
|
||||
}
|
||||
|
||||
HashMap<String, String> map = PageSwitchDataHelper.popLastPageData();
|
||||
@ -423,7 +447,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
|
||||
if (isDownloadCompleted(url)) {
|
||||
downloadEntity.setStatus(DownloadStatus.done);
|
||||
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
} else if (!isTaskDownloading(url)) {
|
||||
startDownloadService(downloadEntity, DownloadStatus.add);
|
||||
}
|
||||
@ -444,7 +468,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
checkDownloadEntryRecordValidate(url);
|
||||
if (isDownloadCompleted(url)) {
|
||||
downloadEntity.setStatus(DownloadStatus.done);
|
||||
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
} else if (!isTaskDownloading(url)) {
|
||||
DownloadEntity daoEntity = mDownloadDao.get(downloadEntity.getUrl());
|
||||
if (automatic) {
|
||||
@ -479,7 +503,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
checkDownloadEntryRecordValidate(url);
|
||||
if (isDownloadCompleted(url)) {
|
||||
downloadEntity.setStatus(DownloadStatus.done);
|
||||
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
} else if (!isTaskDownloading(url)) {
|
||||
startDownloadService(downloadEntity, DownloadStatus.subscribe);
|
||||
}
|
||||
@ -525,7 +549,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 任务是否已经下载中
|
||||
*/
|
||||
public boolean isTaskDownloading(String url) {
|
||||
if (DataChanger.INSTANCE.getDownloadingTasks().get(url) != null) {
|
||||
if (NDataChanger.INSTANCE.getDownloadingTaskUrlSet().contains(url)) {
|
||||
Utils.log(DownloadManager.class.getSimpleName(), url + "正在下载!");
|
||||
return true;
|
||||
}
|
||||
@ -533,7 +557,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
|
||||
private Intent getIntent(DownloadEntity entry, DownloadStatus status) {
|
||||
Intent service = new Intent(mContext, DownloadService.class);
|
||||
Intent service = new Intent(mContext, NDownloadService.class);
|
||||
service.putExtra(DownloadConfig.KEY_DOWNLOAD_ENTRY, entry);
|
||||
service.putExtra(DownloadConfig.KEY_DOWNLOAD_ACTION, status.name());
|
||||
return service;
|
||||
@ -562,6 +586,16 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
return mDownloadDao.getAllSnapshots();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快照
|
||||
*
|
||||
* @param url 下载地址
|
||||
*/
|
||||
@Nullable
|
||||
public DownloadEntity getDownloadEntitySnapshot(String url) {
|
||||
return mDownloadDao.getSnapshot(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取快照
|
||||
*
|
||||
@ -599,7 +633,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 url 获取下载任务快照 (仅保证下载状态一致)
|
||||
* 根据包名获取下载任务快照 (仅保证下载状态一致)
|
||||
*
|
||||
* @param packageName 包名 (多包名一样时取第一个,若使用场景里有多包名,请使用 url 获取下载任务)
|
||||
* @return null 表示下载列表中不存在该任务,否则返回下载任务
|
||||
@ -800,8 +834,11 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
*/
|
||||
public void cancel(String url, boolean isDeleteFile, boolean automatic, boolean cancelSilently) {
|
||||
DownloadEntity entry = mDownloadDao.getSnapshot(url);
|
||||
DownloadDataSimpleHelper.INSTANCE.removeDownloadSimpleEntity(url);
|
||||
if (entry != null) {
|
||||
AppExecutor.getIoExecutor().execute(() -> {
|
||||
NDownloadBridge.INSTANCE.cancel(url);
|
||||
|
||||
mDownloadDao.delete(url);
|
||||
|
||||
if (isDeleteFile) {
|
||||
@ -835,19 +872,12 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
private void cancelAndNotify(DownloadEntity entry, boolean cancelSilently) {
|
||||
mDownloadDao.removeErrorMessage(entry.getUrl());
|
||||
|
||||
DownloadTask task = DataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl());
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
// 改任务队列的状态
|
||||
DataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl());
|
||||
if (!cancelSilently) {
|
||||
DataChanger.INSTANCE.notifyDataChanged(entry);
|
||||
}
|
||||
}
|
||||
DataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
|
||||
// 改任务队列的状态
|
||||
NDataChanger.INSTANCE.getDownloadingTaskUrlSet().remove(entry.getUrl());
|
||||
NDataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
|
||||
if (!cancelSilently) {
|
||||
DataChanger.INSTANCE.notifyDataChanged(entry);
|
||||
DownloadStatusManager.getInstance().onTaskCancelled(entry);
|
||||
NDataChanger.INSTANCE.notifyDataChanged(entry);
|
||||
onTaskCancelled(entry);
|
||||
}
|
||||
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "cancel");
|
||||
@ -857,8 +887,10 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 暂停所有正在下载的任务
|
||||
*/
|
||||
public void pauseAll() {
|
||||
for (DownloadEntity entity : DataChanger.INSTANCE.getDownloadEntries().values()) {
|
||||
pause(entity.getUrl());
|
||||
synchronized (NDataChanger.INSTANCE.getDownloadEntries()) {
|
||||
for (DownloadEntity entity : NDataChanger.INSTANCE.getDownloadEntries().values()) {
|
||||
pause(entity.getUrl());
|
||||
}
|
||||
}
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "pause all");
|
||||
}
|
||||
@ -868,7 +900,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
*/
|
||||
public void pause(String url) {
|
||||
checkDownloadEntryRecordValidate(url);
|
||||
DownloadEntity entry = DataChanger.INSTANCE.getDownloadEntries().get(url);
|
||||
DownloadEntity entry = NDataChanger.INSTANCE.getDownloadEntries().get(url);
|
||||
if (entry != null) {
|
||||
startDownloadService(entry, DownloadStatus.pause);
|
||||
put(url, System.currentTimeMillis());
|
||||
@ -884,14 +916,14 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 3.检查是否显示下载通知栏
|
||||
*/
|
||||
public void initDownloadService() {
|
||||
final List<String> urlList = new ArrayList<>(DataChanger.INSTANCE.getDownloadingTasks().keySet());
|
||||
final Set<String> urlSet = NDataChanger.INSTANCE.getDownloadingTaskUrlSet();
|
||||
for (DownloadEntity downloadEntity : getAllDownloadEntity()) {
|
||||
if (!urlList.contains(downloadEntity.getUrl()) &&
|
||||
(downloadEntity.getStatus().equals(DownloadStatus.downloading)
|
||||
if (!urlSet.contains(downloadEntity.getUrl())
|
||||
&& (downloadEntity.getStatus().equals(DownloadStatus.downloading)
|
||||
|| downloadEntity.getStatus().equals(DownloadStatus.waiting))) {
|
||||
downloadEntity.setStatus(DownloadStatus.subscribe);
|
||||
mDownloadDao.newOrUpdate(downloadEntity);
|
||||
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@ -904,7 +936,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
*/
|
||||
public void addObserver(DataWatcher dataWatcher) {
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "addObserver");
|
||||
DataChanger.INSTANCE.addObserver(dataWatcher);
|
||||
NDataChanger.INSTANCE.addObserver(dataWatcher);
|
||||
|
||||
notifyDownloadStatusASAP(dataWatcher);
|
||||
}
|
||||
@ -914,7 +946,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
*/
|
||||
public void removeObserver(DataWatcher dataWatcher) {
|
||||
Utils.log(DownloadManager.class.getSimpleName(), "removeObserver");
|
||||
DataChanger.INSTANCE.deleteObserver(dataWatcher);
|
||||
NDataChanger.INSTANCE.deleteObserver(dataWatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -930,11 +962,11 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
* 初始化下载服务
|
||||
*/
|
||||
public void startDownloadService() {
|
||||
Intent serviceIntent = new Intent(mContext, DownloadService.class);
|
||||
Intent serviceIntent = new Intent(mContext, NDownloadService.class);
|
||||
// 当满足系统版本大于 8.0 并且应用在后台运行时以前台服务开启
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||
&& !PackageUtils.isAppOnForeground(mContext)) {
|
||||
serviceIntent.putExtra(DownloadService.KEY_SERVICE_ACTION, DownloadService.START_FOREGROUND);
|
||||
serviceIntent.putExtra(NDownloadService.KEY_SERVICE_ACTION, NDownloadService.START_FOREGROUND);
|
||||
mContext.startForegroundService(serviceIntent);
|
||||
} else {
|
||||
/*
|
||||
@ -965,8 +997,11 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
}
|
||||
|
||||
if (status == DownloadStatus.add || status == DownloadStatus.subscribe) {
|
||||
if (downloadEntity.getMeta().get(DownloadDataHelper.DOWNLOAD_FIRST_START) == null) {
|
||||
downloadEntity.getMeta().put(DownloadDataHelper.DOWNLOAD_FIRST_START, "YES");
|
||||
DownloadDataSimpleEntity simpleEntity =
|
||||
DownloadDataSimpleHelper.INSTANCE.getDownloadDataSimpleEntity(downloadEntity.getUrl());
|
||||
|
||||
if (simpleEntity == null || simpleEntity.isFirstTimeDownload() == null) {
|
||||
DownloadDataSimpleHelper.INSTANCE.updateDownloadSimpleEntityFirstTimeDownload(downloadEntity.getUrl(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -974,7 +1009,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
// 当满足系统版本大于 8.0 并且应用在后台运行时以前台服务开启
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||
&& !PackageUtils.isAppOnForeground(mContext)) {
|
||||
serviceIntent.putExtra(DownloadService.KEY_SERVICE_ACTION, DownloadService.START_FOREGROUND);
|
||||
serviceIntent.putExtra(NDownloadService.KEY_SERVICE_ACTION, NDownloadService.START_FOREGROUND);
|
||||
mContext.startForegroundService(serviceIntent);
|
||||
} else {
|
||||
mContext.startService(serviceIntent);
|
||||
@ -1105,7 +1140,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK);
|
||||
if (TextUtils.isEmpty(mark)) {
|
||||
downloadEntity.getMeta().put(DOWNLOADED_IS_READ_MARK, DOWNLOADED_IS_READ_MARK);
|
||||
mDownloadDao.newOrUpdate(downloadEntity);
|
||||
mDownloadDao.update(downloadEntity, false);
|
||||
if (!markHasChanged) markHasChanged = true;
|
||||
}
|
||||
}
|
||||
@ -1145,12 +1180,12 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
String mark = downloadEntity.getMeta().get(DOWNLOADING_IS_READ_MARK);
|
||||
if (TextUtils.isEmpty(mark)) {
|
||||
downloadEntity.getMeta().put(DOWNLOADING_IS_READ_MARK, DOWNLOADING_IS_READ_MARK);
|
||||
mDownloadDao.newOrUpdate(downloadEntity);
|
||||
mDownloadDao.update(downloadEntity, false);
|
||||
if (!markHasChanged) markHasChanged = true;
|
||||
}
|
||||
} else {
|
||||
downloadEntity.getMeta().put(DOWNLOADING_IS_READ_MARK, "");
|
||||
mDownloadDao.newOrUpdate(downloadEntity);
|
||||
mDownloadDao.update(downloadEntity, false);
|
||||
if (!markHasChanged) markHasChanged = true;
|
||||
}
|
||||
}
|
||||
@ -1206,9 +1241,12 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
|
||||
/**
|
||||
* 更新数据库中的下载实体
|
||||
*
|
||||
* @deprecated 随意更新数据库可能会出现意想不到的情况,建议不要随意调用
|
||||
*/
|
||||
@Deprecated()
|
||||
public void updateDownloadEntity(DownloadEntity downloadEntity) {
|
||||
mDownloadDao.newOrUpdate(downloadEntity);
|
||||
mDownloadDao.update(downloadEntity, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1270,7 +1308,8 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
*/
|
||||
public static void updateDownloadMetaMap() {
|
||||
String isOverwrite;
|
||||
if (LunchType.UPDATE.name().equals(SPUtils.getString(Constants.SP_INSTALL_TYPE))) {
|
||||
String installType = SPUtils.getString(Constants.SP_INSTALL_TYPE);
|
||||
if (LunchType.UPDATE.name().equals(installType)) {
|
||||
isOverwrite = "true";
|
||||
} else {
|
||||
isOverwrite = "false";
|
||||
@ -1285,6 +1324,7 @@ public class DownloadManager implements DownloadStatusListener {
|
||||
map.put(HttpDnsManager.IMEI, MetaUtil.getBase64EncodedIMEI());
|
||||
map.put(HttpDnsManager.TOKEN, UserManager.getInstance().getToken());
|
||||
map.put(HttpDnsManager.IS_OVERWRITE, isOverwrite);
|
||||
map.put(HttpDnsManager.INSTALL_TYPE, installType);
|
||||
|
||||
HttpDnsManager.metaMap = map;
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import com.gh.common.util.ConcernUtils
|
||||
import com.gh.common.util.DataCollectionUtils
|
||||
import com.gh.common.util.PackageInstaller
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.loghub.LoghubUtils
|
||||
@ -32,13 +33,15 @@ import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
object PackageObserver {
|
||||
|
||||
private val mPackageViewModel: PackageViewModel
|
||||
by lazy { PackageViewModel(HaloApp.getInstance().application, PackageRepository) }
|
||||
|
||||
private val mPackageChangeListenerList: ArrayList<PackageChangeListener> = arrayListOf()
|
||||
private val mPackageChangeListenerList = CopyOnWriteArrayList<PackageChangeListener>()
|
||||
|
||||
fun registerPackageChangeChangeListener(listener: PackageChangeListener) {
|
||||
mPackageChangeListenerList.add(listener)
|
||||
@ -91,9 +94,11 @@ object PackageObserver {
|
||||
}
|
||||
|
||||
if (EBPackage.TYPE_INSTALLED == busFour.type) {
|
||||
mPackageViewModel.addInstalledGame(packageName)
|
||||
|
||||
BrowserInstallHelper.onApkInstalled(mDownloadEntity?.path)
|
||||
if (!busFour.isVGame) {
|
||||
// 非畅玩游戏才执行下面的代码
|
||||
mPackageViewModel.addInstalledGame(packageName)
|
||||
BrowserInstallHelper.onApkInstalled(mDownloadEntity?.path)
|
||||
}
|
||||
|
||||
if (mDownloadEntity != null) {
|
||||
// 没有光环 ID 的都记录一下游戏 ID,供'我的游戏'区分同包名不同插件用
|
||||
@ -106,6 +111,10 @@ object PackageObserver {
|
||||
runOnIoThread { FileUtils.deleteFile(mDownloadEntity.path) }
|
||||
}
|
||||
|
||||
if (mDownloadEntity.format == Constants.XAPK_FORMAT) {
|
||||
XapkInstaller.onInstalled(mDownloadEntity.path)
|
||||
}
|
||||
|
||||
DownloadManager.getInstance().cancel(mDownloadEntity.url, false, true, false)
|
||||
|
||||
if (SPUtils.getBoolean(Constants.SP_CONCERN_GAME, true)) { //设置页面控制是否安装后自动关注
|
||||
@ -136,12 +145,13 @@ object PackageObserver {
|
||||
runOnIoThread { postNewlyInstalledApp(gameId, packageName) }
|
||||
}
|
||||
|
||||
if ("卸载" == busFour.type) {
|
||||
if (EBPackage.TYPE_UNINSTALLED == busFour.type) {
|
||||
mPackageViewModel.addUninstalledGame(packageName)
|
||||
mDownloadEntity?.let {
|
||||
if (it.isVGame()) return@let
|
||||
|
||||
if (it.isPluggable || it.isUpdate) {
|
||||
if (it.isPluggable
|
||||
|| (it.isUpdate && !PackageUtils.isInstalled(application, it.packageName))) {
|
||||
PackageInstaller.install(application, mDownloadEntity)
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import tv.danmaku.ijk.media.exo2.ExoSourceManager
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object ExoCacheManager {
|
||||
|
||||
@ -98,7 +99,9 @@ object ExoCacheManager {
|
||||
.build()
|
||||
var response: Response? = null
|
||||
try {
|
||||
response = OkHttpClient.Builder().build().newCall(request).execute()
|
||||
response =
|
||||
OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS).build()
|
||||
.newCall(request).execute()
|
||||
if (response!!.isSuccessful && response.body() != null) {
|
||||
val length = response.body()!!.contentLength()
|
||||
contentLength = if (length == 0L) -1L else length
|
||||
|
||||
@ -178,9 +178,18 @@ class DownloadDialog : BaseDraggableDialogFragment() {
|
||||
for (i in 0 until it.itemCount) {
|
||||
val apkEntity = itemList[i].normal ?: continue
|
||||
val apkCollection = apkEntity.apkCollection
|
||||
if (apkCollection != null && apkCollection.name == mPlatformName) {
|
||||
scrollAndDownload(recyclerView, false, i)
|
||||
break
|
||||
if (apkCollection != null) {
|
||||
if (apkCollection.name == mPlatformName) {
|
||||
scrollAndDownload(recyclerView, false, i)
|
||||
break
|
||||
} else {
|
||||
apkCollection.saveApkEntity?.forEach { entity ->
|
||||
if (entity.getPlatformName() == mPlatformName || entity.packageName == mPackageName) {
|
||||
scrollAndDownload(recyclerView, false, i)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (apkEntity.getPlatformName() == mPlatformName || apkEntity.packageName == mPackageName) {
|
||||
scrollAndDownload(recyclerView, true, i)
|
||||
|
||||
@ -83,7 +83,7 @@ class DownloadDialogAdapter(
|
||||
holder.binding.root.layoutParams = this
|
||||
}
|
||||
val section = listData[position].section
|
||||
holder.binding.title.text = if (section == DownloadDialogSectionType.OTHER) "其它版本" else "我的版本"
|
||||
holder.binding.title.text = if (section == DownloadDialogSectionType.OTHER) "更多版本" else "我的版本"
|
||||
holder.binding.otherVersionHint.goneIf(section != DownloadDialogSectionType.OTHER)
|
||||
}
|
||||
is DownloadDialogLinkItemViewHolder -> {
|
||||
|
||||
@ -10,12 +10,9 @@ import com.gh.common.constant.Config
|
||||
import com.gh.common.dialog.CertificationDialog
|
||||
import com.gh.common.dialog.DeviceRemindDialog
|
||||
import com.gh.common.dialog.PackageCheckDialogFragment
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.DownloadDialogHelper
|
||||
import com.gh.common.util.PackageInstaller
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.download.server.BrowserInstallHelper
|
||||
import com.gh.gamecenter.DownloadManagerActivity
|
||||
@ -244,7 +241,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_下载"
|
||||
}
|
||||
DownloadDialogItemStatus.LAUNCH -> {
|
||||
PackageUtils.launchApplicationByPackageName(it.context, apkEntity.packageName)
|
||||
PackageLauncher.launchApp(it.context, gameEntity, apkEntity.packageName)
|
||||
|
||||
mtaValue = gameEntity.name + "_" + apkEntity.getPlatformName() + "_启动"
|
||||
}
|
||||
@ -282,7 +279,7 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
DownloadManager.getInstance().cancel(apkEntity.url)
|
||||
} else {
|
||||
if (PackageUtils.isCanPluggable(apkEntity)) {
|
||||
DialogHelper.showPluginDialog(it.context) {
|
||||
DialogHelper.showPluginDialog(it.context, gameEntity.pluginDesc) {
|
||||
PackageInstaller.uninstall(it.context, downloadEntity.path)
|
||||
}
|
||||
} else {
|
||||
@ -352,52 +349,46 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
|
||||
if (msg.isNullOrEmpty()) {
|
||||
BrowserInstallHelper.showBrowserInstallHintDialog(
|
||||
context,
|
||||
gameEntity.isVGame(),
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(
|
||||
gameEntity.isVGame() || gameEntity.isSplitXApk()
|
||||
) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(
|
||||
context,
|
||||
gameEntity,
|
||||
apkEntity
|
||||
) {
|
||||
PackageCheckDialogFragment.show(
|
||||
context as AppCompatActivity,
|
||||
gameEntity
|
||||
) {
|
||||
CertificationDialog.showCertificationDialog(
|
||||
context,
|
||||
gameEntity,
|
||||
apkEntity,
|
||||
object : EmptyCallback {
|
||||
override fun onCallback() {
|
||||
PackageCheckDialogFragment.show(
|
||||
context as AppCompatActivity,
|
||||
gameEntity,
|
||||
object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
CertificationDialog.showCertificationDialog(
|
||||
context,
|
||||
gameEntity,
|
||||
object : ConfirmListener {
|
||||
override fun onConfirm() {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apkEntity.size
|
||||
) { isSubscribe ->
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
downloadMethod,
|
||||
entrance,
|
||||
location,
|
||||
isSubscribe, traceEvent
|
||||
)
|
||||
gameEntity
|
||||
) {
|
||||
DialogUtils.checkDownload(
|
||||
context,
|
||||
apkEntity.size,
|
||||
gameEntity.id,
|
||||
gameEntity.name
|
||||
) { isSubscribe ->
|
||||
DownloadManager.createDownload(
|
||||
context,
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
downloadMethod,
|
||||
entrance,
|
||||
location,
|
||||
isSubscribe, traceEvent
|
||||
)
|
||||
|
||||
DeviceRemindDialog.showDeviceRemindDialog(
|
||||
context,
|
||||
gameEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
DeviceRemindDialog.showDeviceRemindDialog(
|
||||
context,
|
||||
gameEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, msg)
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ import com.gh.gamecenter.common.utils.tryCatchInRelease
|
||||
import com.gh.gamecenter.core.utils.EmptyCallback
|
||||
import com.gh.gamecenter.core.utils.GsonUtils
|
||||
import com.gh.gamecenter.core.utils.SPUtils
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.google.gson.JsonObject
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
@ -93,6 +94,10 @@ object BrowserInstallHelper {
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun shouldAutoSwitchAssistantInstall(gameEntity: GameEntity): Boolean =
|
||||
isUseBrowserToInstallEnabled() && shouldUseBrowserToInstall() && gameEntity.isSplitXApk()
|
||||
|
||||
/**
|
||||
* 是否显示使用浏览器来安装弹窗
|
||||
*/
|
||||
@ -144,7 +149,8 @@ object BrowserInstallHelper {
|
||||
val manufacturer = Build.MANUFACTURER.toUpperCase(Locale.CHINA)
|
||||
var contentText = "当前安装方式为助手安装,如果出现游戏无法安装的问题,可选择切换安装方式为“浏览器安装”"
|
||||
if (manufacturer == "OPPO" || manufacturer == "VIVO") {
|
||||
contentText = "当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”"
|
||||
contentText =
|
||||
"当前安装方式为助手安装,下载安装游戏需要验证账户密码或指纹。如需免密码安装,可选择切换安装方式为“浏览器安装”"
|
||||
}
|
||||
|
||||
DialogHelper.showDialog(
|
||||
|
||||
@ -55,23 +55,21 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
* @param status 下载状态
|
||||
*/
|
||||
override fun onStatusChanged(id: String, status: DownloadStatus) {
|
||||
val entity = findEntity(id)
|
||||
val entity = findEntity(id) ?: return
|
||||
|
||||
if (entity != null) {
|
||||
entity.status = status
|
||||
entity.status = status
|
||||
|
||||
if (status == DownloadStatus.COMPLETED) {
|
||||
SimpleDownloadManager.resumeQueuedTask()
|
||||
}
|
||||
if (status == DownloadStatus.COMPLETED) {
|
||||
SimpleDownloadManager.resumeQueuedTask()
|
||||
}
|
||||
|
||||
ExecutorProvider.getInstance().backgroundExecutor.execute {
|
||||
updateDownloadToDatabase(entity)
|
||||
updateDownloadList()
|
||||
}
|
||||
ExecutorProvider.getInstance().backgroundExecutor.execute {
|
||||
updateDownloadToDatabase(entity)
|
||||
updateDownloadList()
|
||||
}
|
||||
|
||||
for (listener in mGlobalStatusChangedListenerList) {
|
||||
listener.invoke(entity!!, status)
|
||||
listener.invoke(entity, status)
|
||||
}
|
||||
|
||||
val listenerList = mListenerMap[id] ?: return
|
||||
@ -83,10 +81,6 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDownloadComplete(id: String?, elapsedTime: Long) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* 重定向中的回调
|
||||
* @param id 下载 id
|
||||
@ -169,7 +163,7 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
* @param error 错误类型
|
||||
* @param exception 包裹错误的 Exception
|
||||
*/
|
||||
override fun onError(id: String, error: DownloadError?, exception: Exception) {
|
||||
override fun onError(id: String, error: DownloadError?, exception: Exception?) {
|
||||
error ?: return
|
||||
|
||||
when (error) {
|
||||
@ -218,6 +212,10 @@ object DownloadMessageHandler : InnerDownloadListener {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override fun onDownloadComplete(id: String?, elapsedTime: Long) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fun registerListener(id: String, listener: DownloadListener) {
|
||||
var listenerList = mListenerMap[id]
|
||||
if (listenerList == null) {
|
||||
|
||||
@ -7,14 +7,21 @@ import com.gh.base.DownloadToolbarActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.utils.updateStatusBarColor
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureSource
|
||||
import com.gh.gamecenter.game.GameFragment
|
||||
|
||||
class BlockActivity : DownloadToolbarActivity() {
|
||||
|
||||
companion object {
|
||||
fun getIntent(context: Context, blockData: SubjectRecommendEntity, entrance: String): Intent {
|
||||
fun getIntent(context: Context,
|
||||
blockData: SubjectRecommendEntity,
|
||||
exposureSourceList: ArrayList<ExposureSource>? = null,
|
||||
entrance: String): Intent {
|
||||
val args = Bundle()
|
||||
args.putParcelable(EntranceConsts.KEY_BLOCK_DATA, blockData)
|
||||
if (exposureSourceList != null) {
|
||||
args.putParcelableArrayList(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST, exposureSourceList)
|
||||
}
|
||||
args.putString(EntranceConsts.KEY_ENTRANCE, entrance)
|
||||
return getTargetIntent(context, BlockActivity::class.java, GameFragment::class.java, args)
|
||||
}
|
||||
@ -27,7 +34,7 @@ class BlockActivity : DownloadToolbarActivity() {
|
||||
}
|
||||
|
||||
override fun provideNormalIntent(): Intent {
|
||||
return getTargetIntent(this, BlockActivity::class.java, GameFragment::class.java)
|
||||
return getTargetIntent(this, BlockActivity::class.java, GameFragment::class.java, intent?.extras)
|
||||
}
|
||||
|
||||
override fun showDownloadMenu(): Boolean {
|
||||
|
||||
@ -101,7 +101,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
entrance: String,
|
||||
traceEvent: ExposureEvent?
|
||||
) {
|
||||
startGameDetailActivity(context, gameEntity, entrance, -1, traceEvent = traceEvent)
|
||||
startGameDetailActivity(context, gameEntity, entrance, "", traceEvent = traceEvent)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,7 +117,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
context: Context,
|
||||
gameEntity: GameEntity?,
|
||||
entrance: String,
|
||||
defaultTab: Int = -1,
|
||||
defaultTab: String = "",
|
||||
isSkipGameComment: Boolean = false,
|
||||
scrollToLibao: Boolean = false,
|
||||
scrollToServer: Boolean = false,
|
||||
@ -140,18 +140,18 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
)
|
||||
traceEvent.payload = payload
|
||||
}
|
||||
if (defaultTab != -1) {
|
||||
bundle.putInt(EntranceConsts.KEY_TARGET, defaultTab)
|
||||
if (defaultTab.isNotEmpty()) {
|
||||
bundle.putString(EntranceConsts.KEY_TARGET, defaultTab)
|
||||
}
|
||||
if (isSkipGameComment) {
|
||||
bundle.putBoolean(EntranceConsts.KEY_SKIP_GAME_COMMENT, true)
|
||||
}
|
||||
if (scrollToLibao) {
|
||||
bundle.putInt(EntranceConsts.KEY_TARGET, GameDetailFragment.INDEX_DESC)
|
||||
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailFragment.TAB_DESC)
|
||||
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO, true)
|
||||
}
|
||||
if (scrollToServer) {
|
||||
bundle.putInt(EntranceConsts.KEY_TARGET, GameDetailFragment.INDEX_DESC)
|
||||
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailFragment.TAB_DESC)
|
||||
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_SERVER, true)
|
||||
}
|
||||
bundle.putString(EntranceConsts.KEY_GAMEID, gameEntity?.id)
|
||||
@ -257,7 +257,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
}
|
||||
if (openVideoStreaming) {
|
||||
bundle.putBoolean(EntranceConsts.KEY_OPEN_VIDEO_STREAMING, true)
|
||||
bundle.putInt(EntranceConsts.KEY_TARGET, GameDetailFragment.INDEX_DESC)
|
||||
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailFragment.TAB_DESC)
|
||||
}
|
||||
if (openPlatformWindow) {
|
||||
bundle.putBoolean(EntranceConsts.KEY_OPEN_PLATFORM_WINDOW, true)
|
||||
@ -269,7 +269,7 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
}
|
||||
}
|
||||
if (scrollToLibao) {
|
||||
bundle.putInt(EntranceConsts.KEY_TARGET, GameDetailFragment.INDEX_TRENDES)
|
||||
bundle.putString(EntranceConsts.KEY_TARGET, GameDetailFragment.TAB_DESC)
|
||||
bundle.putBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO, true)
|
||||
}
|
||||
bundle.putString(EntranceConsts.KEY_GAMEID, gameId)
|
||||
|
||||
@ -38,21 +38,21 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.imagepipeline.core.ImagePipeline
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.common.utils.ImageUtils.getTransformedUrl
|
||||
import com.gh.gamecenter.common.view.DraggableBigImageView
|
||||
import com.gh.gamecenter.common.view.Gh_RelativeLayout
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
import com.gh.gamecenter.core.runOnIoThread
|
||||
import com.gh.gamecenter.core.utils.*
|
||||
import com.gh.gamecenter.databinding.ActivityViewimageBinding
|
||||
import com.gh.gamecenter.common.entity.CommunityEntity
|
||||
import com.gh.gamecenter.entity.ImageInfoEntity
|
||||
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
|
||||
import com.gh.gamecenter.feature.entity.AnswerEntity
|
||||
import com.gh.gamecenter.common.retrofit.Response
|
||||
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.github.piasy.biv.view.BigImageView
|
||||
import com.github.piasy.biv.view.FrescoImageViewFactory
|
||||
@ -849,9 +849,9 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
// ssiv.resetScaleAndCenter()
|
||||
// }
|
||||
// })
|
||||
ssiv.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
imageView.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -861,7 +861,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
imageView.setOnLongClickListener {
|
||||
// 下滑的时候不弹
|
||||
if (imageView.isDragging()) {
|
||||
return@setOnLongClickListener false
|
||||
return@setOnLongClickListener true
|
||||
}
|
||||
|
||||
val dialog = Dialog(this@ImageViewerActivity)
|
||||
@ -897,7 +897,7 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
|
||||
}
|
||||
dialog.cancel()
|
||||
}
|
||||
false
|
||||
true
|
||||
}
|
||||
view.tag = position
|
||||
container.addView(view)
|
||||
|
||||
@ -4,6 +4,7 @@ import static com.gh.gamecenter.common.constant.Constants.LOGIN_TAG;
|
||||
import static com.gh.gamecenter.common.constant.Constants.LOGOUT_TAG;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.ENTRANCE_BROWSER;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_LAUNCH_SIMULATOR_GAME;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_LAUNCH_VM_GAME;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_QQ_GROUP;
|
||||
import static com.gh.gamecenter.common.constant.EntranceConsts.HOST_WEB;
|
||||
@ -32,15 +33,17 @@ import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
|
||||
import com.alibaba.android.arouter.launcher.ARouter;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.DefaultUrlHandler;
|
||||
import com.gh.common.constant.Config;
|
||||
@ -74,6 +77,7 @@ import com.gh.gamecenter.common.base.fragment.ToolbarFragment;
|
||||
import com.gh.gamecenter.common.constant.CommonConsts;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.constant.RouteConsts;
|
||||
import com.gh.gamecenter.common.entity.LinkEntity;
|
||||
import com.gh.gamecenter.common.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.common.entity.SuggestType;
|
||||
@ -88,6 +92,7 @@ import com.gh.gamecenter.common.utils.ImageUtils;
|
||||
import com.gh.gamecenter.common.utils.NotificationHelper;
|
||||
import com.gh.gamecenter.common.utils.ShareUtils;
|
||||
import com.gh.gamecenter.core.AppExecutor;
|
||||
import com.gh.gamecenter.core.provider.IStartUpAdProvider;
|
||||
import com.gh.gamecenter.core.utils.ClassUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.GsonUtils;
|
||||
@ -116,6 +121,7 @@ import com.gh.gamecenter.packagehelper.PackageViewModel;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.gh.gamecenter.room.AppDatabase;
|
||||
import com.gh.gamecenter.room.dao.SimulatorGameDao;
|
||||
import com.gh.vspace.VHelper;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
@ -186,11 +192,12 @@ public class MainActivity extends BaseActivity {
|
||||
private final Handler handler = new Handler();
|
||||
public boolean showAd = false; // 是否显示广告
|
||||
|
||||
private IStartUpAdProvider mStartUpAdProvider;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
showAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
|
||||
|
||||
HaloApp.getInstance().initFresco();
|
||||
HaloApp.getInstance().isAlreadyUpAndRunning = true;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -304,18 +311,21 @@ public class MainActivity extends BaseActivity {
|
||||
if (showAd) {
|
||||
observeStartUp();
|
||||
} else {
|
||||
checkDialog();
|
||||
hideStartUp();
|
||||
hideStartUpAd();
|
||||
}
|
||||
|
||||
// 默认配置为空时重试
|
||||
if (Config.getSettings() == null) {
|
||||
Config.getGhzsSettings();
|
||||
} else if (Config.getVSettingEntity() == null) {
|
||||
Config.refreshVSettingEntity();
|
||||
}
|
||||
|
||||
// 耗时操作
|
||||
AppExecutor.getIoExecutor().execute(() -> {
|
||||
// 上传数据
|
||||
DataCollectionManager.getInstance().upload();
|
||||
// 获取默认配置
|
||||
|
||||
if (Config.getSettings() == null) {
|
||||
Config.getGhzsSettings();
|
||||
}
|
||||
|
||||
// 初始化PlatformUtils
|
||||
PlatformUtils.getInstance(getApplicationContext());
|
||||
@ -465,6 +475,8 @@ public class MainActivity extends BaseActivity {
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
|
||||
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
releaseExoSourceCache();
|
||||
}
|
||||
@ -498,8 +510,17 @@ public class MainActivity extends BaseActivity {
|
||||
showStartUp(startUp);
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> {
|
||||
hideStartUp();
|
||||
observeStartUpAd();
|
||||
initStartUpAd();
|
||||
}, 2000);
|
||||
} else {
|
||||
initStartUpAd();
|
||||
}
|
||||
}
|
||||
|
||||
private void initStartUpAd() {
|
||||
mStartUpAdProvider = (IStartUpAdProvider) ARouter.getInstance().build(RouteConsts.provider.adSdk).navigation();
|
||||
if (mStartUpAdProvider != null && mStartUpAdProvider.shouldEnableSDK(HaloApp.getInstance().getChannel())) {
|
||||
initSDKStartUpAd();
|
||||
} else {
|
||||
observeStartUpAd();
|
||||
}
|
||||
@ -507,7 +528,27 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
private void observeStartUpAd() {
|
||||
final StartupAdEntity startUpAd = AdHelper.getStartUpAd();
|
||||
|
||||
if (startUpAd != null && !TextUtils.isEmpty(startUpAd.getImg())) {
|
||||
// 根据接口返回的广告时间,判断该图片广告是否还有必要显示
|
||||
boolean isAdValid = false;
|
||||
if (startUpAd.getTime() != null) {
|
||||
long currentTimeInSecond = System.currentTimeMillis() / 1000;
|
||||
if (currentTimeInSecond > startUpAd.getTime().getStart()
|
||||
&& currentTimeInSecond < startUpAd.getTime().getEnd()) {
|
||||
isAdValid = true;
|
||||
}
|
||||
} else {
|
||||
// 接口没有返回开始和结束时间时,默认有效
|
||||
isAdValid = true;
|
||||
}
|
||||
|
||||
// 图片广告无效,跳过
|
||||
if (!isAdValid) {
|
||||
hideStartUpAd();
|
||||
return;
|
||||
}
|
||||
|
||||
final String showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "");
|
||||
final String rule = startUpAd.getRule();
|
||||
switch (rule) {
|
||||
@ -573,6 +614,12 @@ public class MainActivity extends BaseActivity {
|
||||
startAdContainer.setVisibility(View.GONE);
|
||||
ExtensionsKt.removeFromParent(startAdContainer);
|
||||
}
|
||||
View startSdkAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
if (startSdkAdContainer != null) {
|
||||
startSdkAdContainer.setVisibility(View.GONE);
|
||||
ExtensionsKt.removeFromParent(startSdkAdContainer);
|
||||
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
|
||||
}
|
||||
checkDialog();
|
||||
}
|
||||
|
||||
@ -594,7 +641,7 @@ public class MainActivity extends BaseActivity {
|
||||
SimpleDraweeView adImage = findViewById(R.id.adImage);
|
||||
startAdContainer.setVisibility(View.VISIBLE);
|
||||
jumpDetailBtn.setText(ad.getDesc());
|
||||
ExtensionsKt.setDrawableEnd(jumpDetailBtn, VectorDrawableCompat.create(getResources(), R.drawable.ic_startup_ad_arrow, null), null, null);
|
||||
ExtensionsKt.setDrawableEnd(jumpDetailBtn, AppCompatResources.getDrawable(this, R.drawable.ic_startup_ad_arrow), null, null);
|
||||
ImageUtils.display(adImage, ad.getImg());
|
||||
startAdContainer.setOnClickListener(v -> {
|
||||
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
|
||||
@ -630,6 +677,18 @@ public class MainActivity extends BaseActivity {
|
||||
mBaseHandler.sendEmptyMessageDelayed(COUNTDOWN_AD, 1000);
|
||||
}
|
||||
|
||||
private void initSDKStartUpAd() {
|
||||
View startAdContainer = findViewById(R.id.sdkStartAdContainer);
|
||||
startAdContainer.setVisibility(View.VISIBLE);
|
||||
FrameLayout adsFl = findViewById(R.id.adsFl);
|
||||
if (mStartUpAdProvider != null) {
|
||||
mStartUpAdProvider.initStartUpAd(startAdContainer, adsFl, showAd, () -> {
|
||||
hideStartUpAd();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void showStartUp(StartupAdEntity ad) {
|
||||
TextView adContentTv = findViewById(R.id.adContentTv);
|
||||
View containerView = findViewById(R.id.maskContainer);
|
||||
@ -739,6 +798,33 @@ public class MainActivity extends BaseActivity {
|
||||
);
|
||||
}
|
||||
break;
|
||||
case HOST_LAUNCH_VM_GAME:
|
||||
String gamePackageName = getIntent().getStringExtra(EntranceConsts.KEY_GAME_PKG);
|
||||
if (TextUtils.isEmpty(gamePackageName)) {
|
||||
ToastUtils.showToast("游戏启动失败,请联系客服反馈相关信息");
|
||||
return;
|
||||
}
|
||||
|
||||
VHelper.INSTANCE.logLaunchButtonClicked(
|
||||
gamePackageName,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"桌面快捷图标"
|
||||
);
|
||||
|
||||
ToastUtils.showToast("游戏启动中,请稍后~");
|
||||
handler.postDelayed(() -> {
|
||||
VHelper.postOnInitialized(() -> {
|
||||
if (VHelper.isInstalled(gamePackageName)) {
|
||||
VHelper.launch(this, gamePackageName, false, true);
|
||||
} else {
|
||||
ToastUtils.showToast("应用已被卸载!");
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}, 500);
|
||||
break;
|
||||
case KEY_MARKET_DETAILS:
|
||||
redirectGameDetail(bundle.getString(KEY_DATA));
|
||||
break;
|
||||
@ -987,7 +1073,9 @@ public class MainActivity extends BaseActivity {
|
||||
public void onEventMainThread(EBNetworkState busNetworkState) {
|
||||
if (busNetworkState.isNetworkConnected()) {
|
||||
if (Config.getSettings() == null) {
|
||||
AppExecutor.getIoExecutor().execute(Config::getGhzsSettings);
|
||||
Config.getGhzsSettings();
|
||||
} else if (Config.getVSettingEntity() == null) {
|
||||
Config.refreshVSettingEntity();
|
||||
}
|
||||
|
||||
mPackageViewModel.checkData();
|
||||
|
||||
@ -30,7 +30,6 @@ import com.ethanhua.skeleton.ViewSkeletonScreen;
|
||||
import com.gh.base.DownloadToolbarActivity;
|
||||
import com.gh.common.filter.RegionSettingHelper;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.CollectionUtils;
|
||||
import com.gh.common.util.DataCollectionUtils;
|
||||
@ -41,6 +40,8 @@ import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
|
||||
import com.gh.gamecenter.common.callback.OnRequestCallBackListener;
|
||||
import com.gh.gamecenter.common.constant.Constants;
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts;
|
||||
import com.gh.gamecenter.common.eventbus.EBNetworkState;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.common.retrofit.Response;
|
||||
import com.gh.gamecenter.common.utils.ExtensionsKt;
|
||||
import com.gh.gamecenter.common.utils.ShareUtils;
|
||||
@ -49,15 +50,16 @@ import com.gh.gamecenter.common.view.VerticalItemDecoration;
|
||||
import com.gh.gamecenter.core.utils.ClickUtils;
|
||||
import com.gh.gamecenter.core.utils.DisplayUtils;
|
||||
import com.gh.gamecenter.core.utils.MtaHelper;
|
||||
import com.gh.gamecenter.entity.NewsDetailEntity;
|
||||
import com.gh.gamecenter.eventbus.EBConcernChanged;
|
||||
import com.gh.gamecenter.eventbus.EBAddComment;
|
||||
import com.gh.gamecenter.eventbus.EBDeleteComment;
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus;
|
||||
import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.gh.gamecenter.feature.entity.GameEntity;
|
||||
import com.gh.gamecenter.feature.entity.MeEntity;
|
||||
import com.gh.gamecenter.entity.NewsDetailEntity;
|
||||
import com.gh.gamecenter.feature.entity.NewsEntity;
|
||||
import com.gh.gamecenter.eventbus.EBConcernChanged;
|
||||
import com.gh.gamecenter.eventbus.EBDownloadStatus;
|
||||
import com.gh.gamecenter.common.eventbus.EBNetworkState;
|
||||
import com.gh.gamecenter.eventbus.EBPackage;
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
|
||||
import com.gh.gamecenter.newsdetail.NewsDetailAdapter;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.lightgame.download.DataWatcher;
|
||||
@ -92,6 +94,9 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
TextView mNoneDataTv;
|
||||
RelativeLayout mDetailCommentLl;
|
||||
RelativeLayout mSkeletonView;
|
||||
View mCommentContainer;
|
||||
View mDownloadContainer;
|
||||
View mBottomContainer;
|
||||
|
||||
MenuItem mNewsShare;
|
||||
MenuItem mNewsCollection;
|
||||
@ -118,7 +123,7 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
private NewsEntity mNewsEntity;
|
||||
private DownloadEntity mDownloadEntity;
|
||||
|
||||
private Boolean mHideUselessInfo = false;
|
||||
private Boolean mHideUselessInfo = false; // 是否需要隐藏一些额外的信息(评论按钮等)
|
||||
|
||||
private Handler handler = new Handler();
|
||||
|
||||
@ -270,6 +275,9 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
mNoneDataTv = findViewById(R.id.reuseNoneDataTv);
|
||||
mDetailCommentLl = findViewById(R.id.news_detail_ll_coment);
|
||||
mSkeletonView = findViewById(R.id.news_skeleton);
|
||||
mCommentContainer = findViewById(R.id.commentContainer);
|
||||
mDownloadContainer = findViewById(R.id.detail_ll_bottom);
|
||||
mBottomContainer = findViewById(R.id.bottomContainer);
|
||||
|
||||
mViewSkeletonScreen = Skeleton.bind(mSkeletonView).shimmer(false).load(R.layout.news_detail_skeleton).show();
|
||||
// init toolbar
|
||||
@ -292,6 +300,7 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
|
||||
if (mHideUselessInfo) {
|
||||
getMenuItem(R.id.menu_download).setVisible(false);
|
||||
mCommentContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
adapter = new NewsDetailAdapter(this, this, mHideUselessInfo, mEntrance);
|
||||
@ -550,6 +559,17 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onDeleteComment(EBDeleteComment event) {
|
||||
adapter.getNewsCommentNum();
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onAddComment(EBAddComment event) {
|
||||
adapter.getNewsCommentNum();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction() & MotionEventCompat.ACTION_MASK) {
|
||||
@ -666,10 +686,22 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
adapter.notifyItemInserted(1);
|
||||
|
||||
mDetailBottomLl.setVisibility(View.VISIBLE);
|
||||
DetailDownloadUtils.detailInitDownload(getDetailViewHolder(), true);
|
||||
mDownloadContainer.setVisibility(View.VISIBLE);
|
||||
mBottomContainer.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mDetailBottomLl.setVisibility(View.GONE);
|
||||
mCommentContainer.setVisibility(View.GONE);
|
||||
|
||||
// 关联了光环的文章不显示下载按钮
|
||||
if ("光环助手".equals(gameEntity.getName())) {
|
||||
mDetailBottomLl.setVisibility(View.GONE);
|
||||
mBottomContainer.setVisibility(View.GONE);
|
||||
} else {
|
||||
mBottomContainer.setVisibility(View.VISIBLE);
|
||||
mDetailBottomLl.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
DetailDownloadUtils.detailInitDownload(getDetailViewHolder(), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -754,7 +786,7 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
|
||||
mDetailRv.addItemDecoration(mItemDecoration);
|
||||
if (mContentView != null) {
|
||||
mContentView.setBackgroundColor(ContextCompat.getColor(this, R.color.background));
|
||||
findViewById(R.id.commentContainer).setBackgroundColor(ContextCompat.getColor(this, R.color.background_white));
|
||||
findViewById(R.id.bottomContainer).setBackgroundColor(ContextCompat.getColor(this, R.color.background_white));
|
||||
((TextView) findViewById(R.id.commentTv)).setTextColor(ContextCompat.getColor(this, R.color.text_subtitle));
|
||||
}
|
||||
if (adapter != null) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user