Compare commits
1204 Commits
v3.7.6
...
v4.2.0-200
| Author | SHA1 | Date | |
|---|---|---|---|
| 58d2290e12 | |||
| 547e6da027 | |||
| c3e34ba644 | |||
| 077e17c5aa | |||
| f264875b7d | |||
| 351b8a331c | |||
| 479f7c464b | |||
| e04a7fc4b9 | |||
| 595f7747f4 | |||
| 8c1343fdba | |||
| c3717869bd | |||
| 1e56dc533d | |||
| 1444531830 | |||
| 4e759e446b | |||
| ef6c09d27b | |||
| efc241429c | |||
| 07be540ba1 | |||
| 50479d2e87 | |||
| 2934c9dc38 | |||
| 30a60797e6 | |||
| 53562297d5 | |||
| 144ee3ea8c | |||
| e0c8697e75 | |||
| 6aba2906f6 | |||
| 7bb468a1b1 | |||
| 871be728bf | |||
| bbac0c8d93 | |||
| 6b361ed077 | |||
| 1cfa54f8e8 | |||
| 5bd028cbe9 | |||
| b8f8711ba4 | |||
| c1f899f0d5 | |||
| e4fd74da7d | |||
| bf9cc93daa | |||
| 3b974268a9 | |||
| 822853a4be | |||
| f699841427 | |||
| c700910b15 | |||
| 3c8d0cb3ec | |||
| 8492c762b5 | |||
| b2d70392bb | |||
| eb9cb08624 | |||
| a4ca2628dc | |||
| 727d78d0e5 | |||
| 693d8c4385 | |||
| d46e3fac2d | |||
| 7f0ec7f128 | |||
| 73eb2f6ecb | |||
| 6bd7ced28c | |||
| 086c31a7d4 | |||
| 3a839f6770 | |||
| b67c7e2803 | |||
| b7dbf30845 | |||
| ec86970cbe | |||
| 956755b985 | |||
| fe2779196d | |||
| 9eeeba93d0 | |||
| d7df019d6d | |||
| 68bfc26ddc | |||
| 94a1cfe4b2 | |||
| 936c3b00bb | |||
| b34229e4c4 | |||
| b51322b473 | |||
| e0657ccdcc | |||
| 4b67d8b5aa | |||
| 5b8cc49349 | |||
| 612f71e18c | |||
| 6239ccb8ab | |||
| 9680bea412 | |||
| a21d9096c8 | |||
| e6f3ad5cc2 | |||
| c41e996add | |||
| 58f230038c | |||
| bda41d8a26 | |||
| e3f41543a4 | |||
| 78c4d7acef | |||
| 8c884b6d23 | |||
| a5f9af2df2 | |||
| e2fd6dbf97 | |||
| e430b4e2de | |||
| caa3f46c5c | |||
| b2beba4d36 | |||
| 3a9c7fc71d | |||
| a5f8275f64 | |||
| 8fa3f3d832 | |||
| 97472b8259 | |||
| ee07889b30 | |||
| 8582860116 | |||
| b8903e7814 | |||
| b47bcfc2c3 | |||
| 35a987a835 | |||
| 6f413b27d4 | |||
| 92173b4794 | |||
| 89e79154aa | |||
| de9145cd70 | |||
| 8bf509ee2d | |||
| d7144265e1 | |||
| cc6c759658 | |||
| 8e5d482f9e | |||
| 5ed8f2499a | |||
| a8c9bcc1b0 | |||
| 21aabcc561 | |||
| a2b86a9e21 | |||
| 74882f56ee | |||
| 1eb9ec1dd3 | |||
| 9e95c0cc7e | |||
| 877238d2d5 | |||
| 9c6f69b16a | |||
| 64af456182 | |||
| 1a84477700 | |||
| a0b6285596 | |||
| 951c139062 | |||
| 99efcd6bbf | |||
| 3482f58b1b | |||
| 6b4f751a16 | |||
| 3be1308230 | |||
| b7710cffa3 | |||
| dc4fe89521 | |||
| c33eb6829a | |||
| e1793d57eb | |||
| cc4c48f718 | |||
| aa20ed9744 | |||
| b6d8688a40 | |||
| d1da2bb7fa | |||
| 7828bce732 | |||
| 026a8d7093 | |||
| 6a9a29c5ff | |||
| 16b4b6cc81 | |||
| 863e570b61 | |||
| c9e8408804 | |||
| 31984f1737 | |||
| ad2a0debdd | |||
| 4c45657092 | |||
| 5d7fc94d51 | |||
| 641b430fe5 | |||
| e1bb02f4e0 | |||
| 36fd8cf408 | |||
| e48b47b315 | |||
| 46935e4cad | |||
| b8a6b4baea | |||
| 8a8f0a95ed | |||
| cdbefd2d4f | |||
| 7e79b4e328 | |||
| 11dc9f9be0 | |||
| ec255099eb | |||
| 64738dceaf | |||
| 7d518696f0 | |||
| fcd97b66df | |||
| 47f5c3b7c1 | |||
| b64fee9d25 | |||
| 498efdf5ea | |||
| 59d6450ded | |||
| 7da206af7e | |||
| 8bd669e11a | |||
| 62570aed9e | |||
| bfe9c04384 | |||
| b27d007d47 | |||
| 7e50e6570d | |||
| 336d449889 | |||
| 3dfea1e6f9 | |||
| 3c1780d9b5 | |||
| 35ee7cf03d | |||
| 72e8c18f9c | |||
| f3f876d213 | |||
| 398907db90 | |||
| 5dd251eaa8 | |||
| 2c73e55f43 | |||
| f4406d7960 | |||
| 3e0a620ac5 | |||
| 9ea8c32608 | |||
| e2ea197f9e | |||
| f92038b5bf | |||
| fa9eee2c4a | |||
| 3e62fb61e1 | |||
| 5d71e0ccc1 | |||
| 4699923058 | |||
| 9206938938 | |||
| 46ac569f70 | |||
| b90d1b4f38 | |||
| 592b7bbc5e | |||
| 3ccb8b3772 | |||
| 422abe1b87 | |||
| a14f35a4f0 | |||
| 3bebc92106 | |||
| 21413cf250 | |||
| 04a34af370 | |||
| e1e6924b6e | |||
| fbd3a42e81 | |||
| 80a2cbb8cd | |||
| 96fc6cc183 | |||
| b5ff891db1 | |||
| d2171e7a3b | |||
| c3a06f57b1 | |||
| 18f41743bf | |||
| fcc647a1f8 | |||
| e80b198aa5 | |||
| 52efa96e2c | |||
| 816dd60298 | |||
| a181292f80 | |||
| 1b946c325c | |||
| befb323721 | |||
| e62c0aaaad | |||
| 4ecc0c073b | |||
| faa41248eb | |||
| 6dca13e80b | |||
| f3fab1b3f6 | |||
| 5340a41298 | |||
| 553ebc137b | |||
| caf2a379d9 | |||
| c59b79427c | |||
| dd2338021e | |||
| e54fcca53e | |||
| ad416c6a5d | |||
| 4a65c1a5c8 | |||
| 878529f646 | |||
| d01bc1e2d1 | |||
| d63f5f5ab2 | |||
| ad0fb7a55a | |||
| b0258eef77 | |||
| 86d4df8ad9 | |||
| bb11d984f9 | |||
| d3f3d2ca98 | |||
| 0c1e712c79 | |||
| e193a40651 | |||
| 03f36476cb | |||
| a721637be3 | |||
| 722fb1ad64 | |||
| 52a05c3aa4 | |||
| bcbdac6afc | |||
| a9507af3f4 | |||
| 68601ca8be | |||
| a7adc27896 | |||
| d19d0eb571 | |||
| d8e365fe08 | |||
| b34f61ce0d | |||
| 1f24d16f95 | |||
| 738074ec00 | |||
| c8eee33475 | |||
| badf9f9c20 | |||
| 0398cc4ffc | |||
| b88abf6b9a | |||
| a0d193bc52 | |||
| 6ac635f8c6 | |||
| 30c7d71114 | |||
| 0223b3ab22 | |||
| c9663662d5 | |||
| 12bed97638 | |||
| a857af970d | |||
| 7da621583f | |||
| 46a32b62c2 | |||
| 45bcc95e7d | |||
| 7d7bcfaa1d | |||
| 3a9a561c77 | |||
| e8d344256a | |||
| 1a7c1119bf | |||
| 0b6a2503aa | |||
| 459b9f65a9 | |||
| 6c1ebe531e | |||
| 604450292b | |||
| e42361e84a | |||
| a974652f7f | |||
| 309ab54e90 | |||
| 486d680c26 | |||
| 61a5f3a275 | |||
| c865417a4b | |||
| b142feaaae | |||
| 7380854133 | |||
| 8a0f185eda | |||
| bd9604a53e | |||
| 1aeab51f94 | |||
| b16a6fedc6 | |||
| b97c381ed4 | |||
| acb8c723a3 | |||
| 4492307e23 | |||
| e31224b332 | |||
| 6933d6c590 | |||
| 3d58841ce5 | |||
| 0654b0a25f | |||
| 44dde3f91b | |||
| abad30595f | |||
| c4df411560 | |||
| 2974fa4562 | |||
| b086b1cb0c | |||
| 22cf026335 | |||
| 90bd53fe61 | |||
| 9c580a356e | |||
| 7198c28e6f | |||
| 7bf074fddc | |||
| bea1a336e9 | |||
| 97a9e03192 | |||
| 244d57b6bc | |||
| 3cbd484147 | |||
| 8b81819c30 | |||
| 1873ac5d4e | |||
| cf70c1e7fe | |||
| 6f6b26ea4d | |||
| e2708d9078 | |||
| fb5a40c6e4 | |||
| e2a10c1410 | |||
| 5461d3d548 | |||
| c47365e626 | |||
| 3476f8df3a | |||
| f812c1e5c8 | |||
| 391f196005 | |||
| 097dbca26e | |||
| a147118381 | |||
| e6bdde8273 | |||
| 747757faa7 | |||
| 6f21b9d0ae | |||
| e505554aac | |||
| 3323cce890 | |||
| ffd468db1e | |||
| e98e0d1522 | |||
| 13a4f2014c | |||
| 8cbfe6450a | |||
| bcc866888e | |||
| 60911d5dcb | |||
| 7e77d5749e | |||
| 6c3be5627d | |||
| f6a9585700 | |||
| 06fddb7dcd | |||
| 3a3f9a625b | |||
| 3702b104fc | |||
| 3e023089a1 | |||
| 7455674f6b | |||
| c93c0f2fc6 | |||
| 727f02e571 | |||
| 784fae1f5d | |||
| 42ef075912 | |||
| 15307c5223 | |||
| aad3b48883 | |||
| d65d8f1c4c | |||
| c581496975 | |||
| d5481a8888 | |||
| e0a61278fc | |||
| 2c36283833 | |||
| 1b5a8f3a7e | |||
| 95c918b4e3 | |||
| f32cc1673c | |||
| f0fc2f06da | |||
| b6c6abaa5b | |||
| 6ed67c911c | |||
| 1eda223a1e | |||
| 316c0c28ab | |||
| 895d4d5cf1 | |||
| 877df95e02 | |||
| 801f0b95e7 | |||
| 9019f555b5 | |||
| 106b03a316 | |||
| d8faa554be | |||
| 93080a74a7 | |||
| 3ea2ede0cb | |||
| 1242848b6f | |||
| 24d44a2c90 | |||
| 971779a529 | |||
| 14f561c237 | |||
| 3a38e746f6 | |||
| dd3bc9d39d | |||
| 39a8062aef | |||
| 55b6ccb760 | |||
| a8a55eb9bd | |||
| 3eb73439aa | |||
| 466e118579 | |||
| b38032074b | |||
| 9ee771e528 | |||
| 9253ed47e6 | |||
| bc82263286 | |||
| 11979240ab | |||
| 255e6182a9 | |||
| f170abb7ea | |||
| eb80deb413 | |||
| 10ba5a9ba5 | |||
| 94c49cba8b | |||
| 354dca8b04 | |||
| 034488ff34 | |||
| 59c70e23dd | |||
| 7d98a842f1 | |||
| 5f8006dc5a | |||
| 239bd69580 | |||
| bc96f102a1 | |||
| e2ef3f4d01 | |||
| 5c20bbf5e4 | |||
| b07edd256a | |||
| 1478d37889 | |||
| 7151b56de3 | |||
| 220fd9528b | |||
| 1c26c35571 | |||
| 78eb6b7b02 | |||
| 9dc9add896 | |||
| 2d09f8c008 | |||
| 166e1e77ec | |||
| ea782d002b | |||
| f525a3c46d | |||
| bef6cbb212 | |||
| 5e0af8654a | |||
| 032a89e0cd | |||
| c9afb6df02 | |||
| b8092447ff | |||
| bff20bea49 | |||
| 87f2d9c85f | |||
| 154dfc8538 | |||
| 59c4176983 | |||
| fddcdfb3aa | |||
| cdbf7d39a5 | |||
| 6a55821d4d | |||
| a305db7b13 | |||
| 58b1cd4b12 | |||
| 5e7559e43f | |||
| 2a74e35388 | |||
| 5b9bef79da | |||
| e89750c364 | |||
| 9da6cbf097 | |||
| f83f719283 | |||
| 4a1c81ffb4 | |||
| be26f5168b | |||
| 4e6c75995c | |||
| df693ce0c2 | |||
| f0236d7ad5 | |||
| 1d3e2b5c16 | |||
| 545d257135 | |||
| f5164d2102 | |||
| 9af83be9a7 | |||
| 49b0b982f5 | |||
| ad7543e7bc | |||
| 1bd0db013b | |||
| ef6a2c58ff | |||
| 2aa41661a2 | |||
| e63a374da1 | |||
| e326f072d2 | |||
| f53cc18ab6 | |||
| 723a504d7c | |||
| dab48607e8 | |||
| 3ee69146bb | |||
| ca86a66b14 | |||
| c92bdd3014 | |||
| 0be23f26f2 | |||
| 6ce4592e5e | |||
| 92caedb011 | |||
| f796411fa8 | |||
| d45f185f77 | |||
| 6564de8a72 | |||
| 10028dfebc | |||
| fa06795cef | |||
| c1eb324d79 | |||
| cdf9528583 | |||
| 5f5a621bd1 | |||
| b8d54dfa59 | |||
| b4f39d09e4 | |||
| d57ac57f43 | |||
| a3aea6259c | |||
| 73e4c90956 | |||
| c1432159f3 | |||
| 45f47d98ba | |||
| 2e9638b8c5 | |||
| 7ea30c1d0e | |||
| 034e04944a | |||
| 99326596d5 | |||
| 1cc2b85816 | |||
| 942291d7c5 | |||
| f4cd9419a4 | |||
| a24b9d92c7 | |||
| 8e7e83ad72 | |||
| cd810f0048 | |||
| fa050039cd | |||
| 935fb1149f | |||
| 951817455a | |||
| de597bdd36 | |||
| e71e7f6163 | |||
| 09be5e157d | |||
| 1f5e59fc1d | |||
| e58861afa4 | |||
| 44e51ecb0a | |||
| 794c17a1bb | |||
| 1b287962f0 | |||
| 8bdf98b9d8 | |||
| e1aeb61c9b | |||
| a39a70ac2d | |||
| 4fdcaaf591 | |||
| b4502638ff | |||
| 05502d56b1 | |||
| 90e1e8a40f | |||
| b10293da50 | |||
| 83cf0687e6 | |||
| f56b03716a | |||
| 61a41e6039 | |||
| 20ae9fe0ec | |||
| 74fdec9d72 | |||
| 3437265cc1 | |||
| 271993a876 | |||
| 3a8b7bb920 | |||
| fd85f3889d | |||
| 556ecea749 | |||
| 8a97844676 | |||
| f152296e7a | |||
| 4ccc789c7c | |||
| 747b02eb7a | |||
| a73c033c03 | |||
| 939db8c820 | |||
| 8601440d97 | |||
| 7a1fa90175 | |||
| 46722ba69d | |||
| 70d9d461bf | |||
| 91944df6a4 | |||
| ef86c1158c | |||
| 0f3b6ed34b | |||
| 8b50620ddc | |||
| 8b2a9eb6ca | |||
| 7297f5480e | |||
| 3bee8cc034 | |||
| 584a16e111 | |||
| 6460c7f8d6 | |||
| feb99c9f78 | |||
| 68ac809bcb | |||
| de207f66d9 | |||
| 054fcd2049 | |||
| 497fc998fe | |||
| 03f76453ab | |||
| 0a87bd354a | |||
| 1baceaef15 | |||
| 9719a7fa28 | |||
| 1718a66126 | |||
| b317ef3a39 | |||
| 8b0cd69ae6 | |||
| c7126e9836 | |||
| f3d01335a4 | |||
| 88e029b129 | |||
| 2bc72328c1 | |||
| 81179b1f72 | |||
| 9a7d4997c2 | |||
| 3b6ac881c2 | |||
| 6b5fb7d8bc | |||
| 1551b0a358 | |||
| 6540af8386 | |||
| 9badcdc382 | |||
| 0ba94fa56f | |||
| 52c1343ade | |||
| 7a0e633b79 | |||
| 9b68b05d7d | |||
| 9e7f6b0854 | |||
| cf20ad6fc2 | |||
| cb7bdba338 | |||
| f1fc06ca84 | |||
| 18f9fe7fcf | |||
| 18816a8a4e | |||
| 8d379501cb | |||
| 8f4c6abfd3 | |||
| a24d0a9618 | |||
| 8cdd66cd89 | |||
| 3fd34576e8 | |||
| 78d5cbcc42 | |||
| 803f2bef75 | |||
| 40c7e8f9e6 | |||
| b3c5ca6112 | |||
| 31067ea66d | |||
| 4e7626ff41 | |||
| e62822505e | |||
| cbc705d1eb | |||
| aa2e147a51 | |||
| 6249726839 | |||
| 8f4bc5a164 | |||
| eee459d08a | |||
| 81b4e40dbf | |||
| 261068e286 | |||
| 84364a7c66 | |||
| 3beb47a8be | |||
| ca76af4474 | |||
| bc33673533 | |||
| c5d038a173 | |||
| b1e492df1b | |||
| 9d9c213af7 | |||
| d3f97ea527 | |||
| 0a5fb4cb1d | |||
| 6905f7191a | |||
| bad7fb4922 | |||
| 250fa7eb7b | |||
| f0cd8567cb | |||
| f6dd35e4b8 | |||
| 2dc299e7f4 | |||
| 366e8ded14 | |||
| 8175742143 | |||
| fc858f1272 | |||
| 84b668714b | |||
| 5ea5346ee8 | |||
| c2eb0b267c | |||
| 7fb502e87e | |||
| 98726ddc3a | |||
| 75ff76acf4 | |||
| ba552812a3 | |||
| 83bfeb0abc | |||
| 70f1b7a678 | |||
| 455d53fee0 | |||
| 39e4b5bf55 | |||
| 40a729b6f8 | |||
| 9643176e06 | |||
| 1a70c33bef | |||
| 888ebe5f54 | |||
| cb02dbae57 | |||
| 2683d02dcd | |||
| ceb924e8f1 | |||
| bd91609a80 | |||
| 2fd74a4698 | |||
| e9e0d3b43e | |||
| 17e09ddad3 | |||
| 65427c55d6 | |||
| e1fc23a1bb | |||
| 2d551a3f73 | |||
| 7f99f75c6f | |||
| 548aea8d13 | |||
| a177137744 | |||
| 3c6443d78f | |||
| ba81ed9cb0 | |||
| 6a1cbd10c6 | |||
| 9b205366f7 | |||
| 7e9ac0c4f1 | |||
| fe889639b3 | |||
| 848e43af28 | |||
| c7a3893fae | |||
| f7d633188c | |||
| e1e7d2d3d6 | |||
| 2b8a280768 | |||
| 6efe96eb0d | |||
| 3562fe9273 | |||
| 739ef44a8b | |||
| 879b42dbf2 | |||
| fae626bb98 | |||
| cebd639d78 | |||
| 17a99a1cda | |||
| 2a03683e1e | |||
| a579b3fe10 | |||
| 9c75dd18df | |||
| cdc9c86852 | |||
| fab1851436 | |||
| a6704e46a9 | |||
| e188f70eb6 | |||
| 02dd115886 | |||
| 5cbfc7b461 | |||
| b4742b5645 | |||
| 5ec25475ea | |||
| c58040ef83 | |||
| 75701b6875 | |||
| 2155a33689 | |||
| 68a9d5d771 | |||
| ebf6107faf | |||
| e4bc36a743 | |||
| 7a64251811 | |||
| 65409d75a7 | |||
| d40081d58b | |||
| f276e981ed | |||
| e50db66b47 | |||
| fc84022852 | |||
| b593f2f3ea | |||
| e782d0542c | |||
| 1a085cad98 | |||
| 1c33a0c4c5 | |||
| 3c4a7961c2 | |||
| 712f9b84cf | |||
| 2efb7b76cc | |||
| 5c4d93ce15 | |||
| 7addd92058 | |||
| 82c5898b9a | |||
| cced6b7035 | |||
| ae0b5b3738 | |||
| 6fdf9cbe5d | |||
| 009244c65d | |||
| 73a720bb9c | |||
| fd9df9904f | |||
| e75fb3a40d | |||
| 0bef1a2aa8 | |||
| 395eb641e5 | |||
| 9019242ffb | |||
| 9433bb72ca | |||
| 500f751152 | |||
| 9ebe3f4a0e | |||
| 4727f22b0f | |||
| 8c92fc9a42 | |||
| 2a7cb34218 | |||
| e1a42b49c1 | |||
| 5a825debf5 | |||
| e46b0a42b0 | |||
| eb0c442a5e | |||
| eb6460236b | |||
| ef051daffd | |||
| b6acb302d2 | |||
| 5cfc5a3971 | |||
| 04de97af16 | |||
| 6367f90589 | |||
| bc8f9d07bb | |||
| a3d693ddc1 | |||
| e205abd120 | |||
| 5da8fccef7 | |||
| c7e78142ee | |||
| 79cbb44d51 | |||
| dcde3db33a | |||
| 44fbc7a182 | |||
| 354c7d1f85 | |||
| d7a85edb76 | |||
| ceb9dc6707 | |||
| b0f20ee017 | |||
| cdf78f2bc5 | |||
| d3f0a8fe4a | |||
| 17acf1bd86 | |||
| 31a0bb24c7 | |||
| 13ff1f4343 | |||
| ec76be9d5e | |||
| 84d53616a0 | |||
| 2758216ae2 | |||
| c492f066ca | |||
| 897478e30e | |||
| a94d825ead | |||
| ba05e6137e | |||
| dc55342343 | |||
| 3ea96d27db | |||
| 48842c099b | |||
| 4f87cac46a | |||
| 52680b63b9 | |||
| f89defc78f | |||
| 46e9a161a4 | |||
| 8e602e8169 | |||
| c60df98577 | |||
| ad7db50336 | |||
| e40ef5292e | |||
| 94b844788c | |||
| 9c222baf91 | |||
| 0794606e57 | |||
| be34c486bf | |||
| fa7a5fef9b | |||
| 9e518d5414 | |||
| 2d17ecd438 | |||
| 56d6c28811 | |||
| 86b77e29e2 | |||
| 23b8b09834 | |||
| 30eb397c66 | |||
| 05bcc0f818 | |||
| 3f9434239f | |||
| 4caf7eabc0 | |||
| 0aee08bbb0 | |||
| 602dbff3c8 | |||
| d52cfd475f | |||
| 4512accb37 | |||
| 2d57c00149 | |||
| cae908da6a | |||
| 38f97673b8 | |||
| ed2bf89413 | |||
| 259d343e31 | |||
| 8e9dbafb4d | |||
| 7e737d7a46 | |||
| 50fd30d173 | |||
| 4c7310f71e | |||
| b3e7168922 | |||
| 261cc5b0eb | |||
| 60218eea97 | |||
| bc1945326a | |||
| 2fd12d56ed | |||
| cb28838b40 | |||
| 4cfd6952c0 | |||
| f5761e378e | |||
| 314144c384 | |||
| 81debc1cd8 | |||
| 9a2baf1d8c | |||
| 55ec26bd3d | |||
| 4c372eeb2b | |||
| c2f9e28edd | |||
| 65a8297fe0 | |||
| 1a48cca197 | |||
| 24984b5d67 | |||
| 619660e5e5 | |||
| c9c4a996dc | |||
| b8ae8b68dc | |||
| a9f4620d8b | |||
| 66abdb1eed | |||
| 1dc4be2d54 | |||
| a286f51801 | |||
| 27708da1bf | |||
| 3aa0e19b0f | |||
| 4d5627348a | |||
| 2aefeb5e53 | |||
| 728b663c7a | |||
| 36156cddc4 | |||
| 2b98702ceb | |||
| 2c2ab02398 | |||
| 8ae8c6d6fb | |||
| 1171424f19 | |||
| 3444922861 | |||
| 5821a519ee | |||
| 439a2353b0 | |||
| 8f8f3193dd | |||
| 5907b8b1a5 | |||
| ba5783417e | |||
| 56573deea1 | |||
| 892933888c | |||
| b3725baad0 | |||
| cf79735780 | |||
| ad059fe18d | |||
| 03fa2052da | |||
| d7d55b7341 | |||
| 6ea9a7de90 | |||
| 3bc65f42c7 | |||
| 854227304f | |||
| 62d34c6c06 | |||
| 69f0beff9c | |||
| 2a32859c48 | |||
| c6bdb4ee8d | |||
| cf5e981758 | |||
| 2bf246562b | |||
| c1cd25b89b | |||
| 2eb259055a | |||
| fe743590c9 | |||
| d3de1c238c | |||
| 931593d726 | |||
| 8f002fc804 | |||
| 10e0d0123e | |||
| b93cb06662 | |||
| 5471099e7b | |||
| 5a2f86be87 | |||
| 3d7ce17b07 | |||
| cf0e237529 | |||
| 60c84153e5 | |||
| f9a8efe084 | |||
| 6b48c546c4 | |||
| b1893718f6 | |||
| 7ad95d5f26 | |||
| 778b0e8f16 | |||
| ad847f6113 | |||
| 27778c2b31 | |||
| 484694cbdb | |||
| 969680a7ad | |||
| 6357e008dc | |||
| a570cfe32b | |||
| ccba561d47 | |||
| 0dcf86ce1c | |||
| 961d4ebb5c | |||
| 54b947504c | |||
| f5abd7e075 | |||
| 35cd97c751 | |||
| 147bc150f5 | |||
| ee7f102d34 | |||
| 7f0e59aba5 | |||
| 135b55f6f9 | |||
| 6986bd9a57 | |||
| 17782a500f | |||
| 64a64960ac | |||
| d4be850e68 | |||
| a6feb57f85 | |||
| 50fee01249 | |||
| 4ff12e91aa | |||
| 24b196f216 | |||
| 414064699a | |||
| d36b2f99ee | |||
| 704b73aef7 | |||
| 99878606d5 | |||
| e1cfccfcc0 | |||
| 4c2a46875d | |||
| 6ce64892e4 | |||
| 92e1c55913 | |||
| 72cfcd66b1 | |||
| 0cb65ab216 | |||
| d18731ccfe | |||
| b0a4aa66f6 | |||
| aad92e529e | |||
| 6e03e75110 | |||
| 91f79a5ff1 | |||
| cc53a1f3d6 | |||
| 25cd086298 | |||
| b27ecab969 | |||
| db1c0d954f | |||
| 03d20aed61 | |||
| d37929548e | |||
| 663891dd54 | |||
| 79d1c4fed4 | |||
| ecc8196701 | |||
| c2fb1a58db | |||
| 55998c3c4d | |||
| 83e44808cb | |||
| bfbc9900ed | |||
| 1735ba3312 | |||
| 1ef8fa5deb | |||
| d0a2868e5a | |||
| 49c2366a89 | |||
| cb7d985195 | |||
| bead0bded1 | |||
| cc92d5f639 | |||
| 84c281122e | |||
| bb4a35a6a9 | |||
| 71ae36fbf0 | |||
| 04864e059c | |||
| 7a47184af3 | |||
| 48e2831e96 | |||
| c1caa23b10 | |||
| 443cc6007d | |||
| 7d99923960 | |||
| 7342d0706f | |||
| c15c194feb | |||
| 3b6a5b5a20 | |||
| f9028ea8a5 | |||
| 8cd06a80ba | |||
| 6c80266abb | |||
| ca3c1fa8c2 | |||
| 2b7deaef2c | |||
| 42f1898bd1 | |||
| 0bdff3eac7 | |||
| a00f6660a1 | |||
| 67d1ad497f | |||
| f1bbf4e9fc | |||
| 00ff5e6a94 | |||
| 7f77a8fd63 | |||
| 7c1267148b | |||
| 2dbb7b67cb | |||
| c41db52b05 | |||
| 72f3a262ca | |||
| 2fbe6a4937 | |||
| c6fb63afe6 | |||
| 2e05320ddf | |||
| a3f86ab604 | |||
| 5d2efda925 | |||
| 4a30ac04b7 | |||
| 1097068393 | |||
| df88502c3d | |||
| b8df485a7e | |||
| a8a66a7b1e | |||
| a1548faeda | |||
| 34f452be6e | |||
| bef04854e3 | |||
| 757782e43b | |||
| 8a69f565a3 | |||
| be20d1fec6 | |||
| 7a71e457ef | |||
| 3af9fa0a10 | |||
| ff8b3efde9 | |||
| 161f63a664 | |||
| 3206e04639 | |||
| f1dea0f200 | |||
| d94a83a7c3 | |||
| 6bbc7104d9 | |||
| a2180196ee | |||
| a6dc4c7891 | |||
| fa7355c5c6 | |||
| 0140c10f15 | |||
| 796da0e673 | |||
| 743f78096a | |||
| 52d726b6f3 | |||
| bed4450900 | |||
| c2ab369d0c | |||
| 32a7f37b6a | |||
| b299199579 | |||
| 7091ea179d | |||
| dceb582bb1 | |||
| 6e2e9f7dcf | |||
| c27025269e | |||
| cf1411b412 | |||
| b167f5bb8b | |||
| 87d0fd9edb | |||
| b59a169e10 | |||
| 941e3985b0 | |||
| 127fb76c19 | |||
| 5f3028f795 | |||
| b596f04dba | |||
| 0bb96ecf12 | |||
| 60f21f6113 | |||
| 051000e4a8 | |||
| 14e8020147 | |||
| a99b1499a2 | |||
| 6a1c01556b | |||
| c41327640b | |||
| 7df5834ebc | |||
| ebafc2f98f | |||
| 92c9d81171 | |||
| 7d34a3972d | |||
| 90f1254c6c | |||
| 8b71d68749 | |||
| 17c0cf52b6 | |||
| 045be4ff09 | |||
| af7948fcb5 | |||
| e1c12d5007 | |||
| 8676b20fbb | |||
| 54db9fb910 | |||
| 0eaee1ae63 | |||
| e141dfb6b5 | |||
| b14b8c9f66 | |||
| b4b589f307 | |||
| 7a74bc0d04 | |||
| b826c0a9ad | |||
| a197b59200 | |||
| c25503d7f8 | |||
| 2c0449dcf6 | |||
| 59655daa3b | |||
| 1c36d7b923 | |||
| a51175620c | |||
| 7b95c265df | |||
| a11bb9c210 | |||
| 72227a5591 | |||
| f9f2eb4c05 | |||
| e9c57df5fb | |||
| 158c47d94b | |||
| 7616435098 | |||
| 69443ff457 | |||
| 6a257c0a9f | |||
| eddd56e53a | |||
| de6648867b | |||
| 567a6ceda5 | |||
| 59330bcd7e | |||
| 36803f24bc | |||
| 46458e2667 | |||
| d0aa6e1fe5 | |||
| 9bef919123 | |||
| 88a0603d50 | |||
| 106dbb3d8d | |||
| 4214d924a4 | |||
| c3b40f9264 | |||
| 69f00626a2 | |||
| c485b1f7f8 | |||
| 7186c73a64 | |||
| 88f9f65fb6 | |||
| 714573ec6b | |||
| a979445ffc | |||
| 3cf38eb3fc | |||
| 94ceca35bf | |||
| 2bd4eb2004 | |||
| 355e71e620 | |||
| 7d9520d97b | |||
| ce0957cea7 | |||
| c93169fe97 | |||
| 485dd96e93 | |||
| 9b0f0892ff | |||
| 9a04f3ae38 | |||
| 968d668afa | |||
| 85d19ed2bd | |||
| 28e490f8d4 | |||
| 298ae7f657 | |||
| d50f29b3dc | |||
| f167eff21c | |||
| 69d4f00807 | |||
| 904dc4fe2e | |||
| c870cc683d | |||
| deb29fd2e4 | |||
| 19f1bc947a | |||
| 60d1b47c66 | |||
| d67b845dfd | |||
| 6f1c7c7ded | |||
| 46e9118d73 | |||
| 8aa1557b7a | |||
| 6058c3f8c1 | |||
| d409e6f2a9 | |||
| a4d272c556 | |||
| 911d7c04ec | |||
| afc379d449 | |||
| 18feca49e2 | |||
| 792b19d40d | |||
| 108d05edea | |||
| d8882da17b | |||
| f120dfda15 | |||
| dd60ed7abd | |||
| d0b478c743 | |||
| defe69ba18 | |||
| 32d748efae | |||
| f194dc9bf6 | |||
| 075fbd77b2 | |||
| edb3e3713a | |||
| c70648e038 | |||
| 966f4ee57d | |||
| f90ced4c31 | |||
| 6bda4d80bf | |||
| 3ecb6b30c9 | |||
| 3c337b618c | |||
| 40a90bbcfa | |||
| e54b124252 | |||
| 18923efe23 | |||
| 5c5ad63cc6 | |||
| d5fd444ae5 | |||
| 4a22f70e30 | |||
| 9805bd4caa | |||
| 0690f13bea | |||
| da8faea4c8 | |||
| ff927bab09 | |||
| e3e5def3b6 | |||
| ba246585ad | |||
| f242a6a3bc | |||
| 0c89e76b39 | |||
| 1fa82e72f1 | |||
| b4e6b04e47 | |||
| 002f824f5c | |||
| 1aaf7f8de1 | |||
| 82ba19842c | |||
| 32ed1bf622 | |||
| 0d4838c536 | |||
| 11527b46f9 | |||
| 20c1957b59 | |||
| ed2630e016 | |||
| 8cc2ac2cad | |||
| 37745ca548 | |||
| 29edcdca4b | |||
| 92669d6974 | |||
| 351a64f592 | |||
| a29e56543b | |||
| 6db3e8c671 | |||
| 20c4d24698 | |||
| 114e185bcb | |||
| a293bff964 | |||
| 98b4d9f95d | |||
| 8489e87586 | |||
| 6f7ee2179d | |||
| ea6b442a48 | |||
| 12d26edd76 | |||
| 27053eecd7 | |||
| 151d5b9c1f | |||
| d35c558658 | |||
| baa4dc7a23 | |||
| 9b565c32d1 | |||
| 243dd26d73 | |||
| 263234fecb | |||
| 0ba598ee67 | |||
| 29430b9967 | |||
| 2038b16dce | |||
| 9ea793397b | |||
| 6061938129 | |||
| 62277aa525 | |||
| 1c118b06c9 | |||
| a41c315e36 | |||
| 40576e0012 | |||
| a582db52f4 | |||
| cb2656ad85 | |||
| da1c686d42 | |||
| b613fe2ba0 | |||
| 83e29b1cf3 | |||
| 5bbd23bf33 | |||
| 9f69b83b51 | |||
| 4f77781e24 | |||
| b23d589a29 | |||
| 7f16a69301 | |||
| 006da73737 | |||
| 3f998cdf75 | |||
| 3e94cd9d8c | |||
| 5922f92caf | |||
| f5f5909fde | |||
| 7e67357887 | |||
| d5750c6cb8 | |||
| b2983d5c96 | |||
| 5a19e46d26 | |||
| 8456a5a1d6 | |||
| b9329a092e | |||
| 6ecad9eebd | |||
| f32dd9efee | |||
| 48cbaf03b7 | |||
| 7f23cda97a | |||
| 49c1809aa2 | |||
| 173aa82134 | |||
| c57e8b2c76 | |||
| bb741013d4 | |||
| 5b014a5a1d | |||
| a85548ac33 | |||
| 77e689fec4 | |||
| fe942dcf73 | |||
| da3b700403 | |||
| fcd46cb2ea | |||
| e918b19e2e | |||
| afb8badc74 | |||
| 4e22a5c7bb | |||
| b5d2e02606 | |||
| 28afb4f14c | |||
| 165659a664 | |||
| 7b3d910b10 | |||
| 1e4a85719a | |||
| 4269cb37d2 | |||
| b7ce3e8c20 | |||
| 15a0240808 | |||
| 0aa68ea04b | |||
| 2d9b69fd1e | |||
| 48d6023e0d | |||
| 0612582a46 | |||
| a3d0d91dd7 | |||
| 982e8f67bf | |||
| 0bb871bff2 | |||
| 0eb43d6552 | |||
| b4f29f4856 | |||
| 4fd68565d2 | |||
| 8241551438 | |||
| d7bb45f287 | |||
| dbb3078300 | |||
| a7d141efcc | |||
| 31c404021c | |||
| 631cec2fc6 | |||
| be6eab0cae | |||
| 71ee8bfd29 | |||
| 66c9c02dc6 | |||
| 7880ee4aef | |||
| 6274d1f778 | |||
| 5e98813f92 | |||
| 1a30800fb4 | |||
| 454e6933f4 | |||
| e3072071b7 | |||
| 83a88326f0 | |||
| 27109a810f | |||
| 3d5bd424c5 | |||
| c7cd56e7be | |||
| 860769c44a | |||
| a83761b88d | |||
| a79fc9c0b1 | |||
| 877bd63d9d | |||
| bb9d0582c4 | |||
| df7e89e7e4 | |||
| a12593ea51 | |||
| 5ca0af4285 | |||
| 89e72a0fea | |||
| fc25ad7ddb | |||
| 6b656cf446 |
@ -42,7 +42,7 @@ android {
|
||||
}
|
||||
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
abiFilters "armeabi-v7a"
|
||||
}
|
||||
|
||||
// 由于app只针对中文用户,所以仅保留zh资源,其他删掉
|
||||
@ -65,6 +65,17 @@ android {
|
||||
buildConfigField "String", "WEIBO_APPKEY", "\"${WEIBO_APPKEY}\""
|
||||
buildConfigField "String", "MTA_APPKEY", "\"${MTA_APPKEY}\""
|
||||
buildConfigField "String", "TD_APPID", "\"${TD_APPID}\""
|
||||
buildConfigField "String", "LETO_APPID", "\"${LETO_APPID}\""
|
||||
buildConfigField "String", "TTAD_APPID", "\"${TTAD_APPID}\""
|
||||
buildConfigField "String", "DOUYIN_CLIENTKEY", "\"${DOUYIN_CLIENTKEY}\""
|
||||
buildConfigField "String", "DOUYIN_CLIENTSECRET", "\"${DOUYIN_CLIENTSECRET}\""
|
||||
|
||||
buildConfigField "String", "MIPUSH_APPID", "\"${MIPUSH_APPID}\""
|
||||
buildConfigField "String", "MIPUSH_APPKEY", "\"${MIPUSH_APPKEY}\""
|
||||
buildConfigField "String", "MEIZUPUSH_APPID", "\"${MEIZUPUSH_APPID}\""
|
||||
buildConfigField "String", "MEIZUPUSH_APPKEY", "\"${MEIZUPUSH_APPKEY}\""
|
||||
|
||||
resValue "string", "huawei_push_appid", "appid=${HUAWEI_PUSH_APPID}"
|
||||
|
||||
/**
|
||||
* Build Time 供区分 jenkins 打包时间用
|
||||
@ -93,7 +104,7 @@ android {
|
||||
signingConfig signingConfigs.debug
|
||||
|
||||
buildConfigField "String", "EXPOSURE_REPO", "\"test\""
|
||||
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
|
||||
buildConfigField "String", "EXPOSURE_VERSION", "\"E4\""
|
||||
|
||||
multiDexKeepProguard file("tinker_multidexkeep.pro")
|
||||
}
|
||||
@ -105,7 +116,7 @@ android {
|
||||
signingConfig signingConfigs.release
|
||||
|
||||
buildConfigField "String", "EXPOSURE_REPO", "\"exposure\""
|
||||
buildConfigField "String", "EXPOSURE_VERSION", "\"E3\""
|
||||
buildConfigField "String", "EXPOSURE_VERSION", "\"E4\""
|
||||
|
||||
multiDexKeepProguard file("tinker_multidexkeep.pro")
|
||||
}
|
||||
@ -121,16 +132,11 @@ android {
|
||||
publish {
|
||||
dimension "nonsense"
|
||||
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
|
||||
buildConfigField "String", "COMMENT_HOST", "\"${COMMENT_HOST}\""
|
||||
buildConfigField "String", "DATA_HOST", "\"${DATA_HOST}\""
|
||||
|
||||
buildConfigField "String", "SENSITIVE_API_HOST", "\"${SENSITIVE_API_HOST}\""
|
||||
|
||||
buildConfigField "String", "UMENG_APPKEY", "\"${UMENG_APPKEY}\""
|
||||
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${UMENG_MESSAGE_SECRET}\""
|
||||
buildConfigField "String", "MIPUSH_APPID", "\"${MIPUSH_APPID}\""
|
||||
buildConfigField "String", "MIPUSH_APPKEY", "\"${MIPUSH_APPKEY}\""
|
||||
buildConfigField "String", "MEIZUPUSH_APPID", "\"${MEIZUPUSH_APPID}\""
|
||||
buildConfigField "String", "MEIZUPUSH_APPKEY", "\"${MEIZUPUSH_APPKEY}\""
|
||||
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${BUGLY_APPID}\""
|
||||
}
|
||||
// internal test dev host
|
||||
@ -139,17 +145,12 @@ android {
|
||||
versionNameSuffix "-debug"
|
||||
|
||||
buildConfigField "String", "API_HOST", "\"${DEV_API_HOST}\""
|
||||
buildConfigField "String", "COMMENT_HOST", "\"${DEV_COMMENT_HOST}\""
|
||||
buildConfigField "String", "DATA_HOST", "\"${DEV_DATA_HOST}\""
|
||||
|
||||
buildConfigField "String", "UMENG_APPKEY", "\"${DEBUG_UMENG_APPKEY}\""
|
||||
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${DEBUG_UMENG_MESSAGE_SECRET}\""
|
||||
buildConfigField "String", "MIPUSH_APPID", "\"${DEBUG_MIPUSH_APPID}\""
|
||||
buildConfigField "String", "MIPUSH_APPKEY", "\"${DEBUG_MIPUSH_APPKEY}\""
|
||||
buildConfigField "String", "MEIZUPUSH_APPID", "\"${DEBUG_MEIZUPUSH_APPID}\""
|
||||
buildConfigField "String", "MEIZUPUSH_APPKEY", "\"${DEBUG_MEIZUPUSH_APPKEY}\""
|
||||
buildConfigField "String", "SENSITIVE_API_HOST", "\"${DEV_API_HOST}\""
|
||||
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${DEBUG_BUGLY_APPID}\""
|
||||
buildConfigField "String", "UMENG_APPKEY", "\"${DEV_UMENG_APPKEY}\""
|
||||
buildConfigField "String", "UMENG_MESSAGE_SECRET", "\"${DEV_UMENG_MESSAGE_SECRET}\""
|
||||
buildConfigField "String", "BUGLY_APPID", "\"${DEV_BUGLY_APPID}\""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,7 +174,7 @@ rebuildChannel {
|
||||
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs 'libs/aars'
|
||||
dirs 'libs', 'libs/aars'
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,9 +198,6 @@ dependencies {
|
||||
implementation "androidx.annotation:annotation:${annotation}"
|
||||
implementation "androidx.constraintlayout:constraintlayout:${constraintLayout}"
|
||||
implementation "androidx.recyclerview:recyclerview:${recyclerView}"
|
||||
// implementation "androidx.lifecycle:lifecycle-runtime:${lifeCycle}"
|
||||
// implementation "androidx.lifecycle:lifecycle-extensions:${lifeCycle}"
|
||||
// kapt "androidx.lifecycle:lifecycle-compiler:${lifeCycle}"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifeCycle"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifeCycle"
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:$lifeCycle"
|
||||
@ -208,7 +206,6 @@ dependencies {
|
||||
implementation "androidx.core:core-ktx:${ktx}"
|
||||
implementation "androidx.viewpager2:viewpager2:${viewpager2}"
|
||||
kapt "androidx.room:room-compiler:${room}"
|
||||
// kapt "androidx.databinding:databinding-compiler:${databinding}"
|
||||
|
||||
implementation "com.google.android.material:material:${material}"
|
||||
|
||||
@ -269,14 +266,11 @@ dependencies {
|
||||
implementation "com.squareup.picasso:picasso:${picasso}"
|
||||
|
||||
// for video streaming
|
||||
implementation ("com.shuyu:gsyVideoPlayer-java:$gsyVideo",{
|
||||
implementation("com.shuyu:gsyVideoPlayer-java:$gsyVideo", {
|
||||
exclude module: "gsyvideoplayer-androidvideocache"
|
||||
exclude group: "tv.danmaku.ijk.media"
|
||||
})
|
||||
implementation "com.shuyu:GSYVideoPlayer-exo2:$gsyVideo"
|
||||
// implementation "com.shuyu:gsyVideoPlayer-armv7a:$gsyVideo"
|
||||
// implementation "com.shuyu:gsyVideoPlayer-x86:$gsyVideo"
|
||||
|
||||
implementation "com.github.wendux:DSBridge-Android:$dsBridge"
|
||||
|
||||
implementation "android.arch.work:work-runtime:${workManager}"
|
||||
|
||||
@ -292,17 +286,21 @@ dependencies {
|
||||
debugImplementation "com.github.nichbar.chucker:library:$chucker"
|
||||
releaseImplementation "com.github.nichbar.chucker:library-no-op:$chucker"
|
||||
implementation "com.bytedance.applog:RangersAppLog-Lite-cn:$bytedanceApplog"
|
||||
implementation "com.bytedance.ies.ugc.aweme:opensdk-china-external:$bytedanceAweme"
|
||||
implementation "com.bytedance.ies.ugc.aweme:opensdk-common:$bytedanceAweme"
|
||||
|
||||
implementation "com.aliyun.dpa:oss-android-sdk:${oss}"
|
||||
|
||||
implementation "com.airbnb.android:lottie:$lottie"
|
||||
|
||||
implementation "net.lingala.zip4j:zip4j:${zip4j}"
|
||||
|
||||
implementation("com.github.piasy:BigImageViewer:$bigImageViewer", {
|
||||
exclude group: 'com.squareup.okhttp3'
|
||||
exclude group: 'androidx.swiperefreshlayout'
|
||||
exclude group: 'com.github.bumptech.glide'
|
||||
})
|
||||
|
||||
debugImplementation "com.github.markzhai:blockcanary-android:$blockcanary"
|
||||
releaseImplementation "com.github.markzhai:blockcanary-no-op:$blockcanary"
|
||||
implementation "com.github.PhilJay:MPAndroidChart:${chart}"
|
||||
|
||||
implementation project(':libraries:LGLibrary')
|
||||
implementation project(':libraries:MTA')
|
||||
@ -312,7 +310,6 @@ dependencies {
|
||||
// implementation project(':libraries:WechatShare')
|
||||
implementation project(':libraries:im')
|
||||
implementation project(':libraries:Matisse')
|
||||
implementation project(path: ':libraries:gsyVideoPlayer-proxy_cache')
|
||||
}
|
||||
File propFile = file('sign.properties')
|
||||
if (propFile.exists()) {
|
||||
@ -343,7 +340,7 @@ if (propFile.exists()) {
|
||||
android.buildTypes.release.signingConfig = null
|
||||
}
|
||||
|
||||
// 用于测试读取 META-INF 里的 JSON 的代码
|
||||
// 用于测试读取 META-INF 里的文件
|
||||
//task generateMetaJson {
|
||||
// def resDir = new File(buildDir, 'generated/FILES_FOR_META_INF/')
|
||||
// def destDir = new File(resDir, 'META-INF/')
|
||||
|
||||
BIN
app/libs/AVMPSDK-external-release-5.4.1002.aar
Normal file
BIN
app/libs/AVMPSDK-external-release-5.4.1002.aar
Normal file
Binary file not shown.
BIN
app/libs/SecurityBodySDK-external-release-5.4.112-preInstall.aar
Normal file
BIN
app/libs/SecurityBodySDK-external-release-5.4.112-preInstall.aar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/libs/gid-1.1.jar
Normal file
BIN
app/libs/gid-1.1.jar
Normal file
Binary file not shown.
@ -240,4 +240,18 @@
|
||||
-keep class com.shuyu.gsyvideoplayer.utils.** { *; }
|
||||
-dontwarn com.shuyu.gsyvideoplayer.utils.**
|
||||
-keep class tv.danmaku.ijk.** { *; }
|
||||
-dontwarn tv.danmaku.ijk.**
|
||||
-dontwarn tv.danmaku.ijk.**
|
||||
|
||||
#穿山甲
|
||||
-keep class com.bytedance.sdk.openadsdk.** { *; }
|
||||
-keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*;}
|
||||
-keep class com.pgl.sys.ces.* {*;}
|
||||
|
||||
-keep class com.gyf.immersionbar.* {*;}
|
||||
-dontwarn com.gyf.immersionbar.**
|
||||
|
||||
-keep class com.taobao.securityjni.**{*;}
|
||||
-keep class com.taobao.wireless.security.**{*;}
|
||||
-keep class com.ut.secbody.**{*;}
|
||||
-keep class com.taobao.dp.**{*;}
|
||||
-keep class com.alibaba.wireless.security.**{*;}
|
||||
@ -4,8 +4,6 @@ import android.app.Application;
|
||||
|
||||
import com.facebook.stetho.Stetho;
|
||||
import com.facebook.stetho.okhttp3.StethoInterceptor;
|
||||
import com.gu.toolargetool.TooLargeTool;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
@ -19,18 +17,11 @@ import okhttp3.logging.HttpLoggingInterceptor;
|
||||
public class Injection {
|
||||
|
||||
public static boolean appInit(Application application) {
|
||||
|
||||
// init leakcanary
|
||||
if (LeakCanary.isInAnalyzerProcess(application)) {
|
||||
// This process is dedicated to LeakCanary for heap analysis.
|
||||
// You should not init your app in this process.
|
||||
return false;
|
||||
}
|
||||
LeakCanary.install(application);
|
||||
|
||||
// init stetho
|
||||
Stetho.initializeWithDefaults(application);
|
||||
TooLargeTool.startLogging(application);
|
||||
|
||||
// 监控Bundle大小,预防溢出(需要调试的时候再开启吧!)
|
||||
// TooLargeTool.startLogging(application);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +36,15 @@
|
||||
<uses-permission android:name="android.permission.READ_LOGS" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<!--可选,穿山甲提供“获取地理位置权限”和“不给予地理位置权限,开发者传入地理位置参数”两种方式上报用户位置,两种方式均可不选,添加位置权限或参数将帮助投放定位广告-->
|
||||
<!--请注意:无论通过何种方式提供给穿山甲用户地理位置,均需向用户声明地理位置权限将应用于穿山甲广告投放,穿山甲不强制获取地理位置信息-->
|
||||
<!--<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />-->
|
||||
|
||||
<!-- 如果有视频相关的广告且使用textureView播放,请务必添加,否则黑屏 -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<uses-sdk tools:overrideLibrary="com.shuyu.gsyvideoplayer,
|
||||
com.shuyu.gsyvideoplayer.lib,
|
||||
com.shuyu.gsyvideoplayer.armv7a,
|
||||
@ -43,8 +52,8 @@
|
||||
com.shuyu.gsy.base,
|
||||
com.google.android.exoplayer2,
|
||||
tv.danmaku.ijk.media.exo2,
|
||||
shuyu.com.androidvideocache,
|
||||
pl.droidsonroids.gif" />
|
||||
pl.droidsonroids.gif,
|
||||
com.donkingliang.consecutivescroller" />
|
||||
|
||||
<!-- 去掉 SDK 一些流氓权限 -->
|
||||
<uses-permission
|
||||
@ -67,6 +76,7 @@
|
||||
android:largeHeap="true"
|
||||
android:resizeableActivity="true"
|
||||
android:theme="@style/AppCompatTheme.APP"
|
||||
tools:replace="android:allowBackup"
|
||||
tools:targetApi="n">
|
||||
|
||||
<!--android:launchMode = "singleTask"-->
|
||||
@ -97,7 +107,9 @@
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!--android:theme = "@android:style/Theme.Black.NoTitleBar.Fullscreen" 退出时屏幕抖动 -->
|
||||
<activity android:name="com.gh.gamecenter.ViewImageActivity" />
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.ImageViewerActivity"
|
||||
android:theme="@style/Theme.Transparent" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.SearchActivity"
|
||||
@ -115,6 +127,10 @@
|
||||
android:name="com.gh.gamecenter.ShellActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.gamedetail.history.HistoryApkListActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.NewsDetailActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -148,6 +164,10 @@
|
||||
android:name="com.gh.gamecenter.WebActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.FullScreenWebActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.ShareCardPicActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -158,7 +178,8 @@
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.MessageDetailActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.LibaoActivity"
|
||||
@ -186,9 +207,18 @@
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.CommentDetailActivity"
|
||||
android:name="com.gh.gamecenter.security.SecurityActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.security.BindPhoneActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.CommentDetailActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.mygame.MyGameActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -367,6 +397,10 @@
|
||||
android:name="com.gh.gamecenter.qa.article.detail.ArticleDetailActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qa.article.detail.comment.ArticleDetailCommentActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.qa.draft.CommunityDraftWrapperActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
@ -398,7 +432,8 @@
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.gamedetail.rating.RatingReplyActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.history.HistoryActivity"
|
||||
@ -426,7 +461,8 @@
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.video.upload.view.UploadVideoActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden"/>
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
|
||||
@ -458,8 +494,8 @@
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.HelpAndFeedbackActivity"
|
||||
android:windowSoftInputMode="stateHidden"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.help.HelpDetailActivity"
|
||||
@ -480,10 +516,57 @@
|
||||
android:name=".gamedetail.myrating.MyRatingActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.QaActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".qa.answer.draft.AnswerDraftActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".gamedetail.rating.RatingFoldActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".video.data.VideoDataActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".video.poster.PosterEditActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".video.poster.PosterClipActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".forum.select.ForumSelectActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".forum.follow.ForumMyFollowActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".forum.detail.ForumDetailActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".forum.moderator.ModeratorListActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".video.label.VideoLabelActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.PushProxyActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@android:style/Theme.Translucent" />
|
||||
|
||||
<activity
|
||||
@ -506,6 +589,12 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
|
||||
|
||||
<activity
|
||||
android:name="${applicationId}.douyinapi.DouYinEntryActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:taskAffinity="${applicationId}"
|
||||
android:exported="true" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}"
|
||||
@ -546,7 +635,7 @@
|
||||
</receiver>
|
||||
|
||||
<!--魅族push应用定义消息receiver声明 -->
|
||||
<receiver android:name="com.gh.gamecenter.receiver.MeizuPushReceiver">
|
||||
<receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">
|
||||
<intent-filter>
|
||||
<!-- 接收push消息 -->
|
||||
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
|
||||
@ -571,10 +660,49 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name="com.gh.base.GHUmengNotificationService" />
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.client.appid"
|
||||
android:value="@string/huawei_push_appid" />
|
||||
|
||||
<service
|
||||
android:name="com.gh.base.GHUmengNotificationService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
|
||||
<!--<service android:name = "com.gh.gamecenter.statistics.AppStaticService" />-->
|
||||
|
||||
<!-- 梦工厂配置 开始 -->
|
||||
<!--<meta-data
|
||||
android:name="MGC_APPID"
|
||||
android:value="1001276" />
|
||||
|
||||
<provider
|
||||
android:name="com.leto.game.base.provider.LetoFileProvider"
|
||||
android:authorities="${applicationId}.leto.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/leto_file_path"
|
||||
tools:replace="android:resource" />
|
||||
</provider>-->
|
||||
<!-- 梦工厂配置 结束 -->
|
||||
|
||||
<!-- 穿山甲配置 开始 -->
|
||||
<!--<provider
|
||||
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
|
||||
android:authorities="${applicationId}.TTFileProvider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
|
||||
android:authorities="${applicationId}.TTMultiProvider"
|
||||
android:exported="false" />-->
|
||||
<!-- 穿山甲配置 结束 -->
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie/tab_forum.json
Normal file
1
app/src/main/assets/lottie/tab_forum.json
Normal file
@ -0,0 +1 @@
|
||||
{"v":"5.6.9","fr":30,"ip":0,"op":20,"w":66,"h":66,"nm":"bottom bar tab/论坛/选中/E","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"矩形","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[110,110,100]},{"t":13,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.5],[1.5,-2.5],[2.5,-1.5],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.5]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-1.25],[1.5,-1.25],[2.5,-0.25],[2.5,0],[0,1.896],[-2.5,0],[-2.5,-0.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":9,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.938],[1.5,-2.938],[2.5,-1.938],[2.5,0],[0,2.833],[-2.5,0],[-2.5,-1.938]],"c":true}]},{"t":13,"s":[{"i":[[-0.55,0],[0,0],[0,-0.55],[0,0],[1.38,0],[0,1.38],[0,0]],"o":[[0,0],[0.55,0],[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.55]],"v":[[-1.5,-2.5],[1.5,-2.5],[2.5,-1.5],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":20,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"路径 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,34.599,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.2,0],[2.19,-0.35],[0,-1.82],[0,0],[0,0],[-1.98,0],[0,0],[0,0],[0,0],[-0.72,0.53],[0,0],[0,0],[0,2.05],[0,0],[1.8,0.28]],"o":[[-2.19,0],[-1.8,0.28],[0,0],[0,0],[0.1,1.96],[0,0],[0,0],[0,0],[0.58,0.65],[0,0],[0,0],[2.05,0],[0,0],[0,-1.82],[-2.2,-0.35]],"v":[[-0.003,-9.745],[-6.583,-9.215],[-9.712,-5.555],[-9.712,3.465],[-9.702,3.665],[-6.003,7.175],[-3.383,7.175],[-2.122,9.065],[-2.023,9.185],[0.277,9.405],[3.238,7.175],[5.997,7.175],[9.717,3.465],[9.717,-5.555],[6.587,-9.215]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-9.712,-9.745],"ix":5},"e":{"a":0,"k":[9.712,9.745],"ix":6},"t":1,"nm":"color","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[33,33,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":9,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":13,"s":[90,90,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"w":66,"h":66,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}
|
||||
132
app/src/main/assets/notification_style.json
Normal file
132
app/src/main/assets/notification_style.json
Normal file
@ -0,0 +1,132 @@
|
||||
[
|
||||
{
|
||||
"login": {
|
||||
"title": "开启消息通知",
|
||||
"content": "新游上线、互动回复,重要推送不错过",
|
||||
"image": "bg_notification_login_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景1"
|
||||
},
|
||||
"question": {
|
||||
"title": "开启消息通知",
|
||||
"content": "及时查看大神回答",
|
||||
"image": "bg_notification_question_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景2"
|
||||
},
|
||||
"answer": {
|
||||
"title": "开启消息通知",
|
||||
"content": "及时查看点赞与评论",
|
||||
"image": "bg_notification_answer_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景3"
|
||||
},
|
||||
"article": {
|
||||
"title": "开启消息通知",
|
||||
"content": "及时查看点赞与评论",
|
||||
"image": "bg_notification_article_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景4"
|
||||
},
|
||||
"video": {
|
||||
"title": "开启消息通知",
|
||||
"content": "实时获取审核与推荐进度",
|
||||
"image": "bg_notification_video_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景5"
|
||||
},
|
||||
"rating": {
|
||||
"title": "开启消息通知",
|
||||
"content": "成功上墙立即知道",
|
||||
"image": "bg_notification_rating_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景6"
|
||||
},
|
||||
"gift": {
|
||||
"title": "开启消息通知",
|
||||
"content": "新上礼包不再错过",
|
||||
"image": "bg_notification_gift_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景7"
|
||||
},
|
||||
"reserveGame": {
|
||||
"title": "开启消息通知",
|
||||
"content": "新游上线即时体验",
|
||||
"image": "bg_notification_reserve_game_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景8"
|
||||
},
|
||||
"feedback": {
|
||||
"title": "开启消息通知",
|
||||
"content": "及时查看客服回复",
|
||||
"image": "bg_notification_feedback_style_1",
|
||||
"styleNo": "样式A",
|
||||
"scenes": "场景9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"login": {
|
||||
"title": "咦!是新的小伙伴耶!",
|
||||
"content": "打开<font color=\"#1383EB\">通知开关</font>,游戏、礼包、抽奖活动不错过",
|
||||
"image": "bg_notification_login_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景1"
|
||||
},
|
||||
"question": {
|
||||
"title": "发布成功!答案马上来!",
|
||||
"content": "为了第一时间通知您,需要打开<font color=\"#1383EB\">通知开关</font>",
|
||||
"image": "bg_notification_question_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景2"
|
||||
},
|
||||
"answer": {
|
||||
"title": "精彩的回答!大佬牛啤!",
|
||||
"content": "打开<font color=\"#1383EB\">通知开关</font>,可以第一时间收获赞美和感谢哟!",
|
||||
"image": "bg_notification_answer_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景3"
|
||||
},
|
||||
"article": {
|
||||
"title": "发布成功!不愧是你!",
|
||||
"content": "打开<font color=\"#1383EB\">通知开关</font>,可以第一时间收获赞美和互动哟!",
|
||||
"image": "bg_notification_article_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景4"
|
||||
},
|
||||
"video": {
|
||||
"title": "“百万”播放预定!",
|
||||
"content": "<font color=\"#1383EB\">打开通知!</font>第一时间知道审核结果和互动信息哟!",
|
||||
"image": "bg_notification_video_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景5"
|
||||
},
|
||||
"rating": {
|
||||
"title": "这游戏超好玩,我说的!",
|
||||
"content": "想知道有多少人吃下安利?<font color=\"#1383EB\">打开通知</font>,马上知道!",
|
||||
"image": "bg_notification_rating_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景6"
|
||||
},
|
||||
"gift": {
|
||||
"title": "获得道具:神奇的游戏礼包!",
|
||||
"content": "<font color=\"#1383EB\">打开通知!</font>礼包上线,马上知道!",
|
||||
"image": "bg_notification_gift_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景7"
|
||||
},
|
||||
"reserveGame": {
|
||||
"title": "玩最新的游戏,做游戏圈最靓的仔",
|
||||
"content": "<font color=\"#1383EB\">打开通知!</font>游戏上线,更快知道!",
|
||||
"image": "bg_notification_reserve_game_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景8"
|
||||
},
|
||||
"feedback": {
|
||||
"title": "真是重要的反馈!",
|
||||
"content": "感恩有你,光环更精彩!<font color=\"#1383EB\">打开通知</font>,客服回复,马上知道!",
|
||||
"image": "bg_notification_feedback_style_2",
|
||||
"styleNo": "样式B",
|
||||
"scenes": "场景9"
|
||||
}
|
||||
}
|
||||
]
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package androidx.swiperefreshlayout.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RadialGradient;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.OvalShape;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
/**
|
||||
* Private class created to work around issues with AnimationListeners being
|
||||
* called before the animation is actually complete and support shadows on older
|
||||
* platforms.
|
||||
*/
|
||||
class CircleImageView extends ImageView {
|
||||
|
||||
private static final int KEY_SHADOW_COLOR = 0x1E000000;
|
||||
private static final int FILL_SHADOW_COLOR = 0x3D000000;
|
||||
// PX
|
||||
private static final float X_OFFSET = 0f;
|
||||
private static final float Y_OFFSET = 1.75f;
|
||||
private static final float SHADOW_RADIUS = 3.5f;
|
||||
private static final int SHADOW_ELEVATION = 4;
|
||||
|
||||
private Animation.AnimationListener mListener;
|
||||
int mShadowRadius;
|
||||
|
||||
CircleImageView(Context context, int color) {
|
||||
super(context);
|
||||
final float density = getContext().getResources().getDisplayMetrics().density;
|
||||
final int shadowYOffset = (int) (density * Y_OFFSET);
|
||||
final int shadowXOffset = (int) (density * X_OFFSET);
|
||||
|
||||
mShadowRadius = (int) (density * SHADOW_RADIUS);
|
||||
|
||||
ShapeDrawable circle;
|
||||
if (elevationSupported()) {
|
||||
circle = new ShapeDrawable(new OvalShape());
|
||||
ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
|
||||
} else {
|
||||
OvalShape oval = new OvalShadow(mShadowRadius);
|
||||
circle = new ShapeDrawable(oval);
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, circle.getPaint());
|
||||
circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
|
||||
KEY_SHADOW_COLOR);
|
||||
final int padding = mShadowRadius;
|
||||
// set padding so the inner image sits correctly within the shadow.
|
||||
setPadding(padding, padding, padding, padding);
|
||||
}
|
||||
circle.getPaint().setColor(color);
|
||||
ViewCompat.setBackground(this, circle);
|
||||
}
|
||||
|
||||
private boolean elevationSupported() {
|
||||
return android.os.Build.VERSION.SDK_INT >= 21;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (!elevationSupported()) {
|
||||
setMeasuredDimension(getMeasuredWidth() + mShadowRadius * 2, getMeasuredHeight()
|
||||
+ mShadowRadius * 2);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAnimationListener(Animation.AnimationListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart() {
|
||||
super.onAnimationStart();
|
||||
if (mListener != null) {
|
||||
mListener.onAnimationStart(getAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd() {
|
||||
super.onAnimationEnd();
|
||||
if (mListener != null) {
|
||||
mListener.onAnimationEnd(getAnimation());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the background color of the circle image view.
|
||||
*
|
||||
* @param colorRes Id of a color resource.
|
||||
*/
|
||||
public void setBackgroundColorRes(int colorRes) {
|
||||
setBackgroundColor(ContextCompat.getColor(getContext(), colorRes));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundColor(int color) {
|
||||
if (getBackground() instanceof ShapeDrawable) {
|
||||
((ShapeDrawable) getBackground()).getPaint().setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
private class OvalShadow extends OvalShape {
|
||||
private RadialGradient mRadialGradient;
|
||||
private Paint mShadowPaint;
|
||||
|
||||
OvalShadow(int shadowRadius) {
|
||||
super();
|
||||
mShadowPaint = new Paint();
|
||||
mShadowRadius = shadowRadius;
|
||||
updateRadialGradient((int) rect().width());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResize(float width, float height) {
|
||||
super.onResize(width, height);
|
||||
updateRadialGradient((int) width);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas, Paint paint) {
|
||||
final int viewWidth = CircleImageView.this.getWidth();
|
||||
final int viewHeight = CircleImageView.this.getHeight();
|
||||
canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2, mShadowPaint);
|
||||
canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2 - mShadowRadius, paint);
|
||||
}
|
||||
|
||||
private void updateRadialGradient(int diameter) {
|
||||
mRadialGradient = new RadialGradient(diameter / 2, diameter / 2,
|
||||
mShadowRadius, new int[] { FILL_SHADOW_COLOR, Color.TRANSPARENT },
|
||||
null, Shader.TileMode.CLAMP);
|
||||
mShadowPaint.setShader(mRadialGradient);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,18 +1,36 @@
|
||||
package com.gh.base;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
import com.gh.base.fragment.BaseFragment;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.common.util.EntranceUtils;
|
||||
import com.gh.common.util.ExtensionsKt;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.RunningUtils;
|
||||
import com.gh.common.util.ShareUtils;
|
||||
import com.gh.common.util.StringUtils;
|
||||
@ -33,8 +51,6 @@ import org.json.JSONObject;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import butterknife.ButterKnife;
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
|
||||
@ -84,17 +100,20 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (requestCode == com.tencent.connect.common.Constants.REQUEST_QQ_SHARE
|
||||
|| requestCode == com.tencent.connect.common.Constants.REQUEST_QZONE_SHARE) {
|
||||
Tencent.onActivityResultData(requestCode, resultCode, data, ShareUtils.getInstance(this).QqShareListener);
|
||||
}
|
||||
ExtensionsKt.tryCatchInRelease(() -> {
|
||||
if (requestCode == com.tencent.connect.common.Constants.REQUEST_QQ_SHARE
|
||||
|| requestCode == com.tencent.connect.common.Constants.REQUEST_QZONE_SHARE) {
|
||||
Tencent.onActivityResultData(requestCode, resultCode, data, ShareUtils.getInstance(this).QqShareListener);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EventBus.getDefault().register(this);
|
||||
ButterKnife.bind(this);
|
||||
if (useEventBus()) EventBus.getDefault().register(this);
|
||||
if (useButterKnife()) ButterKnife.bind(this);
|
||||
mEntrance = getIntent().getStringExtra(KEY_ENTRANCE);
|
||||
if (TextUtils.isEmpty(mEntrance)) {
|
||||
mEntrance = Constants.ENTRANCE_UNKNOWN;
|
||||
@ -105,9 +124,18 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void setContentView(View view) {
|
||||
if (BuildConfig.DEBUG || BuildConfig.BUILD_TIME != 0) {
|
||||
view = getRootViewWithEnvIndicator(view);
|
||||
}
|
||||
super.setContentView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
if (useEventBus()) EventBus.getDefault().unregister(this);
|
||||
mBaseHandler.removeCallbacksAndMessages(null);
|
||||
super.onDestroy();
|
||||
}
|
||||
@ -124,21 +152,63 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
String icon,
|
||||
String shareTitle,
|
||||
String shareSummary,
|
||||
ShareUtils.ShareType shareType) {
|
||||
ShareUtils.ShareEntrance shareEntrance, String id) {
|
||||
ShareUtils.getInstance(this).showShareWindows(this,
|
||||
getWindow().getDecorView(),
|
||||
url,
|
||||
icon,
|
||||
shareTitle,
|
||||
shareSummary,
|
||||
shareType);
|
||||
if (shareType == ShareUtils.ShareType.game || shareType == ShareUtils.ShareType.plugin) {
|
||||
shareEntrance, id);
|
||||
if (shareEntrance == ShareUtils.ShareEntrance.game || shareEntrance == ShareUtils.ShareEntrance.plugin) {
|
||||
MtaHelper.onEvent("内容分享", "内容分享", shareTitle + shareSummary);
|
||||
} else {
|
||||
MtaHelper.onEvent("内容分享", "内容分享", shareTitle);
|
||||
}
|
||||
}
|
||||
|
||||
private View getRootViewWithEnvIndicator(View view) {
|
||||
RelativeLayout screenRootView = new RelativeLayout(this);
|
||||
screenRootView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
|
||||
|
||||
LinearLayout ll = new LinearLayout(this);
|
||||
TextView tv = new TextView(this);
|
||||
String envText = "正式环境";
|
||||
tv.setBackground(ContextCompat.getDrawable(this, R.color.theme));
|
||||
if (BuildConfig.FLAVOR.equals("internal")) {
|
||||
envText = "测试环境";
|
||||
tv.setBackground(ContextCompat.getDrawable(this, R.color.red));
|
||||
}
|
||||
tv.setText(envText);
|
||||
tv.setGravity(Gravity.CENTER);
|
||||
tv.setTextColor(Color.WHITE);
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 13);
|
||||
tv.measure(0, 0);
|
||||
tv.setAlpha(0.15F);
|
||||
int height = tv.getMeasuredHeight();
|
||||
int width = tv.getMeasuredWidth();
|
||||
tv.setPadding(DisplayUtils.dip2px(20), 0, DisplayUtils.dip2px(20), 0);
|
||||
ll.setTranslationX(DisplayUtils.dip2px(20));
|
||||
ll.setRotation(45);
|
||||
ll.addView(tv);
|
||||
ll.setPadding(0, (width - height) / 2, 0, (width - height) / 2);
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
tv.setOnLongClickListener(v -> {
|
||||
EntranceUtils.saveShortcut(this.getClass().getName(), getIntent().getExtras());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
screenRootView.addView(view);
|
||||
screenRootView.addView(ll);
|
||||
|
||||
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) ll.getLayoutParams();
|
||||
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
|
||||
return screenRootView;
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onEventMainThread(final EBShowDialog showDialog) {
|
||||
if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
|
||||
@ -150,7 +220,7 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
if (FileUtils.isEmptyFile(showDialog.getPath())) {
|
||||
toast(R.string.install_failure_hint);
|
||||
} else {
|
||||
startActivity(PackageUtils.getUninstallIntent(BaseActivity.this, showDialog.getPath()));
|
||||
PackageInstaller.uninstall(BaseActivity.this, showDialog.getPath());
|
||||
}
|
||||
});
|
||||
} else if (LOGIN_EXCEPTION.equals(showDialog.getType())) {
|
||||
@ -180,6 +250,11 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
super.onPause();
|
||||
if (isFinishing()) {
|
||||
onFinish();
|
||||
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
|
||||
if (fragment.isAdded() && fragment instanceof BaseFragment) {
|
||||
((BaseFragment) fragment).onParentActivityFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,13 +262,12 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 可凭借此回调确定当前 activity 已经执行了 finish() 处于 isFinishing 状态
|
||||
* 可在后续进行
|
||||
* 此回调可用于确认当前 activity 已经执行了 finish() 方法并处于 isFinishing 状态
|
||||
*/
|
||||
protected void onFinish() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -246,4 +320,22 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
return StringUtils.buildString(entrance, "+(", path, ")");
|
||||
}
|
||||
|
||||
protected boolean useEventBus() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean useButterKnife() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resources getResources() {
|
||||
Resources resources = super.getResources();
|
||||
if (resources.getConfiguration().fontScale != 1.0f) {
|
||||
Configuration configuration = resources.getConfiguration();
|
||||
configuration.fontScale = 1.0f;
|
||||
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
|
||||
}
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
@ -45,7 +46,7 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
|
||||
protected abstract void initTabTitleList(List<String> tabTitleList);
|
||||
|
||||
protected int provideIndicatorWidth() {
|
||||
return 65;
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected View provideTabView(int position, String tabTitle) {
|
||||
@ -89,11 +90,14 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
|
||||
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
|
||||
TabLayout.Tab tab = mTabLayout.getTabAt(i);
|
||||
if (tab == null) continue;
|
||||
View tabView = provideTabView(i, tab.getText() != null ? tab.getText().toString() : "");
|
||||
if (tabView == null) continue;
|
||||
String tabTitle = tab.getText() != null ? tab.getText().toString() : "";
|
||||
View tabView = provideTabView(i, tabTitle);
|
||||
if (tabView == null)
|
||||
tabView = BaseFragment_TabLayout.createDefaultTabCustomView(tabTitle);
|
||||
tab.setCustomView(tabView);
|
||||
}
|
||||
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -9,6 +9,7 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.webkit.JavascriptInterface
|
||||
import android.widget.TextView
|
||||
import butterknife.OnClick
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.MtaHelper
|
||||
@ -16,6 +17,7 @@ import com.gh.common.view.RichEditor
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.MyVideoEntity
|
||||
import com.gh.gamecenter.qa.answer.edit.AnswerEditActivity
|
||||
import com.gh.gamecenter.qa.editor.GameActivity
|
||||
import com.gh.gamecenter.qa.editor.InsertAnswerWrapperActivity
|
||||
import com.gh.gamecenter.qa.editor.InsertArticleWrapperActivity
|
||||
@ -31,7 +33,9 @@ import kotterknife.bindView
|
||||
abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
|
||||
val mRichEditor by bindView<RichEditor>(R.id.rich_editor)
|
||||
val mDraftBtn by bindView<TextView>(R.id.draft_btn)
|
||||
|
||||
private val mEditorTextNumTv by bindView<TextView>(R.id.editorTextNumTv)
|
||||
private val mEditorFont by bindView<CheckableImageView>(R.id.editor_font)
|
||||
private val mEditorLink by bindView<CheckableImageView>(R.id.editor_link)
|
||||
private val mEditorParagraph by bindView<CheckableImageView>(R.id.editor_paragraph)
|
||||
@ -86,7 +90,12 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
// 防止个别手机在Js里无法获取粘贴内容
|
||||
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
|
||||
mRichEditor.addJavascriptInterface(OnCursorChangeListener(), "OnCursorChangeListener")
|
||||
mRichEditor.addJavascriptInterface(OnEditorTextChangeListener(), "OnEditorTextChangeListener")
|
||||
mRichEditor.setInputEnabled(true)
|
||||
|
||||
mDraftBtn.text = if (this is AnswerEditActivity) {
|
||||
"回答草稿"
|
||||
} else "帖子草稿"
|
||||
}
|
||||
|
||||
@OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_paragraph,
|
||||
@ -251,6 +260,14 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private inner class OnEditorTextChangeListener {
|
||||
@JavascriptInterface
|
||||
fun onTextChange(count: Int) {
|
||||
val num = if (count > MAX_INPUT_TEXT_NUM) MAX_INPUT_TEXT_NUM - count else count
|
||||
mEditorTextNumTv.text = num.toString()
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun mtaEventName(): String
|
||||
|
||||
companion object {
|
||||
@ -266,5 +283,6 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
const val INSERT_ANSWER_CODE = 411
|
||||
const val INSERT_ARTICLE_CODE = 412
|
||||
const val INSERT_GAME_CODE = 413
|
||||
const val MAX_INPUT_TEXT_NUM = 10000
|
||||
}
|
||||
}
|
||||
@ -12,11 +12,9 @@ import android.preference.PreferenceManager
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.text.htmlEncode
|
||||
import com.gh.common.notifier.Notifier
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.util.StringUtils
|
||||
import com.gh.common.util.toObject
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.PushEntity
|
||||
import com.gh.gamecenter.entity.PushMessageEntity
|
||||
@ -97,7 +95,7 @@ class GHUmengNotificationService : UmengMessageService() {
|
||||
|
||||
// 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
|
||||
if (data != null
|
||||
&& data.link?.target == "system"
|
||||
&& data.link?.link == "system"
|
||||
&& !UserManager.getInstance().isLoggedIn) {
|
||||
return
|
||||
}
|
||||
@ -132,7 +130,7 @@ class GHUmengNotificationService : UmengMessageService() {
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setTicker(pushData.body?.ticker)
|
||||
.setContentTitle(pushData.body?.title)
|
||||
.setContentText(pushData.body?.text)
|
||||
.setContentText(pushData.body?.text?.fromHtml())
|
||||
.setContentIntent(clickPendingIntent)
|
||||
.setDeleteIntent(deletePendingIntent)
|
||||
.build()
|
||||
|
||||
@ -3,7 +3,6 @@ package com.gh.base;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
@ -12,12 +11,17 @@ import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
@ -34,13 +38,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
|
||||
/**
|
||||
* 需要用到工具栏的页面使用
|
||||
* <p>
|
||||
@ -52,6 +49,8 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
@Nullable
|
||||
private PackageViewModel mPackageViewModel;
|
||||
|
||||
protected View mToolbarContainer;
|
||||
|
||||
protected Toolbar mToolbar;
|
||||
|
||||
protected TextView mTitleTv;
|
||||
@ -62,7 +61,6 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setStatusBarDarkMode(true, this);
|
||||
initToolbar();
|
||||
|
||||
@ -88,6 +86,7 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
}
|
||||
|
||||
private void initToolbar() {
|
||||
mToolbarContainer = findViewById(R.id.normal_toolbar_container);
|
||||
mToolbar = findViewById(R.id.normal_toolbar);
|
||||
mTitleTv = findViewById(R.id.normal_title);
|
||||
if (mToolbar != null) {
|
||||
@ -239,7 +238,7 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (item.getItemId() == R.id.menu_download) {
|
||||
MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
|
||||
// MtaHelper.onEvent("下载管理", "下载管理入口", getActivityNameInChinese());
|
||||
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(this, mEntrance);
|
||||
startActivity(intent);
|
||||
}
|
||||
@ -253,4 +252,11 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
protected boolean showDownloadMenu() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideToolbar(boolean isHide) {
|
||||
if (mToolbarContainer != null) {
|
||||
mToolbarContainer.setVisibility(isHide ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +145,10 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
} else {
|
||||
mCachedView = View.inflate(getContext(), getLayoutId(), null);
|
||||
}
|
||||
ButterKnife.bind(this, mCachedView);
|
||||
|
||||
if (useButterKnife()) {
|
||||
ButterKnife.bind(this, mCachedView);
|
||||
}
|
||||
|
||||
initView(mCachedView);
|
||||
|
||||
@ -208,6 +211,13 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
return mCachedView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
mCachedView = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@ -301,6 +311,10 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
return this;
|
||||
}
|
||||
|
||||
public void onParentActivityFinish() {
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected RecyclerView.Adapter provideSyncAdapter() {
|
||||
return null;
|
||||
@ -309,4 +323,8 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
|
||||
protected boolean addSyncPageObserver() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean useButterKnife() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,28 @@
|
||||
package com.gh.base.fragment;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CheckedTextView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.lightgame.view.NoScrollableViewPager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -46,7 +56,7 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
|
||||
protected abstract void initTabTitleList(List<String> tabTitleList);
|
||||
|
||||
protected int provideIndicatorWidth() {
|
||||
return 65;
|
||||
return 20;
|
||||
}
|
||||
|
||||
protected View provideTabView(int position, String tabTitle) {
|
||||
@ -94,11 +104,71 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
|
||||
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
|
||||
TabLayout.Tab tab = mTabLayout.getTabAt(i);
|
||||
if (tab == null) continue;
|
||||
View tabView = provideTabView(i, tab.getText() != null ? tab.getText().toString() : "");
|
||||
if (tabView == null) continue;
|
||||
String tabTitle = tab.getText() != null ? tab.getText().toString() : "";
|
||||
View tabView = provideTabView(i, tabTitle);
|
||||
if (tabView == null) tabView = createDefaultTabCustomView(tabTitle);
|
||||
tab.setCustomView(tabView);
|
||||
}
|
||||
|
||||
initTabStyle(mTabLayout, mCheckedIndex);
|
||||
}
|
||||
|
||||
public static void initTabStyle(TabLayout tabLayout, int currentItem) {
|
||||
// 默认选择addOnTabSelectedListener不会回调
|
||||
int tabCount = tabLayout.getTabCount();
|
||||
if (tabCount > 0) {
|
||||
TabLayout.Tab tab = tabLayout.getTabAt(currentItem);
|
||||
if (tab != null) updateTabStyle(tab, true);
|
||||
}
|
||||
|
||||
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
updateTabStyle(tab, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
updateTabStyle(tab, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
updateTabStyle(tab, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void updateTabStyle(TabLayout.Tab tab, boolean isChecked) {
|
||||
View tabView = tab.getCustomView();
|
||||
if (tabView == null) {
|
||||
Utils.log("TabLayout->Tab样式不是通用样式,请检查");
|
||||
return;
|
||||
}
|
||||
|
||||
TextView tabTitle;
|
||||
if (tabView instanceof TextView) {
|
||||
tabTitle = (TextView) tabView;
|
||||
} else {
|
||||
tabTitle = tabView.findViewById(R.id.tab_title);
|
||||
}
|
||||
|
||||
if (tabTitle == null) {
|
||||
Utils.log("TabLayout->Tab样式不是通用样式,请检查");
|
||||
return;
|
||||
}
|
||||
tabTitle.setTypeface(isChecked ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);
|
||||
}
|
||||
|
||||
// 如果不设置View的话,无法动态设置字体样式
|
||||
@NonNull
|
||||
public static View createDefaultTabCustomView(String title) {
|
||||
View view = LayoutInflater.from(HaloApp.getInstance().getApplication().getBaseContext()).inflate(R.layout.tab_item, null);
|
||||
View tabTitle = view.findViewById(R.id.tab_title);
|
||||
if (tabTitle instanceof CheckedTextView) {
|
||||
((CheckedTextView) tabTitle).setText(title);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.base.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import com.gh.gamecenter.normal.NormalFragment
|
||||
import com.lightgame.utils.Utils
|
||||
|
||||
/**
|
||||
* 懒加载(支持多层嵌套)
|
||||
@ -104,7 +105,7 @@ abstract class BaseLazyFragment : NormalFragment() {
|
||||
isSupportVisible = visible
|
||||
|
||||
if (visible) {
|
||||
if (mIsFirstVisible) {
|
||||
if (mIsFirstVisible && view != null) {
|
||||
mIsFirstVisible = false
|
||||
onFragmentFirstVisible()
|
||||
}
|
||||
|
||||
107
app/src/main/java/com/gh/base/fragment/BaseLazyTabFragment.kt
Normal file
107
app/src/main/java/com/gh/base/fragment/BaseLazyTabFragment.kt
Normal file
@ -0,0 +1,107 @@
|
||||
package com.gh.base.fragment
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import butterknife.BindView
|
||||
import com.gh.base.adapter.FragmentAdapter
|
||||
import com.gh.common.view.TabIndicatorView
|
||||
import com.gh.gamecenter.R
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import com.lightgame.utils.Utils
|
||||
import com.lightgame.view.NoScrollableViewPager
|
||||
|
||||
abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeListener {
|
||||
|
||||
@BindView(R.id.fragment_tab_layout)
|
||||
lateinit var mTabLayout: TabLayout
|
||||
|
||||
@BindView(R.id.fragment_view_pager)
|
||||
lateinit var mViewPager: NoScrollableViewPager
|
||||
|
||||
@BindView(R.id.fragment_tab_indicator)
|
||||
lateinit var mTabIndicatorView: TabIndicatorView
|
||||
|
||||
var mFragmentsList: MutableList<Fragment> = arrayListOf()
|
||||
|
||||
var mTabTitleList: MutableList<String> = arrayListOf()
|
||||
|
||||
var mCheckedIndex = 0
|
||||
|
||||
abstract fun initFragmentList(fragments: MutableList<Fragment>)
|
||||
|
||||
abstract fun initTabTitleList(tabTitleList: MutableList<String>)
|
||||
|
||||
protected open fun provideIndicatorWidth(): Int {
|
||||
return 20
|
||||
}
|
||||
|
||||
protected open fun provideTabView(position: Int, tabTitle: String?): View? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.fragment_tablayout_viewpager
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
val fragments = childFragmentManager.fragments
|
||||
if (fragments != null) {
|
||||
for (fragment in fragments) {
|
||||
fragment.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (arguments != null) mCheckedIndex = requireArguments().getInt(PAGE_INDEX, 0)
|
||||
}
|
||||
|
||||
open fun providePagerAdapter(): PagerAdapter? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
super.onFragmentFirstVisible()
|
||||
|
||||
initFragmentList(mFragmentsList)
|
||||
initTabTitleList(mTabTitleList)
|
||||
|
||||
mViewPager.offscreenPageLimit = mFragmentsList.size
|
||||
mViewPager.addOnPageChangeListener(this)
|
||||
mViewPager.adapter = providePagerAdapter()
|
||||
?: FragmentAdapter(childFragmentManager, mFragmentsList, mTabTitleList)
|
||||
mViewPager.currentItem = mCheckedIndex
|
||||
mTabLayout.setupWithViewPager(mViewPager)
|
||||
mTabIndicatorView.setupWithTabLayout(mTabLayout)
|
||||
mTabIndicatorView.setupWithViewPager(mViewPager)
|
||||
mTabIndicatorView.setIndicatorWidth(provideIndicatorWidth())
|
||||
for (i in 0 until mTabLayout.tabCount) {
|
||||
val tab = mTabLayout.getTabAt(i) ?: continue
|
||||
val tabTitle = if (tab.text != null) tab.text.toString() else ""
|
||||
var tabView = provideTabView(i, tabTitle)
|
||||
if (tabView == null) tabView = BaseFragment_TabLayout.createDefaultTabCustomView(tabTitle)
|
||||
tab.customView = tabView
|
||||
}
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex)
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
|
||||
override fun onPageSelected(position: Int) {}
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {}
|
||||
|
||||
companion object {
|
||||
const val PAGE_INDEX = "PAGE_INDEX"
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,9 @@ import android.os.Looper
|
||||
import com.gh.common.AppExecutor.ioExecutor
|
||||
import com.gh.common.AppExecutor.lightWeightIoExecutor
|
||||
import com.gh.common.AppExecutor.uiExecutor
|
||||
import java.util.concurrent.*
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* APP 线程池管理类
|
||||
@ -18,11 +20,13 @@ import java.util.concurrent.*
|
||||
object AppExecutor {
|
||||
|
||||
@JvmStatic
|
||||
var uiExecutor = MainThreadExecutor()
|
||||
val uiExecutor by lazy { MainThreadExecutor() }
|
||||
@JvmStatic
|
||||
var lightWeightIoExecutor = Executors.newSingleThreadExecutor()
|
||||
val lightWeightIoExecutor by lazy { Executors.newSingleThreadExecutor() }
|
||||
@JvmStatic
|
||||
var ioExecutor = Executors.newCachedThreadPool()
|
||||
val ioExecutor = Executors.newCachedThreadPool() // 用 by lazy 可能影响初始化速度
|
||||
|
||||
val cachedScheduler by lazy { Schedulers.from(ioExecutor) }
|
||||
|
||||
class MainThreadExecutor : Executor {
|
||||
private val mainThreadHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
@ -1,20 +1,24 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.webkit.JavascriptInterface
|
||||
import androidx.annotation.Keep
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.base.CurrentActivityHolder
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.view.dsbridge.CompletionHandler
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.ImageViewerActivity
|
||||
import com.gh.gamecenter.LoginActivity
|
||||
import com.gh.gamecenter.ViewImageActivity
|
||||
import com.gh.gamecenter.entity.Badge
|
||||
import com.gh.gamecenter.entity.MtaEvent
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.room.AppDatabase
|
||||
import com.gh.gamecenter.user.LoginTag
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
@ -23,7 +27,8 @@ import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import wendu.dsbridge.CompletionHandler
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class DefaultJsApi(var context: Context) {
|
||||
|
||||
@ -70,7 +75,6 @@ class DefaultJsApi(var context: Context) {
|
||||
userInfoEntity.badge = null
|
||||
}
|
||||
UserManager.getInstance().userInfoEntity = userInfoEntity
|
||||
AppDatabase.getInstance(context).userInfoDao().updateUserInfo(userInfoEntity)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -83,6 +87,11 @@ class DefaultJsApi(var context: Context) {
|
||||
return BuildConfig.VERSION_NAME
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getAppVersionCode(msg: Any): Int {
|
||||
return PackageUtils.getVersionCode()
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun bindWechat(msg: Any, handler: CompletionHandler<Any>) {
|
||||
context.ifLogin("浏览器") {
|
||||
@ -139,7 +148,21 @@ class DefaultJsApi(var context: Context) {
|
||||
|
||||
val context = CurrentActivityHolder.getCurrentActivity()
|
||||
|
||||
context?.startActivity(ViewImageActivity.getViewImageIntent(context, imageEvent.imageList, imageEvent.position, "浏览器"))
|
||||
context?.startActivity(ImageViewerActivity.getIntent(context, imageEvent.imageList, imageEvent.position, "浏览器"))
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun isInstalled(event: Any): String {
|
||||
val localInstalledPackageList = PackageUtils.getAllPackageName(HaloApp.getInstance().application)
|
||||
val packageNameList: ArrayList<String> = event.toString().toObject() ?: ArrayList()
|
||||
|
||||
for (packageName in packageNameList) {
|
||||
if (!localInstalledPackageList.contains(packageName)) {
|
||||
return "false"
|
||||
}
|
||||
}
|
||||
|
||||
return "true"
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -148,7 +171,48 @@ class DefaultJsApi(var context: Context) {
|
||||
|
||||
Base64ImageHolder.image = event.toString()
|
||||
|
||||
context?.startActivity(ViewImageActivity.getBase64ViewImageIntent(context, true))
|
||||
context?.startActivity(ImageViewerActivity.getBase64Intent(context, true))
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun openNotificationSetting(msg: Any) {
|
||||
NotificationHelper.show(context as AppCompatActivity, NotificationUgc.LOGIN)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun useDarkStatusBarText(msg: Any) {
|
||||
runOnUiThread {
|
||||
DisplayUtils.transparentStatusBar(context as AppCompatActivity)
|
||||
DisplayUtils.setLightStatusBar(context as AppCompatActivity, msg.toString() == "true")
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun exitWebView(msg: Any) {
|
||||
runOnUiThread { (context as Activity).finish() }
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun updateRegulationTestStatus(msg: Any) {
|
||||
if (msg.toString().toLowerCase(Locale.getDefault()) == "pass") {
|
||||
SPUtils.setString(Constants.SP_REGULATION_TEST_PASS_STATUS, "pass")
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getStatusBarHeight(msg: Any): String {
|
||||
val statusBarHeight = DisplayUtils.getStatusBarHeight(context.resources)
|
||||
return "$statusBarHeight"
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getGid(msg: Any): String {
|
||||
return HaloApp.getInstance().gid
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun showIncompatibleVersionDialog(msg: Any) {
|
||||
DialogUtils.showLowVersionDialog(context)
|
||||
}
|
||||
|
||||
@Keep
|
||||
|
||||
391
app/src/main/java/com/gh/common/DefaultUrlHandler.kt
Normal file
391
app/src/main/java/com/gh/common/DefaultUrlHandler.kt
Normal file
@ -0,0 +1,391 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.util.Base64
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DirectUtils.directToGameDetailVideoStreaming
|
||||
import com.gh.common.util.DirectUtils.directToGameServerCalendar
|
||||
import com.gh.common.util.DirectUtils.directToGameVideo
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.DirectUtils.directToVideoDetail
|
||||
import com.gh.common.util.GsonUtils.gson
|
||||
import com.gh.gamecenter.LibaoDetailActivity
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.NewsDetailActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.subject.SubjectActivity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
import com.lightgame.utils.Utils
|
||||
import java.nio.charset.Charset
|
||||
|
||||
object DefaultUrlHandler {
|
||||
|
||||
@JvmStatic
|
||||
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
|
||||
val uri = Uri.parse(url)
|
||||
if ("ghzhushou" == uri.scheme) {
|
||||
Utils.log("url = $url")
|
||||
Utils.log("url = " + uri.scheme!!)
|
||||
val host = uri.host
|
||||
val path = uri.path
|
||||
var id = ""
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
id = path!!.substring(1)
|
||||
}
|
||||
val intent: Intent
|
||||
when (host) {
|
||||
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
|
||||
|
||||
"game" -> DirectUtils.directToGameDetail(context, id = id, tab = uri.getQueryParameter("to"), autoDownload = uri.getQueryParameter("auto_download") == "true", entrance = entrance)
|
||||
|
||||
"column" -> SubjectActivity.startSubjectActivity(context, id, uri.getQueryParameter("name"), false, entrance)
|
||||
|
||||
"libao" -> context.startActivity(LibaoDetailActivity.getIntentById(context, id, entrance))
|
||||
|
||||
"qq" -> try {
|
||||
DirectUtils.directToQqConversation(context, id)
|
||||
} catch (e: Throwable) {
|
||||
Utils.toast(context, "请检查是否已经安装手机QQ")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_QQ_QUN -> {
|
||||
val key = uri.getQueryParameter("key")
|
||||
if (!DirectUtils.directToQqGroup(context, key)) {
|
||||
Utils.toast(context, "请检查是否已经安装手机QQ")
|
||||
}
|
||||
}
|
||||
|
||||
"inurl" -> {
|
||||
intent = Intent(context, WebActivity::class.java)
|
||||
intent.putExtra(EntranceUtils.KEY_URL, uri.getQueryParameter("url"))
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
"outurl" -> {
|
||||
intent = Intent()
|
||||
intent.action = Intent.ACTION_VIEW
|
||||
intent.data = Uri.parse(uri.getQueryParameter("url"))
|
||||
try {
|
||||
context.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Utils.toast(context, "请检查是否已经安装手机浏览器")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
|
||||
|
||||
"community" -> {
|
||||
val community = CommunityEntity()
|
||||
community.id = id
|
||||
community.name = uri.getQueryParameter("name") ?: ""
|
||||
DirectUtils.directToCommunity(context, community)
|
||||
}
|
||||
|
||||
"community_column" -> {
|
||||
val community = CommunityEntity()
|
||||
community.id = uri.getQueryParameter("community_id") ?: ""
|
||||
community.name = uri.getQueryParameter("community_name") ?: ""
|
||||
val columnId = uri.getQueryParameter("column_id") ?: ""
|
||||
DirectUtils.directToCommunityColumn(context, community, columnId, entrance, "文章链接")
|
||||
}
|
||||
|
||||
"answer" -> DirectUtils.directToAnswerDetail(context, id, entrance, "文章链接")
|
||||
|
||||
"communities" -> {
|
||||
// ghzhushou://communities/5a32405b2397ab000f688de3/articles/5c99d262c140b321564f04e3
|
||||
var communityId = ""
|
||||
var type = ""
|
||||
var typeId = ""
|
||||
val split = id.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
for (text in split) {
|
||||
if (TextUtils.isEmpty(communityId)) {
|
||||
communityId = text
|
||||
continue
|
||||
}
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
type = text
|
||||
continue
|
||||
}
|
||||
if (TextUtils.isEmpty(typeId)) {
|
||||
typeId = text
|
||||
}
|
||||
}
|
||||
if ("articles" == type) {
|
||||
DirectUtils.directToCommunityArticle(
|
||||
context, typeId, communityId,
|
||||
entrance, "文章链接")
|
||||
}
|
||||
}
|
||||
EntranceUtils.HOST_UPLOAD_VIDEO -> {
|
||||
val titleParameter = uri.getQueryParameter("title")
|
||||
val title = if (titleParameter.isNullOrEmpty()) "" else "#$titleParameter#"
|
||||
val categoryId = uri.getQueryParameter("category_id") ?: ""
|
||||
val link = uri.getQueryParameter("link") ?: ""
|
||||
val gameId = uri.getQueryParameter("gameId") ?: ""
|
||||
val gameName = uri.getQueryParameter("gameName") ?: ""
|
||||
val tagActivityId = uri.getQueryParameter("tagActivityId") ?: ""
|
||||
val tagActivityName = uri.getQueryParameter("tagActivityName") ?: ""
|
||||
val linkEntity = VideoLinkEntity(title, categoryId, link, tagActivityId, tagActivityName)
|
||||
val simpleGameEntity = SimpleGameEntity(gameId, gameName)
|
||||
CheckLoginUtils.checkLogin(context, null, true, EntranceUtils.ENTRANCE_BROWSER) {
|
||||
DirectUtils.directToVideoManager(context, linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "")
|
||||
}
|
||||
}
|
||||
EntranceUtils.HOST_USERHOME -> {
|
||||
val position = uri.getQueryParameter("position")
|
||||
DirectUtils.directToHomeActivity(context, id, if (position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
|
||||
}
|
||||
EntranceUtils.HOST_VIDEO_MORE -> {
|
||||
val referer = uri.getQueryParameter("referer") ?: ""
|
||||
val type = uri.getQueryParameter("type") ?: ""
|
||||
val act = uri.getQueryParameter("act") ?: ""
|
||||
val gameId = uri.getQueryParameter("gameId") ?: ""
|
||||
val fieldId = uri.getQueryParameter("fieldId") ?: ""
|
||||
val sectionName = uri.getQueryParameter("sectionName") ?: ""
|
||||
val paginationType = uri.getQueryParameter("paginationType")
|
||||
?: "page"//活动分页方式 page filter
|
||||
val location = if (!TextUtils.isEmpty(act)) {
|
||||
VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value
|
||||
} else if (!TextUtils.isEmpty(fieldId)) {
|
||||
VideoDetailContainerViewModel.Location.GAME_ZONE.value
|
||||
} else {
|
||||
id
|
||||
}
|
||||
directToVideoDetail(context, id, location, false, gameId, entrance, "", referer, type, act, paginationType, fieldId, sectionName)
|
||||
}
|
||||
EntranceUtils.HOST_VIDEO_SINGLE -> {
|
||||
val referer = uri.getQueryParameter("referer") ?: ""
|
||||
directToVideoDetail(context, id, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.value,
|
||||
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer)
|
||||
}
|
||||
EntranceUtils.HOST_VIDEO_STREAMING_HOME -> {
|
||||
intent = Intent(context, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
EntranceUtils.HOST_VIDEO_STREAMING_DESC -> {
|
||||
directToGameDetailVideoStreaming(context, id, entrance)
|
||||
}
|
||||
EntranceUtils.HOST_VIDEO_COLLECTION -> {
|
||||
directToGameVideo(context, id, entrance, "")
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_CATEGORY -> {
|
||||
val title = uri.getQueryParameter("title")
|
||||
DirectUtils.directCategoryDirectory(context, id, title ?: "", entrance, "")
|
||||
}
|
||||
EntranceUtils.HOST_COLUMN_COLLECTION -> {
|
||||
val name = uri.getQueryParameter("name")
|
||||
DirectUtils.directToColumnCollection(context, id, -1, entrance, name ?: "")
|
||||
}
|
||||
EntranceUtils.HOST_COLUMN -> {
|
||||
DirectUtils.directToSubject(context, id, uri.getQueryParameter(EntranceUtils.KEY_NAME), entrance)
|
||||
}
|
||||
EntranceUtils.HOST_COMMUNITY_QUESTION_LABEL_DETAIL -> {
|
||||
val community = CommunityEntity()
|
||||
community.id = uri.getQueryParameter("community_id") ?: ""
|
||||
community.name = uri.getQueryParameter("community_name") ?: ""
|
||||
val tag = uri.getQueryParameter("tag") ?: ""
|
||||
DirectUtils.directAskColumnLabelDetail(context, tag, community, entrance, "")
|
||||
}
|
||||
EntranceUtils.HOST_COMMUNITY_COLUMN_DETAIL -> {
|
||||
val community = CommunityEntity()
|
||||
community.id = uri.getQueryParameter("community_id") ?: ""
|
||||
community.name = uri.getQueryParameter("community_name") ?: ""
|
||||
val columnId = uri.getQueryParameter("column_id") ?: ""
|
||||
DirectUtils.directAskColumnDetail(context, columnId, community, entrance, "")
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_BLOCK -> {
|
||||
val name = uri.getQueryParameter("name")
|
||||
?: ""
|
||||
val entity = SubjectRecommendEntity(link = id, name = name, text = name)
|
||||
DirectUtils.directToBlock(context, entity, entrance)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_SERVER_BLOCK -> {
|
||||
DirectUtils.directToGameServers(context, entrance = entrance, path = "")
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_AMWAY_BLOCK -> {
|
||||
DirectUtils.directToAmway(context, entrance = entrance, path = "")
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_HELP -> {
|
||||
val name = uri.getQueryParameter("name")
|
||||
?: ""
|
||||
DirectUtils.directToQa(context, name, id)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_HELP_COLLECTION -> {
|
||||
val name = uri.getQueryParameter("name")
|
||||
?: ""
|
||||
DirectUtils.directToQaCollection(context, name, id)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_GAME_UPLOAD -> {
|
||||
DirectUtils.directGameUpload(context, entrance = entrance, path = "")
|
||||
}
|
||||
EntranceUtils.HOST_GAME_ZONE -> {
|
||||
val zoneUrl = uri.getQueryParameter("url") ?: ""
|
||||
DirectUtils.directGameZone(context, id, zoneUrl, entrance)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_LINK -> {
|
||||
try {
|
||||
val dataString = uri.getQueryParameter("data")
|
||||
if (!TextUtils.isEmpty(dataString)) {
|
||||
val linkData = Base64.decode(dataString, Base64.DEFAULT)
|
||||
val linkDataString = String(linkData, Charset.defaultCharset())
|
||||
val le = gson.fromJson(linkDataString, LinkEntity::class.java)
|
||||
directToLinkPage(context, le, entrance, "")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_GAME_NEWS -> {
|
||||
DirectUtils.directToGameNews(
|
||||
context,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_ID),
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
entrance);
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_GAME_CALENDAR -> {
|
||||
directToGameServerCalendar(context, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID))
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_HISTORY_APK -> {
|
||||
DirectUtils.directToHistoryApk(context, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID))
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_FORUM_DETAIL -> {
|
||||
DirectUtils.directForumDetail(context, id, entrance)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_GAME_RATING_DETAIL -> {
|
||||
DirectUtils.directToGameRatingDetail(context, uri.getQueryParameter(EntranceUtils.KEY_GAME_ID), uri.getQueryParameter(EntranceUtils.KEY_COMMENT_ID), EntranceUtils.ENTRANCE_BROWSER)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_FORUM -> {
|
||||
DirectUtils.directToForum(context);
|
||||
}
|
||||
else -> DialogUtils.showLowVersionDialog(context)
|
||||
}
|
||||
return true
|
||||
} else if ("zhiqu" == uri.scheme) {
|
||||
if (PackageUtils.isInstalled(context, "com.beieryouxi.zqyxh")) {
|
||||
val intent = Intent()
|
||||
intent.data = Uri.parse(url)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
Utils.toast(context, "请安装指趣游戏盒")
|
||||
}
|
||||
}
|
||||
|
||||
if (url.startsWith("alipays:") || url.startsWith("alipay")) {
|
||||
try {
|
||||
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast("请安装支付宝客户端")
|
||||
}
|
||||
return true
|
||||
} else if (url.startsWith("weixin")) {
|
||||
try {
|
||||
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast("请安装微信客户端")
|
||||
}
|
||||
return true
|
||||
} else if (url.startsWith("mqqwpa")) {
|
||||
try {
|
||||
context.startActivity(Intent("android.intent.action.VIEW", Uri.parse(url)))
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast("请安装QQ客户端")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if ("http" != uri.scheme && "https" != uri.scheme) return true
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun transformNormalScheme(context: Context, url: String, entrance: String): Boolean {
|
||||
val uri = Uri.parse(url)
|
||||
if (uri.host == "www.ghzs666.com"
|
||||
|| uri.host == "www.ghzs.com"
|
||||
|| uri.host == "ask.ghzs.com"
|
||||
|| uri.host == "m.ghzs.com"
|
||||
|| uri.host == "m.ghzs666.com") {
|
||||
Utils.log(uri.path)
|
||||
uri.path?.apply {
|
||||
when {
|
||||
contains("game") -> {
|
||||
val gameId = uri.getQueryParameter("gameId") ?: ""
|
||||
DirectUtils.directToGameDetail(context, gameId, entrance, autoDownload = false, traceEvent = null)
|
||||
}
|
||||
contains("question") -> {
|
||||
val questionId = split("/")[2]
|
||||
val answerId = uri.getQueryParameter("answer")
|
||||
if (answerId.isNullOrEmpty()) {
|
||||
DirectUtils.directToQuestionDetail(context, questionId, entrance, "")
|
||||
} else {
|
||||
DirectUtils.directToAnswerDetail(context, answerId, entrance, "")
|
||||
}
|
||||
}
|
||||
contains("communities") && contains("article") -> {
|
||||
var communityId = ""
|
||||
var type = ""
|
||||
var typeId = ""
|
||||
val split = replace("/communities", "").replace(".html", "").split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
for (text in split) {
|
||||
if (TextUtils.isEmpty(communityId)) {
|
||||
communityId = text
|
||||
continue
|
||||
}
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
type = text
|
||||
continue
|
||||
}
|
||||
if (TextUtils.isEmpty(typeId)) {
|
||||
typeId = text
|
||||
}
|
||||
}
|
||||
if ("articles" == type) {
|
||||
DirectUtils.directToCommunityArticle(
|
||||
context, typeId, communityId,
|
||||
entrance, "文章链接")
|
||||
}
|
||||
}
|
||||
contains("article") -> {
|
||||
val articleId = split("/")[2].replace(".html", "")
|
||||
DirectUtils.directToArticle(context, articleId, entrance)
|
||||
}
|
||||
contains("columns") -> {
|
||||
val columnsId = split("/")[3]
|
||||
val id = uri.getQueryParameter("communityId") ?: ""
|
||||
val name = uri.getQueryParameter("communityName") ?: ""
|
||||
DirectUtils.directToCommunityColumn(context, CommunityEntity(id, name), columnsId, entrance, "")
|
||||
}
|
||||
contains("zone") -> {
|
||||
val gameId = split("/")[2]
|
||||
DirectUtils.directGameZone(context, gameId, url, entrance)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -1,148 +0,0 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.common.util.EntranceUtils.ENTRANCE_BROWSER
|
||||
import com.gh.gamecenter.GameDetailActivity
|
||||
import com.gh.gamecenter.LibaoDetailActivity
|
||||
import com.gh.gamecenter.NewsDetailActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.CommunityEntity
|
||||
import com.gh.gamecenter.entity.VideoLinkEntity
|
||||
import com.gh.gamecenter.subject.SubjectActivity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
import com.lightgame.utils.Utils
|
||||
import com.moor.imkf.requesturl.RequestUrl.type
|
||||
|
||||
object DefaultWebViewUrlHandler {
|
||||
|
||||
@JvmStatic
|
||||
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
|
||||
val uri = Uri.parse(url)
|
||||
if ("ghzhushou" == uri.scheme) {
|
||||
Utils.log("url = $url")
|
||||
Utils.log("url = " + uri.scheme!!)
|
||||
val host = uri.host
|
||||
val path = uri.path
|
||||
var id = ""
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
id = path!!.substring(1)
|
||||
}
|
||||
val intent: Intent
|
||||
when (host) {
|
||||
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
|
||||
|
||||
"game" -> GameDetailActivity.startGameDetailActivity(context, id, "libao" == uri.getQueryParameter("to"), entrance)
|
||||
|
||||
"column" -> SubjectActivity.startSubjectActivity(context, id, uri.getQueryParameter("name"), false, entrance)
|
||||
|
||||
"libao" -> context.startActivity(LibaoDetailActivity.getIntentById(context, id, entrance))
|
||||
|
||||
"qq" -> try {
|
||||
DirectUtils.directToQqConversation(context, id)
|
||||
} catch (e: Exception) {
|
||||
Utils.toast(context, "请检查是否已经安装手机QQ")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
"qqqun" -> {
|
||||
val key = uri.getQueryParameter("key")
|
||||
if (!DirectUtils.directToQqGroup(context, key)) {
|
||||
Utils.toast(context, "请检查是否已经安装手机QQ")
|
||||
}
|
||||
}
|
||||
|
||||
"inurl" -> {
|
||||
intent = Intent(context, WebActivity::class.java)
|
||||
intent.putExtra(EntranceUtils.KEY_URL, uri.getQueryParameter("url"))
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
"outurl" -> {
|
||||
intent = Intent()
|
||||
intent.action = Intent.ACTION_VIEW
|
||||
intent.data = Uri.parse(uri.getQueryParameter("url"))
|
||||
try {
|
||||
context.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
Utils.toast(context, "请检查是否已经安装手机浏览器")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
|
||||
|
||||
"community" -> {
|
||||
val community = CommunityEntity()
|
||||
community.id = id
|
||||
community.name = uri.getQueryParameter("name")
|
||||
DirectUtils.directToCommunity(context, community)
|
||||
}
|
||||
|
||||
"answer" -> DirectUtils.directToAnswerDetail(context, id, entrance, "文章链接")
|
||||
|
||||
"communities" -> {
|
||||
// ghzhushou://communities/5a32405b2397ab000f688de3/articles/5c99d262c140b321564f04e3
|
||||
var communityId = ""
|
||||
var type = ""
|
||||
var typeId = ""
|
||||
val split = id.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
for (text in split) {
|
||||
if (TextUtils.isEmpty(communityId)) {
|
||||
communityId = text
|
||||
continue
|
||||
}
|
||||
if (TextUtils.isEmpty(type)) {
|
||||
type = text
|
||||
continue
|
||||
}
|
||||
if (TextUtils.isEmpty(typeId)) {
|
||||
typeId = text
|
||||
}
|
||||
}
|
||||
if ("articles" == type) {
|
||||
DirectUtils.directToCommunityArticle(
|
||||
context, typeId, communityId,
|
||||
entrance, "文章链接")
|
||||
}
|
||||
}
|
||||
EntranceUtils.HOST_UPLOAD_VIDEO -> {
|
||||
val titleParameter = uri.getQueryParameter("title")
|
||||
val title = if (titleParameter.isNullOrEmpty()) "" else "#$titleParameter#"
|
||||
val categoryId = uri.getQueryParameter("category_id") ?: ""
|
||||
val link = uri.getQueryParameter("link") ?: ""
|
||||
val linkEntity = VideoLinkEntity(title, categoryId, link)
|
||||
// if (!CheckLoginUtils.isLogin()) {
|
||||
// HaloApp.put(EntranceUtils.HOST_UPLOAD_VIDEO, linkEntity)
|
||||
// }
|
||||
CheckLoginUtils.checkLogin(context, null, true, EntranceUtils.ENTRANCE_BROWSER) {
|
||||
DirectUtils.directToVideoManager(context, linkEntity, EntranceUtils.ENTRANCE_BROWSER, "")
|
||||
}
|
||||
}
|
||||
EntranceUtils.HOST_USERHOME -> {
|
||||
val position = uri.getQueryParameter("position")
|
||||
DirectUtils.directToHomeActivity(context, id, if (position.isNullOrEmpty()) -1 else position.toInt(), entrance, "")
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_VIDEO_MORE -> {
|
||||
val referer = uri.getQueryParameter("referer") ?: ""
|
||||
val type = uri.getQueryParameter("type") ?: ""
|
||||
val act = uri.getQueryParameter("act") ?: ""
|
||||
val loaction = if (TextUtils.isEmpty(act)) id else VideoDetailContainerViewModel.Location.VIDEO_ACTIVITY.value
|
||||
DirectUtils.directToVideoDetail(context, id, loaction, false, "", entrance, "", referer, type, act)
|
||||
}
|
||||
|
||||
else -> DialogUtils.showLowVersionDialog(context)
|
||||
}
|
||||
return true
|
||||
}
|
||||
if ("http" != uri.scheme && "https" != uri.scheme) return true
|
||||
return false
|
||||
}
|
||||
}
|
||||
80
app/src/main/java/com/gh/common/FixedRateJobHelper.kt
Normal file
80
app/src/main/java/com/gh/common/FixedRateJobHelper.kt
Normal file
@ -0,0 +1,80 @@
|
||||
package com.gh.common
|
||||
|
||||
import com.gh.common.exposure.ExposureManager
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.common.loghub.LoghubUtils
|
||||
import com.gh.common.util.doOnMainProcessOnly
|
||||
import com.gh.common.util.tryCatchInRelease
|
||||
import com.gh.common.videolog.VideoRecordUtils
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.gamecenter.entity.TimeEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
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 = 300 * 1000L
|
||||
private const val VIDEO_RECORD_PERIOD: Long = 60 * 1000L
|
||||
|
||||
private const val DOWNLOAD_HEARTBEAT_PERIOD: Long = 60 * 1000L
|
||||
private const val DOWNLOAD_HEARTBEAT_SHEET_PERIOD: Long = 15 * 1000L
|
||||
|
||||
private var mExecuteCount: Int = 0
|
||||
|
||||
var timeDeltaBetweenServerAndClient: Long = 0
|
||||
|
||||
@JvmStatic
|
||||
fun begin() {
|
||||
doOnMainProcessOnly {
|
||||
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
|
||||
// 时间校对,10分钟一次
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % TIME_PERIOD == 0L) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
|
||||
.subscribeOn(AppExecutor.cachedScheduler)
|
||||
.subscribe(object : Response<TimeEntity>() {
|
||||
override fun onResponse(response: TimeEntity?) {
|
||||
val serverTime = response?.time
|
||||
serverTime?.let { timeDeltaBetweenServerAndClient = it * 1000 - System.currentTimeMillis() }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 提交曝光数据
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % EXPOSURE_PERIOD == 0L) {
|
||||
ExposureManager.commitSavedExposureEvents(true)
|
||||
}
|
||||
|
||||
// 分片检测下载进度
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
|
||||
tryCatchInRelease {
|
||||
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
|
||||
DownloadDataHelper.uploadDownloadHeartbeat(upload)
|
||||
}
|
||||
}
|
||||
|
||||
// 提交普通 loghub 数据
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % LOGHUB_PERIOD == 0L) {
|
||||
LoghubUtils.commitSavedLoghubEvents()
|
||||
}
|
||||
|
||||
// 更新游戏屏蔽信息
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % REGION_SETTING_PERIOD == 0L) {
|
||||
RegionSettingHelper.getRegionSetting()
|
||||
}
|
||||
|
||||
// 提交视频浏览记录数据
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % VIDEO_RECORD_PERIOD == 0L) {
|
||||
VideoRecordUtils.commitVideoRecord()
|
||||
}
|
||||
|
||||
// ExposureUtils.logADownloadCompleteExposureEvent(GameEntity(id = mExecuteCount.toString(), name = "测试曝光上传"), platform = "", trace = null, downloadType = ExposureUtils.DownloadType.DOWNLOAD)
|
||||
mExecuteCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.util.edit
|
||||
import com.gh.common.util.toJson
|
||||
import com.gh.common.util.toObject
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.entity.AliasEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
@ -35,33 +36,29 @@ object PushManager {
|
||||
|
||||
@JvmStatic
|
||||
fun init(channel: String) {
|
||||
//初始化友盟推送
|
||||
UMConfigure.init(mApplication,
|
||||
Config.UMENG_APPKEY, channel,
|
||||
UMConfigure.DEVICE_TYPE_PHONE,
|
||||
Config.UMENG_MESSAGE_SECRET)
|
||||
tryWithDefaultCatch {
|
||||
//初始化友盟推送
|
||||
UMConfigure.init(mApplication, Config.UMENG_APPKEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Config.UMENG_MESSAGE_SECRET)
|
||||
|
||||
// 注册小米、华为和魅族通道
|
||||
MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
|
||||
HuaWeiRegister.register(mApplication)
|
||||
MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
//友盟推送
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
pushAgent.onAppStart() // 开启App统计
|
||||
runOnIoThread { registerDevice() }
|
||||
|
||||
//注册推送服务,每次调用register方法都会回调该接口
|
||||
registerDevice()
|
||||
// 注册小米、华为和魅族通道
|
||||
MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
|
||||
HuaWeiRegister.register(mApplication)
|
||||
MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
|
||||
|
||||
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
|
||||
mPreviousAlias = aliasInSp?.toObject()
|
||||
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
|
||||
mPreviousAlias = aliasInSp?.toObject()
|
||||
|
||||
if (mPreviousAlias == null) {
|
||||
getAndSetAlias()
|
||||
if (mPreviousAlias == null) {
|
||||
getAndSetAlias()
|
||||
}
|
||||
|
||||
// 完全自定义处理(透传)
|
||||
pushAgent.setPushIntentServiceClass(GHUmengNotificationService::class.java)
|
||||
}
|
||||
|
||||
// 完全自定义处理(透传)
|
||||
pushAgent.setPushIntentServiceClass(GHUmengNotificationService::class.java)
|
||||
}
|
||||
|
||||
private fun registerDevice() {
|
||||
@ -98,6 +95,7 @@ object PushManager {
|
||||
jsonObject.put("os", meta.os)
|
||||
jsonObject.put("os_version", meta.android_version)
|
||||
jsonObject.put("mac", meta.mac)
|
||||
jsonObject.put("gid", meta.gid)
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
@ -113,7 +114,7 @@ class TimeElapsedHelper(val fragment: Fragment?, val activity: Activity?) {
|
||||
}
|
||||
|
||||
object TimeElapsedThreadHolder {
|
||||
val threadService = Executors.newSingleThreadExecutor()
|
||||
val threadService: ExecutorService by lazy { Executors.newSingleThreadExecutor() }
|
||||
}
|
||||
|
||||
interface TimeoutCallback {
|
||||
|
||||
@ -5,6 +5,8 @@ import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.util.GsonUtils;
|
||||
import com.gh.common.util.PackageHelper;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
@ -23,15 +25,13 @@ import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
public class Config {
|
||||
|
||||
public static final String API_HOST = BuildConfig.API_HOST;
|
||||
public static final String COMMENT_HOST = BuildConfig.COMMENT_HOST;
|
||||
public static final String DATA_HOST = BuildConfig.DATA_HOST;
|
||||
public static final String SENSITIVE_API_HOST = BuildConfig.SENSITIVE_API_HOST;
|
||||
|
||||
/**
|
||||
* 需要配置的请使用{@link PreferenceManager#getDefaultSharedPreferences(Context)}
|
||||
@ -49,6 +49,10 @@ public class Config {
|
||||
public static final String UMENG_APPKEY = BuildConfig.UMENG_APPKEY;
|
||||
public static final String UMENG_MESSAGE_SECRET = BuildConfig.UMENG_MESSAGE_SECRET;
|
||||
public static final String BUGLY_APPID = BuildConfig.BUGLY_APPID;
|
||||
public static final String LETO_APPID = BuildConfig.LETO_APPID;
|
||||
public static final String TTAD_APPID = BuildConfig.TTAD_APPID;
|
||||
public static final String DOUYIN_CLIENTKEY = BuildConfig.DOUYIN_CLIENTKEY;
|
||||
public static final String DOUYIN_CLIENTSECRET = BuildConfig.DOUYIN_CLIENTSECRET;
|
||||
// http://www.ghzs666.com/article/${articleId}.html
|
||||
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
|
||||
public static final String PATCHES = "patches";
|
||||
@ -234,6 +238,10 @@ public class Config {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isGameDomeSwitchOpen() {
|
||||
return getSettings() != null && getSettings().getGameDomeSwitch().equals("on");
|
||||
}
|
||||
|
||||
public static void fixHideFunction() {
|
||||
SharedPreferences preferences = PreferenceManager.
|
||||
getDefaultSharedPreferences(HaloApp.getInstance().getApplication());
|
||||
@ -248,7 +256,7 @@ public class Config {
|
||||
public static void getGhzsSettings() {
|
||||
String channel = HaloApp.getInstance().getChannel();
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().getApplication())
|
||||
.getApi().getSettings(PackageUtils.getVersionName(), channel)
|
||||
.getSensitiveApi().getSettings(PackageUtils.getVersionName(), channel)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<SettingsEntity>() {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.constant;
|
||||
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
|
||||
public class Constants {
|
||||
|
||||
@ -12,11 +13,12 @@ public class Constants {
|
||||
|
||||
public final static int NOT_NETWORK_CODE = 504; // 没有网络的状态码(应该是这个吧!)
|
||||
|
||||
public static final String LOGIN_TOKEN_ID = "userToken_id"; // 用户ID 与服务器无关
|
||||
|
||||
public static final String USER_TOKEN_KEY = "userTokenKey";
|
||||
public static final String USER_INFO_KEY = "userInfoKey";
|
||||
|
||||
public static final String WELCOME_DIALOG_ID = "welcome_dialog_id";
|
||||
public static final String WELCOME_DIALOG_LINK_TITLE = "welcome_dialog_link_title";
|
||||
|
||||
public static final String DEVICE_KEY = "deviceKey";
|
||||
|
||||
public static final String HAS_REQUESTED_NOTIFICATION_PERMISSIONS = "has_requested_notification_permissions";
|
||||
@ -29,10 +31,31 @@ public class Constants {
|
||||
|
||||
public static final String EB_QUIT_LOGIN = "quit_login";
|
||||
|
||||
// 用于避免历史下载掺和到普通下载状态的 ID 修饰符
|
||||
public static final String GAME_ID_DIVIDER = ":";
|
||||
// 用于避免历史下载影响到部分依赖名字作为数据更新条件的修饰符
|
||||
public static final String GAME_NAME_DECORATOR = " ";
|
||||
|
||||
// 游戏详情进入时的自定义栏目标签是否已经默认展开过一次的标记
|
||||
public static final String SP_HAS_EXPANDED_GAME_DETAIL_TAGS = "has_expanded_game_detail_tags";
|
||||
// 游戏详情进入时的自定义栏目标签是否已经显示过一次展开更多的浮窗提示
|
||||
public static final String SP_HAS_SHOWN_EXPANDED_GAME_DETAIL_TAGS_HINT = "has_shown_expanded_game_detail_tags_hint";
|
||||
|
||||
// 最近显示的弹窗信息
|
||||
public static final String SP_LAST_OPENING_ID = "last_opening_dialog_id";
|
||||
public static final String SP_LAST_OPENING_TIME = "last_opening_dialog_time";
|
||||
|
||||
// 游戏图标和图标角标
|
||||
public static final String RAW_GAME_ICON = "raw_game_icon";
|
||||
public static final String GAME_ICON_SUBSCRIPT = "game_icon_subscript";
|
||||
|
||||
public static final String EXTRA_DOWNLOAD_TYPE = "extra_download_type";
|
||||
public static final String SILENT_UPDATE = "静默更新";
|
||||
public static final String LAST_GHZS_UPDATE_FILE_SIZE = "last_ghzs_update_file_size";
|
||||
|
||||
// 新用户首次启动光环的时间
|
||||
public static final String SP_INITIAL_USAGE_TIME = "initial_usage_time";
|
||||
|
||||
//引导设置 “通知管理” 引导弹窗
|
||||
public static final String SP_SHOWED_NOTIFICATION_LOGIN = "show_notification_login_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_QUESTION = "show_notification_question_hint";
|
||||
@ -40,6 +63,9 @@ public class Constants {
|
||||
public static final String SP_SHOWED_NOTIFICATION_ARTICLE = "show_notification_article_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_VIDEO = "show_notification_video_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_RATING = "show_notification_rating_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_GIFT = "show_notification_gift_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_RESERVE_GAME = "show_notification_reserve_game_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_FEEDBACK = "show_notification_feedback_hint";
|
||||
// 新版本 也要触发一次“通知管理” 引导弹窗
|
||||
public static final String SP_SHOWED_NOTIFICATION_NEW_VERSION = "show_notification_new_version";
|
||||
// 今天是否已经触发了 “通知管理” 引导弹窗
|
||||
@ -64,6 +90,31 @@ public class Constants {
|
||||
public static final String SP_NON_WIFI_TIPS = "non_wifi_tips";
|
||||
//首页视频最新tab提示
|
||||
public static final String SP_HOME_NEW_VIDEO_TIPS = "home_new_video";
|
||||
//游戏设备弹窗提示
|
||||
public static final String SP_DEVICE_REMIND = "device_remind";
|
||||
//是否是第一次弹出游戏设备弹窗提示
|
||||
public static final String SP_FIRST_DEVICE_REMIND = "first_device_remind";
|
||||
//游戏设备弹窗不再提示
|
||||
public static final String SP_NO_REMIND_AGAIN = "no_remind_again";
|
||||
//游戏详情过滤标签数据
|
||||
public static final String SP_FILTER_TAGS = "filter_tags";
|
||||
//实名认证弹窗分类数据
|
||||
public static final String SP_AUTH_DIALOG = "auth_dialog";
|
||||
//顶部视频进度保存,重启恢复
|
||||
public static final String SP_TOP_VIDEO_SCHEDULE = "top_video_schedule";
|
||||
//我的光环小红点提示
|
||||
public static final String SP_GH_RED_POINT_REMIND = "gh_red_point_remind";
|
||||
//论坛首页引导
|
||||
public static final String SP_FORUM_GUIDE = "forum_guide";
|
||||
//礼仪考试开启状态
|
||||
public static final String SP_REGULATION_TEST_LAST_REMIND_TIME = "regulation_test_last_remind_time";
|
||||
public static final String SP_REGULATION_TEST_STATUS = "regulation_test_status";
|
||||
public static final String SP_REGULATION_TEST_PASS_STATUS = "regulation_test_pass_status";
|
||||
//相同设备号,每一种第三方登录方式登录后弹出绑定手机页面的次数
|
||||
public static final String SP_QQ_SHOW_BIND_PHONE_TIME = "qq_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
public static final String SP_WECHAT_SHOW_BIND_PHONE_TIME = "wechat_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
public static final String SP_WEIBO_SHOW_BIND_PHONE_TIME = "weibo_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
public static final String SP_DOUYIN_SHOW_BIND_PHONE_TIME = "douyin_show_bind_phone_time" + HaloApp.getInstance().getGid();
|
||||
|
||||
//手机号码匹配规则
|
||||
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
||||
@ -73,14 +124,24 @@ public class Constants {
|
||||
//输入规则
|
||||
public static final String INPUT_RULE = "0123456789abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLNMOPQRSTUVWXYZ_";
|
||||
|
||||
// 微信绑定地址地址
|
||||
// 微信绑定地址
|
||||
public static final String WECHAT_BIND_ADDRESS_DEV = "https://resource.ghzs.com/page/wechat_dev/index.html#/";
|
||||
public static final String WECHAT_BIND_ADDRESS = "https://resource.ghzs.com/page/wechat_pro/index.html#/";
|
||||
|
||||
// 礼仪考试地址
|
||||
public static final String REGULATION_TEST_ADDRESS_DEV = "https://static-web.ghzs.com/etiquette-dev/index.html#/";
|
||||
public static final String REGULATION_TEST_ADDRESS = "https://static-web.ghzs.com/etiquette/index.html#/";
|
||||
|
||||
// 徽章
|
||||
public static final String BADGE_ADDRESS_DEV = "http://resource.ghzs.com/page/badge_dev/index.html#/";
|
||||
public static final String BADGE_ADDRESS = "http://resource.ghzs.com/page/badge_pro/index.html#/";
|
||||
|
||||
// 腾讯企点地址
|
||||
public static final String TENCENT_QIDIAN_ADDRESS = "https://url.cn/D80iyMVV?_type=wpa&qidian=true";
|
||||
|
||||
//版规声明
|
||||
public static final String FORUM_REGULATIONS_NEWS_ID = "5f4db9cc34d44d01b92fd670";
|
||||
|
||||
//最少需要多少数据才能上传
|
||||
public static final int DATA_AMOUNT = 20;
|
||||
|
||||
@ -100,13 +161,16 @@ public class Constants {
|
||||
public static final int ADDONS_CD = 10 * 60 * 1000;
|
||||
//已收录包名更新 cd间隔
|
||||
public static final int PACKAGES_CD = 60 * 1000;
|
||||
|
||||
|
||||
public static final String[] REPORT_LIST = new String[]{"垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它"};
|
||||
|
||||
public static final String ENTRANCE_UNKNOWN = "(unknown)";
|
||||
|
||||
public static final String DEFAULT_TEXT_WRAPPER = "###";
|
||||
|
||||
|
||||
// 触发了安装事件的标记
|
||||
public static final String MARK_ALREADY_TRIGGERED_INSTALLATION = "triggered_installation";
|
||||
|
||||
// 标记下载重试标记(值为任务已下载大小,为空表示需要重试)
|
||||
public static final String MARK_RETRY_DOWNLOAD = "retry_download";
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package com.gh.common.databind;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
@ -13,12 +14,19 @@ import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.base.OnViewClickListener;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.CertificationDialog;
|
||||
import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.exposure.ExposureUtils;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DataUtils;
|
||||
@ -32,14 +40,16 @@ import com.gh.common.util.LogUtils;
|
||||
import com.gh.common.util.MtaHelper;
|
||||
import com.gh.common.util.NewsUtils;
|
||||
import com.gh.common.util.NumberUtils;
|
||||
import com.gh.common.util.PackageInstaller;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
import com.gh.common.util.PermissionHelper;
|
||||
import com.gh.common.util.PlatformUtils;
|
||||
import com.gh.common.util.ReservationHelper;
|
||||
import com.gh.common.view.DownloadDialog;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
import com.gh.common.view.DrawableView;
|
||||
import com.gh.common.view.GameIconView;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
@ -52,6 +62,7 @@ import com.gh.gamecenter.entity.LinkEntity;
|
||||
import com.gh.gamecenter.entity.PluginLocation;
|
||||
import com.gh.gamecenter.entity.ServerCalendarEntity;
|
||||
import com.gh.gamecenter.entity.TagStyleEntity;
|
||||
import com.gh.gamecenter.entity.TestEntity;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.gh.gamecenter.qa.entity.CommunityVideoEntity;
|
||||
@ -62,15 +73,10 @@ import com.lightgame.utils.Utils;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
/**
|
||||
* Created by khy on 12/02/18.
|
||||
*/
|
||||
@ -92,6 +98,26 @@ public class BindingAdapters {
|
||||
view.setTextSize(number);
|
||||
}
|
||||
|
||||
@BindingAdapter("setTypeface")
|
||||
public static void setTypeface(TextView view, String type) {
|
||||
if (type == null) return;
|
||||
|
||||
switch (type) {
|
||||
case "bold":
|
||||
view.setTypeface(null, Typeface.BOLD);
|
||||
break;
|
||||
case "italic":
|
||||
view.setTypeface(null, Typeface.ITALIC);
|
||||
break;
|
||||
case "bold_italic":
|
||||
view.setTypeface(null, Typeface.BOLD_ITALIC);
|
||||
break;
|
||||
default:
|
||||
view.setTypeface(null, Typeface.NORMAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"addDetailKaiFuView", "addDetailKaiFuViewListener", "isReadyPatch"})
|
||||
public static void addDetailKaiFuView(LinearLayout view, List<ServerCalendarEntity> list
|
||||
, OnViewClickListener listener, Boolean isReadyPatch) {
|
||||
@ -198,6 +224,17 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("textColorFromString")
|
||||
public static void textColorFromString(TextView tv, String hexString) {
|
||||
if (TextUtils.isEmpty(hexString)) return;
|
||||
|
||||
try {
|
||||
tv.setTextColor(Color.parseColor(hexString));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("visibleGone")
|
||||
public static void showHide(View view, Boolean show) {
|
||||
if (show != null && show) {
|
||||
@ -207,6 +244,40 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("goneIf")
|
||||
public static void goneIf(View view, Boolean gone) {
|
||||
if (gone != null && gone) {
|
||||
view.setVisibility(View.GONE);
|
||||
} else {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* lazy 的 paddingTop
|
||||
*/
|
||||
@BindingAdapter("lazyPaddingTop")
|
||||
public static void lazyPaddingTop(View view, int paddingTopInDp) {
|
||||
view.setPadding(view.getPaddingLeft(), DisplayUtils.dip2px(paddingTopInDp), view.getPaddingRight(), view.getPaddingBottom());
|
||||
}
|
||||
|
||||
/**
|
||||
* lazy 的 paddingBottom
|
||||
*/
|
||||
@BindingAdapter("lazyPaddingBottom")
|
||||
public static void lazyPaddingBottom(View view, int paddingBottomInDp) {
|
||||
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), DisplayUtils.dip2px(paddingBottomInDp));
|
||||
}
|
||||
|
||||
@BindingAdapter("visibleInvisible")
|
||||
public static void visibleInvisible(View view, Boolean show) {
|
||||
if (show != null && show) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("messageUnread")
|
||||
public static void setMessageUnread(TextView view, int unreadCount) {
|
||||
if (unreadCount < 100) {
|
||||
@ -244,6 +315,13 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("game")
|
||||
public static void setGame(View view, GameEntity gameEntity) {
|
||||
if (gameEntity != null && view instanceof GameIconView) {
|
||||
((GameIconView) view).displayGameIcon(gameEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter("articleType")
|
||||
public static void setArticleType(TextView view, String articleType) {
|
||||
NewsUtils.setNewsType(view, articleType, 0, 0);
|
||||
@ -358,17 +436,27 @@ public class BindingAdapters {
|
||||
case PLUGIN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
ApkEntity apk = gameEntity.getApk().get(0);
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
apk,
|
||||
() -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
|
||||
entrance, location + gameEntity.getName(), traceEvent);
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
traceEvent,
|
||||
entrance,
|
||||
location + ":" + gameEntity.getName());
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
case LAUNCH_OR_OPEN:
|
||||
@ -376,8 +464,12 @@ public class BindingAdapters {
|
||||
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
|
||||
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
|
||||
entrance, location + gameEntity.getName(), traceEvent);
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
traceEvent,
|
||||
entrance,
|
||||
location + ":" + gameEntity.getName());
|
||||
}
|
||||
break;
|
||||
case INSTALL_PLUGIN:
|
||||
@ -385,7 +477,7 @@ public class BindingAdapters {
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
DownloadEntity downloadEntity = DownloadManager.getInstance(progressBar.getContext()).getDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
PackageUtils.launchSetup(v.getContext(), downloadEntity);
|
||||
PackageInstaller.install(v.getContext(), downloadEntity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -416,9 +508,15 @@ public class BindingAdapters {
|
||||
}
|
||||
break;
|
||||
case H5_GAME:
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), "play".equals(linkEntity.getType())));
|
||||
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
|
||||
|
||||
if (isPlay) {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton()));
|
||||
progressBar.getContext().startActivity(i);
|
||||
break;
|
||||
}
|
||||
@ -455,7 +553,7 @@ public class BindingAdapters {
|
||||
}
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
String status = GameUtils.getDownloadBtnText(progressBar.getContext(), gameEntity, PluginLocation.only_game);
|
||||
switch (status) {
|
||||
@ -511,6 +609,23 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
/*private static void download(DownloadProgressBar progressBar, GameEntity gameEntity, ExposureEvent traceEvent, @Nullable String entrance, @Nullable String location, View v) {
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
ApkEntity apk = gameEntity.getApk().get(0);
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
apk,
|
||||
() -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
});
|
||||
} else {
|
||||
DownloadDialog.getInstance(v.getContext()).showPopupWindow(v, gameEntity,
|
||||
entrance, location + gameEntity.getName(), traceEvent);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
private static void updateReservation(DownloadProgressBar progressBar, GameEntity gameEntity) {
|
||||
// 显示预约
|
||||
@ -546,10 +661,7 @@ public class BindingAdapters {
|
||||
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(progressBar.getContext(), gameEntity.getName(), apkEntity.getPlatform(), entrance, "下载开始", method);
|
||||
|
||||
ExposureUtils.DownloadType downloadType = ExposureUtils.getDownloadType(apkEntity, method);
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, apkEntity.getPlatform(), traceEvent, downloadType);
|
||||
|
||||
|
||||
DownloadManager.createDownload(progressBar.getContext(),
|
||||
apkEntity,
|
||||
gameEntity,
|
||||
@ -557,7 +669,7 @@ public class BindingAdapters {
|
||||
entrance,
|
||||
location + gameEntity.getName(),
|
||||
isSubscribe,
|
||||
downloadExposureEvent);
|
||||
traceEvent);
|
||||
|
||||
progressBar.setProgress(0);
|
||||
progressBar.setDownloadType("插件化".equals(method) ?
|
||||
@ -567,27 +679,36 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"gameLabelList", "subjectTag"})
|
||||
public static void setGameLabelList(LinearLayout layout, GameEntity gameEntity, String subjectTag) {
|
||||
if (gameEntity == null) return;
|
||||
if (gameEntity.getTest() != null) {
|
||||
layout.removeAllViews();
|
||||
View testView = LayoutInflater.from(layout.getContext()).inflate(R.layout.game_test_label, null);
|
||||
TextView testType = testView.findViewById(R.id.test_type);
|
||||
TextView testTime = testView.findViewById(R.id.test_time);
|
||||
testType.setText(gameEntity.getTest().getType());
|
||||
testType.setBackgroundColor(ContextCompat.getColor(layout.getContext(), R.color.tag_yellow));
|
||||
@BindingAdapter("gameLabelList")
|
||||
public static void setGameLabelList(LinearLayout layout, List<TagStyleEntity> tagStyle) {
|
||||
GameViewUtils.setLabelList(layout.getContext(), layout, tagStyle);
|
||||
}
|
||||
|
||||
if (gameEntity.getTest().getStart() == 0) {
|
||||
testTime.setVisibility(View.GONE);
|
||||
// 包含测试开服标签
|
||||
@BindingAdapter("setGameTags")
|
||||
public static void setGameTags(LinearLayout layout, GameEntity gameEntity) {
|
||||
try {
|
||||
ArrayList<TagStyleEntity> tagStyle = new ArrayList<>();
|
||||
TestEntity test = gameEntity.getTest();
|
||||
if (test != null) {
|
||||
TagStyleEntity typeTag = new TagStyleEntity();
|
||||
typeTag.setName(test.getType() != null ? test.getType() : "");
|
||||
typeTag.setBackground("FFF3E0");
|
||||
typeTag.setColor("FA8500");
|
||||
tagStyle.add(typeTag);
|
||||
|
||||
TagStyleEntity timeTag = new TagStyleEntity();
|
||||
timeTag.setName(GameViewUtils.getGameTestDate(test.getStart()));
|
||||
timeTag.setBackground("E0FFF9");
|
||||
timeTag.setColor("00A887");
|
||||
tagStyle.add(timeTag);
|
||||
} else {
|
||||
testTime.setText(GameViewUtils.getGameTestDate(gameEntity.getTest().getStart()));
|
||||
tagStyle = gameEntity.getTagStyle();
|
||||
}
|
||||
layout.addView(testView);
|
||||
} else {
|
||||
GameViewUtils.setLabelList(layout.getContext(), layout, gameEntity.getTag(), subjectTag, gameEntity.getTagStyle());
|
||||
GameViewUtils.setLabelList(layout.getContext(), layout, tagStyle);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@BindingAdapter("isRefreshing")
|
||||
@ -597,14 +718,15 @@ public class BindingAdapters {
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"setGameName", "isShowPlatform"})
|
||||
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform) {
|
||||
@BindingAdapter({"setGameName", "isShowPlatform", "isShowSuffix"})
|
||||
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
|
||||
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
|
||||
if (isShowPlatform && game.getApk().size() > 0) {
|
||||
view.setText(String.format("%s - %s", game.getName(),
|
||||
view.setText(String.format("%s - %s", !isShowSuffix ? game.getNameWithoutSuffix() : game.getName(),
|
||||
PlatformUtils.getInstance(view.getContext()).getPlatformName(
|
||||
game.getApk().get(0).getPlatform())));
|
||||
} else {
|
||||
view.setText(game.getName());
|
||||
view.setText(!isShowSuffix ? game.getNameWithoutSuffix() : game.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@ -663,4 +785,17 @@ public class BindingAdapters {
|
||||
}
|
||||
view.setText(span);
|
||||
}
|
||||
|
||||
@BindingAdapter({"setVideoData"})
|
||||
public static void setVideoData(TextView view, int count) {
|
||||
if (count > 0) {
|
||||
view.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(view.getContext(), R.drawable.ic_video_data_up), null, null, null);
|
||||
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.text_EA3333));
|
||||
view.setText(count + "");
|
||||
} else {
|
||||
view.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
|
||||
view.setTextColor(ContextCompat.getColor(view.getContext(), R.color.text_999999));
|
||||
view.setText("-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ abstract class BaseTrackableDialogFragment : BaseDialogFragment() {
|
||||
|
||||
abstract fun getEvent(): String
|
||||
abstract fun getKey(): String
|
||||
open fun getValue(): String = ""
|
||||
|
||||
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
|
||||
private val mIsCanceledByClickOutsideOfDialog = AtomicBoolean(true)
|
||||
@ -47,6 +48,9 @@ abstract class BaseTrackableDialogFragment : BaseDialogFragment() {
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), value)
|
||||
} else {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), value)
|
||||
if (getValue().isNotEmpty()) {
|
||||
MtaHelper.onEvent(getEvent(), value, getValue())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
196
app/src/main/java/com/gh/common/dialog/CertificationDialog.kt
Normal file
196
app/src/main/java/com/gh/common/dialog/CertificationDialog.kt
Normal file
@ -0,0 +1,196 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.common.avoidcallback.AvoidOnResultManager
|
||||
import com.gh.common.avoidcallback.Callback
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.CheckLoginUtils
|
||||
import com.gh.common.util.DialogUtils
|
||||
import com.gh.common.util.GsonUtils
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.UserInfoEditActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.AuthDialogEntity
|
||||
import com.gh.gamecenter.entity.AuthDialogLevel
|
||||
import com.gh.gamecenter.entity.DeviceDialogEntity
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.user.UserViewModel
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.halo.assistant.fragment.user.UserInfoEditFragment
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class CertificationDialog(context: Context, private val authDialogEntity: AuthDialogEntity, val gameId: String, val listener: DialogUtils.ConfirmListener) :
|
||||
Dialog(context, R.style.GhAlertDialog) {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var detailedDesTv: TextView
|
||||
private lateinit var noRemindAgainCb: CheckBox
|
||||
private lateinit var actionLeftTv: TextView
|
||||
private lateinit var actionRightTv: TextView
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
view = LayoutInflater.from(context).inflate(R.layout.dialog_sertification, null)
|
||||
setContentView(view)
|
||||
detailedDesTv = view.findViewById(R.id.detailedDesTv)
|
||||
noRemindAgainCb = view.findViewById(R.id.noRemindAgainCb)
|
||||
actionLeftTv = view.findViewById(R.id.actionLeftTv)
|
||||
actionRightTv = view.findViewById(R.id.actionRightTv)
|
||||
|
||||
detailedDesTv.paint.flags = Paint.UNDERLINE_TEXT_FLAG
|
||||
detailedDesTv.paint.isAntiAlias = true
|
||||
|
||||
detailedDesTv.setOnClickListener {
|
||||
context.startActivity(WebActivity.getIntentByUrl(context, authDialogEntity.link))
|
||||
}
|
||||
|
||||
when (authDialogEntity.level) {
|
||||
AuthDialogLevel.MUST_PASS.value -> {
|
||||
actionLeftTv.text = "暂不下载"
|
||||
actionRightTv.text = "去实名认证"
|
||||
noRemindAgainCb.visibility = View.GONE
|
||||
actionLeftTv.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
actionRightTv.setOnClickListener {
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
gotoAuthPage()
|
||||
} else {
|
||||
gotoLoginPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
AuthDialogLevel.ALWAYS_HINT.value -> {
|
||||
actionLeftTv.text = "去实名认证"
|
||||
actionRightTv.text = "继续下载"
|
||||
noRemindAgainCb.visibility = View.GONE
|
||||
actionLeftTv.setOnClickListener {
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
gotoAuthPage()
|
||||
} else {
|
||||
gotoLoginPage()
|
||||
}
|
||||
}
|
||||
actionRightTv.setOnClickListener {
|
||||
listener.onConfirm()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
AuthDialogLevel.OPTIONAL_HINT.value -> {
|
||||
actionLeftTv.text = "去实名认证"
|
||||
actionRightTv.text = "继续下载"
|
||||
noRemindAgainCb.visibility = View.VISIBLE
|
||||
actionLeftTv.setOnClickListener {
|
||||
if (noRemindAgainCb.isChecked) {
|
||||
SPUtils.setBoolean(gameId, true)
|
||||
}
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
gotoAuthPage()
|
||||
} else {
|
||||
gotoLoginPage()
|
||||
}
|
||||
}
|
||||
actionRightTv.setOnClickListener {
|
||||
if (noRemindAgainCb.isChecked) {
|
||||
SPUtils.getBoolean(gameId, true)
|
||||
}
|
||||
listener.onConfirm()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//跳转登录页面
|
||||
private fun gotoLoginPage() {
|
||||
CheckLoginUtils.checkLogin(AppManager.getInstance().currentActivity() as AppCompatActivity,
|
||||
null, true, "实名认证弹窗") {
|
||||
if (UserManager.getInstance().isAuth) {
|
||||
listener.onConfirm()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//跳转实名认证页面
|
||||
private fun gotoAuthPage() {
|
||||
AvoidOnResultManager.getInstance(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
.startForResult(UserInfoEditActivity.getIntent(context, UserViewModel.TYPE_ID_CARD), object : Callback {
|
||||
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
val isAuthSuccess = data.getBooleanExtra(UserInfoEditFragment.AUTH_SUCCESS, false)
|
||||
if (isAuthSuccess) {
|
||||
listener.onConfirm()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun showCertificationDialog(context: Context, game: GameEntity, listener: DialogUtils.ConfirmListener) {
|
||||
//1.先判断是否登录 是执行2 否执行3
|
||||
//2.判断是否实名认证 是终止 否执行3
|
||||
//3.判断是否需要弹出认证弹窗接口
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
if (UserManager.getInstance().isAuth) {//已实名认证
|
||||
listener.onConfirm()
|
||||
} else {
|
||||
authDialog(context, game, listener)
|
||||
}
|
||||
} else {
|
||||
authDialog(context, game, listener)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun authDialog(context: Context, game: GameEntity, listener: DialogUtils.ConfirmListener) {
|
||||
var authDialog: AuthDialogEntity? = null
|
||||
if (game.authDialog != null) {
|
||||
authDialog = game.authDialog
|
||||
}
|
||||
if (authDialog == null) {
|
||||
val datas = SPUtils.getString(Constants.SP_AUTH_DIALOG)
|
||||
val type = object : TypeToken<List<AuthDialogEntity>>() {}.type
|
||||
val authDialogs = GsonUtils.gson.fromJson<List<AuthDialogEntity>>(datas, type)
|
||||
if (!authDialogs.isNullOrEmpty()) {
|
||||
authDialog = authDialogs.find { it.gameCategory == game.category }
|
||||
}
|
||||
}
|
||||
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)
|
||||
dialog.show()
|
||||
} else {
|
||||
listener.onConfirm()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
233
app/src/main/java/com/gh/common/dialog/DeviceRemindDialog.kt
Normal file
233
app/src/main/java/com/gh/common/dialog/DeviceRemindDialog.kt
Normal file
@ -0,0 +1,233 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.preference.PreferenceManager
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.DeviceDialogEntity
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.halo.assistant.fragment.SettingsFragment.AUTO_INSTALL_SP_KEY
|
||||
import com.lightgame.download.DataWatcher
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlinx.android.synthetic.main.dialog_device_remind.view.*
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* 设备提醒弹窗
|
||||
*/
|
||||
class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val gameEntity: GameEntity) : Dialog(context, R.style.GhAlertDialog) {
|
||||
private lateinit var view: View
|
||||
private var currentPage = 0
|
||||
private var mSlideLooperInterval = 3000L
|
||||
private lateinit var mLooperHandle: LooperHandle
|
||||
private lateinit var mAdapter: BannerAdapter
|
||||
private var mDatas: ArrayList<String> = ArrayList()
|
||||
private val mSlideLooperKey = 100
|
||||
private var disposable: Disposable? = null
|
||||
private val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
if (downloadEntity.status == DownloadStatus.done && downloadEntity.name == gameEntity.name) {
|
||||
val sp = PreferenceManager.getDefaultSharedPreferences(getContext())
|
||||
val autoInstall = sp.getBoolean(AUTO_INSTALL_SP_KEY, true)
|
||||
if (autoInstall) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun showDeviceRemindDialog(context: Context, gameEntity: GameEntity) {
|
||||
val datas = SPUtils.getString(Constants.SP_DEVICE_REMIND)
|
||||
if (datas.isNotEmpty()) {
|
||||
val type = object : TypeToken<List<DeviceDialogEntity>>() {}.type
|
||||
val entitys = GsonUtils.gson.fromJson<List<DeviceDialogEntity>>(datas, type)
|
||||
//1.判断设备是否匹配
|
||||
val entity = entitys.find { it.manufacturer.toLowerCase().startsWith(Build.MANUFACTURER.toLowerCase()) }
|
||||
?: return
|
||||
//2.判断游戏不含剔除标签
|
||||
gameEntity.tagStyle.forEach {
|
||||
if (entity.excludeTags.contains(it.name)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
//3.不再弹出提示判断
|
||||
val isNoRemindAgain = SPUtils.getBoolean(Constants.SP_NO_REMIND_AGAIN, false)
|
||||
if (isNoRemindAgain) return
|
||||
|
||||
val dialog = DeviceRemindDialog(context, entity, gameEntity)
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
view = LayoutInflater.from(context).inflate(R.layout.dialog_device_remind, null)
|
||||
setContentView(view)
|
||||
mDatas.addAll(entity.gallery)
|
||||
view.titleTv.text = entity.title
|
||||
view.contentTv.text = entity.content
|
||||
|
||||
view.bannerView.apply {
|
||||
orientation = ViewPager2.ORIENTATION_HORIZONTAL
|
||||
mAdapter = BannerAdapter()
|
||||
val recyclerView = getChildAt(0) as RecyclerView
|
||||
recyclerView.overScrollMode = RecyclerView.OVER_SCROLL_NEVER
|
||||
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
currentPage = position
|
||||
slideIndicator(currentPage % mDatas.size)
|
||||
}
|
||||
})
|
||||
recyclerView.addOnItemTouchListener(object : RecyclerView.SimpleOnItemTouchListener() {
|
||||
override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
|
||||
val isStop = e.action == MotionEvent.ACTION_DOWN || e.action == MotionEvent.ACTION_MOVE
|
||||
if (isStop) mAdapter.stopScroll() else mAdapter.startScroll()
|
||||
return false
|
||||
}
|
||||
})
|
||||
adapter = mAdapter
|
||||
mLooperHandle = LooperHandle(mAdapter)
|
||||
currentPage = (adapter as BannerAdapter).getActualFirstPositionInCenter()
|
||||
setCurrentItem(currentPage, false)
|
||||
if (mDatas.size > 1) {
|
||||
addIndicator()
|
||||
slideIndicator(currentPage % mDatas.size)
|
||||
autoPlay()
|
||||
}
|
||||
}
|
||||
val isFirst = SPUtils.getBoolean(Constants.SP_FIRST_DEVICE_REMIND, false)
|
||||
if (!isFirst) {
|
||||
view.cancelTv.isEnabled = false
|
||||
view.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_round_f5f5f5)
|
||||
disposable = countDownTimer(3) { finish, time ->
|
||||
if (finish) {
|
||||
view.cancelTv.isEnabled = true
|
||||
view.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
|
||||
view.cancelTv.text = "我知道了"
|
||||
view.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
} else {
|
||||
view.cancelTv.text = "我知道了(${time}S)"
|
||||
}
|
||||
}
|
||||
|
||||
SPUtils.setBoolean(Constants.SP_FIRST_DEVICE_REMIND, true)
|
||||
} else {
|
||||
view.noRemindAgainCb.visibility = View.VISIBLE
|
||||
view.cancelTv.text = "我知道了"
|
||||
view.cancelTv.isEnabled = true
|
||||
view.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
view.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
|
||||
}
|
||||
view.cancelTv.setOnClickListener {
|
||||
SPUtils.setBoolean(Constants.SP_NO_REMIND_AGAIN, view.noRemindAgainCb.isChecked)
|
||||
dismiss()
|
||||
}
|
||||
DownloadManager.getInstance(context).addObserver(dataWatcher)
|
||||
}
|
||||
|
||||
private fun addIndicator() {
|
||||
view.indicatorLl.removeAllViews()
|
||||
mDatas.forEach { _ ->
|
||||
val indicatorView = ImageView(context).apply {
|
||||
setImageResource(R.drawable.selector_device_remind_indicator)
|
||||
val params = LinearLayout.LayoutParams(DisplayUtils.dip2px(8F), LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
params.leftMargin = DisplayUtils.dip2px(1F)
|
||||
params.rightMargin = DisplayUtils.dip2px(1F)
|
||||
layoutParams = params
|
||||
}
|
||||
view.indicatorLl.addView(indicatorView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun slideIndicator(position: Int) {
|
||||
for (i in 0 until view.indicatorLl.childCount) {
|
||||
val childAt = view.indicatorLl.getChildAt(i)
|
||||
childAt.isSelected = i == position
|
||||
}
|
||||
}
|
||||
|
||||
private fun autoPlay() {
|
||||
mAdapter.startScroll()
|
||||
}
|
||||
|
||||
inner class BannerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return object : RecyclerView.ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_device_remind_banner, parent, false)) {}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = if (mDatas.size == 1) mDatas.size else Int.MAX_VALUE
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
val data = mDatas[position % mDatas.size]
|
||||
val view = holder.itemView as SimpleDraweeView
|
||||
ImageUtils.display(view, data)
|
||||
}
|
||||
|
||||
fun getActualFirstPositionInCenter(): Int {
|
||||
if (mDatas.size == 1) return 0
|
||||
var index = itemCount / 2
|
||||
if (index % mDatas.size != 0) {
|
||||
index -= (index % mDatas.size)
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
fun scrollToNextPage() {
|
||||
currentPage++
|
||||
view.bannerView.setCurrentItem(currentPage, true)
|
||||
}
|
||||
|
||||
fun startScroll() {
|
||||
mLooperHandle.removeMessages(mSlideLooperKey)
|
||||
mLooperHandle.sendEmptyMessageDelayed(mSlideLooperKey, mSlideLooperInterval)
|
||||
}
|
||||
|
||||
fun stopScroll() {
|
||||
mLooperHandle.removeMessages(mSlideLooperKey)
|
||||
}
|
||||
}
|
||||
|
||||
class LooperHandle(val mAdapter: BannerAdapter) : Handler() {
|
||||
private val mWeakReference: WeakReference<BannerAdapter> = WeakReference(mAdapter)
|
||||
override fun handleMessage(msg: Message?) {
|
||||
val adapter = mWeakReference.get()
|
||||
adapter?.scrollToNextPage()
|
||||
adapter?.startScroll()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
if (disposable != null && !disposable!!.isDisposed) {
|
||||
disposable!!.dispose()
|
||||
disposable = null
|
||||
}
|
||||
DownloadManager.getInstance(context).removeObserver(dataWatcher)
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.text.HtmlCompat
|
||||
import com.gh.base.fragment.BaseDialogFragment
|
||||
import com.gh.common.util.DirectUtils
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.common.util.MtaHelper
|
||||
@ -18,7 +19,10 @@ import com.gh.gamecenter.entity.GameEntity
|
||||
import kotlinx.android.synthetic.main.dialog_game_off_service.*
|
||||
|
||||
// 游戏关闭下载弹窗
|
||||
class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
|
||||
class GameOffServiceDialogFragment
|
||||
// : BaseTrackableDialogFragment()
|
||||
:BaseDialogFragment() {
|
||||
|
||||
private var mDialog: GameEntity.Dialog? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
@ -42,7 +46,7 @@ class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
|
||||
siteTv.text = site.text
|
||||
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
siteTv.setOnClickListener {
|
||||
MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
|
||||
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
|
||||
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
|
||||
dismiss()
|
||||
}
|
||||
@ -52,13 +56,13 @@ class GameOffServiceDialogFragment : BaseTrackableDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEvent(): String {
|
||||
return "游戏下载状态按钮"
|
||||
}
|
||||
|
||||
override fun getKey(): String {
|
||||
return "查看详情弹窗"
|
||||
}
|
||||
// override fun getEvent(): String {
|
||||
// return "游戏下载状态按钮"
|
||||
// }
|
||||
//
|
||||
// override fun getKey(): String {
|
||||
// return "查看详情弹窗"
|
||||
// }
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
|
||||
@ -2,28 +2,34 @@ package com.gh.common.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.content.res.AssetManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.gh.common.util.GsonUtils
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.util.PermissionHelper
|
||||
import com.gh.common.util.fromHtml
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.NotificationHint
|
||||
import com.gh.gamecenter.entity.NotificationStyleEntity
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.lightgame.utils.Utils
|
||||
import kotlinx.android.synthetic.main.dialog_notification_hint.*
|
||||
import org.json.JSONArray
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import kotlin.random.Random
|
||||
|
||||
// 通知权限弹窗
|
||||
class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
|
||||
private var mNotificationHint: NotificationHint? = null
|
||||
private var mNotificationUgc: NotificationUgc? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.dialog_notification_hint, null)
|
||||
@ -34,23 +40,34 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
titleTv.text = mNotificationHint?.title
|
||||
|
||||
contentContainer.removeAllViews()
|
||||
for (item in mNotificationHint?.content ?: arrayListOf()) {
|
||||
val tv = TextView(context)
|
||||
|
||||
tv.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
|
||||
topMargin = if (contentContainer.childCount == 0) 0 else DisplayUtils.dip2px(12f)
|
||||
}
|
||||
tv.text = item
|
||||
tv.setTextColor(Color.parseColor("#1383EB"))
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
|
||||
contentContainer.addView(tv)
|
||||
val jsonString = getJsonFromAssets()
|
||||
if (jsonString.isNullOrEmpty()) {
|
||||
Utils.log("Failed to obtain configuration file")
|
||||
return
|
||||
}
|
||||
val index = Random.nextInt(2)
|
||||
val jsonArray = JSONArray(jsonString)
|
||||
val jsonObj = jsonArray.getJSONObject(index)
|
||||
if (!jsonObj.has(mNotificationUgc!!.value)) {
|
||||
Utils.log("ugc type error")
|
||||
return
|
||||
}
|
||||
val styleEntityJson = jsonObj.getJSONObject(mNotificationUgc!!.value)
|
||||
val styleEntity = GsonUtils.fromJson(styleEntityJson.toString(), NotificationStyleEntity::class.java)
|
||||
val drawableId = resources.getIdentifier(styleEntity.image, "drawable", requireContext().packageName)
|
||||
notificationIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), drawableId))
|
||||
notificationTitle.text = styleEntity.title
|
||||
notificationContent.text = styleEntity.content.fromHtml()
|
||||
if (index == 0) {
|
||||
closeIv.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_notification_close_1))
|
||||
} else {
|
||||
activateTv.background = ContextCompat.getDrawable(requireContext(), R.drawable.bg_notification_open_btn_style_1)
|
||||
activateTv.text = "优雅的开启"
|
||||
}
|
||||
|
||||
activateTv.setOnClickListener {
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击立即开启")
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击立即开启")
|
||||
dismiss()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
||||
@ -63,9 +80,10 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
laterTv.setOnClickListener {
|
||||
closeIv.setOnClickListener {
|
||||
dismiss()
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击以后再说")
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "点击关闭")
|
||||
MtaHelper.onEventWithBasicDeviceInfo(getEvent(), getKey(), "${styleEntity.scenes}_${styleEntity.styleNo}_点击关闭")
|
||||
}
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(true)
|
||||
@ -81,10 +99,30 @@ class NotificationHintDialogFragment : BaseTrackableDialogFragment() {
|
||||
|
||||
override fun trackWithBasicDeviceInfo() = true
|
||||
|
||||
private fun getJsonFromAssets(): String? {
|
||||
val stringBuilder = StringBuilder()
|
||||
var bufferedReader: BufferedReader? = null
|
||||
var inputStreamReader: InputStreamReader? = null
|
||||
try {
|
||||
inputStreamReader = InputStreamReader(requireContext().assets.open("notification_style.json"))
|
||||
bufferedReader = BufferedReader(inputStreamReader)
|
||||
var line: String?
|
||||
while (bufferedReader.readLine().also { line = it } != null) {
|
||||
stringBuilder.append(line)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
inputStreamReader?.close()
|
||||
bufferedReader?.close()
|
||||
}
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(hint: NotificationHint) = NotificationHintDialogFragment().apply {
|
||||
mNotificationHint = hint
|
||||
fun getInstance(ugc: NotificationUgc) = NotificationHintDialogFragment().apply {
|
||||
mNotificationUgc = ugc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,71 +4,114 @@ import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import butterknife.BindView
|
||||
import butterknife.ButterKnife
|
||||
import butterknife.OnClick
|
||||
import com.gh.base.fragment.BaseDialogFragment
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.history.HistoryHelper
|
||||
import com.gh.common.repository.ReservationRepository
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
// 预约弹窗
|
||||
class ReserveDialogFragment : BaseTrackableDialogFragment() {
|
||||
class ReserveDialogFragment
|
||||
: BaseDialogFragment(), KeyboardHeightObserver {
|
||||
// : BaseTrackableDialogFragment() {
|
||||
|
||||
@BindView(R.id.reserve_hint_tv)
|
||||
lateinit var reserveHintTv: TextView
|
||||
|
||||
@BindView(R.id.reserve_content_tv)
|
||||
lateinit var reserveContentTv: TextView
|
||||
|
||||
@BindView(R.id.reserve_completed_content_tv)
|
||||
lateinit var reserveCompletedContentTv: TextView
|
||||
|
||||
@BindView(R.id.mobile_et)
|
||||
lateinit var mobileEt: EditText
|
||||
|
||||
@BindView(R.id.reserve_container)
|
||||
lateinit var reserveContainer: View
|
||||
|
||||
@BindView(R.id.reserve_completed_container)
|
||||
lateinit var reserveCompletedContainer: View
|
||||
|
||||
@BindView(R.id.customizable_btn)
|
||||
lateinit var customizableBtn: TextView
|
||||
|
||||
@BindView(R.id.content_container)
|
||||
lateinit var contentContainer: View
|
||||
|
||||
@BindView(R.id.mobile_index_container)
|
||||
lateinit var mobileIndexContainer: View
|
||||
|
||||
@BindView(R.id.mobile_index_reserve)
|
||||
lateinit var mobileIndexReserve: TextView
|
||||
|
||||
@BindView(R.id.mobile_index_user)
|
||||
lateinit var mobileIndexUser: TextView
|
||||
|
||||
@BindView(R.id.mobile_et_delete)
|
||||
lateinit var mobileEtDelete: View
|
||||
|
||||
@BindView(R.id.layout_container)
|
||||
lateinit var layoutContainer: View
|
||||
|
||||
private lateinit var mViewModel: ReserveViewModel
|
||||
|
||||
private var mSuccessCallback: SuccessCallback? = null
|
||||
|
||||
private var mGame: GameEntity? = null
|
||||
private var mGameId: String = ""
|
||||
private var mGameName: String = ""
|
||||
|
||||
private var mKeyboardHeightProvider: KeyboardHeightProvider? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
mViewModel = viewModelProvider()
|
||||
mKeyboardHeightProvider = KeyboardHeightProvider(activity)
|
||||
mKeyboardHeightProvider?.start()
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.dialog_reserve_game, null)
|
||||
}
|
||||
|
||||
override fun getEvent(): String {
|
||||
return "预约游戏"
|
||||
}
|
||||
|
||||
override fun getKey(): String {
|
||||
return "预约功能操作"
|
||||
}
|
||||
// override fun getEvent(): String {
|
||||
// return "预约游戏"
|
||||
// }
|
||||
//
|
||||
// override fun getKey(): String {
|
||||
// return "预约功能操作"
|
||||
// }
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@SuppressLint("SetTextI18n")
|
||||
@ -76,18 +119,27 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
ButterKnife.bind(this, view)
|
||||
|
||||
val reserveContent = "游戏上线,您将<font color='#ff4147'>免费</font>收到短信提醒"
|
||||
|
||||
val reserveContent = "游戏上线,您将收到<font color='#1383EB'>免费短信</font>提醒"
|
||||
reserveContentTv.text = Html.fromHtml(reserveContent)
|
||||
mobileEt.setText(UserManager.getInstance().userInfoEntity.mobile)
|
||||
mobileEt.setSelection(mobileEt.text.length)
|
||||
|
||||
|
||||
mobileEt.setTextChangedListener { s, _, _, _ ->
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
mobileEtDelete.goneIf(s.trim().isEmpty())
|
||||
}
|
||||
|
||||
mViewModel.reservation.observeNonNull(this) {
|
||||
if (it.success) {
|
||||
showSuccessDialog(it.withMobile, it.boundWechat)
|
||||
mSuccessCallback?.onSuccess()
|
||||
HistoryHelper.insertGameEntity(mGame!!)
|
||||
}
|
||||
}
|
||||
|
||||
mViewModel.reserveMobile.observe(viewLifecycleOwner, Observer {
|
||||
setMobileIndexHint(it)
|
||||
})
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(true)
|
||||
}
|
||||
|
||||
@ -106,7 +158,7 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
|
||||
} else {
|
||||
customizableBtn.text = dialogConfig?.text
|
||||
customizableBtn.setOnClickListener {
|
||||
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击跳转按钮")
|
||||
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击跳转按钮")
|
||||
DirectUtils.directToLinkPage(
|
||||
requireContext(),
|
||||
dialogConfig!!.toLinkEntity(),
|
||||
@ -117,38 +169,136 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setMobileIndexHint(reserveMobile: String?) {
|
||||
var userMobile = UserManager.getInstance().userInfoEntity.mobile
|
||||
if (reserveMobile == userMobile) userMobile = null
|
||||
|
||||
if (!reserveMobile.isNullOrEmpty()) {
|
||||
mobileIndexReserve.visibility = View.VISIBLE
|
||||
mobileIndexReserve.text = reserveMobile
|
||||
} else {
|
||||
mobileIndexReserve.visibility = View.GONE
|
||||
}
|
||||
|
||||
if (!userMobile.isNullOrEmpty()) {
|
||||
mobileIndexUser.visibility = View.VISIBLE
|
||||
mobileIndexUser.text = userMobile
|
||||
} else {
|
||||
mobileIndexUser.visibility = View.GONE
|
||||
}
|
||||
mobileIndexContainer.goneIf(mobileIndexUser.visibility == View.GONE && mobileIndexReserve.visibility == View.GONE)
|
||||
if (mobileIndexContainer.visibility ==View.VISIBLE) {
|
||||
mobileIndexContainer.animation = AnimationUtils.loadAnimation(requireContext(), R.anim.reserve_dialog_index_anim)
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.reserve_with_mobile_btn,
|
||||
R.id.reserve_without_mobile_btn,
|
||||
R.id.content_container,
|
||||
R.id.close_btn,
|
||||
R.id.customizable_btn)
|
||||
R.id.customizable_btn,
|
||||
R.id.mobile_index_reserve,
|
||||
R.id.mobile_index_user,
|
||||
R.id.mobile_et_delete,
|
||||
R.id.mobile_et,
|
||||
R.id.layout_container)
|
||||
fun onClick(view: View) {
|
||||
when (view.id) {
|
||||
R.id.reserve_without_mobile_btn -> {
|
||||
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击无手机号预约")
|
||||
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击无手机号预约")
|
||||
if (mobileIndexContainer.visibility == View.VISIBLE) {
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
mViewModel.reserve(gameId = mGameId, gameName = mGameName)
|
||||
}
|
||||
|
||||
R.id.reserve_with_mobile_btn -> {
|
||||
if (mobileIndexContainer.visibility == View.VISIBLE) {
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
val mobile = mobileEt.text.toString()
|
||||
if (mobile.length < 11 || !mobile.startsWith("1")) {
|
||||
Utils.toast(context, "手机号格式错误,请检查并重新输入")
|
||||
return
|
||||
}
|
||||
|
||||
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击立即预约")
|
||||
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击立即预约")
|
||||
mViewModel.reserve(gameId = mGameId, gameName = mGameName, mobile = mobile)
|
||||
}
|
||||
|
||||
R.id.close_btn -> {
|
||||
MtaHelper.onEvent("预约游戏", "预约功能操作", "点击关闭")
|
||||
// MtaHelper.onEvent("预约游戏", "预约功能操作", "点击关闭")
|
||||
dismissAllowingStateLoss()
|
||||
AppExecutor.uiExecutor.executeWithDelay(Runnable {
|
||||
NotificationHelper.showNotificationHintDialog(NotificationUgc.RESERVE_GAME)
|
||||
}, 1000)
|
||||
}
|
||||
R.id.content_container -> {
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
}
|
||||
R.id.mobile_index_reserve -> {
|
||||
mobileEt.setText(mobileIndexReserve.text.toString())
|
||||
mobileEt.setSelection(mobileEt.text.length)
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
}
|
||||
R.id.mobile_index_user -> {
|
||||
mobileEt.setText(mobileIndexUser.text.toString())
|
||||
mobileEt.setSelection(mobileEt.text.length)
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
}
|
||||
R.id.mobile_et_delete -> {
|
||||
mobileEt.setText("")
|
||||
}
|
||||
R.id.mobile_et -> {
|
||||
mobileIndexContainer.visibility = View.GONE
|
||||
}
|
||||
R.id.layout_container -> {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (HaloApp.getInstance().mCacheKeyboardHeight > 0) {
|
||||
val attributes = dialog?.window?.attributes
|
||||
val heightPixels = requireContext().resources.displayMetrics.heightPixels
|
||||
val mCacheKeyboardHeight = HaloApp.getInstance().mCacheKeyboardHeight
|
||||
val statusBarHeight = DisplayUtils.getStatusBarHeight(requireContext().resources)
|
||||
dialog?.window?.attributes?.height = heightPixels - mCacheKeyboardHeight - statusBarHeight
|
||||
attributes?.gravity = Gravity.TOP
|
||||
dialog?.window?.attributes = attributes
|
||||
}
|
||||
mKeyboardHeightProvider?.setKeyboardHeightObserver(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mKeyboardHeightProvider?.setKeyboardHeightObserver(null)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mKeyboardHeightProvider?.close()
|
||||
}
|
||||
|
||||
override fun onKeyboardHeightChanged(height: Int, orientation: Int) {
|
||||
if (height > 0) {
|
||||
val attributes = dialog?.window?.attributes
|
||||
attributes?.gravity = Gravity.CENTER
|
||||
dialog?.window?.attributes = attributes
|
||||
HaloApp.getInstance().mCacheKeyboardHeight = height
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(gameEntity: GameEntity, successCallback: SuccessCallback) = ReserveDialogFragment().apply {
|
||||
this.mGame = gameEntity
|
||||
this.mGameId = gameEntity.id
|
||||
this.mGameName = gameEntity.name ?: ""
|
||||
this.mSuccessCallback = successCallback
|
||||
@ -163,6 +313,12 @@ class ReserveDialogFragment : BaseTrackableDialogFragment() {
|
||||
class ReserveViewModel(application: Application) : AndroidViewModel(application) {
|
||||
val reservation = MutableLiveData<Reservation>()
|
||||
|
||||
val reserveMobile = MutableLiveData<String>()
|
||||
|
||||
init {
|
||||
getAppointmentMobile()
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun reserve(gameId: String, gameName: String, mobile: String = "") {
|
||||
|
||||
@ -185,7 +341,7 @@ class ReserveViewModel(application: Application) : AndroidViewModel(application)
|
||||
reservation.postValue(Reservation(success = true, withMobile = mobile.isNotEmpty(), boundWechat = boundWechat))
|
||||
ReservationRepository.addReservationToMemoryAndRefresh(gameId)
|
||||
|
||||
MtaHelper.onEvent("预约游戏", "预约", gameName)
|
||||
// MtaHelper.onEvent("预约游戏", "预约", gameName)
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
@ -194,5 +350,30 @@ class ReserveViewModel(application: Application) : AndroidViewModel(application)
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun getAppointmentMobile() {
|
||||
RetrofitManager.getInstance(getApplication()).api
|
||||
.getAppointmentMobile(UserManager.getInstance().userId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
var mobile: String? = null
|
||||
tryCatchInRelease {
|
||||
val jsonArray = JSONArray(data.string())
|
||||
if (jsonArray.length() > 0) {
|
||||
mobile = jsonArray.get(0).toString()
|
||||
}
|
||||
}
|
||||
|
||||
reserveMobile.postValue(mobile)
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
reserveMobile.postValue(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
class Reservation(var success: Boolean = false, var withMobile: Boolean = false, var boundWechat: Boolean = false)
|
||||
}
|
||||
@ -8,12 +8,13 @@ import com.gh.common.util.MtaHelper
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
open class TrackableDialog(context: Context,
|
||||
themeResId: Int,
|
||||
private var mEvent: String,
|
||||
private var mKey: String,
|
||||
private var mCancelValue: String? = null,
|
||||
private var mKeyBackValue: String? = null,
|
||||
private var mLogShowEvent: Boolean = true)
|
||||
themeResId: Int,
|
||||
private var mEvent: String,
|
||||
private var mKey: String,
|
||||
private var mValue: String? = null,
|
||||
private var mCancelValue: String? = null,
|
||||
private var mKeyBackValue: String? = null,
|
||||
private var mLogShowEvent: Boolean = true)
|
||||
: Dialog(context, themeResId) {
|
||||
|
||||
// 区分此 dialog 是点击 dialog 外部取消的还是点击返回取消的
|
||||
@ -25,6 +26,9 @@ open class TrackableDialog(context: Context,
|
||||
setOnCancelListener {
|
||||
if (mIsCanceledByClickOutsideOfDialog.get()) {
|
||||
MtaHelper.onEvent(mEvent, mKey, mCancelValue ?: "点击空白")
|
||||
if (!mValue.isNullOrEmpty()) {
|
||||
MtaHelper.onEvent(mEvent, "点击空白", mValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +36,9 @@ open class TrackableDialog(context: Context,
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
|
||||
mIsCanceledByClickOutsideOfDialog.set(false)
|
||||
MtaHelper.onEvent(mEvent, mKey, mKeyBackValue ?: "点击返回")
|
||||
if (mValue != null) {
|
||||
MtaHelper.onEvent(mEvent, "点击返回", mValue)
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
@ -41,6 +48,9 @@ open class TrackableDialog(context: Context,
|
||||
super.show()
|
||||
if (mLogShowEvent) {
|
||||
MtaHelper.onEvent(mEvent, mKey, "出现弹窗")
|
||||
if (!mValue.isNullOrEmpty()) {
|
||||
MtaHelper.onEvent(mEvent, "出现弹窗", mValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,15 @@ data class ExposureEntity(
|
||||
@SerializedName("game_id")
|
||||
val gameId: String? = "",
|
||||
val gameName: String? = "",
|
||||
val gameVersion: String? = "",
|
||||
val sequence: Int? = 0,
|
||||
val platform: String? = "",
|
||||
val downloadType: String? = "",
|
||||
val downloadCompleteType: String? = ""
|
||||
val downloadCompleteType: String? = "",
|
||||
|
||||
// 统计启动弹窗相关数据用的 (ugly)
|
||||
@SerializedName("dialog_id")
|
||||
var welcomeDialogId: String? = "",
|
||||
@SerializedName("link_title")
|
||||
var welcomeDialogLinkTitle: String? = ""
|
||||
) : Parcelable
|
||||
@ -4,9 +4,11 @@ import android.os.Parcelable
|
||||
import androidx.annotation.Keep
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.meta.Meta
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.exposure.time.TimeUtil
|
||||
import com.gh.common.util.getFirstElementDividedByDivider
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import java.util.*
|
||||
@ -26,13 +28,21 @@ data class ExposureEvent(
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createEvent(gameEntity: GameEntity?, source: List<ExposureSource>, eTrace: List<ExposureEvent>? = null, event: ExposureType = ExposureType.EXPOSURE): ExposureEvent {
|
||||
if (gameEntity?.getApk()?.size == 1) {
|
||||
gameEntity.gameVersion = gameEntity.getApk().elementAtOrNull(0)?.version ?: ""
|
||||
}
|
||||
return ExposureEvent(
|
||||
payload = ExposureEntity(gameId = gameEntity?.id,
|
||||
gameName = gameEntity?.name,
|
||||
payload = ExposureEntity(
|
||||
gameId = gameEntity?.id?.getFirstElementDividedByDivider(Constants.GAME_ID_DIVIDER),
|
||||
gameName = gameEntity?.name?.removeSuffix(Constants.GAME_NAME_DECORATOR),
|
||||
gameVersion = gameEntity?.gameVersion,
|
||||
sequence = gameEntity?.sequence,
|
||||
platform = gameEntity?.platform,
|
||||
downloadType = gameEntity?.downloadType,
|
||||
downloadCompleteType = gameEntity?.downloadCompleteType),
|
||||
downloadCompleteType = gameEntity?.downloadCompleteType,
|
||||
// ugly
|
||||
welcomeDialogId = gameEntity?.welcomeDialogId ?: eTrace?.firstOrNull()?.payload?.welcomeDialogId,
|
||||
welcomeDialogLinkTitle = gameEntity?.welcomeDialogTitle ?: eTrace?.firstOrNull()?.payload?.welcomeDialogLinkTitle),
|
||||
source = source,
|
||||
eTrace = eTrace,
|
||||
event = event).apply { gameEntity?.exposureEvent = this }
|
||||
|
||||
@ -26,6 +26,10 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
visibleState?.let { commitExposure(it) }
|
||||
throttleBus?.clear()
|
||||
}
|
||||
|
||||
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {
|
||||
fragment.fragmentManager?.unregisterFragmentLifecycleCallbacks(this)
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@ import com.gh.loghub.LoghubHelper
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
/**
|
||||
* A handful tool for committing logs to aliyun loghub.
|
||||
@ -17,7 +16,7 @@ import kotlin.concurrent.fixedRateTimer
|
||||
* 如何简单地统计列表中每个 item 的曝光事件?
|
||||
*
|
||||
* 1. Adapter 实现 IExposable 接口,在 BindView 阶段更新 ExposureEvent,ExposureEvent 供 getEventByPosition(pos) 方法获取用
|
||||
* 2. 构建一个 ExposureListener 并作为入参添加至 recyclerview 的 Scroll 回调中
|
||||
* 2. 构建一个 ExposureListener 并作为入参添加至 recyclerview 的 onScroll 回调中
|
||||
* 3. 没了
|
||||
*/
|
||||
object ExposureManager {
|
||||
@ -25,31 +24,24 @@ object ExposureManager {
|
||||
private const val ENDPOINT = "cn-qingdao.log.aliyuncs.com"
|
||||
private const val PROJECT = "ghzs"
|
||||
private const val STORE_SIZE = 100
|
||||
private const val STORE_FORCE_UPLOAD_PERIOD = 300 * 1000L
|
||||
private const val LOG_STORE = BuildConfig.EXPOSURE_REPO
|
||||
|
||||
private val loghubHelper = LoghubHelper.getInstance()
|
||||
|
||||
// exposureCache 用来过滤掉具有相同 id 的曝光事件,避免重复发送事件
|
||||
private val exposureSet = hashSetOf<ExposureEvent>()
|
||||
private val exposureExecutor = Executors.newSingleThreadExecutor()
|
||||
private val exposureCache = FixedSizeLinkedHashSet<String>(300)
|
||||
private val exposureSet by lazy { hashSetOf<ExposureEvent>() }
|
||||
private val exposureExecutor by lazy { Executors.newSingleThreadExecutor() }
|
||||
private val exposureCache by lazy { FixedSizeLinkedHashSet<String>(300) }
|
||||
private val exposureDao by lazy { ExposureDatabase.buildDatabase(HaloApp.getInstance().application).logHubEventDao() }
|
||||
|
||||
@JvmStatic
|
||||
fun init() {
|
||||
TimeUtil.init()
|
||||
|
||||
loghubHelper.init(HaloApp.getInstance().application, ENDPOINT, PROJECT, LOG_STORE) { TimeUtil.currentTimeMillis() }
|
||||
|
||||
exposureExecutor.execute {
|
||||
val eventList = exposureDao.getAll()
|
||||
exposureSet.addAll(eventList)
|
||||
}
|
||||
|
||||
fixedRateTimer(name = "ExposureManager-Store-Checker", initialDelay = 500, period = STORE_FORCE_UPLOAD_PERIOD) {
|
||||
commitSavedExposureEvents(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package com.gh.common.exposure
|
||||
|
||||
import android.text.TextUtils
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.common.util.toObject
|
||||
import com.gh.gamecenter.entity.ApkEntity
|
||||
@ -15,6 +18,12 @@ object ExposureUtils {
|
||||
traceEvent: ExposureEvent?,
|
||||
downloadType: DownloadType): ExposureEvent {
|
||||
val gameEntity = entity.clone()
|
||||
gameEntity.id = if (entity.id.contains(Constants.GAME_ID_DIVIDER)) {
|
||||
entity.id.split(Constants.GAME_ID_DIVIDER).toTypedArray()[0]
|
||||
} else {
|
||||
entity.id
|
||||
}
|
||||
gameEntity.gameVersion = entity.getApk().elementAtOrNull(0)?.version ?: gameEntity.gameVersion
|
||||
gameEntity.platform = platform
|
||||
gameEntity.downloadType = downloadType.toString()
|
||||
val exposureEvent = ExposureEvent.createEvent(gameEntity = gameEntity,
|
||||
@ -43,29 +52,30 @@ object ExposureUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getDownloadType(apkEntity: ApkEntity, method: String) : DownloadType {
|
||||
return if ("更新" == method) {
|
||||
if (PackageUtils.isSignature(HaloApp.getInstance().application, apkEntity.packageName)) {
|
||||
DownloadType.PLUGIN_UPDATE
|
||||
fun getDownloadType(apkEntity: ApkEntity, gameId: String): DownloadType {
|
||||
return if (PackageUtils.isInstalled(HaloApp.getInstance().application, apkEntity.packageName)) {
|
||||
if (PackageUtils.isSignedByGh(HaloApp.getInstance().application, apkEntity.packageName)) {
|
||||
if (PackageUtils.isCanUpdate(apkEntity, gameId)) {
|
||||
DownloadType.PLUGIN_UPDATE
|
||||
} else {
|
||||
if (Version(apkEntity.version).isHigherThan(PackageUtils.getVersionByPackage(apkEntity.packageName))) {
|
||||
DownloadType.UPDATE
|
||||
} else {
|
||||
DownloadType.DOWNLOAD
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DownloadType.UPDATE
|
||||
if (!TextUtils.isEmpty(apkEntity.ghVersion)) {
|
||||
DownloadType.PLUGIN_DOWNLOAD
|
||||
} else {
|
||||
DownloadType.UPDATE
|
||||
}
|
||||
}
|
||||
} else if ("插件化" == method) {
|
||||
DownloadType.PLUGIN_DOWNLOAD
|
||||
} else {
|
||||
DownloadType.DOWNLOAD
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getUpdateType(apkEntity: ApkEntity) : DownloadType {
|
||||
return if (PackageUtils.isSignature(HaloApp.getInstance().application, apkEntity.packageName)) {
|
||||
DownloadType.PLUGIN_UPDATE
|
||||
} else {
|
||||
DownloadType.UPDATE
|
||||
}
|
||||
}
|
||||
|
||||
enum class DownloadType {
|
||||
DOWNLOAD,
|
||||
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
package com.gh.common.exposure.time
|
||||
|
||||
import com.gh.gamecenter.entity.TimeEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
class Corrector {
|
||||
|
||||
companion object {
|
||||
const val TIME_CORRECTOR_ADJUST_PERIOD: Long = 600000
|
||||
}
|
||||
|
||||
var delta: Long = 0
|
||||
|
||||
init {
|
||||
fixedRateTimer("TimeUtil-Corrector-Checker", initialDelay = 0, period = TIME_CORRECTOR_ADJUST_PERIOD) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Response<TimeEntity>() {
|
||||
override fun onResponse(response: TimeEntity?) {
|
||||
val serverTime = response?.time
|
||||
serverTime?.let { delta = it * 1000 - System.currentTimeMillis() }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,23 +1,15 @@
|
||||
package com.gh.common.exposure.time
|
||||
|
||||
import com.gh.common.FixedRateJobHelper
|
||||
|
||||
object TimeUtil {
|
||||
|
||||
private lateinit var corrector: Corrector
|
||||
|
||||
fun init() {
|
||||
corrector = Corrector()
|
||||
}
|
||||
|
||||
fun currentTimeMillis(): Long {
|
||||
return corrector.delta + System.currentTimeMillis()
|
||||
return FixedRateJobHelper.timeDeltaBetweenServerAndClient + System.currentTimeMillis()
|
||||
}
|
||||
|
||||
fun currentTime(): Int {
|
||||
return if (::corrector.isInitialized) {
|
||||
((corrector.delta + System.currentTimeMillis()) / 1000).toInt()
|
||||
} else {
|
||||
(System.currentTimeMillis() / 1000).toInt()
|
||||
}
|
||||
return ((FixedRateJobHelper.timeDeltaBetweenServerAndClient + System.currentTimeMillis()) / 1000).toInt()
|
||||
}
|
||||
|
||||
}
|
||||
21
app/src/main/java/com/gh/common/filter/RegionSetting.kt
Normal file
21
app/src/main/java/com/gh/common/filter/RegionSetting.kt
Normal file
@ -0,0 +1,21 @@
|
||||
package com.gh.common.filter
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@Keep
|
||||
data class RegionSetting(
|
||||
@SerializedName("game_mirror")
|
||||
var mirrorGameIdSet: HashSet<String>,
|
||||
@SerializedName("game_block")
|
||||
var filterGameIdSet: HashSet<String>,
|
||||
@SerializedName("channel_control")
|
||||
var channelControl: ChannelControl) {
|
||||
|
||||
@Keep
|
||||
data class ChannelControl(
|
||||
@SerializedName("game_category")
|
||||
var gameCategory: String,
|
||||
@SerializedName("effect")
|
||||
var effect: Boolean)
|
||||
}
|
||||
101
app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt
Normal file
101
app/src/main/java/com/gh/common/filter/RegionSettingHelper.kt
Normal file
@ -0,0 +1,101 @@
|
||||
package com.gh.common.filter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.common.util.debounceActionWithInterval
|
||||
import com.gh.common.util.toJson
|
||||
import com.gh.common.util.toObject
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.functions.Function
|
||||
|
||||
object RegionSettingHelper {
|
||||
|
||||
private var mChannelControl: RegionSetting.ChannelControl? = null
|
||||
private var mFilterGameIdSet: HashSet<String>? = hashSetOf()
|
||||
private var mDisplayMirrorIfoGameIdSet: HashSet<String>? = hashSetOf()
|
||||
|
||||
private const val SP_SETTING = "region_setting"
|
||||
|
||||
fun shouldThisGameDisplayMirrorInfo(gameId: String): Boolean {
|
||||
return mDisplayMirrorIfoGameIdSet?.contains(gameId) ?: false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun shouldThisGameBeFiltered(gameId: String?): Boolean {
|
||||
return mFilterGameIdSet?.contains(gameId) ?: false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun filterGame(list: List<GameEntity>?): ArrayList<GameEntity> {
|
||||
if (list == null) return arrayListOf()
|
||||
|
||||
if (mFilterGameIdSet?.isEmpty() == true) {
|
||||
if (list is ArrayList) return list
|
||||
}
|
||||
|
||||
val listCopy: ArrayList<GameEntity> = if (list is ArrayList) list else ArrayList(list)
|
||||
listCopy.removeAll { mFilterGameIdSet?.contains(it.id) ?: false }
|
||||
return listCopy
|
||||
}
|
||||
|
||||
@JvmField
|
||||
var filterGame = Function { list: List<GameEntity> ->
|
||||
filterGame(list)
|
||||
list
|
||||
}
|
||||
|
||||
fun shouldGameOfThisCategoryUseMirrorInfo(category: String): Boolean {
|
||||
return if (mChannelControl == null || mChannelControl?.effect == false || !isUserUsedLessThan24Hours()) {
|
||||
false
|
||||
} else {
|
||||
mChannelControl?.gameCategory == category
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getRegionSetting() {
|
||||
debounceActionWithInterval(R.string.name, 3000) {
|
||||
// 使用默认的 Schdulers.io() 可能会触发 OOM
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.sensitiveApi
|
||||
.getRegionSetting(HaloApp.getInstance().channel)
|
||||
.subscribeOn(AppExecutor.cachedScheduler)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<RegionSetting>() {
|
||||
override fun onSuccess(data: RegionSetting) {
|
||||
updateSettingsInMemory(data)
|
||||
SPUtils.setString(SP_SETTING, data.toJson())
|
||||
}
|
||||
|
||||
override fun onFailure(exception: Exception) {
|
||||
SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
|
||||
updateSettingsInMemory(it)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSettingsInMemory(data: RegionSetting) {
|
||||
mFilterGameIdSet = data.filterGameIdSet
|
||||
mDisplayMirrorIfoGameIdSet = data.mirrorGameIdSet
|
||||
mChannelControl = data.channelControl
|
||||
}
|
||||
|
||||
/**
|
||||
* 该用户是否是使用了不到 24 小时的新用户
|
||||
*/
|
||||
private fun isUserUsedLessThan24Hours(): Boolean {
|
||||
val initialUsageTime = SPUtils.getLong(Constants.SP_INITIAL_USAGE_TIME, 0)
|
||||
return !(initialUsageTime == 0L || System.currentTimeMillis() - initialUsageTime > 86400000)
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ import com.gh.gamecenter.room.converter.*
|
||||
import com.gh.gamecenter.room.dao.*
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class], version = 5, exportSchema = false)
|
||||
@Database(entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class], version = 7, exportSchema = false)
|
||||
@TypeConverters(CountConverter::class,
|
||||
CommunityConverter::class,
|
||||
TimeConverter::class,
|
||||
@ -23,7 +23,8 @@ import com.halo.assistant.HaloApp
|
||||
ThumbnailConverter::class,
|
||||
TagStyleListConverter::class,
|
||||
StringArrayListConverter::class,
|
||||
CommunityVideoConverter::class)
|
||||
CommunityVideoConverter::class,
|
||||
UserConverter::class)
|
||||
|
||||
abstract class HistoryDatabase : RoomDatabase() {
|
||||
|
||||
@ -54,11 +55,27 @@ abstract class HistoryDatabase : RoomDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_5_6: Migration = object : Migration(5, 6) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("Alter TABLE MyVideoEntity add title TEXT NOT NULL DEFAULT ''")
|
||||
database.execSQL("Alter TABLE MyVideoEntity add commentCount INTEGER NOT NULL DEFAULT 0")
|
||||
database.execSQL("Alter TABLE MyVideoEntity add user TEXT NOT NULL DEFAULT ''")
|
||||
}
|
||||
}
|
||||
|
||||
val MIGRATION_6_7: Migration = object : Migration(6, 7) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("Alter TABLE HistoryGameEntity add iconSubscript TEXT DEFAULT ''")
|
||||
}
|
||||
}
|
||||
|
||||
val instance by lazy {
|
||||
Room.databaseBuilder(HaloApp.getInstance().application, HistoryDatabase::class.java, "USER_TRACK_HISTORY_DATABASE")
|
||||
.addMigrations(MIGRATION_2_3)
|
||||
.addMigrations(MIGRATION_3_4)
|
||||
.addMigrations(MIGRATION_4_5)
|
||||
.addMigrations(MIGRATION_5_6)
|
||||
.addMigrations(MIGRATION_6_7)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,7 @@ import com.gh.common.runOnIoThread
|
||||
import com.gh.common.util.clearHtmlFormatCompletely
|
||||
import com.gh.common.util.removeInsertedContent
|
||||
import com.gh.common.util.removeVideoContent
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.HistoryGameEntity
|
||||
import com.gh.gamecenter.entity.NewsEntity
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
|
||||
import com.gh.gamecenter.qa.entity.AnswerEntity
|
||||
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
|
||||
@ -24,11 +22,33 @@ object HistoryHelper {
|
||||
runOnIoThread { HistoryDatabase.instance.articleDao().addArticle(articleEntity) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun insertGameEntity(gameEntity: GameEntity) {
|
||||
val historyGameEntity = convertGameEntityToHistoryGameEntity(gameEntity)
|
||||
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun insertGameEntity(updateEntity: GameUpdateEntity) {
|
||||
val historyGameEntity = convertGameUpdateEntityToHistoryGameEntity(updateEntity)
|
||||
runOnIoThread { HistoryDatabase.instance.gameDao().addGame(historyGameEntity) }
|
||||
}
|
||||
|
||||
private fun convertGameUpdateEntityToHistoryGameEntity(updateEntity: GameUpdateEntity): HistoryGameEntity{
|
||||
val historyGame = HistoryGameEntity()
|
||||
|
||||
historyGame.orderTag = System.currentTimeMillis()
|
||||
historyGame.id = updateEntity.id
|
||||
historyGame.brief = updateEntity.brief
|
||||
historyGame.des = ""
|
||||
historyGame.icon = updateEntity.rawIcon ?: updateEntity.icon
|
||||
historyGame.iconSubscript = historyGame.iconSubscript
|
||||
historyGame.name = updateEntity.name
|
||||
historyGame.tagStyle = updateEntity.tagStyle
|
||||
historyGame.tag = updateEntity.tag
|
||||
return historyGame
|
||||
}
|
||||
|
||||
private fun convertGameEntityToHistoryGameEntity(gameEntity: GameEntity): HistoryGameEntity {
|
||||
val historyGame = HistoryGameEntity()
|
||||
|
||||
@ -36,11 +56,11 @@ object HistoryHelper {
|
||||
historyGame.id = gameEntity.id
|
||||
historyGame.brief = gameEntity.brief
|
||||
historyGame.des = gameEntity.des
|
||||
historyGame.icon = gameEntity.icon
|
||||
historyGame.icon = gameEntity.rawIcon ?: gameEntity.icon
|
||||
historyGame.iconSubscript = gameEntity.iconSubscript
|
||||
historyGame.name = gameEntity.name
|
||||
historyGame.tagStyle = gameEntity.tagStyle
|
||||
historyGame.tag = gameEntity.getTag()
|
||||
historyGame.isLibaoExist = gameEntity.isLibaoExists
|
||||
return historyGame
|
||||
}
|
||||
|
||||
@ -70,6 +90,11 @@ object HistoryHelper {
|
||||
runOnIoThread { HistoryDatabase.instance.answerDao().deleteAnswer(AnswerEntity().apply { primaryKey = answerId }) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteVideoEntity(videoId: String) {
|
||||
runOnIoThread { HistoryDatabase.instance.videoHistoryDao().deleteVideo(MyVideoEntity().apply { id = videoId }) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun emptyDatabase() {
|
||||
runOnIoThread { HistoryDatabase.instance.clearAllTables() }
|
||||
@ -85,6 +110,7 @@ object HistoryHelper {
|
||||
clearHtmlFormatCompletely().
|
||||
replace(" +".toRegex()," ")
|
||||
articleEntity.count = articleDetailEntity.count
|
||||
articleDetailEntity.community.id = articleDetailEntity.communityId
|
||||
articleEntity.community = articleDetailEntity.community
|
||||
articleEntity.time = articleDetailEntity.time
|
||||
articleEntity.title = articleDetailEntity.title
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
package com.gh.common.iinterface
|
||||
|
||||
interface IScrollable {
|
||||
fun scrollToTop()
|
||||
}
|
||||
@ -10,6 +10,7 @@ import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.gh.base.CurrentActivityHolder
|
||||
import com.gh.common.util.doOnMainProcessOnly
|
||||
import com.gh.gamecenter.R
|
||||
import com.m7.imkfsdk.chat.ChatActivity
|
||||
import com.m7.imkfsdk.utils.Utils
|
||||
@ -25,51 +26,53 @@ class ImReceiver : BroadcastReceiver() {
|
||||
var notificationManager: NotificationManager? = null
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
intent?.let {
|
||||
if (intent.action == IMChatManager.NEW_MSG_ACTION) {
|
||||
notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// 判断 ImActivity 是否在最顶端
|
||||
if (CurrentActivityHolder.getCurrentActivity() is ChatActivity) {
|
||||
ImManager.showFloatingWindow()
|
||||
ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
} else {
|
||||
val contentIntent = Intent(Utils.getApp(), ChatActivity::class.java)
|
||||
|
||||
contentIntent.putExtra("PeerId", "")
|
||||
contentIntent.putExtra("type", "peedId")
|
||||
|
||||
contentIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val resultPendingIntent = PendingIntent.getActivity(
|
||||
Utils.getApp(),
|
||||
0,
|
||||
contentIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
// 新的通知
|
||||
val builder = NotificationCompat.Builder(Utils.getApp(), "Halo_IM")
|
||||
val notification = builder.setTicker("您有新的消息")
|
||||
.setDefaults(Notification.DEFAULT_ALL)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setContentIntent(resultPendingIntent)
|
||||
.setContentTitle("光环助手客服回复")
|
||||
.setContentText("您有新的消息")
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel("Halo_IM", "Halo_IM", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
notificationManager?.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
if (notification != null) {
|
||||
notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||
context?.doOnMainProcessOnly {
|
||||
intent?.let {
|
||||
if (intent.action == IMChatManager.NEW_MSG_ACTION) {
|
||||
notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// 判断 ImActivity 是否在最顶端
|
||||
if (CurrentActivityHolder.getCurrentActivity() is ChatActivity) {
|
||||
ImManager.showFloatingWindow()
|
||||
ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
} else {
|
||||
val contentIntent = Intent(Utils.getApp(), ChatActivity::class.java)
|
||||
|
||||
contentIntent.putExtra("PeerId", "")
|
||||
contentIntent.putExtra("type", "peedId")
|
||||
|
||||
contentIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val resultPendingIntent = PendingIntent.getActivity(
|
||||
Utils.getApp(),
|
||||
0,
|
||||
contentIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
// 新的通知
|
||||
val builder = NotificationCompat.Builder(Utils.getApp(), "Halo_IM")
|
||||
val notification = builder.setTicker("您有新的消息")
|
||||
.setDefaults(Notification.DEFAULT_ALL)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setContentIntent(resultPendingIntent)
|
||||
.setContentTitle("光环助手客服回复")
|
||||
.setContentText("您有新的消息")
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel("Halo_IM", "Halo_IM", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
notificationManager?.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
if (notification != null) {
|
||||
notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||
ImManager.showFloatingWindow()
|
||||
}
|
||||
}
|
||||
} else if (intent.action == IMChatManager.FINISH_ACTION) {
|
||||
ImManager.dismissFloatingWindow()
|
||||
}
|
||||
} else if (intent.action == IMChatManager.FINISH_ACTION) {
|
||||
ImManager.dismissFloatingWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
package com.gh.common.loghub
|
||||
|
||||
import android.app.Application
|
||||
import androidx.annotation.Keep
|
||||
import com.aliyun.sls.android.sdk.model.Log
|
||||
import com.aliyun.sls.android.sdk.model.LogGroup
|
||||
import com.gh.common.exposure.ExposureEntity
|
||||
import com.gh.common.exposure.meta.Meta
|
||||
import com.gh.loghub.LoghubHelper
|
||||
import org.json.JSONObject
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
object LoghubUtils {
|
||||
|
||||
private const val STORE_SIZE = 100
|
||||
private const val STORE_FORCE_UPLOAD_INTERVAL = 120 * 1000L
|
||||
|
||||
private lateinit var mApplication: Application
|
||||
|
||||
private val loghubEventSet = hashSetOf<LoghubEvent>()
|
||||
private val loghubEventSet by lazy { hashSetOf<LoghubEvent>() }
|
||||
private val loghubEventExecutor by lazy { Executors.newSingleThreadExecutor() }
|
||||
private val loghubEventDao by lazy { LoghubDatabase.buildDatabase(mApplication).logHubEventDao() }
|
||||
|
||||
@ -27,10 +27,6 @@ object LoghubUtils {
|
||||
val eventList = loghubEventDao.getAll()
|
||||
loghubEventSet.addAll(eventList)
|
||||
}
|
||||
|
||||
fixedRateTimer(name = "Loghub-Event-Checker", initialDelay = 1000, period = STORE_FORCE_UPLOAD_INTERVAL) {
|
||||
commitSavedLoghubEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -50,11 +46,28 @@ object LoghubUtils {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun log(jsonString: String, logStore: String, forcedUpload: Boolean) {
|
||||
loghubEventExecutor.execute {
|
||||
try {
|
||||
val event = LoghubEvent(time = (System.currentTimeMillis() / 1000L).toString(), content = jsonString, logStore = logStore)
|
||||
loghubEventSet.add(event)
|
||||
loghubEventDao.insert(event)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
if (forcedUpload || loghubEventSet.size >= STORE_SIZE) {
|
||||
commitSavedLoghubEvents()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uploadLogGroup(logGroup: LogGroup, logStore: String) {
|
||||
LoghubHelper.getInstance().uploadLogGroup(logGroup, logStore)
|
||||
}
|
||||
|
||||
private fun commitSavedLoghubEvents() {
|
||||
fun commitSavedLoghubEvents() {
|
||||
loghubEventExecutor.execute {
|
||||
if (loghubEventSet.isEmpty()) return@execute
|
||||
|
||||
@ -75,8 +88,16 @@ object LoghubUtils {
|
||||
}
|
||||
|
||||
val log = Log()
|
||||
log.PutContent("current time ", event.time)
|
||||
log.PutContent("content", event.content)
|
||||
// 特殊处理,以下logStore不需要用content包裹数据
|
||||
if (event.logStore == "collection" || event.logStore == "common" || event.logStore == "halo-api-device-installed") {
|
||||
val contentJson = JSONObject(event.content)
|
||||
for (key in contentJson.keys()) {
|
||||
log.PutContent(key, contentJson.get(key).toString())
|
||||
}
|
||||
} else {
|
||||
log.PutContent("current time ", event.time)
|
||||
log.PutContent("content", event.content)
|
||||
}
|
||||
logGroupHashMap[event.logStore]?.PutLog(log)
|
||||
}
|
||||
|
||||
@ -85,4 +106,12 @@ object LoghubUtils {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
data class SimpleLogContainerEntity(
|
||||
var event: String? = null,
|
||||
var action: String? = null,
|
||||
var meta: Meta? = null,
|
||||
var payload: ExposureEntity? = null,
|
||||
var timestamp: Long? = 0)
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.repository
|
||||
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.common.util.ApkActiveUtils
|
||||
import com.gh.common.util.RandomUtils
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
@ -15,7 +16,8 @@ object RemenkapaiRepository {
|
||||
@JvmStatic
|
||||
fun getRemenkapai(size: Int): Observable<List<GameEntity>> {
|
||||
return if (remenkapaiList.isEmpty()) {
|
||||
RetrofitManager.getInstance(getApplication()).api.remenkapai
|
||||
RetrofitManager.getInstance(getApplication()).sensitiveApi.remenkapai
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map { gameList -> filterEntityWithoutApk(gameList) }
|
||||
.map { pickRandomSizeEntity(size) }
|
||||
.map(ApkActiveUtils.filterMapperList)
|
||||
|
||||
@ -5,13 +5,19 @@ object SyncFieldConstants {
|
||||
// 是否点赞
|
||||
const val ANSWER_VOTE = "ANSWER_VOTE"
|
||||
const val ARTICLE_VOTE = "ARTICLE_VOTE"
|
||||
const val ARTICLE_COMMENT_VOTE = "ARTICLE_COMMENT_VOTE"
|
||||
|
||||
// 赞同数量
|
||||
const val ANSWER_VOTE_COUNT = "ANSWER_VOTE_COUNT"
|
||||
const val ARTICLE_VOTE_COUNT = "ARTICLE_VOTE_COUNT"
|
||||
const val ARTICLE_COMMENT_VOTE_COUNT = "ARTICLE_COMMENT_VOTE_COUNT"
|
||||
|
||||
// 评论数量
|
||||
const val ANSWER_COMMENT_COUNT = "ANSWER_COMMENT_COUNT"
|
||||
const val ARTICLE_COMMENT_COUNT = "ARTICLE_COMMENT_COUNT"
|
||||
const val ARTICLE_COMMENT_REPLY_COUNT = "ARTICLE_COMMENT_REPLY_COUNT"
|
||||
|
||||
// 回答数量
|
||||
const val ANSWER_COUNT = "ANSWER_COUNT"
|
||||
|
||||
}
|
||||
14
app/src/main/java/com/gh/common/util/AntiBotHelper.kt
Normal file
14
app/src/main/java/com/gh/common/util/AntiBotHelper.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.alibaba.wireless.security.jaq.avmp.IJAQAVMPSignComponent
|
||||
import com.alibaba.wireless.security.open.SecurityGuardManager
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object AntiBotHelper {
|
||||
@JvmStatic
|
||||
val manager by lazy {
|
||||
SecurityGuardManager.getInstance(HaloApp.getInstance().application).getInterface(IJAQAVMPSignComponent::class.java).apply {
|
||||
this.initialize()
|
||||
}
|
||||
}
|
||||
}
|
||||
6
app/src/main/java/com/gh/common/util/BiCallback.kt
Normal file
6
app/src/main/java/com/gh/common/util/BiCallback.kt
Normal file
@ -0,0 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
interface BiCallback<FIRST, SECOND> {
|
||||
fun onFirst(first: FIRST)
|
||||
fun onSecond(second: SECOND)
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.gamecenter.room.AppDatabase
|
||||
import com.gh.gamecenter.room.dao.CommentDraftDao
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object CommentDraftContainer {
|
||||
val commentDraftDao: CommentDraftDao by lazy { AppDatabase.getInstance(HaloApp.getInstance().application).commentDraftDao() }
|
||||
}
|
||||
@ -1,14 +1,19 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.gh.common.util.CommentUtils.copyText
|
||||
import com.gh.common.view.BugFixedPopupWindow
|
||||
import com.gh.gamecenter.CommentDetailActivity
|
||||
import com.gh.gamecenter.MessageDetailActivity
|
||||
import com.gh.gamecenter.adapter.OnCommentCallBackListener
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.CommentEntity
|
||||
import com.gh.gamecenter.entity.MeEntity
|
||||
import com.gh.gamecenter.entity.Permissions
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.qa.comment.OnCommentOptionClickListener
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.lightgame.utils.Utils
|
||||
@ -23,27 +28,29 @@ import retrofit2.HttpException
|
||||
object CommentHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun showCommunityArticleCommentOptions(context: Context,
|
||||
fun showCommunityArticleCommentOptions(view: View,
|
||||
commentEntity: CommentEntity,
|
||||
showConversation: Boolean,
|
||||
articleId: String,
|
||||
communityId: String,
|
||||
listener: OnCommentCallBackListener?) {
|
||||
showCommentOptions(context = context,
|
||||
ignoreModerator: Boolean = false,
|
||||
listener: OnCommentOptionClickListener?) {
|
||||
showCommentOptions(view = view,
|
||||
commentEntity = commentEntity,
|
||||
showConversation = showConversation,
|
||||
articleId = articleId,
|
||||
communityId = communityId,
|
||||
ignoreModerator = ignoreModerator,
|
||||
listener = listener)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showAnswerCommentOptions(context: Context,
|
||||
fun showAnswerCommentOptions(view: View,
|
||||
commentEntity: CommentEntity,
|
||||
showConversation: Boolean,
|
||||
answerId: String,
|
||||
listener: OnCommentCallBackListener?) {
|
||||
showCommentOptions(context = context,
|
||||
listener: OnCommentOptionClickListener?) {
|
||||
showCommentOptions(view = view,
|
||||
commentEntity = commentEntity,
|
||||
showConversation = showConversation,
|
||||
answerId = answerId,
|
||||
@ -51,31 +58,41 @@ object CommentHelper {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showVideoCommentOptions(context: Context,
|
||||
fun showVideoCommentOptions(view: View,
|
||||
commentEntity: CommentEntity,
|
||||
showConversation: Boolean,
|
||||
videoId: String,
|
||||
listener: OnCommentCallBackListener?) {
|
||||
showCommentOptions(context = context,
|
||||
isVideoAuthor: Boolean,
|
||||
listener: OnCommentOptionClickListener?) {
|
||||
showCommentOptions(view = view,
|
||||
commentEntity = commentEntity,
|
||||
showConversation = showConversation,
|
||||
videoId = videoId,
|
||||
isVideoAuthor = isVideoAuthor,
|
||||
listener = listener)
|
||||
}
|
||||
|
||||
private fun showCommentOptions(context: Context,
|
||||
private fun showCommentOptions(view: View,
|
||||
commentEntity: CommentEntity,
|
||||
showConversation: Boolean,
|
||||
articleId: String? = null,
|
||||
communityId: String? = null,
|
||||
answerId: String? = null,
|
||||
videoId: String? = null,
|
||||
listener: OnCommentCallBackListener? = null) {
|
||||
ignoreModerator: Boolean = false,
|
||||
isVideoAuthor: Boolean = false,
|
||||
listener: OnCommentOptionClickListener? = null) {
|
||||
val context = view.context
|
||||
val dialogOptions = ArrayList<String>()
|
||||
if (isVideoAuthor || (videoId != null && commentEntity.user.id == UserManager.getInstance().userId)) {
|
||||
dialogOptions.add("删除评论")
|
||||
}
|
||||
dialogOptions.add("复制")
|
||||
dialogOptions.add("投诉")
|
||||
|
||||
commentEntity.me?.let {
|
||||
if (ignoreModerator) return@let
|
||||
|
||||
if (it.isModerator || (it.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|
||||
|| it.moderatorPermissions.topAnswerComment > Permissions.GUEST
|
||||
|| it.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST
|
||||
@ -88,55 +105,75 @@ object CommentHelper {
|
||||
dialogOptions.add("查看对话")
|
||||
}
|
||||
|
||||
DialogUtils.showListDialog(context, dialogOptions, null) {
|
||||
when (it) {
|
||||
"管理" -> showControlDialog(context, answerId, articleId, communityId, commentEntity, commentEntity.me!!)
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val layout = inflater.inflate(R.layout.comment_more_option, null)
|
||||
val popupWindow = BugFixedPopupWindow(layout,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
val container = layout.findViewById<LinearLayout>(R.id.container)
|
||||
for (text in dialogOptions) {
|
||||
val item = inflater.inflate(R.layout.comment_more_option_item, container, false)
|
||||
container.addView(item)
|
||||
|
||||
"复制" -> copyText(commentEntity.content, context)
|
||||
val hitText = item.findViewById<TextView>(R.id.hint_text)
|
||||
hitText.text = text
|
||||
|
||||
"投诉" -> {
|
||||
context.ifLogin("回答详情-评论-投诉") {
|
||||
showReportTypeDialog(context) { reportType ->
|
||||
item.setOnClickListener {
|
||||
popupWindow.dismiss()
|
||||
listener?.onCommentOptionClick(commentEntity, text)
|
||||
when (text) {
|
||||
"管理" -> showControlDialog(context, answerId, articleId, communityId, commentEntity, commentEntity.me!!)
|
||||
|
||||
val commentListener = object : PostCommentUtils.PostCommentListener {
|
||||
override fun postSuccess(response: JSONObject?) {
|
||||
Utils.toast(context, "感谢您的投诉")
|
||||
}
|
||||
"复制" -> copyText(commentEntity.content, context)
|
||||
|
||||
override fun postFailed(error: Throwable?) {
|
||||
if (error == null) {
|
||||
Utils.toast(context, "投诉失败,请稍后重试")
|
||||
} else {
|
||||
Utils.toast(context, "投诉失败,${error.message}")
|
||||
"投诉" -> {
|
||||
context.ifLogin("回答详情-评论-投诉") {
|
||||
showReportTypeDialog(context) { reportType ->
|
||||
|
||||
val commentListener = object : PostCommentUtils.PostCommentListener {
|
||||
override fun postSuccess(response: JSONObject?) {
|
||||
Utils.toast(context, "感谢您的投诉")
|
||||
}
|
||||
|
||||
override fun postFailed(error: Throwable?) {
|
||||
if (error == null) {
|
||||
Utils.toast(context, "投诉失败,请稍后重试")
|
||||
} else {
|
||||
Utils.toast(context, "投诉失败,${error.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (answerId != null) {
|
||||
PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
|
||||
} else if (articleId != null) {
|
||||
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
|
||||
} else {
|
||||
PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
|
||||
if (answerId != null) {
|
||||
PostCommentUtils.postAnswerReportData(context, commentEntity.id, answerId, reportType, commentListener)
|
||||
} else if (articleId != null) {
|
||||
PostCommentUtils.reportCommunityArticleComment(context, communityId, articleId, commentEntity.id, reportType, commentListener)
|
||||
} else {
|
||||
PostCommentUtils.reportVideoComment(context, videoId, commentEntity.id, reportType, commentListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"查看对话" -> {
|
||||
if (answerId != null) {
|
||||
context.startActivity(CommentDetailActivity
|
||||
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
|
||||
} else if (articleId != null) {
|
||||
context.startActivity(CommentDetailActivity
|
||||
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
|
||||
} else {
|
||||
context.startActivity(CommentDetailActivity
|
||||
.getVideoCommentIntent(context, commentEntity.id, videoId, null))
|
||||
"查看对话" -> {
|
||||
if (answerId != null) {
|
||||
context.startActivity(CommentDetailActivity
|
||||
.getAnswerCommentIntent(context, commentEntity.id, answerId, null))
|
||||
} else if (articleId != null) {
|
||||
context.startActivity(CommentDetailActivity
|
||||
.getCommunityArticleCommentIntent(context, articleId, commentEntity.id, communityId, null))
|
||||
} else {
|
||||
context.startActivity(CommentDetailActivity
|
||||
.getVideoCommentIntent(context, commentEntity.id, videoId, isVideoAuthor, null))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
popupWindow.isTouchable = true
|
||||
popupWindow.isFocusable = true
|
||||
|
||||
popupWindow.showAutoOrientation(view)
|
||||
}
|
||||
|
||||
private fun showControlDialog(context: Context,
|
||||
|
||||
@ -12,6 +12,8 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.gamecenter.CommentDetailActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
|
||||
@ -33,11 +35,11 @@ import java.lang.ref.WeakReference;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.ResponseBody;
|
||||
@ -49,37 +51,51 @@ import retrofit2.HttpException;
|
||||
public class CommentUtils {
|
||||
|
||||
public static void setCommentTime(TextView textView, long time) {
|
||||
textView.setText(getCommentTime(time));
|
||||
}
|
||||
|
||||
public static String getCommentTime(long timestamp) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
|
||||
try {
|
||||
long day = timestamp * 1000;
|
||||
String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
|
||||
format.applyPattern("yyyy");
|
||||
String currentYear = format.format(day);
|
||||
format.applyPattern("yyyyMMdd");
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
long day = time * 1000;
|
||||
if (day >= today && day < today + 86400 * 1000) {
|
||||
long min = new Date().getTime() / 1000 - day / 1000;
|
||||
int hour = (int) (min / (60 * 60));
|
||||
if (hour == 0) {
|
||||
if (min < 60) {
|
||||
textView.setText("刚刚");
|
||||
return "刚刚";
|
||||
} else {
|
||||
textView.setText(String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60)));
|
||||
return String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60));
|
||||
}
|
||||
} else {
|
||||
textView.setText(String.format(Locale.getDefault(), "%d小时前", hour));
|
||||
return String.format(Locale.getDefault(), "%d小时前", hour);
|
||||
}
|
||||
} else if (day >= today - 86400 * 1000 && day < today) {
|
||||
format.applyPattern("HH:mm");
|
||||
textView.setText("昨天 ");
|
||||
return "昨天 ";
|
||||
} else if (day >= today - 86400 * 1000 * 7 && day < today - 86400 * 1000) {
|
||||
format.applyPattern("HH:mm");
|
||||
long days = (today - day) / 86400000 + 1;
|
||||
return String.format(Locale.getDefault(), "%d天前 ", days);
|
||||
} else if (day < today - 86400 * 1000 * 7 && year.equals(currentYear)) {
|
||||
format.applyPattern("MM-dd");
|
||||
return format.format(day);
|
||||
} else {
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
textView.setText(format.format(day));
|
||||
return format.format(day);
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
textView.setText(format.format(time * 1000));
|
||||
return format.format(timestamp * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void showReportDialog(final CommentEntity commentEntity,
|
||||
final Context context,
|
||||
final boolean showConversation,
|
||||
@ -199,7 +215,7 @@ public class CommentUtils {
|
||||
final TextView commentLikeCountTv, final ImageView commentLikeIv,
|
||||
final OnVoteListener listener) {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
return;
|
||||
}
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
@ -236,7 +252,7 @@ public class CommentUtils {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
@ -265,7 +281,7 @@ public class CommentUtils {
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
return;
|
||||
}
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
@ -301,7 +317,7 @@ public class CommentUtils {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
Utils.toast(context, "已经点过赞啦!");
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
@ -421,7 +437,7 @@ public class CommentUtils {
|
||||
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
cmb.setText(copyContent);
|
||||
|
||||
Utils.toast(context, "复制成功");
|
||||
ToastUtils.INSTANCE.showToast("复制成功");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import android.graphics.BitmapFactory
|
||||
import android.graphics.Matrix
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.entity.SettingsEntity
|
||||
import com.github.piasy.biv.metadata.ImageInfoExtractor
|
||||
import com.halo.assistant.HaloApp
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@ -26,11 +27,16 @@ object CompressImageUtils {
|
||||
* 压缩图片并保存到目标文件
|
||||
* 该压缩方法是同步执行 请勿在主线程执行
|
||||
* 返回源文件的三种情况:小于特定值,图片类型为GIF,压缩失败
|
||||
* ---------------------------------------------------------------------------------------------
|
||||
* 关于压缩格式问题:
|
||||
* 1.图片详情对动态Webp/静态Webp的判断存在问题,导致部分静态Webp图片误判为动态Webp而直接委托Fresco处理,出现无法缩放问题
|
||||
* 2.为了解决上述问题,如果压缩是检测到是动态Webp时直接压缩为JPEG,这样就能解决图片详情无法缩放问题(todo 这样会导致动态Webp无法播放)
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
fun compressImageAndSaveToFile(imageFile: File, compressGif: Boolean): File {
|
||||
val imageType = ImageInfoExtractor.getImageType(imageFile)
|
||||
// 小于某一个设定的值时,直接返回原图
|
||||
if (imageFile.length() < getImageSetting().processLimitSize) {
|
||||
if (imageType != ImageInfoExtractor.TYPE_ANIMATED_WEBP && imageFile.length() < getImageSetting().processLimitSize) {
|
||||
return imageFile
|
||||
}
|
||||
|
||||
@ -49,7 +55,7 @@ object CompressImageUtils {
|
||||
} else if (options.outMimeType.contains("gif") && !compressGif) { // gif直接返回原图
|
||||
return imageFile
|
||||
} else {
|
||||
Bitmap.CompressFormat.WEBP
|
||||
Bitmap.CompressFormat.JPEG
|
||||
}
|
||||
|
||||
fileOutputStream = FileOutputStream(cacheDir)
|
||||
@ -165,6 +171,7 @@ object CompressImageUtils {
|
||||
enum class CompressType {
|
||||
// 0: 短边等比压缩至1280 H:长边 W:短边
|
||||
LIMIT_SHORT,
|
||||
|
||||
// 1: 取长边等比压缩至1280 H:短边 W: 长边
|
||||
LIMIT_LONG
|
||||
}
|
||||
@ -6,7 +6,7 @@ import android.widget.LinearLayout;
|
||||
|
||||
import com.facebook.drawee.drawable.ScalingUtils;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.gamecenter.ViewImageActivity;
|
||||
import com.gh.gamecenter.ImageViewerActivity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -93,7 +93,7 @@ public class ConcernContentUtils {
|
||||
break;
|
||||
}
|
||||
imageView.setOnClickListener(v -> {
|
||||
Intent checkIntent = ViewImageActivity.getViewImageIntent(context, (ArrayList<String>) list, position, entrance);
|
||||
Intent checkIntent = ImageViewerActivity.getIntent(context, (ArrayList<String>) list, position, entrance);
|
||||
context.startActivity(checkIntent);
|
||||
});
|
||||
return imageView;
|
||||
|
||||
@ -3,17 +3,18 @@ package com.gh.common.util;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.NewsDetailEntity;
|
||||
import com.gh.gamecenter.manager.DataCollectionManager;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import kotlin.text.StringsKt;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/12/9.
|
||||
* 数据收集 工具类(data.ghzs666.com)
|
||||
@ -33,8 +34,8 @@ public class DataCollectionUtils {
|
||||
// 上传下载数据(开始、完成)
|
||||
public static void uploadDownload(Context context, DownloadEntity downloadEntity, String status) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("game", downloadEntity.getName());
|
||||
map.put("game_id", downloadEntity.getGameId());
|
||||
map.put("game", StringsKt.removeSuffix(downloadEntity.getName(), Constants.GAME_NAME_DECORATOR));
|
||||
map.put("game_id", downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER));
|
||||
if (downloadEntity.isPluggable()) {
|
||||
map.put("method", "插件化");
|
||||
map.put("btn_status", "插件化");
|
||||
@ -169,24 +170,4 @@ public class DataCollectionUtils {
|
||||
map.put("type", args[2]);
|
||||
DataCollectionManager.onEvent(context, "concern", map);
|
||||
}
|
||||
|
||||
//上传推荐位数据
|
||||
public static void uploadPosition(Context context, String... args) {
|
||||
if (args.length < 3) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("page", args[0]);
|
||||
map.put("location", args[1]);
|
||||
map.put("name", args[2]);
|
||||
DataCollectionManager.onEvent(context, "position", map);
|
||||
}
|
||||
|
||||
//上传应用列表
|
||||
public static void uploadAppList(Context context, JSONArray applist) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("applist", applist);
|
||||
DataCollectionManager.onEvent(context, "applist", map);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,8 +2,7 @@ package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.gh.common.loghub.LoghubUtils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
@ -14,12 +13,6 @@ import org.json.JSONObject;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/12/8.
|
||||
* 日志上传工具类
|
||||
@ -27,12 +20,13 @@ import okhttp3.ResponseBody;
|
||||
public class DataLogUtils {
|
||||
|
||||
// 轮播图
|
||||
public static void uploadLunbotuLog(Context context, String type, String text, String index, String source) {
|
||||
public static void uploadLunbotuLog(Context context, String type, String text, String title, String index, String source) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("index", index);
|
||||
map.put("type", type);
|
||||
map.put("text", text);
|
||||
map.put("source", source);
|
||||
map.put("slide_title", title);
|
||||
uploadLog(context, "slide", map);
|
||||
}
|
||||
|
||||
@ -68,12 +62,7 @@ public class DataLogUtils {
|
||||
params.put("time", String.valueOf(Utils.getTime(context)));
|
||||
params.put("content", new JSONObject(map).toString());
|
||||
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"),
|
||||
new JSONObject(params).toString());
|
||||
RetrofitManager.getInstance(context).getData().postLog(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>());
|
||||
LoghubUtils.log(new JSONObject(params), "common", true);
|
||||
}
|
||||
|
||||
// 网络错误
|
||||
|
||||
@ -3,19 +3,16 @@ package com.gh.common.util;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gid.GidCallback;
|
||||
import com.gh.gid.GidHelper;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
import com.tencent.stat.MtaSDkException;
|
||||
@ -126,18 +123,25 @@ public class DataUtils {
|
||||
public static void getGid() {
|
||||
GidHelper.getInstance().registerDevice(new GidCallback() {
|
||||
@Override
|
||||
public void onSuccess(String s) {
|
||||
Utils.log("Gid", s);
|
||||
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, s).apply();
|
||||
public void onSuccess(String gid) {
|
||||
Utils.log("Gid", gid);
|
||||
PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().getApplication()).edit().putString(Constants.DEVICE_KEY, gid).apply();
|
||||
|
||||
String originalGid = HaloApp.getInstance().getGid();
|
||||
HaloApp.getInstance().setGid(gid);
|
||||
|
||||
// 避免重复调用
|
||||
if (!TextUtils.isEmpty(gid) && !gid.equals(originalGid)) {
|
||||
GameSubstituteRepositoryHelper.updateSubstitutableGames();
|
||||
}
|
||||
|
||||
HaloApp.getInstance().setGid(s);
|
||||
// 避免初始化顺序问题导致 MetaUtil 一直持有空的 gid
|
||||
MetaUtil.INSTANCE.refreshMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String s) {
|
||||
Utils.log(s);
|
||||
MtaHelper.onEventWithBasicDeviceInfo("开发辅助", "GID 获取异常", s);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -197,36 +201,36 @@ public class DataUtils {
|
||||
|
||||
// 游戏下载
|
||||
public static void onGameDownloadEvent(Context context, String gameName, String platform, String entrance, String status, String method) {
|
||||
Map<String, Object> kv = new HashMap<>();
|
||||
|
||||
platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
|
||||
|
||||
kv.put("版本", platform);
|
||||
kv.put("用户机型", Build.MODEL);
|
||||
kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
|
||||
kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
kv.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
kv.put("位置", entrance);
|
||||
kv.put("类型", method);
|
||||
kv.put("厂商", Build.MANUFACTURER);
|
||||
kv.put("Android版本", Build.VERSION.RELEASE);
|
||||
onEvent(context, "游戏下载", gameName, kv);
|
||||
|
||||
Map<String, Object> kv2 = new HashMap<>();
|
||||
kv2.put("状态", status);
|
||||
kv2.put("位置", entrance);
|
||||
|
||||
if (status.equals("开始")) {
|
||||
kv2.put("版本", entrance + "-开始");
|
||||
kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
|
||||
kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
|
||||
} else {
|
||||
kv2.put("版本", platform);
|
||||
kv2.put("游戏分平台", gameName + "-" + platform);
|
||||
kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
}
|
||||
|
||||
onEvent(context, "游戏下载位置", gameName, kv2);
|
||||
// Map<String, Object> kv = new HashMap<>();
|
||||
//
|
||||
// platform = PlatformUtils.getInstance(HaloApp.getInstance().getApplication()).getPlatformName(platform);
|
||||
//
|
||||
// kv.put("版本", platform);
|
||||
// kv.put("用户机型", Build.MODEL);
|
||||
// kv.put("设备IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().getApplication()));
|
||||
// kv.put("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().getApplication()));
|
||||
// kv.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
// kv.put("位置", entrance);
|
||||
// kv.put("类型", method);
|
||||
// kv.put("厂商", Build.MANUFACTURER);
|
||||
// kv.put("Android版本", Build.VERSION.RELEASE);
|
||||
// onEvent(context, "游戏下载", gameName, kv);
|
||||
//
|
||||
// Map<String, Object> kv2 = new HashMap<>();
|
||||
// kv2.put("状态", status);
|
||||
// kv2.put("位置", entrance);
|
||||
//
|
||||
// if (status.equals("开始")) {
|
||||
// kv2.put("版本", entrance + "-开始");
|
||||
// kv2.put("游戏分平台", gameName + "-" + platform + "-开始");
|
||||
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME + "-开始");
|
||||
// } else {
|
||||
// kv2.put("版本", platform);
|
||||
// kv2.put("游戏分平台", gameName + "-" + platform);
|
||||
// kv2.put("光环助手版本", BuildConfig.VERSION_NAME);
|
||||
// }
|
||||
//
|
||||
// onEvent(context, "游戏下载位置", gameName, kv2);
|
||||
}
|
||||
|
||||
// 游戏更新
|
||||
|
||||
@ -6,6 +6,8 @@ import android.view.View;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
|
||||
@ -22,6 +24,7 @@ import com.lightgame.download.DownloadEntity;
|
||||
public class DetailDownloadUtils {
|
||||
|
||||
public static void detailInitDownload(DetailViewHolder viewHolder, boolean isCheck) {
|
||||
String downloadAddWord = viewHolder.gameEntity.getDownloadAddWord();
|
||||
|
||||
if (viewHolder.gameEntity != null
|
||||
&& Config.isShowDownload(viewHolder.gameEntity.getId())
|
||||
@ -34,10 +37,11 @@ public class DetailDownloadUtils {
|
||||
|
||||
if (viewHolder.gameEntity.isReservable()) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(viewHolder.gameEntity.getId())) {
|
||||
if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
|
||||
if (TextUtils.isEmpty(downloadAddWord)) {
|
||||
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》", viewHolder.gameEntity.getName()));
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》%s", viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
viewHolder.mDownloadPb.setText(String.format("预约" + "《%s》%s", viewHolder.gameEntity.getName(), downloadAddWord));
|
||||
}
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.RESERVABLE);
|
||||
} else {
|
||||
@ -49,10 +53,10 @@ public class DetailDownloadUtils {
|
||||
|
||||
if (viewHolder.gameEntity.getApk().isEmpty() || viewHolder.gameEntity.getDownloadOffStatus() != null) {
|
||||
LinkEntity h5LinkEntity = viewHolder.gameEntity.getH5Link();
|
||||
|
||||
|
||||
if (h5LinkEntity != null) {
|
||||
if ("play".equals(h5LinkEntity.getType())) {
|
||||
String defaultString = String.format("开始玩" + "《%s》", viewHolder.gameEntity.getName());
|
||||
String defaultString = String.format("开始玩" + "《%s》", viewHolder.gameEntity.getName());
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(h5LinkEntity.getText()) ? defaultString : h5LinkEntity.getText());
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(h5LinkEntity.getText()) ? "查看" : h5LinkEntity.getText());
|
||||
@ -60,35 +64,39 @@ public class DetailDownloadUtils {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.H5_GAME);
|
||||
} else {
|
||||
if ("dialog".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.downloadOffText) ? "查看详情" : viewHolder.downloadOffText);
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "查看详情" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE_WITH_HINT);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.downloadOffText) ? "暂无下载" : viewHolder.downloadOffText);
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "暂无下载" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (viewHolder.gameEntity.getApk().size() == 1) {
|
||||
String status = GameUtils.getDownloadBtnText(viewHolder.context, viewHolder.gameEntity, PluginLocation.only_game);
|
||||
switch (status) {
|
||||
case "插件化":
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.PLUGIN);
|
||||
break;
|
||||
case "打开":
|
||||
case "启动":
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
|
||||
break;
|
||||
default:
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NORMAL);
|
||||
break;
|
||||
if (viewHolder.context.getString(R.string.pluggable).equals(status)) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.PLUGIN);
|
||||
} else if (viewHolder.context.getString(R.string.launch).equals(status)) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NORMAL);
|
||||
}
|
||||
|
||||
String downloadText;
|
||||
if (viewHolder.isNewsDetail) {
|
||||
viewHolder.mDownloadPb.setText(status);
|
||||
} else if (TextUtils.isEmpty(viewHolder.downloadAddWord)) {
|
||||
viewHolder.mDownloadPb.setText(String.format(status + "《%s》", viewHolder.gameEntity.getName()));
|
||||
downloadText = status;
|
||||
} else if (viewHolder.context.getString(R.string.pluggable).equals(status)) {
|
||||
downloadText = "升级" + (TextUtils.isEmpty(downloadAddWord) ? "" : "至" + downloadAddWord) + getDownloadSizeText(viewHolder);
|
||||
} else if (viewHolder.context.getString(R.string.launch).equals(status)) {
|
||||
downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord);
|
||||
} else if (viewHolder.context.getString(R.string.attempt).equals(status)) {
|
||||
downloadText = status + getDownloadSizeText(viewHolder);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(String.format(status + "《%s》%s", viewHolder.gameEntity.getName(), viewHolder.downloadAddWord));
|
||||
downloadText = status + (TextUtils.isEmpty(downloadAddWord) ? "" : downloadAddWord) + getDownloadSizeText(viewHolder);
|
||||
}
|
||||
viewHolder.mDownloadPb.setText(downloadText);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText("选择下载你的版本" + (TextUtils.isEmpty(downloadAddWord) ? "" : "-" + downloadAddWord) + " >");
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NORMAL);
|
||||
}
|
||||
if (isCheck && viewHolder.gameEntity.getApk().size() == 1) {
|
||||
String url = viewHolder.gameEntity.getApk().get(0).getUrl();
|
||||
@ -100,9 +108,23 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private static String getDownloadSizeText(DetailViewHolder viewHolder) {
|
||||
return String.format("(%s)", viewHolder.gameEntity.getApk().get(0).getSize());
|
||||
}
|
||||
|
||||
public static void detailInvalidate(DetailViewHolder viewHolder) {
|
||||
viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
|
||||
DownloadEntity downloadEntity = viewHolder.downloadEntity;
|
||||
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
|
||||
|
||||
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
|
||||
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
|
||||
viewHolder.mDownloadPb.setText("解压中(" + percent + "%)");
|
||||
viewHolder.mDownloadPb.setProgress((int) (Float.valueOf(percent) * 10));
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.XAPK_UNZIPPING);
|
||||
return;
|
||||
}
|
||||
|
||||
viewHolder.mDownloadPb.setProgress((int) (viewHolder.downloadEntity.getPercent() * 10));
|
||||
switch (downloadEntity.getStatus()) {
|
||||
case downloading:
|
||||
case pause:
|
||||
@ -128,7 +150,7 @@ public class DetailDownloadUtils {
|
||||
case done:
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
@ -143,6 +165,4 @@ public class DetailDownloadUtils {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.tencent.stat.StatConfig;
|
||||
@ -222,8 +224,7 @@ public class DeviceUtils {
|
||||
|
||||
// get sim
|
||||
public static String getSim(Context context) {
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String imsi = tm.getSubscriberId();
|
||||
String imsi = getTelephonySubscriberId(context);
|
||||
if (imsi == null) {
|
||||
return "";
|
||||
}
|
||||
@ -239,6 +240,12 @@ public class DeviceUtils {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getTelephonySubscriberId(Context context) {
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
return tm.getSubscriberId();
|
||||
}
|
||||
|
||||
// ping domain
|
||||
public static String ping(String domain) {
|
||||
try {
|
||||
@ -269,18 +276,21 @@ public class DeviceUtils {
|
||||
|
||||
// 只能获取WiFi的IpAddress
|
||||
public static String getCurrentIpAddress() {
|
||||
String ipAddress;
|
||||
WifiManager wifiManager = (WifiManager) HaloApp.getInstance().
|
||||
getApplication().
|
||||
getApplicationContext().
|
||||
getSystemService(Context.WIFI_SERVICE);
|
||||
int address = wifiManager.getDhcpInfo().ipAddress;
|
||||
ipAddress = ((address & 0xFF)
|
||||
+ "." + ((address >> 8) & 0xFF)
|
||||
+ "." + ((address >> 16) & 0xFF)
|
||||
+ "." + ((address >> 24) & 0xFF));
|
||||
return ipAddress;
|
||||
String ipAddress = "0.0.0.0";
|
||||
try {
|
||||
WifiManager wifiManager = (WifiManager) HaloApp.getInstance().
|
||||
getApplication().
|
||||
getApplicationContext().
|
||||
getSystemService(Context.WIFI_SERVICE);
|
||||
int address = wifiManager.getDhcpInfo().ipAddress;
|
||||
ipAddress = ((address & 0xFF)
|
||||
+ "." + ((address >> 8) & 0xFF)
|
||||
+ "." + ((address >> 16) & 0xFF)
|
||||
+ "." + ((address >> 24) & 0xFF));
|
||||
return ipAddress;
|
||||
} catch (Exception e) {
|
||||
return ipAddress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||
@ -40,19 +41,31 @@ import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.TrackableDialog;
|
||||
import com.gh.common.view.DrawableView;
|
||||
import com.gh.common.view.FixLinearLayoutManager;
|
||||
import com.gh.common.view.LimitHeightLinearLayout;
|
||||
import com.gh.common.view.MaxHeightNestedScrollView;
|
||||
import com.gh.gamecenter.AboutActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.SuggestionActivity;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder;
|
||||
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.ImprintContentItemBinding;
|
||||
import com.gh.gamecenter.databinding.PrivacyItemBinding;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
|
||||
import com.gh.gamecenter.entity.SettingsEntity;
|
||||
import com.gh.gamecenter.entity.TrackableEntity;
|
||||
import com.gh.gamecenter.suggest.SuggestType;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.halo.assistant.fragment.SettingsFragment;
|
||||
import com.lightgame.adapter.BaseRecyclerAdapter;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.utils.AppManager;
|
||||
import com.lightgame.utils.Util_System_Keyboard;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@ -72,7 +85,6 @@ public class DialogUtils {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
public static void showInstallHintDialog(Context context, final ConfirmListener cmListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
@ -186,7 +198,7 @@ public class DialogUtils {
|
||||
AppExecutor.getUiExecutor().executeWithDelay(() -> Utils.toast(context, "当前使用移动网络下载,请注意流量消耗"), 500);
|
||||
callBack.onResponse(false);
|
||||
} else {
|
||||
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
|
||||
showDownloadDialog(context,
|
||||
() -> callBack.onResponse(false),
|
||||
() -> callBack.onResponse(true));
|
||||
@ -246,12 +258,12 @@ public class DialogUtils {
|
||||
}, 500);
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
|
||||
});
|
||||
wifiAuto.setOnClickListener(v -> {
|
||||
cancelListener.onCancel();
|
||||
dialog.dismiss();
|
||||
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
|
||||
});
|
||||
allowAlways.setOnClickListener(v -> {
|
||||
PreferenceManager
|
||||
@ -266,7 +278,7 @@ public class DialogUtils {
|
||||
}, 500);
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
|
||||
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
@ -531,8 +543,6 @@ public class DialogUtils {
|
||||
clListener.onCancel();
|
||||
});
|
||||
dialog.show();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -576,7 +586,6 @@ public class DialogUtils {
|
||||
dialog.setContentView(contentView);
|
||||
dialog.setCancelable(false);
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -657,7 +666,6 @@ public class DialogUtils {
|
||||
TextPaint tp = mesage.getPaint();
|
||||
tp.setFakeBoldText(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void showSignDialog(Context context, String title, CharSequence message, CharSequence message2
|
||||
@ -1091,17 +1099,43 @@ public class DialogUtils {
|
||||
final ConfirmListener cmListener,
|
||||
final CancelListener clListener,
|
||||
TrackableEntity trackableEntity) {
|
||||
return showTrackableDialog(context, false, title, message, positive, negative, cmListener, clListener, trackableEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param useRoundedCornerStyle 使用圆角样式
|
||||
*/
|
||||
public static Dialog showTrackableDialog(Context context,
|
||||
boolean useRoundedCornerStyle,
|
||||
String title,
|
||||
CharSequence message,
|
||||
String positive,
|
||||
String negative,
|
||||
final ConfirmListener cmListener,
|
||||
final CancelListener clListener,
|
||||
TrackableEntity trackableEntity) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final TrackableDialog dialog = new TrackableDialog(context,
|
||||
R.style.GhAlertDialog,
|
||||
trackableEntity.getEvent(),
|
||||
trackableEntity.getKey(),
|
||||
trackableEntity.getValue(),
|
||||
trackableEntity.getCancelValue(),
|
||||
trackableEntity.getKeyBackValue(),
|
||||
trackableEntity.getLogShowEvent());
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
|
||||
View contentView;
|
||||
if (useRoundedCornerStyle) {
|
||||
contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert_with_rounded_corner, null);
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
} else {
|
||||
contentView = LayoutInflater.from(context).inflate(R.layout.dialog_alert, null);
|
||||
}
|
||||
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView negativeTv = contentView.findViewById(R.id.dialog_negative);
|
||||
@ -1224,6 +1258,351 @@ public class DialogUtils {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showVersionNumberDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
if (!gameEntity.isShowVersionNumber()) {
|
||||
listener.onConfirm();
|
||||
} else {
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_version_number, null);
|
||||
|
||||
TextView contentTv = contentView.findViewById(R.id.contentTv);
|
||||
TextView cancelTv = contentView.findViewById(R.id.cancelTv);
|
||||
TextView continueTv = contentView.findViewById(R.id.continueTv);
|
||||
|
||||
contentTv.setText(gameEntity.getVersionNumberString());
|
||||
cancelTv.setOnClickListener(v -> dialog.dismiss());
|
||||
continueTv.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
// 海外下载地址弹窗
|
||||
public static void showOverseaDownloadDialog(Context context, GameEntity gameEntity, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
if (gameEntity.getOverseasAddressDialog() == null
|
||||
|| gameEntity.getApk().size() == 0
|
||||
|| !gameEntity.getOverseasAddressDialog().isEnable()) {
|
||||
listener.onConfirm();
|
||||
} else {
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
DialogOverseaConfirmationBinding binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.dialog_oversea_confirmation, null, false);
|
||||
|
||||
View contentView = binding.getRoot();
|
||||
|
||||
binding.setGame(gameEntity);
|
||||
binding.urlTv.setText(gameEntity.getOverseasAddressDialog().getLink());
|
||||
binding.closeIv.setOnClickListener(v -> dialog.dismiss());
|
||||
binding.downloadBtn.setText("下载(" + gameEntity.getApk().get(0).getSize() + ")");
|
||||
binding.downloadBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
if ("show&download".equals(gameEntity.getOverseasAddressDialog().getStatus())) {
|
||||
gameEntity.getApk().get(0).setUrl(gameEntity.getOverseasAddressDialog().getLink());
|
||||
}
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void showImprintDialog(Context context, GameEntity gameEntity, String titleName) {
|
||||
context = checkDialogContext(context);
|
||||
Dialog dialog = new Dialog(context, R.style.full_dialog);
|
||||
View inflate = LayoutInflater.from(context).inflate(R.layout.imprint_dialog, null);
|
||||
dialog.setContentView(inflate);
|
||||
dialog.show();
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
WindowManager.LayoutParams params;
|
||||
if (window != null) {
|
||||
params = window.getAttributes();
|
||||
params.width = (int) (context.getResources().getDisplayMetrics().widthPixels * 0.9);
|
||||
window.setAttributes(params);
|
||||
window.setBackgroundDrawableResource(R.drawable.full_dialog_background);
|
||||
}
|
||||
|
||||
inflate.findViewById(R.id.imprint_close).setOnClickListener(v -> dialog.dismiss());
|
||||
LinearLayout content = inflate.findViewById(R.id.imprint_content);
|
||||
((TextView) inflate.findViewById(R.id.imprint_title)).setText(titleName);
|
||||
View head = LayoutInflater.from(context).inflate(R.layout.imprint_content_item, null);
|
||||
content.addView(head, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(30));
|
||||
LimitHeightLinearLayout imprintContainer = inflate.findViewById(R.id.imprint_container);
|
||||
imprintContainer.setLimitHeight((int) (context.getResources().getDisplayMetrics().heightPixels * 0.8));
|
||||
|
||||
ArrayList<ApkEntity> list = gameEntity.getApk();
|
||||
SettingsEntity settings = Config.getSettings();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
ApkEntity apk = gameEntity.getApk().get(i);
|
||||
if (settings != null && settings.getGameDownloadBlackList().contains(apk.getPackageName())) {
|
||||
continue;
|
||||
}
|
||||
View item = LayoutInflater.from(context).inflate(R.layout.imprint_content_item, null);
|
||||
ImprintContentItemBinding bind = DataBindingUtil.bind(item);
|
||||
bind.setApk(apk);
|
||||
bind.setPlatformName(PlatformUtils.getInstance(context).getPlatformName(apk.getPlatform()));
|
||||
content.addView(item, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(40));
|
||||
}
|
||||
|
||||
|
||||
// close line
|
||||
View view = new View(context);
|
||||
view.setBackgroundColor(context.getResources().getColor(R.color.text_5d5d5d));
|
||||
view.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(1)));
|
||||
content.addView(view);
|
||||
}
|
||||
|
||||
public static void showKaifuRemindDialog(Context context, String content, String gameName) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new TrackableDialog(context, R.style.GhAlertDialog, "开服说明弹窗", "弹窗", gameName, null, null, true);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_kaifu_remind, null);
|
||||
|
||||
TextView contentTv = contentView.findViewById(R.id.contentTv);
|
||||
MaxHeightNestedScrollView scrollView = contentView.findViewById(R.id.scrollView);
|
||||
contentTv.setText(Html.fromHtml(content));
|
||||
TextView ok = contentView.findViewById(R.id.dialog_ok);
|
||||
scrollView.setScrollChangedListener((l, t, oldl, oldt) -> {
|
||||
MtaHelper.onEvent("开服说明弹窗", "滑动内容", gameName);
|
||||
});
|
||||
ok.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("开服说明弹窗", "弹窗", "点击我知道了");
|
||||
MtaHelper.onEvent("开服说明弹窗", "点击我知道了", gameName);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showStopServerExplanationDialog(Context context, String content, String gameName) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new TrackableDialog(context, R.style.GhAlertDialog, "评论说明弹窗", "弹窗", gameName, null, null, true);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_stop_service_explanation, null);
|
||||
|
||||
TextView contentTv = contentView.findViewById(R.id.contentTv);
|
||||
MaxHeightNestedScrollView scrollView = contentView.findViewById(R.id.scrollView);
|
||||
if (TextUtils.isEmpty(content)) {
|
||||
content = context.getString(R.string.rating_protection);
|
||||
}
|
||||
contentTv.setText(content);
|
||||
TextView ok = contentView.findViewById(R.id.dialog_ok);
|
||||
scrollView.setScrollChangedListener((l, t, oldl, oldt) -> {
|
||||
MtaHelper.onEvent("评论说明弹窗", "滑动内容", gameName);
|
||||
});
|
||||
ok.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("评论说明弹窗", "弹窗", "点击我知道了");
|
||||
MtaHelper.onEvent("评论说明弹窗", "点击我知道了", gameName);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(60f);
|
||||
window.setAttributes(params);
|
||||
}
|
||||
}
|
||||
|
||||
public static void showPluggableNeverRemindDialog(Context context, String nameAndPlatform, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_pluggable_never_remind, null);
|
||||
|
||||
View cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
View confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
TextView contentTv = contentView.findViewById(R.id.content);
|
||||
|
||||
contentTv.setText(("助手首页将不再提示《" + nameAndPlatform + "》的所有插件化消息,确定吗?"));
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showRegulationTestDialog(Context context, @NonNull ConfirmListener confirmListener, @NonNull CancelListener cancelListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new TrackableDialog(
|
||||
context,
|
||||
R.style.GhAlertDialog,
|
||||
"礼仪考试",
|
||||
"礼仪考试弹窗",
|
||||
null, null, null,
|
||||
true);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_regulation_test, null);
|
||||
|
||||
View cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
View confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
View linkTv = contentView.findViewById(R.id.link);
|
||||
|
||||
Context finalContext = context;
|
||||
linkTv.setOnClickListener(v -> {
|
||||
|
||||
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "了解更多");
|
||||
DirectUtils.directToArticle(finalContext, "5f4477be25e07e19be4e2a22", "(礼仪测试弹窗)");
|
||||
});
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
cancelListener.onCancel();
|
||||
|
||||
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "跳过");
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Context finalContext1 = context;
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
Util_System_Keyboard.hideSoftKeyboard((Activity) finalContext1);
|
||||
|
||||
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "确定");
|
||||
confirmListener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
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() + "》游戏安装包解压失败,问题反馈:";
|
||||
SuggestionActivity.startSuggestionActivity(activityContext, SuggestType.normal, null, hint);
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showNoticeDialog(Context context, String title, String content, @NonNull ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_notice, null);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
|
||||
if (title == null) {
|
||||
titleTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
titleTv.setVisibility(View.VISIBLE);
|
||||
titleTv.setText(title);
|
||||
}
|
||||
contentTv.setText(content);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showUploadVideoChangeLabelDialog(Context context, @NonNull ConfirmListener confirmListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_upload_video_change_label, null);
|
||||
|
||||
View cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
View confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
confirmListener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context may be is application context
|
||||
* @return activity context
|
||||
|
||||
@ -6,11 +6,18 @@ import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.base.ToolBarActivity
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureEvent
|
||||
import com.gh.common.exposure.ExposureEvent.Companion.createEvent
|
||||
import com.gh.common.exposure.ExposureManager.log
|
||||
import com.gh.common.exposure.ExposureTraceUtils.appendTrace
|
||||
import com.gh.common.exposure.ExposureType
|
||||
import com.gh.common.util.EntranceUtils.*
|
||||
import com.gh.gamecenter.*
|
||||
import com.gh.gamecenter.amway.AmwayActivity
|
||||
@ -19,9 +26,14 @@ import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
|
||||
import com.gh.gamecenter.entity.*
|
||||
import com.gh.gamecenter.eventbus.EBReuse
|
||||
import com.gh.gamecenter.eventbus.EBSkip
|
||||
import com.gh.gamecenter.forum.detail.ForumDetailActivity
|
||||
import com.gh.gamecenter.fragment.MainWrapperFragment
|
||||
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailActivity
|
||||
import com.gh.gamecenter.game.upload.GameSubmissionActivity
|
||||
import com.gh.gamecenter.gamedetail.GameDetailFragment
|
||||
import com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity
|
||||
import com.gh.gamecenter.gamedetail.history.HistoryApkListActivity
|
||||
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.mygame.PlayedGameActivity
|
||||
import com.gh.gamecenter.personalhome.UserHomeActivity
|
||||
@ -32,17 +44,24 @@ import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
|
||||
import com.gh.gamecenter.qa.column.detail.AskColumnDetailActivity
|
||||
import com.gh.gamecenter.qa.questions.detail.QuestionsDetailActivity
|
||||
import com.gh.gamecenter.qa.subject.CommunitySubjectActivity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.servers.GameServersActivity
|
||||
import com.gh.gamecenter.subject.SubjectActivity
|
||||
import com.gh.gamecenter.suggest.SuggestType
|
||||
import com.gh.gamecenter.tag.TagsActivity
|
||||
import com.gh.gamecenter.video.data.VideoDataActivity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailActivity
|
||||
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
|
||||
import com.gh.gamecenter.video.game.GameVideoActivity
|
||||
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_ClipboardManager
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import retrofit2.HttpException
|
||||
|
||||
/**
|
||||
* 跳转用的方法
|
||||
@ -79,9 +98,6 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到特定页面,只支持App内部跳转
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
|
||||
directToLinkPage(context, linkEntity, entrance, path, null)
|
||||
@ -124,30 +140,39 @@ object DirectUtils {
|
||||
when (linkEntity.type) {
|
||||
"article", "news", "文章" -> {
|
||||
NewsUtils.statNewsViews(context, linkEntity.link) // 统计阅读量
|
||||
context.startActivity(NewsDetailActivity.getIntentById(context, linkEntity.link, BaseActivity.mergeEntranceAndPath(entrance, path)))
|
||||
directToArticle(context, linkEntity.link
|
||||
?: "", BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
}
|
||||
|
||||
"game", "游戏" -> {
|
||||
if (exposureEvent != null) {
|
||||
GameDetailActivity.startGameDetailActivity(context, linkEntity.link, BaseActivity.mergeEntranceAndPath(entrance, path), exposureEvent)
|
||||
directToGameDetail(context, linkEntity.link
|
||||
?: "", BaseActivity.mergeEntranceAndPath(entrance, path), traceEvent = exposureEvent)
|
||||
} else {
|
||||
GameDetailActivity.startGameDetailActivity(context, linkEntity.link, BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
directToGameDetail(context, linkEntity.link
|
||||
?: "", BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
}
|
||||
}
|
||||
|
||||
"column", "游戏专题" -> SubjectActivity.startSubjectActivity(context, linkEntity.link, linkEntity.text, false, BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
"column", "游戏专题" -> directToSubject(context, linkEntity.link
|
||||
?: "", linkEntity.text, BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
|
||||
"question", "社区问题" -> context.startActivity(QuestionsDetailActivity.getIntent(context, linkEntity.link, entrance, path))
|
||||
"question", "社区问题" -> directToQuestionDetail(context, linkEntity.link
|
||||
?: "", entrance, path)
|
||||
|
||||
"answer", "社区回答" -> context.startActivity(AnswerDetailActivity.getIntent(context, linkEntity.link, entrance, path))
|
||||
"answer", "社区回答" -> directToAnswerDetail(context, linkEntity.link ?: "", entrance, path)
|
||||
|
||||
"community", "问答社区" -> directToCommunity(context, CommunityEntity(linkEntity.link!!, linkEntity.text!!))
|
||||
"community", "问答社区" -> {
|
||||
if (linkEntity.link.isNullOrEmpty()) return
|
||||
directToCommunity(context, CommunityEntity(linkEntity.link!!, linkEntity.text!!))
|
||||
}
|
||||
|
||||
"community_article", "社区文章" -> context.startActivity(ArticleDetailActivity.getIntent(context, linkEntity.community!!, linkEntity.link!!, entrance, path))
|
||||
"community_article", "社区文章" -> directToCommunityArticle(context, linkEntity.community!!, linkEntity.link!!, entrance, path)
|
||||
|
||||
"community_column", "社区专题" -> directToCommunityColumn(context, linkEntity.community, linkEntity.link!!, entrance, path)
|
||||
|
||||
"community_special_column" -> context.startActivity(AskColumnDetailActivity.getIntentByColumnId(context, linkEntity.link, linkEntity.community!!, entrance, path))
|
||||
"community_special_column" -> directAskColumnDetail(context, linkEntity.link
|
||||
?: "", linkEntity.community!!, entrance, path)
|
||||
|
||||
"web", "inurl", "web链接" -> {
|
||||
when {
|
||||
@ -166,37 +191,31 @@ object DirectUtils {
|
||||
|
||||
"tag" -> context.startActivity(TagsActivity.getIntent(context, linkEntity.text!!, linkEntity.title, entrance, path))
|
||||
|
||||
"all_community_article" -> {
|
||||
context.startActivity(SimpleArticleListActivity.getIntent(
|
||||
context,
|
||||
linkEntity.link ?: "",
|
||||
entrance,
|
||||
path))
|
||||
}
|
||||
"all_community_article" -> directSimpleArticleList(context, linkEntity.link
|
||||
?: "", entrance, path)
|
||||
|
||||
"category", "分类" -> {
|
||||
context.startActivity(CategoryDirectoryActivity.getIntent(context, linkEntity.link!!, linkEntity.text!!))
|
||||
}
|
||||
"category", "分类" -> directCategoryDirectory(context, linkEntity.link!!, linkEntity.text!!)
|
||||
|
||||
"block", "版块" -> {
|
||||
context.startActivity(BlockActivity.getIntent(context, SubjectRecommendEntity(
|
||||
link = linkEntity.link,
|
||||
text = linkEntity.text,
|
||||
name = linkEntity.name,
|
||||
display = linkEntity.display ?: Display())))
|
||||
if (linkEntity.link.isNullOrEmpty()) return
|
||||
directToBlock(context,
|
||||
SubjectRecommendEntity(
|
||||
link = linkEntity.link,
|
||||
text = linkEntity.text,
|
||||
name = linkEntity.name,
|
||||
display = linkEntity.display ?: Display()),
|
||||
entrance)
|
||||
}
|
||||
|
||||
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
|
||||
|
||||
"server" -> {
|
||||
context.startActivity(GameServersActivity.getIntent(context, entrance, path))
|
||||
}
|
||||
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path)
|
||||
|
||||
"top_game_comment" -> directToAmway(context, null, entrance, path)
|
||||
|
||||
"wechat_bind" -> context.startActivity(WebActivity.getBindWechatIntent(context))
|
||||
|
||||
"video", "video_stream" -> directToVideoDetail(context,
|
||||
"video", "video_stream", "视频" -> directToVideoDetail(context,
|
||||
videoId = linkEntity.link!!,
|
||||
fromLocation = VideoDetailContainerViewModel.Location.VIDEO_CHOICENESS.value,
|
||||
entrance = entrance,
|
||||
@ -204,6 +223,29 @@ object DirectUtils {
|
||||
|
||||
"game_video" -> directToGameVideo(context, linkEntity.link ?: "", entrance, path)
|
||||
|
||||
"libao", "礼包" -> directToGiftDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
"feedback" -> directToFeedback(context, linkEntity.name, linkEntity.text, entrance)
|
||||
|
||||
"qa", "Q&A" -> directToQa(context, linkEntity.text ?: "", linkEntity.link ?: "")
|
||||
|
||||
"qa_collection", "Q&A合集" -> directToQaCollection(context, linkEntity.text
|
||||
?: "", linkEntity.link
|
||||
?: "")
|
||||
|
||||
"anliwall", "安利墙" -> directToAmway(context, fixedTopAmwayCommentId = null, entrance = entrance, path = path)
|
||||
|
||||
"game_detail_comment" -> directToGameDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
"game_upload", "游戏投稿" -> directGameUpload(context, entrance, path)
|
||||
|
||||
"bbs_detail" -> directForumDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
//"h5_game_center" -> directLetoGameCenter(context)
|
||||
|
||||
"" -> {
|
||||
// do nothing
|
||||
}
|
||||
else -> {
|
||||
if (unknownCallback != null) {
|
||||
unknownCallback.invoke()
|
||||
@ -214,11 +256,84 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至QA
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToQa(context: Context, text: String, id: String) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, QaActivity::class.java.simpleName)
|
||||
bundle.putString(KEY_NAVIGATION_TITLE, text)
|
||||
bundle.putString(KEY_QA_ID, id)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至QA合集
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToQaCollection(context: Context, text: String, id: String) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, QaActivity::class.java.simpleName)
|
||||
bundle.putString(KEY_NAVIGATION_TITLE, text)
|
||||
bundle.putString(KEY_QA_COLLECTION_ID, id)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至专题合集
|
||||
*/
|
||||
fun directToColumnCollection(context: Context, id: String, position: Int = -1, entrance: String) {
|
||||
context.startActivity(ColumnCollectionDetailActivity.getIntent(context, id, position, entrance))
|
||||
@JvmStatic
|
||||
fun directToColumnCollection(context: Context, id: String, position: Int = -1, entrance: String, columnName: String = "") {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, ColumnCollectionDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_COLLECTION_ID, id)
|
||||
bundle.putString(KEY_COLUMNNAME, columnName)
|
||||
bundle.putInt(KEY_POSITION, position)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至资讯文章列表
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameNews(context: Context, gameId: String?, gameName: String?, entrance: String?) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameNewsActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
bundle.putString(KEY_GAMEID, gameId)
|
||||
bundle.putString(KEY_GAMENAME, gameName)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至游戏日历表
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameServerCalendar(context: Context, gameId: String?) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, ServersCalendarActivity::class.java.name)
|
||||
bundle.putParcelable(GameEntity::class.java.simpleName, GameEntity().apply {
|
||||
id = gameId ?: ""
|
||||
})
|
||||
bundle.putParcelable(GameDetailServer::class.java.simpleName, GameDetailServer())
|
||||
bundle.putParcelable(MeEntity::class.java.simpleName, MeEntity())
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至游戏历史版本页面
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToHistoryApk(context: Context, gameId: String?) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, HistoryApkListActivity::class.java.name)
|
||||
bundle.putString(KEY_GAMEID, gameId)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -226,6 +341,7 @@ object DirectUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToArticle(context: Context, id: String, entrance: String? = null) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, NewsDetailActivity::class.java.simpleName)
|
||||
@ -268,19 +384,42 @@ object DirectUtils {
|
||||
* 跳转到游戏详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null, scrollToLibao: Boolean = false) {
|
||||
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null, tab: String? = "", traceEvent: ExposureEvent? = null) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, GameDetailActivity::class.java.simpleName)
|
||||
bundle.putString(KEY_GAMEID, id)
|
||||
if (scrollToLibao) {
|
||||
bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_TRENDES)
|
||||
bundle.putBoolean(KEY_SCROLL_TO_LIBAO, scrollToLibao)
|
||||
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)
|
||||
}
|
||||
}
|
||||
if (traceEvent != null) {
|
||||
val clickEvent = createEvent(GameEntity(id), traceEvent.source, appendTrace(traceEvent), ExposureType.CLICK)
|
||||
log(clickEvent)
|
||||
bundle.putParcelable(KEY_TRACE_EVENT, clickEvent)
|
||||
}
|
||||
bundle.putBoolean(KEY_AUTO_DOWNLOAD, autoDownload ?: false)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到游戏评分详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameRatingDetail(context: Context, gameId: String? = "", commentId: String? = "", entrance: String? = null) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_GAMEID, gameId)
|
||||
bundle.putString(KEY_COMMENTID, commentId)
|
||||
bundle.putString(KEY_TO, RatingReplyActivity::class.java.name)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转视频流-游戏介绍进入
|
||||
*/
|
||||
@ -292,7 +431,16 @@ object DirectUtils {
|
||||
bundle.putString(KEY_GAMEID, id)
|
||||
bundle.putBoolean(KEY_OPEN_VIDEO_STREAMING, true)
|
||||
bundle.putInt(KEY_TARGET, GameDetailFragment.INDEX_DESC)
|
||||
// GameDetailActivity.startGameDetailToVideoStreaming(context, id, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToGameDetail(context: Context, id: String, defaultTab: Int = GameDetailFragment.INDEX_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)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -304,6 +452,7 @@ object DirectUtils {
|
||||
// 专栏
|
||||
@JvmStatic
|
||||
fun directToSubject(context: Context, id: String, subjectName: String? = "", entrance: String? = null) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
val subjectData = SubjectData(subjectId = id, subjectName = subjectName, isOrder = false)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
@ -315,12 +464,21 @@ object DirectUtils {
|
||||
// 反馈
|
||||
@JvmStatic
|
||||
fun directToFeedback(context: Context, content: String? = null, entrance: String? = null) {
|
||||
directToFeedback(context, content, null, entrance)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToFeedback(context: Context, content: String? = null, hintType: String? = null, entrance: String? = null) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, SuggestionActivity::class.java.simpleName)
|
||||
bundle.putString(KEY_CONTENT, content)
|
||||
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
|
||||
bundle.putSerializable(EntranceUtils.KEY_SUGGESTTYPE, SuggestType.gameQuestion)
|
||||
if (TextUtils.isEmpty(hintType)) {
|
||||
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
|
||||
} else {
|
||||
bundle.putString(KEY_SUGGEST_HINT_TYPE, hintType)
|
||||
}
|
||||
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.gameQuestion)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -371,6 +529,7 @@ object DirectUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun directToAnswerDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, AnswerDetailActivity::class.java.name)
|
||||
@ -381,6 +540,7 @@ object DirectUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun directToQuestionDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, QuestionsDetailActivity::class.java.name)
|
||||
@ -391,6 +551,7 @@ object DirectUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun directToWebView(context: Context, url: String, entrance: String? = null) {
|
||||
if (url.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, WebActivity::class.java.simpleName)
|
||||
@ -409,7 +570,11 @@ object DirectUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun directToExternalBrowser(context: Context, url: String) {
|
||||
if (url.isEmpty()) return
|
||||
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
if (context !is AppCompatActivity) {
|
||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(browserIntent)
|
||||
}
|
||||
|
||||
@ -430,7 +595,11 @@ object DirectUtils {
|
||||
chatType = "wpa"
|
||||
}
|
||||
val str = "mqqwpa://im/chat?chat_type=$chatType&uin=$qq&version=1&src_type=web"
|
||||
context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str)))
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(str))
|
||||
if (context !is AppCompatActivity) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
// 没有安装QQ 复制账号
|
||||
Util_System_ClipboardManager.setText(context, qq)
|
||||
@ -441,16 +610,25 @@ object DirectUtils {
|
||||
// 跳转 QQ 群
|
||||
@JvmStatic
|
||||
fun directToQqGroup(context: Context, groupNumber: String? = null): Boolean {
|
||||
val intent = Intent()
|
||||
intent.data = Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$groupNumber")
|
||||
// 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
try {
|
||||
context.startActivity(intent)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
// 未安装手Q或安装的版本不支持
|
||||
if (groupNumber.isNullOrEmpty()) return false
|
||||
if (ShareUtils.isQQClientAvailable(context)) {
|
||||
val intent = Intent()
|
||||
intent.data = Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D$groupNumber")
|
||||
// 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
return try {
|
||||
if (context !is AppCompatActivity) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
Utils.toast(context, "请安装QQ客户端")
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,10 +636,12 @@ object DirectUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGiftDetail(context: Context, giftId: String, entrance: String? = null) {
|
||||
if (giftId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_TO, LibaoDetailActivity::class.java.simpleName)
|
||||
bundle.putString(EntranceUtils.KEY_ID, giftId)
|
||||
HaloApp.put(LibaoEntity.TAG, null)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@ -510,11 +690,24 @@ object DirectUtils {
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToCommunityArticle(context: Context, community: CommunityEntity?, articleId: String?, entrance: String?, path: String?) {
|
||||
if (articleId.isNullOrEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
bundle.putString(KEY_TO, ArticleDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_COMMUNITY_ARTICLE_ID, articleId)
|
||||
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到社区专题
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToCommunityColumn(context: Context, community: CommunityEntity?, subjectId: String, entrance: String?, path: String?) {
|
||||
if (subjectId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_PATH, path)
|
||||
bundle.putString(KEY_TO, CommunitySubjectActivity::class.java.name)
|
||||
@ -528,7 +721,8 @@ object DirectUtils {
|
||||
* @param fromLocation 可见 [VideoDetailContainerViewModel.Location]
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null, path: String? = "", referer: String = "", type: String = "", act: String = "") {
|
||||
fun directToVideoDetail(context: Context, videoId: String, fromLocation: String, showComment: Boolean = false, gameId: String = "", entrance: String? = null,
|
||||
path: String? = "", referer: String = "", type: String = "", act: String = "", paginationType: String = "", fieldId: String = "", sectionName: String = "") {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
@ -541,6 +735,9 @@ object DirectUtils {
|
||||
bundle.putString(KEY_REFERER, referer)
|
||||
bundle.putString(KEY_TYPE, type)
|
||||
bundle.putString(KEY_ACTIVITY_NAME, act)
|
||||
bundle.putString(KEY_PAGINATION_TYPE, paginationType)
|
||||
bundle.putString(KEY_FIELD_ID, fieldId)
|
||||
bundle.putString(KEY_SECTION_NAME, sectionName)
|
||||
jumpActivity(context, bundle)
|
||||
} else {
|
||||
DialogUtils.showLowSystemVersionDialog(context)
|
||||
@ -578,20 +775,37 @@ object DirectUtils {
|
||||
* 跳转至上传视频
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToVideoManager(context: Context, linkEntity: VideoLinkEntity, entrance: String? = null, path: String? = "") {
|
||||
fun directToVideoManager(context: Context, linkEntity: VideoLinkEntity, simpleGameEntity: SimpleGameEntity, entrance: String? = null, path: String? = "") {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_PATH, path)
|
||||
bundle.putParcelable(VideoLinkEntity::class.java.simpleName, linkEntity)
|
||||
bundle.putParcelable(SimpleGameEntity::class.java.simpleName, simpleGameEntity)
|
||||
bundle.putString(KEY_TO, VideoManagerActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, BaseActivity.mergeEntranceAndPath(entrance, path))
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToFullScreenWebPage(context: Context, url: String, webViewHandleBackPressed: Boolean = false) {
|
||||
context.startActivity(FullScreenWebActivity.getIntent(context, url, webViewHandleBackPressed))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directToRegulationTestPage(context: Context) {
|
||||
val url = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.REGULATION_TEST_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.REGULATION_TEST_ADDRESS
|
||||
}
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转视频合集
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameVideo(context: Context, gameId: String, entrance: String? = null, path: String? = "") {
|
||||
if (gameId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_PATH, path)
|
||||
bundle.putString(KEY_TO, GameVideoActivity::class.java.name)
|
||||
@ -609,4 +823,186 @@ object DirectUtils {
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转梦工厂小游戏
|
||||
*/
|
||||
/*@JvmStatic
|
||||
fun directLetoGameCenter(context: Context) {
|
||||
if (UserManager.getInstance().isLoggedIn) {
|
||||
UserManager.getInstance().userInfoEntity?.run {
|
||||
MgcAccountManager.syncAccount(context, if (idCard != null) idCard!!.name else name, mobile, name, icon, true,
|
||||
object : SyncUserInfoListener {
|
||||
override fun onSuccess(data: LoginResultBean?) {}
|
||||
|
||||
override fun onFail(code: String?, message: String?) {}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
MgcAccountManager.exitAccount(context, object : SyncUserInfoListener {
|
||||
override fun onSuccess(data: LoginResultBean?) {}
|
||||
|
||||
override fun onFail(code: String?, message: String?) {}
|
||||
})
|
||||
}
|
||||
Leto.getInstance().startGameCenter(context)
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 跳转分类
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directCategoryDirectory(context: Context, categoryId: String, categoryTitle: String, entrance: String? = null, path: String? = "") {
|
||||
if (categoryId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, CategoryDirectoryActivity::class.java.name)
|
||||
bundle.putString(KEY_CATEGORY_ID, categoryId)
|
||||
bundle.putString(KEY_CATEGORY_TITLE, categoryTitle)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到问题标签详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directAskColumnLabelDetail(context: Context, tag: String, community: CommunityEntity, entrance: String? = null, path: String? = "") {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, AskColumnDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_ASK_TAG, tag)
|
||||
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到专栏详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directAskColumnDetail(context: Context, columnId: String, community: CommunityEntity, entrance: String? = null, path: String? = "") {
|
||||
if (columnId.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, AskColumnDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_COLUMN_ID, columnId)
|
||||
bundle.putParcelable(KEY_COMMUNITY_DATA, community)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到板块
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBlock(context: Context, blockData: SubjectRecommendEntity, entrance: String) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, BlockActivity::class.java.name)
|
||||
bundle.putParcelable(KEY_BLOCK_DATA, blockData)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到开服表
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameServers(context: Context, entrance: String, path: String) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameServersActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, ToolBarActivity.mergeEntranceAndPath(entrance, path))
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到游戏上传
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directGameUpload(context: Context, entrance: String? = null, path: String? = "") {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, GameSubmissionActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 社区文章
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directSimpleArticleList(context: Context, sortType: String, entrance: String? = null, path: String? = "") {
|
||||
if (sortType.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, SimpleArticleListActivity::class.java.name)
|
||||
bundle.putString(KEY_TYPE, sortType)
|
||||
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
|
||||
bundle.putString(KEY_PATH, path)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directGameZone(context: Context, gameId: String, url: String, entrance: String? = null) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.sensitiveApi
|
||||
.getGameDigest(gameId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<GameEntity>() {
|
||||
override fun onResponse(response: GameEntity?) {
|
||||
response?.apply {
|
||||
if (zone.status == "on") {
|
||||
if (zone.style == "link") {
|
||||
directToGameDetail(context, gameId, GameDetailFragment.INDEX_TRENDES, entrance)
|
||||
} else {
|
||||
directToWebView(context, url, entrance)
|
||||
}
|
||||
} else {
|
||||
directToWebView(context, url, entrance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directVideoData(context: Context, entrance: String? = null) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, VideoDataActivity::class.java.name)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun directForumDetail(context: Context, bbsId: String? = "", entrance: String? = null) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, ForumDetailActivity::class.java.name)
|
||||
bundle.putString(KEY_BBS_ID, bbsId)
|
||||
bundle.putString(KEY_ENTRANCE, entrance)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
|
||||
/**
|
||||
* 到首页论坛 tab
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToForum(context: Context) {
|
||||
if (RunningUtils.isRunning(context)
|
||||
&& MainActivity::class.java.name == RunningUtils.getBaseActivity(context)) {
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
context.startActivity(intent)
|
||||
|
||||
// 这里换个线程操作是为了做一点延时
|
||||
AppExecutor.ioExecutor.execute {
|
||||
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.INDEX_ASK))
|
||||
}
|
||||
} else {
|
||||
jumpActivity(context, Bundle().apply { putInt(KEY_POSITION, MainWrapperFragment.INDEX_ASK) })
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
@ -206,6 +207,13 @@ public class DisplayUtils {
|
||||
public static void setStatusBarColor(Activity activity, int color, boolean lightStatusBar) {
|
||||
Window window = activity.getWindow();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (!isMiuiOs()) {
|
||||
//取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
//需要设置这个 flag 才能调用 setStatusBarColor 来设置状态栏颜色
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
}
|
||||
|
||||
window.setStatusBarColor(ContextCompat.getColor(activity, color));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
@ -250,6 +258,40 @@ public class DisplayUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int getScreenWidth() {
|
||||
WindowManager manager = (WindowManager) HaloApp.getInstance().getApplication().getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
manager.getDefaultDisplay().getMetrics(metrics);
|
||||
return metrics.widthPixels;
|
||||
}
|
||||
|
||||
public static int getScreenHeight() {
|
||||
WindowManager manager = (WindowManager) HaloApp.getInstance().getApplication().getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
manager.getDefaultDisplay().getMetrics(metrics);
|
||||
return metrics.heightPixels;
|
||||
}
|
||||
|
||||
public static int getToastOffset() {
|
||||
try {
|
||||
int i = Resources.getSystem().getIdentifier("toast_y_offset", "dimen", "android");
|
||||
return HaloApp.getInstance().getApplication().getResources().getDimensionPixelSize(i);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return dip2px(24);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getToastDefaultGravity() {
|
||||
try {
|
||||
int i = Resources.getSystem().getIdentifier("config_toastDefaultGravity", "integer", "android");
|
||||
return HaloApp.getInstance().getApplication().getResources().getInteger(i);
|
||||
} catch (Resources.NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasSoftKeys(Context context) {
|
||||
if (!(context instanceof Activity)) return false;
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.common.filter.RegionSettingHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
@ -18,8 +19,12 @@ object DownloadHelper {
|
||||
* @param block 成功添加下载任务后执行的代码块
|
||||
*/
|
||||
fun createABrandNewDownloadTaskQuietly(gameId: String? = "", packageName: String? = "", block: () -> Unit) {
|
||||
if (RegionSettingHelper.shouldThisGameBeFiltered(gameId)) {
|
||||
return
|
||||
}
|
||||
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.api
|
||||
.sensitiveApi
|
||||
.getGameDigest(gameId)
|
||||
.map(ApkActiveUtils.filterMapper)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -9,12 +9,16 @@ import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.CertificationDialog;
|
||||
import com.gh.common.dialog.DeviceRemindDialog;
|
||||
import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.exposure.ExposureUtils;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.view.DownloadDialog;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.WebActivity;
|
||||
@ -38,6 +42,9 @@ import androidx.collection.ArrayMap;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* todo 下载判断不能以按钮文案为判断条件,否则按钮文案修改时又要修改判断逻辑
|
||||
*/
|
||||
public class DownloadItemUtils {
|
||||
|
||||
// 更新下载进度条
|
||||
@ -125,20 +132,27 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_pause_dn);
|
||||
}
|
||||
if (gameEntity.isLibaoExists()) {
|
||||
holder.gameLibaoIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.gameLibaoIcon.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
|
||||
boolean isShowPlatform) {
|
||||
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game);
|
||||
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, false, null);
|
||||
}
|
||||
|
||||
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
|
||||
boolean isShowPlatform, PluginLocation pluginLocation) {
|
||||
boolean isShowPlatform, boolean hideDownloadBtnIfNoAvailableContent) {
|
||||
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, hideDownloadBtnIfNoAvailableContent, null);
|
||||
}
|
||||
|
||||
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
|
||||
boolean isShowPlatform, String briefStyle) {
|
||||
updateItem(context, gameEntity, holder, isShowPlatform, PluginLocation.only_game, false, briefStyle);
|
||||
}
|
||||
|
||||
public static void updateItem(Context context, GameEntity gameEntity, GameViewHolder holder,
|
||||
boolean isShowPlatform, PluginLocation pluginLocation,
|
||||
boolean hideDownloadBtnIfNoAvailableContent,
|
||||
@Nullable String briefStyle) {
|
||||
|
||||
// 控制是否显示下载按钮
|
||||
if (!Config.isShowDownload(gameEntity.getId()) || context.getString(R.string.app_name).equals(gameEntity.getName())) {
|
||||
@ -147,17 +161,9 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (gameEntity.isLibaoExists()) {
|
||||
holder.gameLibaoIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.gameLibaoIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// 显示预约
|
||||
if (gameEntity.isReservable()) {
|
||||
holder.gameDes.setVisibility(View.VISIBLE);
|
||||
holder.gameProgressbar.setVisibility(View.GONE);
|
||||
holder.gameInfo.setVisibility(View.GONE);
|
||||
updateItemViewStatus(holder, false, briefStyle);
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
|
||||
holder.gameDownloadBtn.setText("预约");
|
||||
holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
@ -171,14 +177,12 @@ public class DownloadItemUtils {
|
||||
}
|
||||
|
||||
if (gameEntity.getApk().isEmpty()
|
||||
|| gameEntity.getDownloadOffStatus() != null) {
|
||||
|| gameEntity.getDownloadOffStatus() != null) {
|
||||
LinkEntity h5LinkEntity = gameEntity.getH5Link();
|
||||
String offStatus = gameEntity.getDownloadOffStatus();
|
||||
|
||||
holder.gameDes.setVisibility(View.VISIBLE);
|
||||
holder.gameProgressbar.setVisibility(View.GONE);
|
||||
holder.gameInfo.setVisibility(View.GONE);
|
||||
|
||||
|
||||
updateItemViewStatus(holder, false, briefStyle);
|
||||
|
||||
if (h5LinkEntity != null) {
|
||||
if ("play".equals(h5LinkEntity.getType())) {
|
||||
holder.gameDownloadBtn.setText("开始玩");
|
||||
@ -195,20 +199,23 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setText("暂无");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.news_detail_comment);
|
||||
if (hideDownloadBtnIfNoAvailableContent) {
|
||||
holder.gameDownloadBtn.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
holder.gameDownloadBtn.setClickable(false);
|
||||
}
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
updateNormalItem(context, holder, gameEntity, isShowPlatform, pluginLocation);
|
||||
updateNormalItem(context, holder, gameEntity, isShowPlatform, pluginLocation, briefStyle);
|
||||
} else {
|
||||
updatePluginItem(context, holder, gameEntity, isShowPlatform, pluginLocation);
|
||||
updatePluginItem(context, holder, gameEntity, isShowPlatform, pluginLocation, briefStyle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 更新正常的条目,只有一个apk包
|
||||
static void updateNormalItem(Context context, GameViewHolder holder, GameEntity gameEntity,
|
||||
boolean isShowPlatform, PluginLocation pluginLocation) {
|
||||
boolean isShowPlatform, PluginLocation pluginLocation, String briefStyle) {
|
||||
|
||||
final ArrayMap<String, DownloadEntity> entryMap = gameEntity.getEntryMap();
|
||||
final ApkEntity apkEntity = gameEntity.getApk().get(0);
|
||||
@ -224,14 +231,12 @@ public class DownloadItemUtils {
|
||||
|
||||
GameUtils.setDownloadBtnStatus(context, gameEntity, holder.gameDownloadBtn, pluginLocation);
|
||||
|
||||
holder.gameDes.setVisibility(View.VISIBLE);
|
||||
holder.gameProgressbar.setVisibility(View.GONE);
|
||||
holder.gameInfo.setVisibility(View.GONE);
|
||||
updateItemViewStatus(holder, false, briefStyle);
|
||||
}
|
||||
|
||||
// 更新插件的条目,有多个apk包
|
||||
private static void updatePluginItem(Context context, GameViewHolder holder, GameEntity gameEntity,
|
||||
boolean isShowPlatform, PluginLocation pluginLocation) {
|
||||
boolean isShowPlatform, PluginLocation pluginLocation, String briefStyle) {
|
||||
GameUtils.setDownloadBtnStatus(context, gameEntity, holder.gameDownloadBtn, pluginLocation);
|
||||
|
||||
ArrayMap<String, DownloadEntity> entryMap = gameEntity.getEntryMap();
|
||||
@ -250,18 +255,15 @@ public class DownloadItemUtils {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
holder.gameDes.setVisibility(View.VISIBLE);
|
||||
holder.gameProgressbar.setVisibility(View.GONE);
|
||||
holder.gameInfo.setVisibility(View.GONE);
|
||||
updateItemViewStatus(holder, false, briefStyle);
|
||||
}
|
||||
|
||||
// 更改进度条和提示文本的状态
|
||||
public static void changeStatus(Context context, GameViewHolder holder, DownloadEntity downloadEntity,
|
||||
boolean isShowPlatform, boolean isNormal) {
|
||||
holder.gameDes.setVisibility(View.GONE);
|
||||
holder.gameProgressbar.setVisibility(View.VISIBLE);
|
||||
holder.gameInfo.setVisibility(View.VISIBLE);
|
||||
|
||||
updateItemViewStatus(holder, true, null);
|
||||
holder.gameProgressbar.setProgressDrawable(context.getResources().getDrawable(R.drawable.progressbar_bg_style));
|
||||
|
||||
String platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.getPlatform());
|
||||
|
||||
@ -322,6 +324,17 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style));
|
||||
}
|
||||
} else if (status.equals(DownloadStatus.done)) {
|
||||
String xapkStatus = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_STATUS);
|
||||
if (XapkUnzipStatus.UNZIPPING.name().equals(xapkStatus)) {
|
||||
String percent = downloadEntity.getMeta().get(XapkInstaller.XAPK_UNZIP_PERCENT);
|
||||
holder.gameProgressbar.setProgressDrawable(context.getResources().getDrawable(R.drawable.progressbar_xapk_style));
|
||||
holder.gameDownloadSpeed.setText(R.string.unzipping);
|
||||
holder.gameProgressbar.setProgress((int) (Float.valueOf(percent) * 10));
|
||||
holder.gameDownloadPercentage.setText(percent + "%");
|
||||
holder.gameDownloadBtn.setText(R.string.unzipping);
|
||||
return;
|
||||
}
|
||||
|
||||
holder.gameProgressbar.setProgress(1000);
|
||||
if (isShowPlatform && platform != null) {
|
||||
holder.gameDownloadSpeed.setText(String.format("%s - 下载完成", platform));
|
||||
@ -334,15 +347,38 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setText(R.string.install);
|
||||
holder.gameDownloadBtn.setTextColor(Color.WHITE);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.download_button_pluggable_style);
|
||||
} else {
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.download_button_normal_style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateItemViewStatus(GameViewHolder holder, boolean hasDownload, @Nullable String briefStyle) {
|
||||
if (hasDownload) {
|
||||
if (holder.gameRating != null) holder.gameRating.setVisibility(View.GONE);
|
||||
holder.gameDes.setVisibility(View.GONE);
|
||||
holder.gameProgressbar.setVisibility(View.VISIBLE);
|
||||
holder.gameInfo.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.gameProgressbar.setVisibility(View.GONE);
|
||||
holder.gameInfo.setVisibility(View.GONE);
|
||||
if (briefStyle != null && briefStyle.contains("star")) {
|
||||
if (holder.gameRating != null) holder.gameRating.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
if (holder.gameRating != null) holder.gameRating.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(briefStyle) || briefStyle.contains("brief")) {
|
||||
holder.gameDes.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.gameDes.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setOnClickListener(final Context context,
|
||||
final TextView downloadBtn,
|
||||
final GameEntity gameEntity,
|
||||
@ -420,11 +456,19 @@ public class DownloadItemUtils {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (gameEntity.getApk().size() == 0 && gameEntity.getH5Link() != null) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), "play".equals(gameEntity.getH5Link().getType()));
|
||||
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
|
||||
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
|
||||
if (isPlay) {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay,linkEntity.getCloseButton());
|
||||
context.startActivity(i);
|
||||
});
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
@ -449,7 +493,16 @@ public class DownloadItemUtils {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(context, () -> {
|
||||
DownloadDialog.getInstance(context).showPopupWindow(v, gameEntity, entrance, location, traceEvent);
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
traceEvent,
|
||||
entrance,
|
||||
location);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -480,19 +533,42 @@ public class DownloadItemUtils {
|
||||
if (str.equals(context.getString(R.string.download))) {
|
||||
// 先弹下载弹窗(如果需要的话)
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.getId(), gameEntity.getName(), entrance);
|
||||
} else if (str.equals(context.getString(R.string.pluggable))) {
|
||||
} else if (str.equals(context.getString(R.string.attempt))) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
DataLogUtils.uploadGameLog(context, gameEntity.getId(), gameEntity.getName(), entrance);
|
||||
} else if (str.contains("化")) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "插件化", gameEntity.getName());
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
if (gameEntity.getPluggableCollection() != null) {
|
||||
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location);
|
||||
} else {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> plugin(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
});
|
||||
}
|
||||
} else if (str.equals(context.getString(R.string.install))) {
|
||||
install(context, gameEntity, position, adapter);
|
||||
} else if (str.equals(context.getString(R.string.launch))) {
|
||||
@ -501,10 +577,6 @@ public class DownloadItemUtils {
|
||||
}
|
||||
DataUtils.onGameLaunchEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
|
||||
PackageUtils.launchApplicationByPackageName(context, gameEntity.getApk().get(0).getPackageName());
|
||||
} else if (str.equals(context.getString(R.string.waiting))
|
||||
|| str.equals(context.getString(R.string.downloading))) {
|
||||
context.startActivity(DownloadManagerActivity.getDownloadMangerIntent(context,
|
||||
apk.getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
|
||||
} else if (str.equals(context.getString(R.string.update))) {
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "更新", gameEntity.getName());
|
||||
@ -513,6 +585,9 @@ public class DownloadItemUtils {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> update(context, gameEntity, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
} else {
|
||||
context.startActivity(DownloadManagerActivity.getDownloadMangerIntent(context,
|
||||
apk.getUrl(), entrance + "+(" + location.split(":")[0] + ")"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -528,14 +603,13 @@ public class DownloadItemUtils {
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), entrance, "下载开始", "下载");
|
||||
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, gameEntity.getApk().get(0).getPlatform(), traceEvent, ExposureUtils.DownloadType.DOWNLOAD);
|
||||
|
||||
DownloadManager.createDownload(context, gameEntity, context.getString(R.string.download), entrance, location, isSubscribe, downloadExposureEvent);
|
||||
DownloadManager.createDownload(context, gameEntity, context.getString(R.string.download), entrance, location, isSubscribe, traceEvent);
|
||||
Utils.toast(context, gameEntity.getName() + "已加入下载队列");
|
||||
|
||||
downloadBtn.setText(R.string.downloading);
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_downloading_style);
|
||||
downloadBtn.setTextColor(ContextCompat.getColorStateList(context, R.color.text_downloading_style));
|
||||
DeviceRemindDialog.Companion.showDeviceRemindDialog(context, gameEntity);
|
||||
} else {
|
||||
Utils.toast(context, msg);
|
||||
}
|
||||
@ -548,9 +622,7 @@ public class DownloadItemUtils {
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
DataUtils.onGameDownloadEvent(context, gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), entrance, "下载开始", "插件化");
|
||||
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, gameEntity.getApk().get(0).getPlatform(), traceEvent, ExposureUtils.DownloadType.PLUGIN_DOWNLOAD);
|
||||
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, downloadExposureEvent);
|
||||
DownloadManager.createDownload(context, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent);
|
||||
Utils.toast(context, gameEntity.getName() + "已加入下载队列");
|
||||
|
||||
downloadBtn.setText(R.string.downloading);
|
||||
@ -575,8 +647,10 @@ public class DownloadItemUtils {
|
||||
gameEntity.getEntryMap().remove(apkEntity.getPlatform());
|
||||
}
|
||||
adapter.notifyItemChanged(position);
|
||||
} else if (PackageUtils.isCanPluggable(apkEntity)) {
|
||||
DialogUtils.showPluginDialog(context, () -> PackageInstaller.uninstall(context, path));
|
||||
} else {
|
||||
PackageUtils.launchSetup(context, downloadEntity);
|
||||
PackageInstaller.install(context, downloadEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -584,13 +658,9 @@ public class DownloadItemUtils {
|
||||
//更新
|
||||
private static void update(Context context, GameEntity gameEntity, String entrance, String location, boolean isSubscribe, @Nullable ExposureEvent traceEvent) {
|
||||
ApkEntity apkEntity = gameEntity.getApk().get(0);
|
||||
|
||||
ExposureUtils.DownloadType downloadType = ExposureUtils.getUpdateType(apkEntity);
|
||||
|
||||
DataUtils.onGameUpdateEvent(context, gameEntity.getName(), apkEntity.getPlatform(), "下载开始");
|
||||
|
||||
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, apkEntity
|
||||
.getPlatform(), traceEvent, downloadType);
|
||||
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, isSubscribe, downloadExposureEvent);
|
||||
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, isSubscribe, traceEvent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@ import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.gh.common.AppExecutor
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.common.xapk.XapkUnzipStatus
|
||||
import com.gh.gamecenter.R
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
@ -38,9 +40,12 @@ object DownloadNotificationHelper {
|
||||
var requireUpdateNotificationGroupDelay = false
|
||||
val notificationManager = getNotificationManager()
|
||||
val downloadNotificationId = (entity.gameId + entity.packageName).hashCode()
|
||||
val xapkStatus = entity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
|
||||
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SILENT_UPDATE) return
|
||||
|
||||
val intent = Intent()
|
||||
if (entity.status == DownloadStatus.done) {
|
||||
if (entity.status == DownloadStatus.done && xapkStatus != XapkUnzipStatus.FAILURE.name) {
|
||||
intent.putExtra(EntranceUtils.KEY_DATA, entity.toJson())
|
||||
intent.putExtra(EntranceUtils.KEY_PATH, entity.path)
|
||||
intent.action = ACTION_INSTALL
|
||||
@ -53,7 +58,6 @@ object DownloadNotificationHelper {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// importance == IMPORTANCE_DEFAULT 时每次更新都会触发震动
|
||||
val channel = NotificationChannel(DOWNLOAD_CHANNEL_ID, DOWNLOAD_CHANNEL_ID, NotificationManager.IMPORTANCE_LOW)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
@ -65,18 +69,22 @@ object DownloadNotificationHelper {
|
||||
.setContentIntent(pendingIntent)
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setWhen(whenTime)
|
||||
.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
|
||||
|
||||
when (entity.status) {
|
||||
DownloadStatus.downloading -> builder.setContentText(String.format("%s(剩%s)",
|
||||
SpeedUtils.getSpeed(entity.speed),
|
||||
SpeedUtils.getRemainTime(entity.size, entity.progress, entity.speed * 1024)))
|
||||
DownloadStatus.done -> builder.setContentText("下载完成,点击立即安装")
|
||||
DownloadStatus.waiting -> builder.setContentText("等待中")
|
||||
DownloadStatus.subscribe,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror -> builder.setContentText("已暂停,连接WiFi自动下载")
|
||||
else -> builder.setContentText("暂停中")
|
||||
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {
|
||||
builder.setContentText("《" + entity.name + "》解压失败,点击查看详情~")
|
||||
} else {
|
||||
when (entity.status) {
|
||||
DownloadStatus.downloading -> builder.setContentText(String.format("%s(剩%s)",
|
||||
SpeedUtils.getSpeed(entity.speed),
|
||||
SpeedUtils.getRemainTime(entity.size, entity.progress, entity.speed * 1024)))
|
||||
DownloadStatus.done -> builder.setContentText("下载完成,点击立即安装")
|
||||
DownloadStatus.waiting -> builder.setContentText("等待中")
|
||||
DownloadStatus.subscribe,
|
||||
DownloadStatus.timeout,
|
||||
DownloadStatus.neterror -> builder.setContentText("已暂停,连接WiFi自动下载")
|
||||
else -> builder.setContentText("暂停中")
|
||||
}
|
||||
builder.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
|
||||
}
|
||||
|
||||
when {
|
||||
@ -88,30 +96,39 @@ object DownloadNotificationHelper {
|
||||
else -> builder.setSortKey("C")
|
||||
}
|
||||
|
||||
val notification = builder.build()
|
||||
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
|
||||
|
||||
if (entity.status == DownloadStatus.delete
|
||||
|| entity.status == DownloadStatus.cancel
|
||||
|| entity.status == DownloadStatus.hijack
|
||||
|| entity.status == DownloadStatus.notfound
|
||||
|| entity.status == DownloadStatus.overflow
|
||||
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
|
||||
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty())) {
|
||||
requireUpdateNotificationGroupDelay = true
|
||||
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
|
||||
} else {
|
||||
if (entity.status != DownloadStatus.downloading) {
|
||||
notificationManager.notify(entity.path, DOWNLOAD_NOTIFICATION_ID, notification)
|
||||
tryCatchInRelease {
|
||||
val notification = builder.build() // 可能会抛出异常
|
||||
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
|
||||
if (xapkStatus == XapkUnzipStatus.FAILURE.name) {
|
||||
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
|
||||
} else {
|
||||
val time = mNotifyMap[entity.path]
|
||||
val curTime = System.currentTimeMillis()
|
||||
if (time == null || curTime - time > 2000) {
|
||||
mNotifyMap[entity.path] = curTime
|
||||
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
|
||||
}
|
||||
|
||||
if (entity.status == DownloadStatus.delete
|
||||
|| entity.status == DownloadStatus.cancel
|
||||
|| entity.status == DownloadStatus.hijack
|
||||
|| entity.status == DownloadStatus.notfound
|
||||
|| entity.status == DownloadStatus.overflow
|
||||
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
|
||||
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty()
|
||||
&& xapkStatus != XapkUnzipStatus.FAILURE.name)) {
|
||||
requireUpdateNotificationGroupDelay = true
|
||||
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
|
||||
} else {
|
||||
if (entity.status != DownloadStatus.downloading) {
|
||||
notificationManager.notify(entity.path, DOWNLOAD_NOTIFICATION_ID, notification)
|
||||
} else {
|
||||
val time = mNotifyMap[entity.path]
|
||||
val curTime = System.currentTimeMillis()
|
||||
if (time == null || curTime - time > 2000) {
|
||||
mNotifyMap[entity.path] = curTime
|
||||
notificationManager.notify(entity.path, DOWNLOAD_NOTIFICATION_ID, notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (requireUpdateNotificationGroupDelay) {
|
||||
// 虽然运行到这里时 notification 已经被 cancel 了,但在下面的 notificationManager.getActiveNotifications 里它有可能还是 active 状态,
|
||||
// 这里延时 100 ms 避免出现所有的任务都取消了以后依旧有一条 notification group 常驻
|
||||
|
||||
@ -6,6 +6,8 @@ import android.preference.PreferenceManager
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.R
|
||||
@ -35,15 +37,23 @@ import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
object DownloadObserver {
|
||||
|
||||
|
||||
private val mApplication = HaloApp.getInstance().application
|
||||
|
||||
// 如果在WIFI状态下,下载自动暂停,则再重试一遍
|
||||
@JvmStatic
|
||||
fun initObserver() {
|
||||
val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity) {
|
||||
if (downloadEntity.status != DownloadStatus.downloading) {
|
||||
LogUtils.uploadDownloadEvent(downloadEntity)
|
||||
// todo 如何处理xapk安装问题
|
||||
val xapkStatus = downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]
|
||||
if (!xapkStatus.isNullOrEmpty()) return
|
||||
|
||||
val gameId = downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER)
|
||||
val downloadManager = DownloadManager.getInstance(HaloApp.getInstance().application)
|
||||
|
||||
tryCatchInRelease {
|
||||
DownloadDataHelper.uploadDownloadEvent(downloadEntity)
|
||||
}
|
||||
|
||||
if (DownloadStatus.hijack == downloadEntity.status) {
|
||||
@ -51,45 +61,59 @@ object DownloadObserver {
|
||||
processHijack(downloadEntity)
|
||||
val nameAndPlatform = (downloadEntity.name + ":"
|
||||
+ PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
MtaHelper.onEvent( "下载劫持",
|
||||
"游戏名字", nameAndPlatform,
|
||||
"网络状态", DeviceUtils.getNetwork(mApplication))
|
||||
// MtaHelper.onEvent("下载劫持",
|
||||
// "游戏名字", nameAndPlatform,
|
||||
// "网络状态", DeviceUtils.getNetwork(mApplication))
|
||||
return
|
||||
} else if (DownloadStatus.notfound == downloadEntity.status) {
|
||||
// 404 Not Found
|
||||
// 删除任务
|
||||
downloadEntity.status = DownloadStatus.cancel
|
||||
DownloadManager.getInstance(mApplication).cancel(downloadEntity.url)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
Utils.toast(mApplication, "该链接已失效!请联系管理员。")
|
||||
|
||||
MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
|
||||
"游戏", downloadEntity.name,
|
||||
"平台", downloadEntity.platform)
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("下载失败弹窗",
|
||||
// "游戏", downloadEntity.name,
|
||||
// "平台", downloadEntity.platform)
|
||||
|
||||
DialogUtils.showAlertDialog(AppManager.getInstance().currentActivity(), "下载失败", "下载链接已失效,建议提交反馈", "立即反馈", "取消", {
|
||||
SuggestionActivity.startSuggestionActivity(AppManager.getInstance().currentActivity(),
|
||||
SuggestType.gameQuestion, "notfound",
|
||||
StringUtils.buildString(downloadEntity.name, ",问题反馈:下载链接失效"),
|
||||
SimpleGameEntity(downloadEntity.gameId, downloadEntity.name, ""))
|
||||
SimpleGameEntity(gameId, downloadEntity.name, ""))
|
||||
}, null)
|
||||
return
|
||||
} else if (DownloadStatus.neterror == downloadEntity.status || DownloadStatus.timeout == downloadEntity.status) {
|
||||
if (downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD].isNullOrEmpty()
|
||||
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
|
||||
downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD] = downloadEntity.progress.toString()
|
||||
downloadManager.updateDownloadEntity(downloadEntity)
|
||||
downloadManager.startDownload(downloadEntity.url)
|
||||
debugOnly {
|
||||
Utils.log("DownloadObserver", "下载重试->" + downloadEntity.toJson())
|
||||
}
|
||||
} else {
|
||||
Utils.toast(mApplication, "网络不稳定,下载任务已暂停")
|
||||
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
|
||||
|
||||
Utils.toast(mApplication, "网络不稳定,下载任务已暂停")
|
||||
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
|
||||
|
||||
MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停",
|
||||
"游戏", downloadEntity.name,
|
||||
"平台", downloadEntity.platform)
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("下载自动暂停",
|
||||
// "游戏", downloadEntity.name,
|
||||
// "平台", downloadEntity.platform)
|
||||
debugOnly {
|
||||
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DownloadStatus.done == downloadEntity.status) {
|
||||
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
|
||||
MtaHelper.onEvent("软件更新", "下载完成")
|
||||
// 会有 ActivityNotFoundException 异常,catch 掉不管了
|
||||
tryWithDefaultCatch {
|
||||
// 会有 ActivityNotFoundException 异常,catch 掉不管了
|
||||
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path, true))
|
||||
if (Constants.SILENT_UPDATE != downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)) {
|
||||
PackageInstaller.install(mApplication, downloadEntity)
|
||||
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
|
||||
}
|
||||
}
|
||||
DataLogUtils.uploadUpgradeLog(mApplication, "install") //上传更新安装数据
|
||||
} else {
|
||||
statDoneEvent(downloadEntity)
|
||||
|
||||
@ -110,12 +134,12 @@ object DownloadObserver {
|
||||
if (PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)) {
|
||||
if (FileUtils.isEmptyFile(downloadEntity.path)) {
|
||||
Utils.toast(mApplication, R.string.install_failure_hint)
|
||||
DownloadManager.getInstance(mApplication).cancel(downloadEntity.url)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else {
|
||||
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
tryWithDefaultCatch {
|
||||
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path))
|
||||
PackageInstaller.install(mApplication, downloadEntity, false)
|
||||
}
|
||||
} else {
|
||||
// 弹出卸载提示框
|
||||
@ -126,26 +150,33 @@ object DownloadObserver {
|
||||
}
|
||||
|
||||
// 统计下载完成
|
||||
uploadData(downloadEntity.gameId, downloadEntity.platform)
|
||||
uploadData(gameId, downloadEntity.platform)
|
||||
}
|
||||
|
||||
// 下载过程分析统计
|
||||
val pm = mApplication.packageManager
|
||||
val packageInfo = pm.getPackageArchiveInfo(downloadEntity.path, PackageManager.GET_ACTIVITIES)
|
||||
if (packageInfo == null) {
|
||||
MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
|
||||
"游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
|
||||
MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
|
||||
"游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误分析",
|
||||
// "游戏名字", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
//
|
||||
// MtaHelper.onEventWithBasicDeviceInfo("解析包错误_新",
|
||||
// "游戏", downloadEntity.name + ":" + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadEntity.status == DownloadStatus.done) {
|
||||
EventBus.getDefault().post(EBDownloadStatus("done", "", "", "", "", ""))
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,32 +207,34 @@ object DownloadObserver {
|
||||
type = ExposureUtils.DownloadType.DOWNLOAD
|
||||
}
|
||||
|
||||
val kv2 = HashMap<String, Any>()
|
||||
kv2["版本"] = downloadEntity.platform
|
||||
kv2["状态"] = "下载完成"
|
||||
kv2["位置"] = downloadEntity.entrance ?: "null"
|
||||
kv2["游戏分平台"] = downloadEntity.name + "-" + platform
|
||||
kv2["光环助手版本"] = BuildConfig.VERSION_NAME
|
||||
DataUtils.onEvent(mApplication, "游戏下载位置", downloadEntity.name, kv2)
|
||||
// val kv2 = HashMap<String, Any>()
|
||||
// kv2["版本"] = downloadEntity.platform
|
||||
// kv2["状态"] = "下载完成"
|
||||
// kv2["位置"] = downloadEntity.entrance ?: "null"
|
||||
// kv2["游戏分平台"] = downloadEntity.name + "-" + platform
|
||||
// kv2["光环助手版本"] = BuildConfig.VERSION_NAME
|
||||
// DataUtils.onEvent(mApplication, "游戏下载位置", downloadEntity.name, kv2)
|
||||
|
||||
if (downloadEntity.isPluggable) {
|
||||
val kv3 = HashMap<String, Any>()
|
||||
kv3["下载"] = "下载完成"
|
||||
kv3["版本"] = downloadEntity.platform
|
||||
kv3["位置"] = downloadEntity.entrance ?: "null"
|
||||
kv3["位置"] = downloadEntity.entrance ?: "null"
|
||||
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
|
||||
DataUtils.onEvent(mApplication, "插件化", downloadEntity.name, kv3)
|
||||
|
||||
MtaHelper.onEvent(
|
||||
"插件化_新",
|
||||
"位置", downloadEntity.entrance,
|
||||
"游戏", downloadEntity.name + "-" + downloadEntity.platform,
|
||||
"操作", "下载完成",
|
||||
"网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
// MtaHelper.onEvent(
|
||||
// "插件化_新",
|
||||
// "位置", downloadEntity.entrance,
|
||||
// "游戏", downloadEntity.name + "-" + downloadEntity.platform,
|
||||
// "操作", "下载完成",
|
||||
// "网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
}
|
||||
|
||||
ExposureUtils.logADownloadCompleteExposureEvent(
|
||||
GameEntity(downloadEntity.gameId, downloadEntity.name),
|
||||
GameEntity(id = downloadEntity.getRealGameId(Constants.GAME_ID_DIVIDER),
|
||||
mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR),
|
||||
gameVersion = downloadEntity.versionName ?: ""),
|
||||
downloadEntity.platform,
|
||||
downloadEntity.exposureTrace,
|
||||
type)
|
||||
|
||||
@ -1,18 +1,32 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.avoidcallback.AvoidOnResultManager;
|
||||
import com.gh.common.avoidcallback.Callback;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.MainActivity;
|
||||
import com.gh.gamecenter.NormalActivity;
|
||||
import com.gh.gamecenter.SplashScreenActivity;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
* @Date 2017/4/25
|
||||
@ -25,9 +39,12 @@ public class EntranceUtils {
|
||||
public static final String KEY_NEXT_TO = "next_to";
|
||||
public static final String KEY_NEWSID = "newsId";
|
||||
public static final String KEY_GAMEID = "gameId";
|
||||
public static final String KEY_GAME_ID = "game_id";
|
||||
public static final String KEY_ID = "id";
|
||||
public static final String KEY_URL = "url";
|
||||
public static final String KEY_BUNDLE = "bundle";
|
||||
public static final String KEY_GAMENAME = "gameName";
|
||||
public static final String KEY_PACKAGE_MD5 = "package_md5";
|
||||
public static final String HOST_ARTICLE = "article";
|
||||
public static final String HOST_UPLOAD_VIDEO = "upload_video";//上传视频
|
||||
public static final String HOST_VIDEO_SINGLE = "video_single";//指定视频-不能划动
|
||||
@ -37,22 +54,41 @@ public class EntranceUtils {
|
||||
public static final String HOST_VIDEO_COLLECTION = "video_collection";//视频合集
|
||||
public static final String HOST_USERHOME = "userhome";//个人主页
|
||||
public static final String HOST_VIDEO = "video";
|
||||
public static final String HOST_FORUM = "forum";
|
||||
public static final String HOST_CATEGORY = "category";//分类
|
||||
public static final String HOST_COLUMN_COLLECTION = "column_collection";//专题合集
|
||||
public static final String HOST_COMMUNITY_QUESTION_LABEL_DETAIL = "community_question_label_detail";//问题标签详情
|
||||
public static final String HOST_COMMUNITY_COLUMN_DETAIL = "community_column_detail";//专栏详情
|
||||
public static final String HOST_BLOCK = "block";//板块
|
||||
public static final String HOST_SERVER_BLOCK = "server";//开服表板块
|
||||
public static final String HOST_AMWAY_BLOCK = "amway";//安利墙板块
|
||||
public static final String HOST_GAME_CALENDAR = "game_calendar";// 指定游戏的开服表页面
|
||||
public static final String HOST_HISTORY_APK = "history_apk"; // 历史版本页面
|
||||
public static final String HOST_HELP = "help";//Q&A
|
||||
public static final String HOST_HELP_COLLECTION = "help_collection";//Q&A合集
|
||||
public static final String HOST_GAME_UPLOAD = "game_upload";//游戏上传
|
||||
public static final String HOST_GAME_ZONE = "game_zone";//游戏专区
|
||||
public static final String HOST_COMMUNITY_ARTICLE = "community_article";
|
||||
public static final String HOST_COMMUNITY_COLUMN = "community_column";
|
||||
public static final String HOST_GAME = "game";
|
||||
public static final String HOST_GAME_DOWNLOAD = "game_download";
|
||||
public static final String HOST_GAME_NEWS = "game_news";
|
||||
public static final String HOST_COLUMN = "column";
|
||||
public static final String HOST_WEB = "web";
|
||||
public static final String HOST_QQ = "qq";
|
||||
public static final String HOST_QQ_GROUP = "qqgroup";
|
||||
public static final String HOST_QQ_QUN = "qqqun";
|
||||
public static final String HOST_DOWNLOAD = "download";
|
||||
public static final String HOST_UPDATE = "update";
|
||||
public static final String HOST_LINK = "link";
|
||||
public static final String HOST_LIBAO = "libao";
|
||||
public static final String HOST_COMMUNITY = "community";
|
||||
public static final String HOST_SUGGESTION = "suggestion";
|
||||
public static final String HOST_ANSWER = "answer";
|
||||
public static final String HOST_QUESTION = "question";
|
||||
public static final String HOST_TOOLBOX = "toolbox";
|
||||
public static final String HOST_FORUM_DETAIL = "forum_detail";
|
||||
public static final String HOST_GAME_RATING_DETAIL = "game_rating_detail";
|
||||
public static final String KEY_DATA = "data";
|
||||
public static final String KEY_MESSAGE = "message";
|
||||
public static final String KEY_MESSAGE_ID = "message_id";
|
||||
@ -70,6 +106,7 @@ public class EntranceUtils {
|
||||
public static final String ENTRANCE_DOWNLOAD = "(下载跳转)";
|
||||
public static final String ENTRANCE_RECOMMEND = "(落地页)";
|
||||
public static final String ENTRANCE_BLOCK_RECOMMEND = "(推荐入口)";
|
||||
public static final String ENTRANCE_AMWAY = "(安利墙)";
|
||||
public static final String KEY_SUGGEST_HINT_TYPE = "suggestHintType";
|
||||
public static final String KEY_PACKAGENAME = "packageName";
|
||||
public static final String KEY_PLATFORM = "platform";
|
||||
@ -80,12 +117,14 @@ public class EntranceUtils {
|
||||
public static final String KEY_LOCATION = "location";
|
||||
public static final String KEY_CURRENTITEM = "currentItem";
|
||||
public static final String KEY_COMMENTID = "commentId";
|
||||
public static final String KEY_COMMENT_ID = "comment_id";
|
||||
public static final String KEY_SHOW_KEYBOARD_IF_NEEDED = "show_key_board_if_needed";
|
||||
public static final String KEY_PATH = "path";
|
||||
public static final String KEY_OUTER_INFO = "outerInfo";
|
||||
public static final String KEY_OLDERUSER = "isOldUser";
|
||||
public static final String KEY_SEARCHKEY = "searchKey";
|
||||
public static final String KEY_HINT = "hint";
|
||||
public static final String KEY_GAME = "game";
|
||||
public static final String KEY_GAME_ICON_URL = "gameIconUrl";
|
||||
public static final String KEY_SHARECONTENT = "shareContent";
|
||||
public static final String KEY_SUGGESTTYPE = "suggestType";
|
||||
@ -128,6 +167,7 @@ public class EntranceUtils {
|
||||
public static final String KEY_COMMUNITY_ARTICLE_ID = "communityArticleId";
|
||||
public static final String KEY_ARTICLE_COMMENT_ID = "articleCommentId";
|
||||
public static final String KEY_SHOW_ARTICLE_COMMENT = "showArticleComment";
|
||||
public static final String KEY_SCROLL_TO_COMMENT_AREA = "scroll_to_comment_area";
|
||||
public static final String KEY_RATING_STAR_COUNT = "ratingStarCount";
|
||||
public static final String KEY_QUESTION_MODERATOR_PATCH = "questionModeratorPatch";
|
||||
public static final String KEY_SKIP_GAME_COMMENT = "skipGameComment";
|
||||
@ -138,6 +178,7 @@ public class EntranceUtils {
|
||||
public static final String KEY_DIRECT_COMMENT = "directComment";
|
||||
public static final String KEY_SORT = "sort";
|
||||
public static final String KEY_AMWAY = "amway";
|
||||
public static final String KEY_SKIP_SUCCESS_PAGE = "skipSuccessPage";
|
||||
public static final String KEY_COLLECTION_ID = "collectionId";
|
||||
public static final String KEY_NAVIGATION_TITLE = "navigationTitle";
|
||||
public static final String KEY_IMAGE_CROP_RATIO = "imageCropRatio";
|
||||
@ -148,7 +189,24 @@ public class EntranceUtils {
|
||||
public static final String KEY_IS_HOME = "isHome";
|
||||
public static final String KEY_WEB_SHARE = "webShare";
|
||||
public static final String KEY_ACTIVITY_NAME = "activityName";//活动名称
|
||||
public static final String KEY_PAGINATION_TYPE = "paginationType";//活动分页方式
|
||||
public static final String KEY_REQUIRE_REDIRECT = "require_redirect"; // 标记需要再跳转
|
||||
public static final String KEY_FIELD_ID = "field_id"; // 专区板块id
|
||||
public static final String KEY_SECTION_NAME = "section_name"; // 专区专题名
|
||||
public static final String KEY_COLUMNNAME = "columnName";
|
||||
public static final String KEY_QA_ID = "qaId";
|
||||
public static final String KEY_QA_COLLECTION_ID = "qaCollectionId";
|
||||
public static final String KEY_SHOW_EDIT_DRAFT = "showEditDraft";
|
||||
public static final String KEY_ARTICLE_OPEN_IN_NEW_PAGE = "openArticleInNewPage";
|
||||
public static final String KEY_ONLY_CREATE_DRAFT = "onlyCreateDraft";
|
||||
public static final String KEY_KAIFU_SELECT_TIME = "kaifuSelectTime";
|
||||
public static final String KEY_POSTER_PATH = "posterPath";
|
||||
public static final String KEY_BLACK_THEME = "blackTheme";
|
||||
public static final String KEY_FROM_LOGIN = "fromLogin";
|
||||
public static final String KEY_CHANGE_PHONE = "changePhone";
|
||||
public static final String KEY_CONFLICT_PHONE = "conflictPhone";
|
||||
public static final String KEY_CONFLICT_USER = "conflictUser";
|
||||
public static final String KEY_BBS_ID = "bbs_id";
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
@ -204,4 +262,82 @@ public class EntranceUtils {
|
||||
context.startActivity(SplashScreenActivity.getSplashScreenIntent(context, bundle));
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveShortcut(String activityName, @Nullable Bundle bundle) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
if (activityName.contains("MainActivity")) {
|
||||
SPUtils.setString(EntranceUtils.KEY_BUNDLE, "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bundle == null) bundle = new Bundle();
|
||||
try {
|
||||
Set<String> keys = bundle.keySet();
|
||||
json.put(KEY_TO, activityName);
|
||||
for (String key : keys) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
Object object = bundle.get(key);
|
||||
if (object instanceof Parcelable) {
|
||||
if (object.toString().toLowerCase().contains("gameentity")) {
|
||||
Utils.toast(HaloApp.getInstance().getApplication(), "暂不支持带游戏实体的页面保存捷径");
|
||||
return;
|
||||
}
|
||||
|
||||
String parcelableName = key + ":parcelable";
|
||||
String parcelableType = object.getClass().getName();
|
||||
String objectJsonString = GsonUtils.toJson(object);
|
||||
JSONObject jObject = new JSONObject(objectJsonString);
|
||||
json.put(parcelableName, parcelableType);
|
||||
json.put(key, jObject);
|
||||
} else {
|
||||
json.put(key, JSONObject.wrap(bundle.get(key)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Utils.toast(HaloApp.getInstance().getApplication(), "保存捷径成功");
|
||||
SPUtils.setString(EntranceUtils.KEY_BUNDLE, json.toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
SPUtils.setString(EntranceUtils.KEY_BUNDLE, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void jumpShortcut(Activity activity) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
if (!hasShortcut()) return;
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(SPUtils.getString(EntranceUtils.KEY_BUNDLE));
|
||||
Iterator iter = jsonObject.keys();
|
||||
String parcelableName = "";
|
||||
while (iter.hasNext()) {
|
||||
String key = (String) iter.next();
|
||||
String value = jsonObject.getString(key);
|
||||
if (key.contains(":parcelable")) {
|
||||
parcelableName = value;
|
||||
} else {
|
||||
if (!TextUtils.isEmpty(parcelableName)) {
|
||||
Class<?> gClass = Class.forName(parcelableName);
|
||||
bundle.putParcelable(key, ((Parcelable) GsonUtils.fromJson(value, gClass)));
|
||||
} else {
|
||||
bundle.putString(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
jumpActivity(activity, bundle);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasShortcut() {
|
||||
return !TextUtils.isEmpty(SPUtils.getString(EntranceUtils.KEY_BUNDLE));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -116,6 +116,8 @@ object ErrorHelper {
|
||||
403078 -> Utils.toast(context, "已点赞")
|
||||
403072 -> Utils.toast(context, R.string.comment_failed_userblocked)
|
||||
403082 -> Utils.toast(context, "作者已关闭评论")
|
||||
403022 -> Utils.toast(context, "不能回复自己")
|
||||
403056 -> Utils.toast(context, "发布失败,字数已达上限")
|
||||
|
||||
403020 -> if (showHighPriorityHint) {
|
||||
DialogUtils.showAlertDialog(context,
|
||||
|
||||
@ -3,13 +3,17 @@ package com.gh.common.util
|
||||
import android.animation.Animator
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.text.Editable
|
||||
import android.text.Html
|
||||
import android.text.Spanned
|
||||
import android.text.TextWatcher
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.text.*
|
||||
import android.text.style.ClickableSpan
|
||||
import android.text.style.ImageSpan
|
||||
import android.text.style.URLSpan
|
||||
import android.util.TypedValue
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorRes
|
||||
@ -18,16 +22,24 @@ import androidx.core.text.HtmlCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.*
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.gh.common.DefaultUrlHandler
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.view.CenterImageSpan
|
||||
import com.gh.common.view.CustomLinkMovementMethod
|
||||
import com.gh.common.view.ExpandTextView
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@ -35,7 +47,9 @@ import io.reactivex.disposables.Disposable
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import java.net.URI
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
@ -54,6 +68,14 @@ inline fun <reified VM : ViewModel> Fragment.viewModelProviderFromParent(
|
||||
) =
|
||||
ViewModelProviders.of(requireActivity(), provider).get(VM::class.java)
|
||||
|
||||
/**
|
||||
* 创建以 activity 为观察者上下文的 viewModel
|
||||
*/
|
||||
inline fun <reified VM : ViewModel> FragmentActivity.viewModelProviderFromParent(
|
||||
provider: ViewModelProvider.Factory? = null
|
||||
) =
|
||||
ViewModelProviders.of(this, provider).get(VM::class.java)
|
||||
|
||||
/**
|
||||
* 创建以 fragment 为观察者上下文的 viewModel
|
||||
*/
|
||||
@ -152,6 +174,17 @@ fun View.removeSelectableItemBackground() {
|
||||
background = null
|
||||
}
|
||||
|
||||
fun View.setRoundedColorBackground(@ColorRes color: Int, radius: Float) {
|
||||
val shape = GradientDrawable()
|
||||
shape.cornerRadius = radius.dip2px().toFloat()
|
||||
shape.setColor(ContextCompat.getColor(context, color))
|
||||
background = shape
|
||||
}
|
||||
|
||||
fun View.setDebouncedClickListener(action: () -> Unit) {
|
||||
setOnClickListener { debounceActionWithInterval(interval = 300L) { action.invoke() } }
|
||||
}
|
||||
|
||||
/**
|
||||
* LiveData Extensions
|
||||
*/
|
||||
@ -191,6 +224,50 @@ inline fun <reified T : Any> T.toJson(): String {
|
||||
return GsonUtils.toJson(this)
|
||||
}
|
||||
|
||||
fun String.insert(index: Int, string: String): String {
|
||||
return this.substring(0, index) + string + this.substring(index, this.length)
|
||||
}
|
||||
|
||||
/**
|
||||
* TextView 内部处理 ul li ol 得跟 Android 版本走,这里换成专属的标签手动处理
|
||||
*/
|
||||
fun String.replaceUnsupportedHtmlTag(): String {
|
||||
return this.replace("<ul", "<hul")
|
||||
.replace("</ul>", "</hul>")
|
||||
.replace("<li", "<hli")
|
||||
.replace("</li>", "</hli>")
|
||||
.replace("<ol", "<hol")
|
||||
.replace("</ol>", "</hol>")
|
||||
}
|
||||
|
||||
fun String.containHtmlTag(): Boolean {
|
||||
val pattern = Pattern.compile("<(\"[^\"]*\"|'[^']*'|[^'\">])*>")
|
||||
val matcher = pattern.matcher(this)
|
||||
return matcher.find()
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户行为相关
|
||||
*/
|
||||
fun Fragment.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
|
||||
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
|
||||
DialogUtils.showRegulationTestDialog(requireContext(),
|
||||
{ DirectUtils.directToRegulationTestPage(requireContext()) },
|
||||
{ action.invoke() })
|
||||
} else {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.showRegulationTestDialogIfNeeded(action: (() -> Unit)) {
|
||||
if (UserManager.getInstance().userShouldTakeRegulationBaseOnLastRemind()) {
|
||||
DialogUtils.showRegulationTestDialog(this,
|
||||
{ DirectUtils.directToRegulationTestPage(this) },
|
||||
{ action.invoke() })
|
||||
} else {
|
||||
action()
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 在限定 interval 里只触发一次 action
|
||||
*/
|
||||
@ -237,6 +314,24 @@ inline fun tryCatchInRelease(action: (() -> Unit)) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 debug 状态下抛出异常
|
||||
*/
|
||||
fun throwExceptionInDebug(message: String = "", predicate: Boolean = true) {
|
||||
if (predicate && BuildConfig.DEBUG) {
|
||||
throw RuntimeException(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动抛出异常
|
||||
*/
|
||||
fun throwException(message: String = "", predicate: Boolean = true) {
|
||||
if (predicate) {
|
||||
throw RuntimeException(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String related
|
||||
*/
|
||||
@ -276,11 +371,22 @@ fun String.subStringIfPossible(length: Int): String {
|
||||
}
|
||||
}
|
||||
|
||||
fun String.countOccurrences(char: String): Int {
|
||||
return StringTokenizer(" $this ", char).countTokens() - 1
|
||||
}
|
||||
|
||||
fun String.getFirstElementDividedByDivider(divider: String): String {
|
||||
if (this.contains(divider)) {
|
||||
return this.split(divider.toRegex()).toTypedArray()[0]
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun String.copyTextAndToast(toastText: String = "复制成功") {
|
||||
val application = HaloApp.getInstance().application
|
||||
val cmb = application.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
cmb.text = this
|
||||
Utils.toast(application, toastText)
|
||||
ToastUtils.showToast(toastText)
|
||||
}
|
||||
|
||||
fun Map<String, String>.createRequestBody(): RequestBody {
|
||||
@ -319,6 +425,11 @@ fun Float.px2dip(): Int {
|
||||
return (this / scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
fun Float.sp2px():Int{
|
||||
val scale: Float = HaloApp.getInstance().application.resources.displayMetrics.scaledDensity
|
||||
return (this * scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* PopupWindow 自动适配方向
|
||||
* 弹出与锚点右对齐
|
||||
@ -399,6 +510,15 @@ fun FragmentActivity.checkStoragePermissionBeforeAction(action: (() -> Unit)) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* List related.
|
||||
*/
|
||||
|
||||
// Returns the second element, or `null` if the list is empty.
|
||||
fun <T> List<T>.secondOrNull(): T? {
|
||||
return if (isEmpty() || size == 1) null else this[1]
|
||||
}
|
||||
|
||||
/**
|
||||
* TextView related.
|
||||
*/
|
||||
@ -433,6 +553,75 @@ fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截 TextView 中的 Url Span,用应用内页面的形式打开链接
|
||||
* @param shrankText 未展开时的文字
|
||||
* @param expandedText 展开后的文字
|
||||
*/
|
||||
fun ExpandTextView.setTextWithInterceptingInternalUrl(shrankText: CharSequence, expandedText: CharSequence) {
|
||||
var shrankSsb = shrankText.interceptUrlSpanAndRoundImageSpan()
|
||||
var expandedSsb = expandedText.interceptUrlSpanAndRoundImageSpan()
|
||||
|
||||
// 去掉旧版本 Android 系统 [Html.FROM_HTML_MODE_LEGACY] 产生的两个换行符 (丑陋的代码)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
while (shrankSsb.contains("\n\n")) {
|
||||
val index = shrankSsb.indexOf("\n\n", 0, true)
|
||||
shrankSsb = SpannableStringBuilder(shrankSsb.subSequence(0, index)).append(shrankSsb.subSequence(index + "\n".length, shrankSsb.length))
|
||||
}
|
||||
while (expandedSsb.contains("\n\n")) {
|
||||
val index = expandedSsb.indexOf("\n\n", 0, true)
|
||||
expandedSsb = SpannableStringBuilder(expandedSsb.subSequence(0, index)).append(expandedSsb.subSequence(index + "\n".length, expandedSsb.length))
|
||||
}
|
||||
}
|
||||
|
||||
// 去掉多余的 P 标签换行
|
||||
if (expandedSsb.endsWith("\n", true)) {
|
||||
expandedSsb = SpannableStringBuilder((expandedSsb.subSequence(0, expandedSsb.length - "\n".length)))
|
||||
}
|
||||
|
||||
movementMethod = CustomLinkMovementMethod.getInstance()
|
||||
|
||||
shrankSsb = TextHelper.updateSpannableStringWithHighlightedSpan(context, shrankSsb, highlightedTextClickListener = null)
|
||||
expandedSsb = TextHelper.updateSpannableStringWithHighlightedSpan(context, expandedSsb, highlightedTextClickListener = null)
|
||||
setShrankTextAndExpandedText(shrankSsb, expandedSsb)
|
||||
}
|
||||
|
||||
fun CharSequence.interceptUrlSpanAndRoundImageSpan(): SpannableStringBuilder {
|
||||
return SpannableStringBuilder.valueOf(this).apply {
|
||||
getSpans(0, length, URLSpan::class.java).forEach {
|
||||
setSpan(
|
||||
object : ClickableSpan() {
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
super.updateDrawState(ds)
|
||||
ds.color = ContextCompat.getColor(HaloApp.getInstance().application, R.color.theme_font)
|
||||
ds.isUnderlineText = false
|
||||
}
|
||||
|
||||
override fun onClick(widget: View) {
|
||||
if (!DefaultUrlHandler.interceptUrl(widget.context, it.url, "")) {
|
||||
widget.context.startActivity(WebActivity.getIntent(widget.context, it.url, true))
|
||||
}
|
||||
}
|
||||
},
|
||||
getSpanStart(it),
|
||||
getSpanEnd(it),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
removeSpan(it)
|
||||
}
|
||||
|
||||
getSpans(0, length, ImageSpan::class.java).forEach {
|
||||
setSpan(
|
||||
CenterImageSpan(it.drawable),
|
||||
getSpanStart(it),
|
||||
getSpanEnd(it),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
removeSpan(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Int.toColor(): Int {
|
||||
return ContextCompat.getColor(HaloApp.getInstance().application, this)
|
||||
}
|
||||
@ -452,6 +641,50 @@ fun SimpleDraweeView.display(url: String) {
|
||||
ImageUtils.display(this, url)
|
||||
}
|
||||
|
||||
/**
|
||||
* DownloadEntity extension
|
||||
*/
|
||||
fun DownloadEntity.addMetaExtra(key: String, value: String?) {
|
||||
value?.let { meta[key] = value }
|
||||
}
|
||||
|
||||
fun DownloadEntity.getMetaExtra(key: String): String {
|
||||
return meta[key] ?: ""
|
||||
}
|
||||
|
||||
fun DownloadEntity.isSilentUpdate(): Boolean {
|
||||
return Constants.SILENT_UPDATE == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Process related
|
||||
*/
|
||||
fun Context.doOnMainProcessOnly(callback: EmptyCallback) {
|
||||
doOnMainProcessOnly { callback.onCallback() }
|
||||
}
|
||||
|
||||
inline fun Context.doOnMainProcessOnly(f: () -> Unit) {
|
||||
val processName = PackageUtils.obtainProcessName(this)
|
||||
if (processName == null || BuildConfig.APPLICATION_ID == processName) {
|
||||
f.invoke()
|
||||
} else {
|
||||
tryWithDefaultCatch {
|
||||
Utils.log("Block one useless sub process method call from ${Thread.currentThread().stackTrace[3].methodName} -> ${Thread.currentThread().stackTrace[2].methodName}.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun doOnMainProcessOnly(f: () -> Unit) {
|
||||
val processName = PackageUtils.obtainProcessName(HaloApp.getInstance().application)
|
||||
if (processName == null || BuildConfig.APPLICATION_ID == processName) {
|
||||
f.invoke()
|
||||
} else {
|
||||
tryWithDefaultCatch {
|
||||
Utils.log("Block one useless sub process method call from ${Thread.currentThread().stackTrace[3].methodName} -> ${Thread.currentThread().stackTrace[2].methodName}.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试用包裹
|
||||
*/
|
||||
@ -471,15 +704,15 @@ inline fun testChannelOnly(f: () -> Unit) {
|
||||
* 倒计时,单位s
|
||||
*/
|
||||
inline fun countDownTimer(
|
||||
millisUntilFinish: Long,
|
||||
crossinline block: (finish: Boolean, millisUntilFinished: Long) -> Unit
|
||||
timeInSeconds: Long,
|
||||
crossinline block: (finish: Boolean, remainingTime: Long) -> Unit
|
||||
): Disposable {
|
||||
var subscribe: Disposable? = null
|
||||
subscribe = Observable.interval(0, 1000, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
if (it < millisUntilFinish) {
|
||||
block.invoke(false, millisUntilFinish - it)
|
||||
if (it < timeInSeconds) {
|
||||
block.invoke(false, timeInSeconds - it)
|
||||
} else {
|
||||
block.invoke(true, 0)
|
||||
if (subscribe != null && !subscribe!!.isDisposed) {
|
||||
@ -537,4 +770,52 @@ fun LottieAnimationView.doOnAnimationEnd(action: () -> Unit) {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun String?.getExtension(): String? {
|
||||
this ?: return null
|
||||
|
||||
tryCatchInRelease {
|
||||
val lastDotIndex = this.lastIndexOf('.')
|
||||
return if (lastDotIndex == -1) null else this.substring(lastDotIndex + 1)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查内容是否一致
|
||||
* @return true:相同 false:不同
|
||||
*/
|
||||
fun List<String>?.checkSameFromStringArray(check2: List<String>?): Boolean {
|
||||
if (this == check2) {
|
||||
return true
|
||||
}
|
||||
if (this == null && check2 == null) {
|
||||
return true
|
||||
}
|
||||
if (this == null || check2 == null) {
|
||||
return false
|
||||
}
|
||||
if (this.size != check2.size) {
|
||||
return false
|
||||
}
|
||||
for (tag in this) {
|
||||
if (!check2.contains(tag)) return false
|
||||
}
|
||||
for (tag in check2) {
|
||||
if (!this.contains(tag)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* EditText弹出软键盘
|
||||
*/
|
||||
fun EditText.showKeyBoard() {
|
||||
this.postDelayed({
|
||||
this.requestFocus()
|
||||
val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
inputMethodManager.showSoftInput(this, 0)
|
||||
}, 300)
|
||||
}
|
||||
183
app/src/main/java/com/gh/common/util/ExtraTagHandler.kt
Normal file
183
app/src/main/java/com/gh/common/util/ExtraTagHandler.kt
Normal file
@ -0,0 +1,183 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.text.Editable
|
||||
import android.text.Html.TagHandler
|
||||
import android.text.Spanned
|
||||
import android.text.style.BulletSpan
|
||||
import android.text.style.LeadingMarginSpan
|
||||
import android.util.Log
|
||||
import org.xml.sax.XMLReader
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Implements support for ordered (`<ol>`) and unordered (`<ul>`) lists in to Android TextView.
|
||||
*
|
||||
*
|
||||
* This can be used as follows:<br></br>
|
||||
* `textView.setText(Html.fromHtml("<ul><li>item 1</li><li>item 2</li></ul>", null, new HtmlListTagHandler()));`
|
||||
*
|
||||
*
|
||||
* Implementation based on code by Juha Kuitunen (https://bitbucket.org/Kuitsi/android-textview-html-list),
|
||||
* released under Apache License v2.0. Refactored & improved by Matthias Stevens (InThePocket.mobi).
|
||||
*
|
||||
*
|
||||
* **Known issues:**
|
||||
* * The indentation on nested `<ul>`s isn't quite right (TODO fix this)
|
||||
* * the `start` attribute of `<ol>` is not supported. Doing so is tricky because
|
||||
* [Html.TagHandler.handleTag] does not expose tag attributes.
|
||||
* The only way to do it would be to use reflection to access the attribute information kept by the XMLReader
|
||||
* (see: http://stackoverflow.com/a/24534689/1084488).
|
||||
*
|
||||
* https://bitbucket.org/Kuitsi/android-textview-html-list/src/master/app/src/main/java/fi/iki/kuitsi/listtest/MyTagHandler.java
|
||||
*
|
||||
*/
|
||||
class ExtraTagHandler : TagHandler {
|
||||
/**
|
||||
* Keeps track of lists (ol, ul). On bottom of Stack is the outermost list
|
||||
* and on top of Stack is the most nested list
|
||||
*/
|
||||
private val lists = Stack<ListTag>()
|
||||
|
||||
/**
|
||||
* @see android.text.Html.TagHandler.handleTag
|
||||
*/
|
||||
override fun handleTag(opening: Boolean, tag: String, output: Editable, xmlReader: XMLReader) {
|
||||
if (UL_TAG.equals(tag, ignoreCase = true)) {
|
||||
if (opening) { // handle <ul>
|
||||
lists.push(Ul())
|
||||
} else { // handle </ul>
|
||||
lists.pop()
|
||||
}
|
||||
} else if (OL_TAG.equals(tag, ignoreCase = true)) {
|
||||
if (opening) { // handle <ol>
|
||||
lists.push(Ol()) // use default start index of 1
|
||||
} else { // handle </ol>
|
||||
lists.pop()
|
||||
}
|
||||
} else if (LI_TAG.equals(tag, ignoreCase = true)) {
|
||||
if (opening) { // handle <li>
|
||||
lists.peek().openItem(output)
|
||||
} else { // handle </li>
|
||||
lists.peek().closeItem(output, lists.size)
|
||||
}
|
||||
} else {
|
||||
Log.d("TagHandler", "Found an unsupported tag $tag")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract super class for [Ul] and [Ol].
|
||||
*/
|
||||
private abstract class ListTag {
|
||||
/**
|
||||
* Opens a new list item.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
open fun openItem(text: Editable) {
|
||||
if (text.length > 0 && text[text.length - 1] != '\n') {
|
||||
text.append("\n")
|
||||
}
|
||||
val len = text.length
|
||||
text.setSpan(this, len, len, Spanned.SPAN_MARK_MARK)
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes a list item.
|
||||
*
|
||||
* @param text
|
||||
* @param indentation
|
||||
*/
|
||||
fun closeItem(text: Editable, indentation: Int) {
|
||||
if (text.length > 0 && text[text.length - 1] != '\n') {
|
||||
text.append("\n")
|
||||
}
|
||||
val replaces = getReplaces(text, indentation)
|
||||
val len = text.length
|
||||
val listTag = getLast(text)
|
||||
val where = text.getSpanStart(listTag)
|
||||
text.removeSpan(listTag)
|
||||
if (where != len) {
|
||||
for (replace in replaces) {
|
||||
text.setSpan(replace, where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun getReplaces(text: Editable?, indentation: Int): Array<Any>
|
||||
|
||||
/**
|
||||
* Note: This knows that the last returned object from getSpans() will be the most recently added.
|
||||
*
|
||||
* @see Html
|
||||
*/
|
||||
private fun getLast(text: Spanned): ListTag? {
|
||||
val listTags = text.getSpans(0, text.length, ListTag::class.java)
|
||||
return if (listTags.size == 0) {
|
||||
null
|
||||
} else listTags[listTags.size - 1]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing the unordered list (`<ul>`) HTML tag.
|
||||
*/
|
||||
private class Ul : ListTag() {
|
||||
override fun getReplaces(text: Editable?, indentation: Int): Array<Any> {
|
||||
// Nested BulletSpans increases distance between BULLET_SPAN and text, so we must prevent it.
|
||||
var bulletMargin = INDENT_PX
|
||||
if (indentation > 1) {
|
||||
bulletMargin = INDENT_PX - BULLET_SPAN.getLeadingMargin(true)
|
||||
if (indentation > 2) {
|
||||
// This get's more complicated when we add a LeadingMarginSpan into the same line:
|
||||
// we have also counter it's effect to BulletSpan
|
||||
bulletMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX
|
||||
}
|
||||
}
|
||||
return arrayOf(
|
||||
LeadingMarginSpan.Standard(LIST_ITEM_INDENT_PX * (indentation - 1)),
|
||||
BulletSpan(bulletMargin)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing the ordered list (`<ol>`) HTML tag.
|
||||
*/
|
||||
private class Ol
|
||||
/**
|
||||
* Creates a new `<ul>` with start index of 1.
|
||||
*/ @JvmOverloads constructor(private var nextIdx: Int = 1) : ListTag() {
|
||||
override fun openItem(text: Editable) {
|
||||
super.openItem(text)
|
||||
text.append(Integer.toString(nextIdx++)).append(". ")
|
||||
}
|
||||
|
||||
override fun getReplaces(text: Editable?, indentation: Int): Array<Any> {
|
||||
var numberMargin = LIST_ITEM_INDENT_PX * (indentation - 1)
|
||||
if (indentation > 2) {
|
||||
// Same as in ordered lists: counter the effect of nested Spans
|
||||
numberMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX
|
||||
}
|
||||
return arrayOf(LeadingMarginSpan.Standard(numberMargin))
|
||||
}
|
||||
/**
|
||||
* Creates a new `<ul>` with given start index.
|
||||
*
|
||||
* @param nextIdx
|
||||
*/
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val OL_TAG = "hol"
|
||||
private const val UL_TAG = "hul"
|
||||
private const val LI_TAG = "hli"
|
||||
|
||||
/**
|
||||
* List indentation in pixels. Nested lists use multiple of this.
|
||||
*/
|
||||
private const val INDENT_PX = 10
|
||||
private const val LIST_ITEM_INDENT_PX = INDENT_PX * 2
|
||||
private val BULLET_SPAN = BulletSpan(INDENT_PX)
|
||||
}
|
||||
}
|
||||
@ -1,100 +0,0 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* 首页补充游戏库辅助类
|
||||
*/
|
||||
object GameRepositoryHelper {
|
||||
|
||||
private const val KEY_GAME_REPOSITORY = "game_repository"
|
||||
|
||||
var gameCollectionList: List<SubjectEntity> = arrayListOf()
|
||||
|
||||
init {
|
||||
loadSavedRepository()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏补充库
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getGameRepository(context: Context) {
|
||||
|
||||
RetrofitManager.getInstance(context)
|
||||
.api
|
||||
.reserveColumns
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Response<List<SubjectEntity>>() {
|
||||
override fun onResponse(response: List<SubjectEntity>?) {
|
||||
super.onResponse(response)
|
||||
|
||||
updateGameRepository(response)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新内存中的游戏库(即从 SP 中再读一次)
|
||||
*/
|
||||
@JvmStatic
|
||||
fun refreshGameRepository() = loadSavedRepository()
|
||||
|
||||
private fun loadSavedRepository() {
|
||||
gameCollectionList = SPUtils.getString(KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
|
||||
}
|
||||
|
||||
fun updateGameRepository(subjects: List<SubjectEntity>?) {
|
||||
|
||||
if (subjects == null) return
|
||||
|
||||
SPUtils.setString(KEY_GAME_REPOSITORY, subjects.toJson())
|
||||
|
||||
gameCollectionList = subjects
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从补充游戏库相应的专题中取出一个与其它游戏都不相同的游戏,为空时即为游戏用完或不存在该相应专题
|
||||
* @param collectionId 补充游戏库相应专题 ID
|
||||
* @param gameIdList 该专题里已经包含的游戏 ID 列表
|
||||
*/
|
||||
fun getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
|
||||
collectionId?.let {
|
||||
val collection = gameCollectionList.find { it.id == collectionId }
|
||||
collection?.let {
|
||||
val game = collection.data?.find { game -> isThisGameUnique(game, gameIdList) }
|
||||
game?.let {
|
||||
collection.data?.remove(game)
|
||||
// 产品说要记录补充专题的曝光数,所以这个游戏附带了所在专题的名字
|
||||
game.subjectName = collection.name
|
||||
return game
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isThisGameUnique(game: GameEntity, gameIdList: HashSet<String>): Boolean {
|
||||
// 若该补充游戏已经存在关联关系,判定为非唯一
|
||||
for (relatedId in game.relatedGameIds!!) {
|
||||
gameIdList.contains(relatedId)
|
||||
return false
|
||||
}
|
||||
for (apk in game.getApk()) {
|
||||
// 检查本地是否已安装该游戏,已过滤那部分框架服务的包名
|
||||
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return !gameIdList.contains(game.id) && !TextUtils.isEmpty(game.id)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,194 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.SubjectEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* 首页补充游戏库辅助类
|
||||
*/
|
||||
object GameSubstituteRepositoryHelper {
|
||||
|
||||
private const val KEY_GAME_REPOSITORY = "game_substitute_repository"
|
||||
|
||||
private var mSubstitutableGameIdSet = hashSetOf<String>()
|
||||
private var mApi = RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
private val mSensitiveApi = RetrofitManager.getInstance(HaloApp.getInstance().application).sensitiveApi
|
||||
private var mApplicationContext = HaloApp.getInstance().application
|
||||
|
||||
var gameCollectionList: List<SubjectEntity> = arrayListOf()
|
||||
|
||||
init {
|
||||
loadSavedRepository()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取游戏补充库
|
||||
*/
|
||||
@JvmStatic
|
||||
fun updateGameSubstituteRepository() {
|
||||
mSensitiveApi.reserveColumns
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(object : Response<List<SubjectEntity>>() {
|
||||
override fun onResponse(response: List<SubjectEntity>?) {
|
||||
super.onResponse(response)
|
||||
|
||||
updateGameRepository(response)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@SuppressLint("CheckResult")
|
||||
fun updateSubstitutableGames() {
|
||||
mApplicationContext.doOnMainProcessOnly {
|
||||
val single = if (UserManager.getInstance().isLoggedIn) {
|
||||
mApi.getIdListOfPlayedGames(UserManager.getInstance().userId, Utils.getTime(mApplicationContext))
|
||||
} else {
|
||||
mApi.getIdListOfDownloadedGames(HaloApp.getInstance().gid, Utils.getTime(mApplicationContext))
|
||||
}
|
||||
single.subscribeOn(Schedulers.io()).subscribe(object : BiResponse<List<String>>() {
|
||||
override fun onSuccess(data: List<String>) {
|
||||
mSubstitutableGameIdSet = data.toHashSet()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新内存中的游戏库(即从 SP 中再读一次)
|
||||
*/
|
||||
@JvmStatic
|
||||
fun refreshRepositoryFromLocal() = loadSavedRepository()
|
||||
|
||||
private fun loadSavedRepository() {
|
||||
gameCollectionList = SPUtils.getString(KEY_GAME_REPOSITORY).toObject() ?: arrayListOf()
|
||||
}
|
||||
|
||||
private fun updateGameRepository(subjects: List<SubjectEntity>?) {
|
||||
if (subjects == null) return
|
||||
|
||||
SPUtils.setString(KEY_GAME_REPOSITORY, subjects.toJson())
|
||||
|
||||
gameCollectionList = subjects
|
||||
}
|
||||
|
||||
/**
|
||||
* 从补充游戏库相应的专题中取出一个与其它游戏都不相同的游戏,为空时即为游戏用完或不存在该相应专题
|
||||
* @param collectionId 补充游戏库相应专题 ID
|
||||
* @param gameIdList 该专题里已经包含的游戏 ID 列表
|
||||
*/
|
||||
private fun getOneUniqueGame(collectionId: String?, gameIdList: HashSet<String>): GameEntity? {
|
||||
collectionId?.let {
|
||||
val collection = gameCollectionList.find { it.id == collectionId }
|
||||
collection?.let {
|
||||
val game = collection.data?.find { game -> isThisGameUnique(game, gameIdList) }
|
||||
game?.let {
|
||||
collection.data?.remove(game)
|
||||
// 产品说要记录补充专题的曝光数,所以这个游戏附带了所在专题的名字
|
||||
game.subjectName = collection.name
|
||||
return game
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换游戏,包括 已安装,历史下载,历史已安装等类型
|
||||
*/
|
||||
fun replaceGames(gameList: MutableList<GameEntity>,
|
||||
alreadyDisplayedGameIdSet: HashSet<String>,
|
||||
relatedCollectionId: String,
|
||||
shouldLogReplaceEvent: Boolean) {
|
||||
val positionOfTheGameToReplaceList = arrayListOf<Int>()
|
||||
|
||||
// 标记需要替换的已安装游戏
|
||||
for ((index, game) in gameList.withIndex()) {
|
||||
|
||||
// 是大图形式的游戏时不标记替换
|
||||
if ((index == 0 && !gameList[0].image.isNullOrEmpty())) {
|
||||
continue
|
||||
}
|
||||
|
||||
var isThisPositionLabeled = false
|
||||
|
||||
// 从 游戏ID 判断当前游戏是否需要被替换
|
||||
if (mSubstitutableGameIdSet.contains(game.id)) {
|
||||
positionOfTheGameToReplaceList.add(index)
|
||||
isThisPositionLabeled = true
|
||||
}
|
||||
|
||||
// 检查是否已安装该游戏里同包名的 APK
|
||||
if (!isThisPositionLabeled) {
|
||||
for (apk in game.getApk()) {
|
||||
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
|
||||
// 将该位置的游戏标记为需要替换
|
||||
positionOfTheGameToReplaceList.add(index)
|
||||
isThisPositionLabeled = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 若此游戏所包含的 apk 没有已安装,那么再检查是否已安装有预设相关包名
|
||||
if (!isThisPositionLabeled) {
|
||||
var relatedPackageList = arrayListOf<String>()
|
||||
for (entity in PackageHelper.relatedPackageList) {
|
||||
if (entity.gameId == game.id) {
|
||||
relatedPackageList = ArrayList(entity.packages!!)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for (packageName in relatedPackageList) {
|
||||
if (PackageHelper.validLocalPackageNameSet.contains(packageName)) {
|
||||
positionOfTheGameToReplaceList.add(index)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (positionOfTheGameToReplaceList.isNotEmpty()) {
|
||||
if (shouldLogReplaceEvent) {
|
||||
MtaHelper.onEvent("首页_加载", "启动光环", "替换游戏")
|
||||
}
|
||||
for (position in positionOfTheGameToReplaceList) {
|
||||
val replacingGame = getOneUniqueGame(relatedCollectionId, alreadyDisplayedGameIdSet)
|
||||
replacingGame?.let {
|
||||
gameList[position] = replacingGame
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isThisGameUnique(game: GameEntity, gameIdList: HashSet<String>): Boolean {
|
||||
// 判断该游戏是否出现在已安装列表
|
||||
if (mSubstitutableGameIdSet.contains(game.id)) return false
|
||||
|
||||
// 该补充游戏是否已经存在关联关系
|
||||
for (relatedId in game.relatedGameIds!!) {
|
||||
if (gameIdList.contains(relatedId)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for (apk in game.getApk()) {
|
||||
// 检查本地是否已安装该游戏,已过滤那部分框架服务的包名
|
||||
if (PackageHelper.validLocalPackageNameSet.contains(apk.packageName)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return !gameIdList.contains(game.id) && !TextUtils.isEmpty(game.id)
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,12 +5,14 @@ import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.ApkLink;
|
||||
import com.gh.gamecenter.entity.GameCollectionEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.GameUpdateEntity;
|
||||
import com.gh.gamecenter.entity.PluginLocation;
|
||||
@ -19,9 +21,9 @@ import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.download.DownloadStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class GameUtils {
|
||||
|
||||
/**
|
||||
@ -53,13 +55,13 @@ public class GameUtils {
|
||||
String status = getDownloadBtnText(context, gameEntity, pluginLocation);
|
||||
downloadBtn.setTextColor(Color.WHITE);
|
||||
downloadBtn.setText(status);
|
||||
if ("插件化".equals(status)) {
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_plugin_style);
|
||||
} else if ("打开".equals(status) || "启动".equals(status)) {
|
||||
downloadBtn.setBackgroundResource(R.drawable.detail_download_open_style);
|
||||
downloadBtn.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
|
||||
if (context.getString(R.string.pluggable).equals(status)) {
|
||||
downloadBtn.setBackgroundResource(R.drawable.download_button_pluggable_style);
|
||||
String pluginDesc = gameEntity.getPluginDesc();
|
||||
if (pluginDesc.length() > 3) pluginDesc = pluginDesc.substring(0, 3);
|
||||
downloadBtn.setText((pluginDesc + "化"));
|
||||
} else {
|
||||
downloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
downloadBtn.setBackgroundResource(R.drawable.download_button_normal_style);
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +69,10 @@ public class GameUtils {
|
||||
* 获取下载按钮文案
|
||||
*/
|
||||
public static String getDownloadBtnText(Context context, GameEntity gameEntity, PluginLocation pluginLocation) {
|
||||
if (gameEntity.getApk().size() > 1) {
|
||||
return context.getString(R.string.expand);
|
||||
}
|
||||
|
||||
int doneCount = 0; // 下载完成数量
|
||||
int pluginCount = 0; // 可插件化数量
|
||||
int updateCount = 0; // 可更新数量
|
||||
@ -103,7 +109,7 @@ public class GameUtils {
|
||||
gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
|
||||
if (gameEntity.getTag() != null && gameEntity.getTag().size() != 0
|
||||
&& !TextUtils.isEmpty(apkEntity.getGhVersion())
|
||||
&& !PackageUtils.isSignature(context, apkEntity.getPackageName())
|
||||
&& !PackageUtils.isSignedByGh(context, apkEntity.getPackageName())
|
||||
&& apkEntity.isShowPlugin(pluginLocation)) {
|
||||
pluginCount++;
|
||||
} else if (gh_id == null || gh_id.equals(gameEntity.getId())) {
|
||||
@ -118,23 +124,66 @@ public class GameUtils {
|
||||
} else if (updateCount != 0) {
|
||||
return context.getString(R.string.update);
|
||||
} else if (installCount != 0) {
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
return context.getString(R.string.launch);
|
||||
} else {
|
||||
return context.getString(R.string.open);
|
||||
}
|
||||
return context.getString(R.string.launch);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen()) {
|
||||
return context.getString(R.string.attempt);
|
||||
} else {
|
||||
return context.getString(R.string.download);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取GameUpdateEntity
|
||||
* 获取简单的下载按钮文案,只需要知道是否已下载,是否已安装
|
||||
*/
|
||||
public static String getSimpleDownloadBtnText(Context context, GameEntity gameEntity) {
|
||||
int doneCount = 0; // 下载完成数量
|
||||
int installCount = 0; // 已安装数量
|
||||
|
||||
DownloadEntity downloadEntity;
|
||||
Object gh_id;
|
||||
apkFor:
|
||||
for (ApkEntity apkEntity : gameEntity.getApk()) {
|
||||
// filter by packageName
|
||||
SettingsEntity settings = Config.getSettings();
|
||||
if (settings != null && gameEntity.getApk().size() > 1) {
|
||||
for (String pkgName : settings.getGameDownloadBlackList()) {
|
||||
if (pkgName.equals(apkEntity.getPackageName())) {
|
||||
continue apkFor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
downloadEntity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.getUrl());
|
||||
if (downloadEntity != null) {
|
||||
if (downloadEntity.getStatus().equals(DownloadStatus.done)) {
|
||||
doneCount++;
|
||||
}
|
||||
}
|
||||
if (PackagesManager.INSTANCE.isInstalled(apkEntity.getPackageName())) {
|
||||
gh_id = PackageUtils.getMetaData(context, apkEntity.getPackageName(), "gh_id");
|
||||
if (gh_id == null || gh_id.equals(gameEntity.getId())) {
|
||||
installCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} else if (installCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
} else {
|
||||
return context.getString(R.string.download);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取GameUpdateEntity(插件化)
|
||||
*/
|
||||
public static GameUpdateEntity getGameUpdateEntity(GameEntity gameEntity, ApkEntity apkEntity) {
|
||||
GameUpdateEntity gameUpdateEntity = new GameUpdateEntity();
|
||||
gameUpdateEntity.setId(gameEntity.getId());
|
||||
gameUpdateEntity.setIcon(gameEntity.getIcon());
|
||||
gameUpdateEntity.setRawIcon(gameEntity.getRawIcon());
|
||||
gameUpdateEntity.setIconSubscript(gameEntity.getIconSubscript());
|
||||
gameUpdateEntity.setName(gameEntity.getName());
|
||||
gameUpdateEntity.setPackageName(apkEntity.getPackageName());
|
||||
gameUpdateEntity.setSize(apkEntity.getSize());
|
||||
@ -150,7 +199,51 @@ public class GameUtils {
|
||||
gameUpdateEntity.setPlugin(apkEntity.getPlugin());
|
||||
gameUpdateEntity.setDownload(gameEntity.getDownload());
|
||||
gameUpdateEntity.setIndexPlugin(gameEntity.getIndexPlugin());
|
||||
gameUpdateEntity.setPluginDesc(gameEntity.getPluginDesc());
|
||||
gameUpdateEntity.setFormat(apkEntity.getFormat());
|
||||
|
||||
GameCollectionEntity pluggableCollection = getPluggableCollectionFromGameEntity(gameEntity, apkEntity.getPackageName());
|
||||
if (pluggableCollection != null) {
|
||||
gameUpdateEntity.setPluggableCollection(pluggableCollection);
|
||||
}
|
||||
return gameUpdateEntity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GameCollectionEntity getPluggableCollectionFromGameEntity(GameEntity gameEntity, String targetPkg) {
|
||||
// 添加插件化包所在的合集
|
||||
for (GameCollectionEntity collectionEntity : gameEntity.getCollection()) {
|
||||
if (collectionEntity.getPackages().contains(targetPkg)) {
|
||||
ArrayList<ApkEntity> saveApkEntity = new ArrayList<>();
|
||||
for (String pkg : collectionEntity.getPackages()) {
|
||||
for (ApkEntity apk : gameEntity.getApk()) {
|
||||
if (pkg.equals(apk.getPackageName())) {
|
||||
saveApkEntity.add(apk);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<ApkLink> apkLinks = gameEntity.getApkLink();
|
||||
if (apkLinks != null) {
|
||||
for (ApkLink apkLink : apkLinks) {
|
||||
if (apkLink.getCollection().equals(collectionEntity.getId())) {
|
||||
ApkEntity element = new ApkEntity();
|
||||
element.setApkLink(apkLink);
|
||||
if (saveApkEntity.size() > apkLink.getSort()) {
|
||||
saveApkEntity.add(apkLink.getSort(), element);
|
||||
} else {
|
||||
saveApkEntity.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectionEntity.setSaveApkEntity(saveApkEntity);
|
||||
return collectionEntity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,9 @@ import android.widget.LinearLayout;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.common.view.DrawableView;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.TagStyleEntity;
|
||||
|
||||
@ -21,8 +24,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
/**
|
||||
* @author 温冠超
|
||||
* @email 294299195@qq.com
|
||||
@ -32,21 +33,17 @@ import androidx.core.content.ContextCompat;
|
||||
*/
|
||||
public class GameViewUtils {
|
||||
|
||||
public static void setLabelList(Context context, LinearLayout labelLayout, List<String> tag, String tagType, List<TagStyleEntity> tagStyle) {
|
||||
public static void setLabelList(Context context, LinearLayout labelLayout, List<TagStyleEntity> tagStyle) {
|
||||
labelLayout.removeAllViews();
|
||||
if (tag == null || tag.isEmpty()) {
|
||||
labelLayout.addView(getGameTagView(context, "官方版", 0, tagType, null));
|
||||
if (tagStyle == null || tagStyle.isEmpty()) {
|
||||
// 没有数据的话默认不显示
|
||||
// TagStyleEntity tagEntity = new TagStyleEntity();
|
||||
// tagEntity.setName("官方版");
|
||||
// labelLayout.addView(getNewGameTagView(context, tagEntity, 0));
|
||||
} else {
|
||||
for (int i = 0, size = tag.size(); i < size; i++) {
|
||||
View view;
|
||||
if (i == size - 1) {
|
||||
view = getGameTagView(context, tag.get(i), 0, tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
|
||||
} else {
|
||||
view = getGameTagView(context, tag.get(i), DisplayUtils.dip2px(context, 8), tagType, tagStyle.size() > i ? tagStyle.get(i) : null);
|
||||
}
|
||||
if (view != null) {
|
||||
labelLayout.addView(view);
|
||||
}
|
||||
for (int i = 0, size = tagStyle.size(); i < size; i++) {
|
||||
View view = getNewGameTagView(context, tagStyle.get(i), i == size - 1 ? 0 : DisplayUtils.dip2px(context, 8));
|
||||
labelLayout.addView(view);
|
||||
if (labelLayout.getChildCount() == 3) {
|
||||
break;
|
||||
}
|
||||
@ -76,6 +73,32 @@ public class GameViewUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// 新的游戏标签样式 version>=4.0.0
|
||||
private static TextView getNewGameTagView(Context context, TagStyleEntity tagEntity, int rightMargin) {
|
||||
// 参数不全,用旧样式实现
|
||||
if (TextUtils.isEmpty(tagEntity.getBackground())) {
|
||||
return getGameTagView(context, tagEntity.getName(), rightMargin, "type", tagEntity);
|
||||
}
|
||||
|
||||
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
|
||||
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
lparams.rightMargin = rightMargin;
|
||||
TextView tag = new TextView(context);
|
||||
tag.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
|
||||
tag.setSingleLine(true);
|
||||
tag.setText(tagEntity.getName());
|
||||
tag.setLayoutParams(lparams);
|
||||
tag.setPadding(
|
||||
DisplayUtils.dip2px(context, 4),
|
||||
0,
|
||||
DisplayUtils.dip2px(context, 4),
|
||||
DisplayUtils.dip2px(context, 1));
|
||||
|
||||
tag.setTextColor(Color.parseColor("#" + tagEntity.getColor()));
|
||||
tag.setBackground(DrawableView.getServerDrawable(Color.parseColor("#" + tagEntity.getBackground())));
|
||||
return tag;
|
||||
}
|
||||
|
||||
private static TextView getGameTagView(Context context, String tagStr, int rightMargin, String tagType, TagStyleEntity tagEntity) {
|
||||
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(
|
||||
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
|
||||
@ -23,7 +23,7 @@ object GdtHelper {
|
||||
const val PLATFORM = "PLATFORM"
|
||||
|
||||
fun init(application: Application) {
|
||||
GDTAction.init(application, "1110071928", "7fe03caa04ed382e9dce401312b1d0ae")
|
||||
GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
}
|
||||
|
||||
fun logAction(type: String) {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import org.json.JSONArray
|
||||
|
||||
@ -10,6 +11,7 @@ import org.json.JSONArray
|
||||
*/
|
||||
object GsonUtils {
|
||||
val gson: Gson = Gson()
|
||||
val gsonThatIgnoreNull: Gson = GsonBuilder().serializeNulls().create()
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJson(json: String, t: Class<T>): T {
|
||||
@ -22,8 +24,19 @@ object GsonUtils {
|
||||
return gson.fromJson(json.toString(), type)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJsonList(json: String): List<T> {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json, type)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun toJson(any: Any?): String {
|
||||
return gson.toJson(any)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun toJsonIgnoreNull(any: Any?): String {
|
||||
return gsonThatIgnoreNull.toJson(any)
|
||||
}
|
||||
}
|
||||
50
app/src/main/java/com/gh/common/util/HomePluggableHelper.kt
Normal file
50
app/src/main/java/com/gh/common/util/HomePluggableHelper.kt
Normal file
@ -0,0 +1,50 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.entity.HomePluggableFilterEntity
|
||||
import com.gh.gamecenter.room.AppDatabase
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object HomePluggableHelper {
|
||||
|
||||
private val mHomePluggableFilterDao = AppDatabase.getInstance(HaloApp.getInstance().application).homePluggableFilterDao()
|
||||
|
||||
@JvmStatic
|
||||
fun setHomePluggableFilterData(gameEntity: GameEntity, isNever: Boolean) {
|
||||
val apkList = gameEntity.getApk()
|
||||
if (apkList.isNotEmpty()) {
|
||||
val apk = apkList.first()
|
||||
val tag = if (isNever) "never" else apk.version ?: ""
|
||||
mHomePluggableFilterDao.addData(HomePluggableFilterEntity(pkgName = apk.packageName, tag = tag, active = isNever))
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showHomePluggable(gameEntity: GameEntity): Boolean {
|
||||
val apkList = gameEntity.getApk()
|
||||
if (apkList.isNotEmpty()) {
|
||||
val apk = apkList.first()
|
||||
val filterData = mHomePluggableFilterDao.getDataByPkgName(apk.packageName)
|
||||
if (filterData?.active == true) {
|
||||
val filterTag = filterData.tag
|
||||
return filterTag != "never" && apk.version != filterTag
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getPermanentInactivePluggablePackage() = mHomePluggableFilterDao.getDataByTag("never")
|
||||
|
||||
@JvmStatic
|
||||
fun activationFilterData() {
|
||||
val filterList = mHomePluggableFilterDao.getDataByActive(false)
|
||||
|
||||
if (filterList != null) {
|
||||
for (entity in filterList) {
|
||||
entity.active = true
|
||||
}
|
||||
mHomePluggableFilterDao.addData(filterList)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
@ -9,19 +10,21 @@ import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.facebook.common.executors.CallerThreadExecutor
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.drawee.controller.BaseControllerListener
|
||||
import com.facebook.drawee.controller.ControllerListener
|
||||
import com.facebook.drawee.drawable.ScalingUtils
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
||||
import com.facebook.imagepipeline.image.ImageInfo
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.R
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.squareup.picasso.Picasso
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
|
||||
@ -29,6 +32,10 @@ object ImageUtils {
|
||||
|
||||
private const val PIC_MAX_FILE_SIZE: Long = 10 * 1024 * 1024
|
||||
|
||||
private val TINY_GIF_SIZE = 30F.dip2px()
|
||||
private val LARGE_GIF_SIZE = 80F.dip2px()
|
||||
private val STANDARD_GIF_SIZE = 60F.dip2px()
|
||||
|
||||
@JvmStatic
|
||||
fun getUploadFileMaxSize(): Long {
|
||||
val uploadLimitSize = Config.getSettings()?.image?.uploadLimitSize
|
||||
@ -214,17 +221,21 @@ object ImageUtils {
|
||||
.build()
|
||||
}
|
||||
|
||||
// 获取bitmap
|
||||
// 获取bitmap (使用 fresco 获取 gif bitmap 会为空,https://github.com/facebook/fresco/issues/241)
|
||||
// 所以这里换用 picasso
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun display(context: Context?, url: String?, dataSubscriber: BaseBitmapDataSubscriber) {
|
||||
val imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(Uri.parse(url))
|
||||
.setProgressiveRenderingEnabled(true)
|
||||
.build()
|
||||
|
||||
Fresco.getImagePipeline()
|
||||
.fetchDecodedImage(imageRequest, context)
|
||||
.subscribe(dataSubscriber, CallerThreadExecutor.getInstance())
|
||||
fun getBitmap(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
Single.just(url)
|
||||
.map { Picasso.with(HaloApp.getInstance().application).load(url).priority(Picasso.Priority.HIGH).get() }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
callback.onFirst(it)
|
||||
}, {
|
||||
callback.onSecond(true)
|
||||
it.printStackTrace()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,12 +249,23 @@ object ImageUtils {
|
||||
// 图片是以 gif 结尾的就
|
||||
if (it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false) {
|
||||
if (view?.tag == url) return@let
|
||||
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(url)
|
||||
.setAutoPlayAnimations(true)
|
||||
.build()
|
||||
view?.controller = controller
|
||||
val width = view?.layoutParams?.width
|
||||
val height = view?.layoutParams?.height
|
||||
if (width != null && width > 0) {
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(resizeGif(url, width, height ?: 0))
|
||||
.setAutoPlayAnimations(true)
|
||||
.build()
|
||||
view.controller = controller
|
||||
} else {
|
||||
view?.post {
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(resizeGif(url, view.width, view.height))
|
||||
.setAutoPlayAnimations(true)
|
||||
.build()
|
||||
view.controller = controller
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val width = view?.layoutParams?.width
|
||||
if (width != null && width > 0) {
|
||||
@ -323,8 +345,36 @@ object ImageUtils {
|
||||
draweeView.setImageURI("res:///" + res)
|
||||
}
|
||||
|
||||
//预加载图片
|
||||
@JvmStatic
|
||||
fun prefetchToDiskCache(url: String) {
|
||||
val imagePipeline = Fresco.getImagePipeline()
|
||||
val imageRequest = ImageRequest.fromUri(url)
|
||||
imagePipeline.prefetchToDiskCache(imageRequest, HaloApp.getInstance().application)
|
||||
}
|
||||
|
||||
private fun resizeGif(url: String, width: Int, height: Int): String {
|
||||
val idealSize = getIdealGifSize(width, height)
|
||||
return "$url?x-oss-process=image/resize,h_$idealSize,w_$idealSize"
|
||||
}
|
||||
|
||||
private fun getIdealGifSize(width: Int, height: Int): String {
|
||||
return if (width > LARGE_GIF_SIZE || height > LARGE_GIF_SIZE) {
|
||||
"256"
|
||||
} else if (width >= STANDARD_GIF_SIZE || height >= STANDARD_GIF_SIZE) {
|
||||
"192"
|
||||
} else if (width > TINY_GIF_SIZE || height > TINY_GIF_SIZE) {
|
||||
"128"
|
||||
} else {
|
||||
"64"
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnImageloadListener {
|
||||
fun onLoadFinal(imageInfo: ImageInfo?)
|
||||
}
|
||||
|
||||
fun getVideoSnapshot(videoUrl: String, progress: Long): String {
|
||||
return "$videoUrl?x-oss-process=video/snapshot,t_$progress,f_jpg,w_0,h_0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,8 +67,8 @@ public class InstallUtils {
|
||||
String installVersion = PackageUtils.getVersionByPackage(packageName);
|
||||
if (!TextUtils.isEmpty(installVersion) && downloadEntity != null &&
|
||||
installVersion.equals(downloadEntity.getVersionName())) {
|
||||
if (!downloadEntity.isPluggable() || PackageUtils.isSignature(context, packageName)) {
|
||||
EventBus.getDefault().post(new EBPackage("安装", packageName));
|
||||
if (!downloadEntity.isPluggable() || PackageUtils.isSignedByGh(context, packageName)) {
|
||||
EventBus.getDefault().post(new EBPackage("安装", packageName, installVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ public class InstallUtils {
|
||||
keys.add(packageName);
|
||||
} else if (!list.contains(packageName)) {
|
||||
keys.add(packageName);
|
||||
EventBus.getDefault().post(new EBPackage("卸载", packageName));
|
||||
EventBus.getDefault().post(new EBPackage("卸载", packageName, ""));
|
||||
}
|
||||
}
|
||||
for (String key : keys) {
|
||||
|
||||
@ -11,8 +11,6 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.LibaoDetailAdapter;
|
||||
@ -20,6 +18,7 @@ import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.LibaoEntity;
|
||||
import com.gh.gamecenter.entity.LibaoStatusEntity;
|
||||
import com.gh.gamecenter.entity.MeEntity;
|
||||
import com.gh.gamecenter.entity.NotificationUgc;
|
||||
import com.gh.gamecenter.entity.UserDataLibaoEntity;
|
||||
import com.gh.gamecenter.eventbus.EBReuse;
|
||||
import com.gh.gamecenter.eventbus.EBUISwitch;
|
||||
@ -37,6 +36,7 @@ import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
@ -151,76 +151,76 @@ public class LibaoUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static void setLiBaoBtnStatus(final TextView libaoBtn, String status, Context context) {
|
||||
public static void setLiBaoBtnStatusRound(final TextView libaoBtn, String status, Context context) {
|
||||
libaoBtn.setTextColor(Color.WHITE);
|
||||
if (TextUtils.isEmpty(status)) return;
|
||||
switch (status) {
|
||||
case "ling":
|
||||
libaoBtn.setText(R.string.libao_ling);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
break;
|
||||
case "tao":
|
||||
libaoBtn.setText(R.string.libao_tao);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
break;
|
||||
case "coming":
|
||||
libaoBtn.setText(R.string.libao_coming);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
|
||||
break;
|
||||
case "used_up":
|
||||
libaoBtn.setText(R.string.libao_used_up);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
|
||||
break;
|
||||
case "finish":
|
||||
libaoBtn.setText(R.string.libao_finish);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_round_gray);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
break;
|
||||
case "linged":
|
||||
libaoBtn.setText(R.string.libao_linged);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
|
||||
break;
|
||||
case "taoed":
|
||||
libaoBtn.setText(R.string.libao_taoed);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
|
||||
break;
|
||||
case "copy":
|
||||
libaoBtn.setText(R.string.libao_copy);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
break;
|
||||
case "repeatLing":
|
||||
libaoBtn.setText(R.string.libao_repeat_ling);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
|
||||
break;
|
||||
case "repeatLinged":
|
||||
libaoBtn.setText(R.string.libao_repeat_ling);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
break;
|
||||
case "repeatTao":
|
||||
libaoBtn.setText(R.string.libao_repeat_tao);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_border);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_border);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.theme_font));
|
||||
break;
|
||||
case "repeatTaoed":
|
||||
libaoBtn.setText(R.string.libao_repeat_tao);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
break;
|
||||
case "unshelve":
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_round_gray);
|
||||
libaoBtn.setText(R.string.libao_unshelve);
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
break;
|
||||
case "check":
|
||||
libaoBtn.setText(R.string.libao_check);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_style);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
|
||||
break;
|
||||
default:
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_gray);
|
||||
libaoBtn.setBackgroundResource(R.drawable.button_border_round_gray);
|
||||
libaoBtn.setText("异常");
|
||||
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
|
||||
break;
|
||||
@ -230,7 +230,7 @@ public class LibaoUtils {
|
||||
public static void initLibaoBtn(final Context context, final TextView libaoBtn, final LibaoEntity libaoEntity,
|
||||
final boolean isInstallRequired, final LibaoDetailAdapter adapter, final String entrance) {
|
||||
String status = libaoEntity.getStatus();
|
||||
setLiBaoBtnStatus(libaoBtn, status, context);
|
||||
setLiBaoBtnStatusRound(libaoBtn, status, context);
|
||||
|
||||
libaoBtn.setOnClickListener(v -> {
|
||||
String btnStatus = libaoBtn.getText().toString();
|
||||
@ -456,20 +456,26 @@ public class LibaoUtils {
|
||||
|
||||
adapter.initLibaoCode(new UserDataLibaoEntity(libaoCode, "ling", Utils.getTime(context)));
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
final String finalLibaoCode = libaoCode;
|
||||
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, libaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, () -> {
|
||||
copyLink(finalLibaoCode, context);
|
||||
if (isInstallRequired) {
|
||||
libaoBtn.postDelayed(() -> {
|
||||
Spanned msg = Html.fromHtml(context.getString(R.string.linged_copy_dialog, finalLibaoCode));
|
||||
lunningAppDialog(context
|
||||
, msg, libaoEntity);
|
||||
}, 300);
|
||||
}
|
||||
}, null);
|
||||
NotificationHelper.showNotificationHintDialog(NotificationUgc.GIFT, isShow -> {
|
||||
if (!isShow){
|
||||
DialogUtils.showWarningDialog(context, "领取成功", Html.fromHtml(context.getString(R.string.linged_dialog, finalLibaoCode))
|
||||
, "关闭", " 复制礼包码"
|
||||
, () -> {
|
||||
copyLink(finalLibaoCode, context);
|
||||
if (isInstallRequired) {
|
||||
libaoBtn.postDelayed(() -> {
|
||||
Spanned msg = Html.fromHtml(context.getString(R.string.linged_copy_dialog, finalLibaoCode));
|
||||
lunningAppDialog(context
|
||||
, msg, libaoEntity);
|
||||
}, 300);
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,25 +1,32 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.ExposureEntity;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.exposure.ExposureSource;
|
||||
import com.gh.common.exposure.meta.Meta;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.common.loghub.LoghubUtils;
|
||||
import com.gh.download.DownloadDataHelper;
|
||||
import com.gh.common.loghub.SimpleLogContainerEntity;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
import com.gh.gamecenter.entity.CommunityEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.ShareResultEntity;
|
||||
import com.gh.gamecenter.entity.SpecialColumn;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.qa.entity.Questions;
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
@ -29,7 +36,9 @@ import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
/**
|
||||
* Created by khy on 2/01/18.
|
||||
@ -53,55 +62,6 @@ public class LogUtils {
|
||||
uploadVideoStreaming(object);
|
||||
}
|
||||
|
||||
public static void uploadDownloadEvent(DownloadEntity downloadEntity) {
|
||||
Context context = HaloApp.getInstance().getApplication();
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject object = new JSONObject();
|
||||
|
||||
try {
|
||||
object.put("event", DownloadDataHelper.getDownloadStatusAlias(downloadEntity));
|
||||
object.put("msg", downloadEntity.getError());
|
||||
object.put("status", downloadEntity.getStatus().getStatus());
|
||||
|
||||
// payload
|
||||
JSONObject payloadObject = new JSONObject();
|
||||
payloadObject.put("game_id", downloadEntity.getGameId());
|
||||
payloadObject.put("gameName", downloadEntity.getName());
|
||||
payloadObject.put("platform", downloadEntity.getPlatform());
|
||||
payloadObject.put("package", downloadEntity.getPackageName());
|
||||
payloadObject.put("filename", downloadEntity.getPath().substring(downloadEntity.getPath().lastIndexOf("/") + 1));
|
||||
payloadObject.put("total_size", (downloadEntity.getSize() / 1024 / 1024));
|
||||
payloadObject.put("completed_size", (downloadEntity.getProgress() / 1024 / 1024));
|
||||
|
||||
object.put("payload", payloadObject);
|
||||
|
||||
// meta
|
||||
JSONObject metaObject = new JSONObject();
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("android_sdk", meta.getAndroid_sdk());
|
||||
metaObject.put("android_version", meta.getAndroid_version());
|
||||
metaObject.put("appVersion", meta.getAppVersion());
|
||||
metaObject.put("channel", meta.getChannel());
|
||||
metaObject.put("gid", meta.getGid());
|
||||
metaObject.put("imei", meta.getImei());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
metaObject.put("network", DeviceUtils.getNetwork(context));
|
||||
metaObject.put("os", meta.getOs());
|
||||
metaObject.put("userId", meta.getUserId());
|
||||
|
||||
object.put("meta", metaObject);
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "download_debug", false);
|
||||
}
|
||||
|
||||
public static void uploadCommunityArticle(String tracers, String articleId, String articleTitle, int readTime, CommunityEntity community, SpecialColumn specialColumn) {
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
@ -283,7 +243,7 @@ public class LogUtils {
|
||||
|
||||
uploadToReservation(object);
|
||||
}
|
||||
|
||||
|
||||
private static void uploadToCommunity(JSONObject object) {
|
||||
uploadToCommunity(object, false);
|
||||
}
|
||||
@ -419,4 +379,147 @@ public class LogUtils {
|
||||
}
|
||||
uploadVideoStreaming(object);
|
||||
}
|
||||
|
||||
public static void uploadWelcomeDialog(String action, String dialogId, String linkTitle) {
|
||||
ExposureEntity payload = new ExposureEntity();
|
||||
payload.setWelcomeDialogId(dialogId);
|
||||
payload.setWelcomeDialogId(linkTitle);
|
||||
|
||||
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
|
||||
entity.setEvent("dialog");
|
||||
entity.setAction(action);
|
||||
entity.setMeta(MetaUtil.INSTANCE.getMeta());
|
||||
entity.setPayload(payload);
|
||||
entity.setTimestamp(System.currentTimeMillis() / 1000);
|
||||
|
||||
LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false);
|
||||
}
|
||||
|
||||
public static void uploadLikeFromWelcomeDialog() {
|
||||
String dialogId = (String) HaloApp.get(Constants.WELCOME_DIALOG_ID, false);
|
||||
String linkTitle = (String) HaloApp.get(Constants.WELCOME_DIALOG_LINK_TITLE, false);
|
||||
|
||||
ExposureEntity payload = new ExposureEntity();
|
||||
payload.setWelcomeDialogId(dialogId);
|
||||
payload.setWelcomeDialogLinkTitle(linkTitle);
|
||||
|
||||
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
|
||||
entity.setEvent("like");
|
||||
entity.setMeta(MetaUtil.INSTANCE.getMeta());
|
||||
entity.setPayload(payload);
|
||||
entity.setTimestamp(System.currentTimeMillis() / 1000);
|
||||
|
||||
LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false);
|
||||
}
|
||||
|
||||
public static void uploadCommentFromWelcomeDialog() {
|
||||
String dialogId = (String) HaloApp.get(Constants.WELCOME_DIALOG_ID, false);
|
||||
String linkTitle = (String) HaloApp.get(Constants.WELCOME_DIALOG_LINK_TITLE, false);
|
||||
|
||||
ExposureEntity payload = new ExposureEntity();
|
||||
payload.setWelcomeDialogId(dialogId);
|
||||
payload.setWelcomeDialogLinkTitle(linkTitle);
|
||||
|
||||
SimpleLogContainerEntity entity = new SimpleLogContainerEntity();
|
||||
entity.setEvent("comment");
|
||||
entity.setMeta(MetaUtil.INSTANCE.getMeta());
|
||||
entity.setPayload(payload);
|
||||
entity.setTimestamp(System.currentTimeMillis() / 1000);
|
||||
|
||||
LoghubUtils.log(GsonUtils.toJsonIgnoreNull(entity), "event", false);
|
||||
}
|
||||
|
||||
private static void uploadShare(JSONObject object) {
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject metaObject = new JSONObject();
|
||||
try {
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("android_sdk", meta.getAndroid_sdk());
|
||||
metaObject.put("android_version", meta.getAndroid_version());
|
||||
metaObject.put("appVersion", meta.getAppVersion());
|
||||
metaObject.put("channel", meta.getChannel());
|
||||
metaObject.put("gid", meta.getGid());
|
||||
metaObject.put("imei", meta.getImei());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
metaObject.put("network", meta.getNetwork());
|
||||
metaObject.put("os", meta.getOs());
|
||||
metaObject.put("userId", meta.getUserId());
|
||||
|
||||
object.put("event", "SHARE");
|
||||
object.put("meta", metaObject);
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
|
||||
public static void uploadShareEnter(String entrance, String url, String title, String summary, String resourceId) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payloadObject = new JSONObject();
|
||||
try {
|
||||
object.put("action", "entrance_source");
|
||||
payloadObject.put("entrance", entrance);
|
||||
payloadObject.put("url", url);
|
||||
payloadObject.put("title", title);
|
||||
payloadObject.put("summary", summary);
|
||||
payloadObject.put("resource_id", resourceId);
|
||||
object.put("payload", payloadObject);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
uploadShare(object);
|
||||
}
|
||||
|
||||
public static void uploadShareType(String shareType, String entrance, String url, String title, String summary, String resourceId) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payloadObject = new JSONObject();
|
||||
try {
|
||||
object.put("action", "share_type");
|
||||
payloadObject.put("share_type", shareType);
|
||||
payloadObject.put("entrance", entrance);
|
||||
payloadObject.put("url", url);
|
||||
payloadObject.put("title", title);
|
||||
payloadObject.put("summary", summary);
|
||||
payloadObject.put("resource_id", resourceId);
|
||||
object.put("payload", payloadObject);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
uploadShare(object);
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
public static void uploadShareResult(String shareType, String entrance, String shareResult, String url, String title, String summary, String resourceId) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payloadObject = new JSONObject();
|
||||
try {
|
||||
object.put("action", "share_result");
|
||||
payloadObject.put("share_type", shareType);
|
||||
payloadObject.put("entrance", entrance);
|
||||
payloadObject.put("share_result", shareResult);
|
||||
payloadObject.put("url", url);
|
||||
payloadObject.put("title", title);
|
||||
payloadObject.put("summary", summary);
|
||||
payloadObject.put("resource_id", resourceId);
|
||||
object.put("payload", payloadObject);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
uploadShare(object);
|
||||
|
||||
ShareResultEntity entity = new ShareResultEntity(new ShareResultEntity.Content(url, title, summary), shareType, shareResult);
|
||||
RequestBody body = RequestBody.create(MediaType.parse("application/json"), GsonUtils.toJson(entity));
|
||||
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().getApplication()).getApi()
|
||||
.postShareResult(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(new EmptyResponse<>());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,9 @@ package com.gh.common.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import com.bytedance.sdk.open.aweme.authorize.model.Authorization
|
||||
import com.bytedance.sdk.open.douyin.DouYinOpenApiFactory
|
||||
import com.bytedance.sdk.open.douyin.DouYinOpenConfig
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.user.LoginTag
|
||||
@ -23,7 +25,7 @@ import com.tencent.tauth.Tencent
|
||||
import com.tencent.tauth.UiError
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* 第三方登录辅助类
|
||||
@ -37,12 +39,12 @@ object LoginHelper {
|
||||
|
||||
private var mTencent: Tencent // QQ
|
||||
private var mIWXAPI: IWXAPI // 微信
|
||||
private var mSsoHandler: SsoHandler? = null // 微博 // TODO 完成回调时清掉这个 handler ?
|
||||
private var mSsoHandler: WeakReference<SsoHandler>? = null // 微博
|
||||
|
||||
private var mQqLoginListener: IUiListener
|
||||
|
||||
private var mAccessToken: Oauth2AccessToken? = null // weibo
|
||||
private var mLoginCallback: LoginCallback? = null
|
||||
private var mLoginCallback: WeakReference<LoginCallback>? = null
|
||||
|
||||
init {
|
||||
val context = HaloApp.getInstance().application.applicationContext
|
||||
@ -64,11 +66,11 @@ object LoginHelper {
|
||||
content.put("access_token_expire", Utils.getTime(context) + o.getLong("expires_in"))
|
||||
content.put("access_token", o.getString("access_token"))
|
||||
|
||||
mLoginCallback?.onLoginSuccess(LoginTag.qq, content) // 回调QQ登录成功
|
||||
mLoginCallback?.get()?.onLoginSuccess(LoginTag.qq, content) // 回调QQ登录成功
|
||||
} catch (e: JSONException) {
|
||||
val errorString = "QQ登录数据回调异常::$e"
|
||||
|
||||
mLoginCallback?.onLoginFailure(LoginTag.qq, errorString) // 回调QQ登录失败
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.qq, errorString) // 回调QQ登录失败
|
||||
|
||||
Utils.log(errorString)
|
||||
e.printStackTrace()
|
||||
@ -77,18 +79,20 @@ object LoginHelper {
|
||||
}
|
||||
|
||||
override fun onCancel() {
|
||||
mLoginCallback?.onLoginFailure(LoginTag.qq,"登录取消")
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.qq, "登录取消")
|
||||
Utils.log("QQ 登录取消")
|
||||
}
|
||||
|
||||
override fun onError(p0: UiError?) {
|
||||
mLoginCallback?.onLoginFailure(LoginTag.qq,"登录失败")
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.qq, "登录失败")
|
||||
Utils.log("QQ 登录失败")
|
||||
}
|
||||
}
|
||||
|
||||
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
|
||||
|
||||
DouYinOpenApiFactory.init(DouYinOpenConfig(Config.DOUYIN_CLIENTKEY))
|
||||
|
||||
Utils.log("LoginHelper initialization")
|
||||
}
|
||||
|
||||
@ -99,23 +103,33 @@ object LoginHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun onWechatLoginSuccess(content: JSONObject) {
|
||||
mLoginCallback?.onLoginSuccess(LoginTag.wechat, content)
|
||||
mLoginCallback?.get()?.onLoginSuccess(LoginTag.wechat, content)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onWechatLoginFailure(error: String) {
|
||||
mLoginCallback?.onLoginFailure(LoginTag.wechat, error)
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.wechat, error)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onDouYinLoginSuccess(content: JSONObject) {
|
||||
mLoginCallback?.get()?.onLoginSuccess(LoginTag.douyin, content)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onDouYinLoginFailure(error: String) {
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.douyin, error)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onWeiboLoginCallback(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
mSsoHandler?.authorizeCallBack(requestCode, resultCode, data)
|
||||
mSsoHandler?.get()?.authorizeCallBack(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
// QQ登录
|
||||
@JvmStatic
|
||||
fun loginWithQQ(loginCallback: LoginCallback, activity: Activity) {
|
||||
mLoginCallback = loginCallback
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
if (!mTencent.isSessionValid) {
|
||||
Utils.log("QQLogin")
|
||||
mTencent.login(activity, "all", mQqLoginListener)
|
||||
@ -132,7 +146,7 @@ object LoginHelper {
|
||||
// 微信登录
|
||||
@JvmStatic
|
||||
fun loginWithWechat(loginCallback: LoginCallback) {
|
||||
mLoginCallback = loginCallback
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
val register = mIWXAPI.registerApp(Config.WECHAT_APPID)
|
||||
|
||||
val req = SendAuth.Req()
|
||||
@ -149,9 +163,9 @@ object LoginHelper {
|
||||
// 微博登录
|
||||
@JvmStatic
|
||||
fun loginWithWeibo(loginCallback: LoginCallback, context: Activity) {
|
||||
mLoginCallback = loginCallback
|
||||
mSsoHandler = SsoHandler(context)
|
||||
mSsoHandler?.authorizeClientSso(object : WbAuthListener {
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
mSsoHandler = WeakReference(SsoHandler(context))
|
||||
mSsoHandler?.get()?.authorizeClientSso(object : WbAuthListener {
|
||||
override fun onSuccess(token: Oauth2AccessToken?) {
|
||||
token?.let {
|
||||
RuntimeUtils.getInstance().runOnUiThread {
|
||||
@ -159,7 +173,7 @@ object LoginHelper {
|
||||
if (mAccessToken?.isSessionValid == true) {
|
||||
// 保存 Token 到 SharedPreferences
|
||||
AccessTokenKeeper.writeAccessToken(context, mAccessToken)
|
||||
Toast.makeText(context, "授权成功", Toast.LENGTH_SHORT).show()
|
||||
Utils.toast(context, "授权成功")
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,23 +184,36 @@ object LoginHelper {
|
||||
content.put("access_token_expire", Utils.getTime(context) + token.expiresTime)
|
||||
content.put("refresh_token", token.refreshToken)
|
||||
// content.put("refresh_token_expire", Utils.getTime(mContext) + 86400 * 30); // refresh_token 有效期30天
|
||||
mLoginCallback?.onLoginSuccess(LoginTag.weibo, content)// 微博 登录回调
|
||||
mLoginCallback?.get()?.onLoginSuccess(LoginTag.weibo, content)// 微博 登录回调
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(p0: WbConnectErrorMessage?) {
|
||||
mLoginCallback?.onLoginFailure(LoginTag.weibo, "微博登录需要客户端支持,请先安装微博")
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.weibo, "微博登录需要客户端支持,请先安装微博")
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
mLoginCallback?.onLoginFailure(LoginTag.weibo, "取消授权")
|
||||
mLoginCallback?.get()?.onLoginFailure(LoginTag.weibo, "取消授权")
|
||||
}
|
||||
})
|
||||
// 第一次启动本应用,AccessToken 不可用
|
||||
mAccessToken = AccessTokenKeeper.readAccessToken(context)
|
||||
}
|
||||
|
||||
// 抖音登录
|
||||
@JvmStatic
|
||||
fun loginWithDouYin(loginCallback: LoginCallback, context: Activity) {
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
val douYinOpenApi = DouYinOpenApiFactory.create(context)
|
||||
|
||||
val request = Authorization.Request()
|
||||
request.scope = "user_info" // 用户授权时必选权限
|
||||
//request.state = "ww"; // 用于保持请求和回调的状态,授权请求后原样带回给第三方。
|
||||
//request.callerLocalEntry = "com.xxx.xxx...activity";
|
||||
douYinOpenApi.authorize(request)
|
||||
}
|
||||
|
||||
interface LoginCallback {
|
||||
fun onLoginSuccess(loginType: LoginTag, jsonContent: JSONObject)
|
||||
|
||||
|
||||
@ -55,6 +55,7 @@ public class LoginUtils {
|
||||
@Override
|
||||
public void onFailure(HttpException e) {
|
||||
super.onFailure(e);
|
||||
listener.onCaptcha(null);
|
||||
if (e == null) {
|
||||
Utils.toast(context, "无法获取验证码,请检查你的网络状态");
|
||||
return;
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
@ -75,4 +82,61 @@ public class MD5Utils {
|
||||
return bigInt.toString(16);
|
||||
}
|
||||
|
||||
|
||||
public static boolean checkMD5(String md5, File updateFile) {
|
||||
if (TextUtils.isEmpty(md5) || updateFile == null) {
|
||||
Utils.log("MD5 string empty or updateFile null");
|
||||
return false;
|
||||
}
|
||||
|
||||
String calculatedDigest = calculateMD5(updateFile);
|
||||
if (calculatedDigest == null) {
|
||||
Utils.log("calculatedDigest null");
|
||||
return false;
|
||||
}
|
||||
|
||||
Utils.log("Calculated digest: " + calculatedDigest);
|
||||
Utils.log("Provided digest: " + md5);
|
||||
return calculatedDigest.equalsIgnoreCase(md5);
|
||||
}
|
||||
|
||||
public static String calculateMD5(File updateFile) {
|
||||
MessageDigest digest;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("MD5");
|
||||
} catch (Exception e) {
|
||||
Utils.log("Exception while getting digest", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream is;
|
||||
try {
|
||||
is = new FileInputStream(updateFile);
|
||||
} catch (Exception e) {
|
||||
Utils.log("Exception while getting FileInputStream", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[8192];
|
||||
int read;
|
||||
try {
|
||||
while ((read = is.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, read);
|
||||
}
|
||||
byte[] md5sum = digest.digest();
|
||||
BigInteger bigInt = new BigInteger(1, md5sum);
|
||||
String output = bigInt.toString(16);
|
||||
// Fill to 32 chars
|
||||
output = String.format("%32s", output).replace(' ', '0');
|
||||
return output;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to process file for MD5", e);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (Exception e) {
|
||||
Utils.log("Exception on closing MD5 input stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,6 +146,8 @@ public class NetworkUtils {
|
||||
return "3G";
|
||||
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||
return "4G";
|
||||
case 20://暂未适配AndroidQ,这里粗暴设置为20
|
||||
return "5G";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.NewsEntity;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
@ -11,6 +13,7 @@ import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@ -46,7 +49,7 @@ public class NewsUtils {
|
||||
* 统计阅读量
|
||||
*/
|
||||
public static void statNewsViews(Context context, String news_id) {
|
||||
RetrofitManager.getInstance(context).getData().postNewsViews(news_id)
|
||||
RetrofitManager.getInstance(context).getApi().postArticleVisit(news_id)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>());
|
||||
@ -77,7 +80,7 @@ public class NewsUtils {
|
||||
/**
|
||||
* 设置新闻类型
|
||||
*/
|
||||
public static void setNewsType(TextView textView, String type, int priority, int position) {
|
||||
public static void setNewsType(TextView textView, @Nullable String type, int priority, int position) {
|
||||
if (priority != 0) {
|
||||
if (position == 0) {
|
||||
textView.setText(R.string.article_top);
|
||||
@ -91,7 +94,7 @@ public class NewsUtils {
|
||||
}
|
||||
|
||||
textView.setTextColor(Color.WHITE);
|
||||
switch (type) {
|
||||
switch (type != null ? type : "") {
|
||||
case "活动":
|
||||
textView.setBackgroundResource(R.drawable.textview_orange_style);
|
||||
break;
|
||||
@ -117,64 +120,23 @@ public class NewsUtils {
|
||||
* 设置新闻发布时间
|
||||
*/
|
||||
public static void setNewsPublishOn(TextView textView, long time) {
|
||||
time = time * 1000;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
|
||||
try {
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
if (time >= today && time < today + 86400 * 1000) {
|
||||
format.applyPattern("HH:mm");
|
||||
textView.setText(format.format(time));
|
||||
} else if (time >= today - 86400 * 1000 && time < today) {
|
||||
format.applyPattern("HH:mm");
|
||||
textView.setText(String.format("昨天 %s", format.format(time)));
|
||||
} else {
|
||||
format.applyPattern("yyyy年MM月dd日 HH:mm");
|
||||
textView.setText(format.format(time));
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
format.applyPattern("yyyy年MM月dd日 HH:mm");
|
||||
textView.setText(format.format(time));
|
||||
}
|
||||
CommentUtils.setCommentTime(textView, time);
|
||||
}
|
||||
|
||||
|
||||
public static void setNewsDetailTime(TextView textView, long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
|
||||
try {
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
long day = time * 1000;
|
||||
if (day >= today && day < today + 86400 * 1000) {
|
||||
long min = new Date().getTime() / 1000 - day / 1000;
|
||||
int hour = (int) (min / (60 * 60));
|
||||
if (hour == 0) {
|
||||
if (min < 60) {
|
||||
textView.setText("刚刚");
|
||||
} else {
|
||||
textView.setText(String.format(Locale.getDefault(), "%d分钟前", (int) (min / 60)));
|
||||
}
|
||||
} else {
|
||||
textView.setText(String.format(Locale.getDefault(), "%d小时前", hour));
|
||||
}
|
||||
} else if (day >= today - 86400 * 1000 * 100 && day < today) {
|
||||
format.applyPattern("HH:mm");
|
||||
textView.setText("昨天 ");
|
||||
} else {
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
textView.setText(format.format(day));
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
textView.setText(format.format(time * 1000));
|
||||
}
|
||||
CommentUtils.setCommentTime(textView, time);
|
||||
}
|
||||
|
||||
public static String getFormattedTime(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
|
||||
try {
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
long day = time * 1000;
|
||||
String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
|
||||
format.applyPattern("yyyy");
|
||||
String currentYear = format.format(day);
|
||||
format.applyPattern("yyyyMMdd");
|
||||
long today = format.parse(format.format(new Date())).getTime();
|
||||
if (day >= today && day < today + 86400 * 1000) {
|
||||
long min = new Date().getTime() / 1000 - day / 1000;
|
||||
int hour = (int) (min / (60 * 60));
|
||||
@ -190,6 +152,13 @@ public class NewsUtils {
|
||||
} else if (day >= today - 86400 * 1000 && day < today) {
|
||||
format.applyPattern("HH:mm");
|
||||
return ("昨天 ");
|
||||
} else if (day >= today - 86400 * 1000 * 7 && day < today - 86400 * 1000) {
|
||||
format.applyPattern("HH:mm");
|
||||
long days = (today - day) / 86400000 + 1;
|
||||
return String.format(Locale.getDefault(), "%d天前 ", days);
|
||||
} else if (day < today - 86400 * 1000 * 7 && year.equals(currentYear)) {
|
||||
format.applyPattern("MM-dd");
|
||||
return (format.format(day));
|
||||
} else {
|
||||
format.applyPattern("yyyy-MM-dd");
|
||||
return (format.format(day));
|
||||
|
||||
@ -18,7 +18,7 @@ import io.reactivex.schedulers.Schedulers
|
||||
object NotificationHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun showNotificationHintDialog(ugc: NotificationUgc) {
|
||||
fun showNotificationHintDialog(ugc: NotificationUgc, callBack: ((isShow: Boolean) -> Unit)? = null) {
|
||||
val showedNewVersion = SPUtils.getInt(Constants.SP_SHOWED_NOTIFICATION_NEW_VERSION, 0)
|
||||
val currentVersion = PackageUtils.getVersionCode()
|
||||
// 版本升级后重置数据
|
||||
@ -29,6 +29,9 @@ object NotificationHelper {
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_ARTICLE, false)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_VIDEO, false)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RATING, false)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_GIFT, false)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RESERVE_GAME, false)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_FEEDBACK, false)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, "")
|
||||
|
||||
SPUtils.setInt(Constants.SP_SHOWED_NOTIFICATION_NEW_VERSION, currentVersion)
|
||||
@ -37,7 +40,10 @@ object NotificationHelper {
|
||||
|
||||
val isShowedToday = SPUtils.getString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, "")
|
||||
// 每天最多只需提示一次
|
||||
if (isShowedToday == TimeUtils.getToday()) return
|
||||
if (isShowedToday == TimeUtils.getToday()){
|
||||
callBack?.invoke(false)
|
||||
return
|
||||
}
|
||||
|
||||
val isShowedLogin = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_LOGIN, false)
|
||||
val isShowedQuestion = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_QUESTION, false)
|
||||
@ -45,78 +51,115 @@ object NotificationHelper {
|
||||
val isShowedArticle = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_ARTICLE, false)
|
||||
val isShowedVideo = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_VIDEO, false)
|
||||
val isShowedRating = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_RATING, false)
|
||||
val isShowedGift = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_GIFT, false)
|
||||
val isShowedReserveGame = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_RESERVE_GAME, false)
|
||||
val isShowedFeedback = SPUtils.getBoolean(Constants.SP_SHOWED_NOTIFICATION_FEEDBACK, false)
|
||||
|
||||
if (isShowedLogin && isShowedQuestion && isShowedAnswer && isShowedArticle && isShowedVideo && isShowedRating) return
|
||||
if (isShowedLogin && isShowedQuestion && isShowedAnswer && isShowedArticle && isShowedVideo && isShowedRating && isShowedGift && isShowedReserveGame && isShowedFeedback) {
|
||||
callBack?.invoke(false)
|
||||
return
|
||||
}
|
||||
|
||||
when (ugc) {
|
||||
NotificationUgc.LOGIN -> {
|
||||
if (!isShowedLogin) {
|
||||
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_LOGIN, true)
|
||||
// 设置今天的时间,表示今天已经触发过了
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.QUESTION -> {
|
||||
if (!isShowedQuestion) {
|
||||
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_QUESTION, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.ANSWER -> {
|
||||
if (!isShowedAnswer) {
|
||||
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_ANSWER, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.ARTICLE -> {
|
||||
if (!isShowedArticle) {
|
||||
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_ARTICLE, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.VIDEO -> {
|
||||
if (!isShowedVideo) {
|
||||
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_VIDEO, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.RATING -> {
|
||||
if (!isShowedRating) {
|
||||
show(AppManager.getInstance().currentActivity() as AppCompatActivity)
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RATING, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.GIFT -> {
|
||||
if (!isShowedGift) {
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_GIFT, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.RESERVE_GAME -> {
|
||||
if (!isShowedReserveGame) {
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_RESERVE_GAME, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
NotificationUgc.FEEDBACK -> {
|
||||
if (!isShowedFeedback) {
|
||||
show(AppManager.getInstance().recentActiveActivity as AppCompatActivity, ugc, callBack)
|
||||
SPUtils.setBoolean(Constants.SP_SHOWED_NOTIFICATION_FEEDBACK, true)
|
||||
SPUtils.setString(Constants.SP_IS_SHOWED_NOTIFICATION_TODAY, TimeUtils.getToday())
|
||||
} else {
|
||||
callBack?.invoke(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun show(activity: AppCompatActivity?) {
|
||||
fun show(activity: AppCompatActivity?, ugc: NotificationUgc, callBack: ((isShow: Boolean) -> Unit)? = null) {
|
||||
if (activity == null) return
|
||||
RetrofitManager.getInstance(activity).api.bootPopup
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<NotificationHint>() {
|
||||
override fun onSuccess(data: NotificationHint) {
|
||||
try {
|
||||
showEnableNotificationDialogIfItsDisabled(activity, data)
|
||||
} catch (ignore: Exception) {
|
||||
}
|
||||
}
|
||||
})
|
||||
showEnableNotificationDialogIfItsDisabled(activity, ugc, callBack)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun showEnableNotificationDialogIfItsDisabled(activity: AppCompatActivity, notificationHint: NotificationHint) {
|
||||
fun showEnableNotificationDialogIfItsDisabled(activity: AppCompatActivity, ugc: NotificationUgc, callBack: ((isShow: Boolean) -> Unit)? = null) {
|
||||
if (notificationIsEnable()) {
|
||||
Utils.log("notification is enable")
|
||||
callBack?.invoke(false)
|
||||
} else {
|
||||
NotificationHintDialogFragment.getInstance(notificationHint).show(activity.supportFragmentManager, "notification")
|
||||
callBack?.invoke(true)
|
||||
NotificationHintDialogFragment.getInstance(ugc).show(activity.supportFragmentManager, "notification")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,18 @@ object NumberUtils {
|
||||
}
|
||||
return s
|
||||
}
|
||||
@JvmStatic
|
||||
fun transSimpleLetterCount(count: Int): String {
|
||||
val s: String
|
||||
s = if (count > 10000) {
|
||||
val number = count / 10000f
|
||||
val fmt = DecimalFormat("#.0")
|
||||
fmt.format(number) + "W"
|
||||
} else {
|
||||
count.toString()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun transSimpleUsageTime(second: Long): String {
|
||||
|
||||
88
app/src/main/java/com/gh/common/util/OssUploadUtils.kt
Normal file
88
app/src/main/java/com/gh/common/util/OssUploadUtils.kt
Normal file
@ -0,0 +1,88 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.alibaba.sdk.android.oss.ClientConfiguration
|
||||
import com.alibaba.sdk.android.oss.ClientException
|
||||
import com.alibaba.sdk.android.oss.OSSClient
|
||||
import com.alibaba.sdk.android.oss.ServiceException
|
||||
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback
|
||||
import com.alibaba.sdk.android.oss.common.auth.OSSStsTokenCredentialProvider
|
||||
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask
|
||||
import com.alibaba.sdk.android.oss.model.PutObjectRequest
|
||||
import com.alibaba.sdk.android.oss.model.PutObjectResult
|
||||
import com.gh.gamecenter.entity.OssEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
|
||||
object OssUploadUtils {
|
||||
//上传文件类型
|
||||
enum class UploadType(val value: String) {
|
||||
GAME("game")//后缀apk
|
||||
}
|
||||
|
||||
//获取Oss配置
|
||||
private fun getOssUpdateConfig(type: UploadType): Single<OssEntity> {
|
||||
return RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.api
|
||||
.getOssUpdateConfig(type.value)
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
}
|
||||
|
||||
//异步上传文件
|
||||
@JvmStatic
|
||||
fun uploadFile(path: String, uploadType: UploadType, listener: OnUploadFileListener?): Disposable {
|
||||
return getOssUpdateConfig(uploadType)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap { mOssEntity ->
|
||||
Single.create<String> {
|
||||
val conf = ClientConfiguration()
|
||||
conf.connectionTimeout = 15 * 1000
|
||||
conf.socketTimeout = 15 * 1000
|
||||
conf.maxConcurrentRequest = 5
|
||||
conf.maxErrorRetry = 2
|
||||
|
||||
val credentialProvider = OSSStsTokenCredentialProvider(mOssEntity.accessKeyId, mOssEntity.accessKeySecret, mOssEntity.securityToken)
|
||||
val oss = OSSClient(HaloApp.getInstance().application, mOssEntity.endPoint, credentialProvider, conf)
|
||||
|
||||
// 构造上传请求
|
||||
val put = PutObjectRequest(mOssEntity.bucket, mOssEntity.key, path)
|
||||
|
||||
val task: OSSAsyncTask<*> = oss.asyncPutObject(put, object : OSSCompletedCallback<PutObjectRequest?, PutObjectResult> {
|
||||
override fun onSuccess(request: PutObjectRequest?, result: PutObjectResult) {
|
||||
it.onSuccess(mOssEntity.domain + mOssEntity.key)
|
||||
}
|
||||
|
||||
override fun onFailure(request: PutObjectRequest?, clientExcepion: ClientException?, serviceException: ServiceException?) {
|
||||
clientExcepion?.printStackTrace()
|
||||
serviceException?.printStackTrace()
|
||||
if (serviceException != null) {
|
||||
it.onError(Throwable(message = clientExcepion?.message + "/" + serviceException.message))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { url, throwable ->
|
||||
if (url.isNotEmpty()) {
|
||||
listener?.onSuccess(url)
|
||||
return@subscribe
|
||||
}
|
||||
if (throwable != null) {
|
||||
listener?.onError(throwable)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface OnUploadFileListener {
|
||||
fun onSuccess(url: String)
|
||||
fun onError(e: Throwable?)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user