Compare commits
718 Commits
v4.0.2-bug
...
video_only
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a826234d0 | |||
| 9f5ffb084a | |||
| b5d4cbe718 | |||
| b39a47c0bd | |||
| 5ea6647bf7 | |||
| 6fcd8397b6 | |||
| 3478aaba2f | |||
| 1f0b9a95e2 | |||
| 5cdc1635ca | |||
| 3db784509b | |||
| e8f63ea99f | |||
| 97ac4b03a3 | |||
| 883a948b7b | |||
| ebb279c42f | |||
| 261e0cc45a | |||
| 0357a0a71e | |||
| d87de59427 | |||
| d5ee01a2e1 | |||
| 3563637919 | |||
| d881e08aee | |||
| f5ff838d2f | |||
| 52c1b08e59 | |||
| 652972f49d | |||
| 0d122cf8ba | |||
| 2b115c4058 | |||
| cfca7db4ef | |||
| 5f66c029fb | |||
| 8635652fe2 | |||
| a890ad532c | |||
| 65c9d2be2a | |||
| 9620e26f6a | |||
| e4ca1d8406 | |||
| 74ebaa592b | |||
| f9b689efdb | |||
| ed458f08ad | |||
| 9822646acc | |||
| 4259078420 | |||
| 3b9db4e964 | |||
| b7e6cd08fd | |||
| bba1e6f10c | |||
| 3fe2973968 | |||
| b16d33d9fa | |||
| e1a7ed9049 | |||
| 11354030e8 | |||
| ee109060fc | |||
| eebc0c1096 | |||
| 4ec45e2a27 | |||
| 12143f7f95 | |||
| 7025dc45bd | |||
| 772e7861e2 | |||
| ff71c9a3e8 | |||
| b7001cc996 | |||
| 83658e47f8 | |||
| 0699d3ccc4 | |||
| f80b998e98 | |||
| 91e84be708 | |||
| f589c286c6 | |||
| 379650a0f5 | |||
| 3796eb46bd | |||
| c240048c5e | |||
| 2f81c9240d | |||
| da0dc3df97 | |||
| d73c0f2044 | |||
| a6f9e12082 | |||
| 20f8ba0de5 | |||
| f7342a944e | |||
| 1086574b33 | |||
| 59e30d432d | |||
| 58631d540c | |||
| 08763aeb2d | |||
| 039d0ca06c | |||
| f39574c8b3 | |||
| 6067a52fb1 | |||
| a1298547d1 | |||
| 49d5514a25 | |||
| 09c414a02c | |||
| 6a6378f635 | |||
| 920050efc8 | |||
| 103ecc10d3 | |||
| f90e9a8085 | |||
| caa37ead4b | |||
| d18eeaf346 | |||
| b98d287843 | |||
| 66fb57f708 | |||
| 3911c10827 | |||
| c29972df50 | |||
| 8001ce2603 | |||
| b1079e84d8 | |||
| c6cf8aab1c | |||
| 4d7718e3af | |||
| 9cdbcd4935 | |||
| d396ebda44 | |||
| 6ab8bdc422 | |||
| 15352bb379 | |||
| b68536b561 | |||
| 762ee8d300 | |||
| 8dfda56586 | |||
| 93126517b6 | |||
| 04a8f5772c | |||
| 9687ddcd54 | |||
| 04c49cbad7 | |||
| 6addea7d73 | |||
| 229eaa0859 | |||
| 3876096f52 | |||
| bad3ab19c6 | |||
| b2100fe0e5 | |||
| 5998bb9d4a | |||
| fefe29a0b8 | |||
| a16554da21 | |||
| 6efc1e06bb | |||
| e51439d584 | |||
| 907bad48bc | |||
| 582df7da58 | |||
| 28f18a558c | |||
| 658fb8579c | |||
| 45632052e5 | |||
| 311211747a | |||
| 010995b16d | |||
| c82e981f4e | |||
| f9803fa244 | |||
| f21d86c8a7 | |||
| 8db525542e | |||
| 49cf093a44 | |||
| f2302ffc50 | |||
| f85685fd52 | |||
| a80419e4bd | |||
| 0e7b6bb097 | |||
| b795df2de8 | |||
| e99e8328ab | |||
| 500c77d6ed | |||
| 3c13431bd3 | |||
| d5e426a7f0 | |||
| 8a37e0bdf4 | |||
| 230eec78c1 | |||
| 8bb74461e6 | |||
| b0d0d3ca45 | |||
| 356c9432ec | |||
| 31e14fd47b | |||
| c0644dc705 | |||
| 1a43589bb1 | |||
| defd6d9a14 | |||
| 77b4e8f73d | |||
| 61ef40f9b5 | |||
| 13dd5c9892 | |||
| d20aef7107 | |||
| 8c9cd6e0ec | |||
| 487c2fd0a5 | |||
| 0ffdef080b | |||
| ba76dbbd15 | |||
| 7cfe82af47 | |||
| 567977089a | |||
| a258fe1d20 | |||
| 28cf1ab114 | |||
| 0e49c074ec | |||
| 85249f1d94 | |||
| 38bda5ec02 | |||
| 0cc24956e0 | |||
| c17bcd9765 | |||
| 9f1642f577 | |||
| 9c01f75e8b | |||
| a460722ae5 | |||
| 37330c2ab2 | |||
| 5db25f966e | |||
| 4749c743e9 | |||
| f5b614cc63 | |||
| 34b8b00cb2 | |||
| 6af86d871c | |||
| 0b7fade38b | |||
| 3237834f9a | |||
| 53e9554f08 | |||
| 70ee3001c2 | |||
| d7ae2b2aa4 | |||
| 9c9dbfb105 | |||
| c633c228db | |||
| ad82005881 | |||
| 815a0d0600 | |||
| e02f9db81d | |||
| c422b96da4 | |||
| 40a64996d7 | |||
| cbfca66d51 | |||
| f4a110c94d | |||
| f601fd2339 | |||
| e3217eaf22 | |||
| 540515ab41 | |||
| e1c02a6138 | |||
| a508576785 | |||
| 84e57d5c91 | |||
| 62b1005dbf | |||
| 04a5450a41 | |||
| 2ac4dd6c5a | |||
| 441a569f30 | |||
| f319201e74 | |||
| 47b2fa60d8 | |||
| 4d15c15b2d | |||
| 3702094d98 | |||
| 6185ca595d | |||
| 358b93029b | |||
| 38044b1d2b | |||
| 90877738b3 | |||
| 477613d21f | |||
| a77ee0fa70 | |||
| 036fa444c6 | |||
| d83e1e413f | |||
| 19986099ff | |||
| f23dd6a662 | |||
| 951d306765 | |||
| 8adfaa88a3 | |||
| fcb76e71e5 | |||
| 2da536f667 | |||
| 2034b1c587 | |||
| ea2e169199 | |||
| 2cf6c2747c | |||
| dd24b6243a | |||
| 81fc6aa6cb | |||
| 8e3bcf6b5b | |||
| 8e181c9846 | |||
| 7a737da328 | |||
| 5545c112b7 | |||
| a6f187d444 | |||
| 3ad72ee1f8 | |||
| 2cc100b887 | |||
| 761c5dc0bf | |||
| 80d3f140f4 | |||
| b72621ee2b | |||
| 7896f3ee46 | |||
| d33c15e47b | |||
| ddcd3f8169 | |||
| 42f66cd543 | |||
| c0efd4a8e4 | |||
| a4df780a8b | |||
| e8ac144454 | |||
| d543181b92 | |||
| 02cfb7515b | |||
| 4b71e44c51 | |||
| 68f7e1fa58 | |||
| 2f66588455 | |||
| f39cf38313 | |||
| 1141604d20 | |||
| 6b575f0169 | |||
| 6428179c54 | |||
| 44445e6e34 | |||
| fb48316069 | |||
| ea5312d606 | |||
| 5cb6f9e296 | |||
| fdb1d255ba | |||
| 153b19c966 | |||
| ba79d009e6 | |||
| 47f9c967b1 | |||
| 97ab6108cf | |||
| 8e9da6e1f5 | |||
| aca29abde6 | |||
| dac3f7e2d7 | |||
| 9f9254a835 | |||
| 58e3ef83e0 | |||
| 76bb5d1052 | |||
| afff3446c4 | |||
| 2fa6e9c549 | |||
| cb4bcedba7 | |||
| 5dbe10a8a8 | |||
| 13ca69c569 | |||
| 19e18226bd | |||
| 6b51a198c2 | |||
| 5ad38457af | |||
| ee3043875a | |||
| 92c8a698f3 | |||
| 41f78c365b | |||
| 4b8053beee | |||
| 8008266389 | |||
| 1ce04241f6 | |||
| a37701f148 | |||
| add1339f4a | |||
| f29b8da6d0 | |||
| de968a4820 | |||
| 859a2a5672 | |||
| ddddda10a5 | |||
| 30d6dabe4f | |||
| 7655cc25be | |||
| 52824e5baa | |||
| 014c80cd18 | |||
| a7a48ccf77 | |||
| 99eddec84a | |||
| 6b382ab080 | |||
| d492cfdace | |||
| 256f0af0e9 | |||
| 58d2290e12 | |||
| 547e6da027 | |||
| c3e34ba644 | |||
| e9583284d0 | |||
| b670a9c1c4 | |||
| 077e17c5aa | |||
| f264875b7d | |||
| 351b8a331c | |||
| 479f7c464b | |||
| e04a7fc4b9 | |||
| 595f7747f4 | |||
| 8c1343fdba | |||
| c3717869bd | |||
| 1e56dc533d | |||
| 1444531830 | |||
| 4e759e446b | |||
| 33d86a7995 | |||
| ef6c09d27b | |||
| efc241429c | |||
| 07be540ba1 | |||
| 50479d2e87 | |||
| 2934c9dc38 | |||
| 30a60797e6 | |||
| 53562297d5 | |||
| 144ee3ea8c | |||
| e0c8697e75 | |||
| 6aba2906f6 | |||
| 7bb468a1b1 | |||
| 871be728bf | |||
| bbac0c8d93 | |||
| 6b361ed077 | |||
| 1cfa54f8e8 | |||
| 80ce5052d9 | |||
| 5bd028cbe9 | |||
| b8f8711ba4 | |||
| ec805653bb | |||
| 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 | |||
| 49b0b982f5 | |||
| e63a374da1 | |||
| 6564de8a72 | |||
| d57ac57f43 | |||
| 942291d7c5 | |||
| de597bdd36 | |||
| e1fc23a1bb | |||
| 2d551a3f73 | |||
| 9b205366f7 | |||
| 798c4a2089 | |||
| 0686f70df6 | |||
| 3c30564ab6 | |||
| f04070e846 | |||
| fc279839fa |
@ -6,7 +6,7 @@ apply plugin: 'kotlin-kapt'
|
||||
// apkChannelPackage
|
||||
apply plugin: 'channel'
|
||||
|
||||
apply from: 'tinker-support.gradle'
|
||||
//apply from: 'tinker-support.gradle'
|
||||
|
||||
android {
|
||||
|
||||
@ -45,6 +45,9 @@ android {
|
||||
abiFilters "armeabi-v7a"
|
||||
}
|
||||
|
||||
renderscriptTargetApi 18
|
||||
renderscriptSupportModeEnabled true
|
||||
|
||||
// 由于app只针对中文用户,所以仅保留zh资源,其他删掉
|
||||
resConfigs "zh"
|
||||
|
||||
@ -67,6 +70,8 @@ android {
|
||||
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}\""
|
||||
@ -187,6 +192,7 @@ dependencies {
|
||||
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stetho}"
|
||||
debugImplementation "com.squareup.okhttp3:logging-interceptor:${okHttp}"
|
||||
debugImplementation "com.gu.android:toolargetool:${toolargetool}"
|
||||
debugImplementation "com.github.nichbar:WhatTheStack:$whatTheStack"
|
||||
|
||||
implementation "androidx.core:core:${core}"
|
||||
implementation "androidx.fragment:fragment:${fragment}"
|
||||
@ -243,7 +249,7 @@ dependencies {
|
||||
implementation "com.sina.weibo.sdk:core:${weiboSDK}"
|
||||
|
||||
// bugly with tinker support
|
||||
implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
|
||||
// implementation "com.tencent.bugly:crashreport_upgrade:${buglyTinkerSupport}"
|
||||
|
||||
implementation "com.google.android:flexbox:${flexbox}"
|
||||
|
||||
@ -266,6 +272,7 @@ dependencies {
|
||||
// for video streaming
|
||||
implementation("com.shuyu:gsyVideoPlayer-java:$gsyVideo", {
|
||||
exclude module: "gsyvideoplayer-androidvideocache"
|
||||
exclude group: "tv.danmaku.ijk.media"
|
||||
})
|
||||
implementation "com.shuyu:GSYVideoPlayer-exo2:$gsyVideo"
|
||||
|
||||
@ -282,25 +289,31 @@ 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.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'
|
||||
})
|
||||
implementation "com.github.PhilJay:MPAndroidChart:${chart}"
|
||||
|
||||
implementation project(':libraries:LGLibrary')
|
||||
implementation project(':libraries:MTA')
|
||||
// implementation project(':libraries:MTA')
|
||||
implementation project(':libraries:QQShare')
|
||||
implementation project(':libraries:TalkingData')
|
||||
implementation project(':libraries:UmengPush')
|
||||
// implementation project(':libraries:TalkingData')
|
||||
// implementation project(':libraries:UmengPush')
|
||||
// implementation project(':libraries:WechatShare')
|
||||
implementation project(':libraries:im')
|
||||
// implementation project(':libraries:im')
|
||||
implementation project(':libraries:Matisse')
|
||||
implementation project(path: ':libraries:gsyVideoPlayer-proxy_cache')
|
||||
}
|
||||
File propFile = file('sign.properties')
|
||||
if (propFile.exists()) {
|
||||
@ -331,7 +344,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/')
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
app/libs/gid-1.3.jar
Normal file
BIN
app/libs/gid-1.3.jar
Normal file
Binary file not shown.
@ -254,4 +254,8 @@
|
||||
-keep class com.taobao.wireless.security.**{*;}
|
||||
-keep class com.ut.secbody.**{*;}
|
||||
-keep class com.taobao.dp.**{*;}
|
||||
-keep class com.alibaba.wireless.security.**{*;}
|
||||
-keep class com.alibaba.wireless.security.**{*;}
|
||||
|
||||
-keep class com.alibaba.sdk.android.**{*;}
|
||||
-keep class com.ut.**{*;}
|
||||
-keep class com.ta.**{*;}
|
||||
@ -27,6 +27,8 @@
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<!-- 修改系统设置的权限 -->
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<!-- 创建快捷方式的权限 -->
|
||||
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
@ -36,30 +38,22 @@
|
||||
<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" />
|
||||
<!--<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.haroldadmin.whatthestack,
|
||||
com.shuyu.gsyvideoplayer.armv7a,
|
||||
com.shuyu.gsyvideoplayer.x86,
|
||||
com.shuyu.gsy.base,
|
||||
com.google.android.exoplayer2,
|
||||
tv.danmaku.ijk.media.exo2,
|
||||
shuyu.com.androidvideocache,
|
||||
pl.droidsonroids.gif,
|
||||
com.ledong.lib.minigame,
|
||||
com.ledong.lib.leto,
|
||||
com.leto.game.base.glide4,
|
||||
com.leto.game.ad.gdt,
|
||||
com.leto.game.fcm,
|
||||
com.leto.game.ad.toutiao" />
|
||||
pl.droidsonroids.gif" />
|
||||
|
||||
<!-- 去掉 SDK 一些流氓权限 -->
|
||||
<uses-permission
|
||||
@ -75,7 +69,7 @@
|
||||
|
||||
<!--android:largeHeap = "true"-->
|
||||
<application
|
||||
android:name="com.halo.assistant.TinkerApp"
|
||||
android:name="com.halo.assistant.HaloApp"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/logo"
|
||||
android:label="@string/app_name"
|
||||
@ -113,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"
|
||||
@ -168,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" />
|
||||
@ -177,9 +177,9 @@
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar"
|
||||
android:name="com.gh.gamecenter.MessageDetailActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.LibaoActivity"
|
||||
@ -207,10 +207,18 @@
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name="com.gh.gamecenter.CommentDetailActivity"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar"
|
||||
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" />
|
||||
@ -389,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" />
|
||||
@ -419,9 +431,9 @@
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar"
|
||||
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"
|
||||
@ -449,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"
|
||||
@ -514,6 +527,69 @@
|
||||
<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=".personalhome.border.AvatarBorderActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.background.PersonalityBackgroundActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.background.BackgroundPreviewActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.background.BackgroundClipActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/TransparentStatusBarAndNavigationBar"/>
|
||||
|
||||
<activity
|
||||
android:name=".personalhome.excellentcomments.ExcellentCommentsActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".simulatorgame.SimulatorGameActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<activity
|
||||
android:name=".simulatorgame.SimulatorManagementActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 使用小米/华为推送弹窗功能提高推送成功率-->
|
||||
<activity
|
||||
@ -542,6 +618,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}"
|
||||
@ -575,43 +657,45 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="com.gh.gamecenter.UMENG" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMessageReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="com.gh.gamecenter.UMENG" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<!--魅族push应用定义消息receiver声明 -->
|
||||
<receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">
|
||||
<intent-filter>
|
||||
<!-- 接收push消息 -->
|
||||
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
|
||||
<!-- 接收register消息 -->
|
||||
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
|
||||
<!-- 接收unregister消息-->
|
||||
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
|
||||
<!-- 兼容低版本Flyme3推送服务配置 -->
|
||||
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
|
||||
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
|
||||
<!-- <!–魅族push应用定义消息receiver声明 –>-->
|
||||
<!-- <receiver android:name="com.gh.gamecenter.receiver.UmengMeizuPushReceiver">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <!– 接收push消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.MESSAGE" />-->
|
||||
<!-- <!– 接收register消息 –>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 接收unregister消息–>-->
|
||||
<!-- <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />-->
|
||||
<!-- <!– 兼容低版本Flyme3推送服务配置 –>-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.REGISTRATION" />-->
|
||||
<!-- <action android:name="com.meizu.c2dm.intent.RECEIVE" />-->
|
||||
|
||||
<category android:name="${applicationId}" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- <category android:name="${applicationId}" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<receiver
|
||||
android:name="com.gh.common.im.ImReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="com.gh.im" />
|
||||
<action android:name="action_finish" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- <receiver-->
|
||||
<!-- android:name="com.gh.common.im.ImReceiver"-->
|
||||
<!-- android:enabled="true">-->
|
||||
<!-- <intent-filter android:priority="2147483647">-->
|
||||
<!-- <action android:name="com.gh.im" />-->
|
||||
<!-- <action android:name="action_finish" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<meta-data android:name="com.huawei.hms.client.appid" android:value="@string/huawei_push_appid"/>
|
||||
<!-- <meta-data-->
|
||||
<!-- android:name="com.huawei.hms.client.appid"-->
|
||||
<!-- android:value="@string/huawei_push_appid" />-->
|
||||
|
||||
<service
|
||||
android:name="com.gh.base.GHUmengNotificationService"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
<!-- <service-->
|
||||
<!-- android:name="com.gh.base.GHUmengNotificationService"-->
|
||||
<!-- android:permission="android.permission.BIND_JOB_SERVICE" />-->
|
||||
|
||||
<!--<service android:name = "com.gh.gamecenter.statistics.AppStaticService" />-->
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
1
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,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-1.3],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.3],[-1.3,-2.5],[1.3,-2.5]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-0.102],[2.5,0],[0,2.109],[-2.5,0],[-2.5,-0.102],[-1.3,-1.302],[1.3,-1.302]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":9,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.498,-1.845],[2.5,0],[0,2.734],[-2.5,0],[-2.502,-1.845],[-1.302,-3.045],[1.298,-3.045]],"c":true}]},{"t":13,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-1.3],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.3],[-1.3,-2.5],[1.3,-2.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"蓝","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33.76,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.8,0.42],[-3.44,-0.79],[-0.09,-1.71],[0,0],[0,0],[1.98,-0.1],[0,0],[0,0],[0,0],[0.62,0.57],[0,0],[0,0],[0,0],[0,0],[0,0],[0.2,1.89],[0,0],[0,0],[0,0]],"o":[[3.44,-0.79],[1.74,0.41],[0,0],[0,0],[0,2],[0,0],[0,0],[0,0],[-0.69,0.52],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.94,0],[0,0],[0,0],[0,0],[0,-1.8]],"v":[[-6.39,-8.971],[6.39,-8.971],[9.49,-5.471],[9.5,-5.271],[9.5,3.249],[5.95,6.989],[5.75,6.999],[3.25,6.999],[0.3,9.209],[-1.95,9.089],[-2.06,8.969],[-2.17,8.849],[-2.21,8.779],[-3.4,6.999],[-5.75,6.999],[-9.48,3.639],[-9.49,3.449],[-9.5,3.249],[-9.5,-5.271]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-9.5,-9.561],"ix":5},"e":{"a":0,"k":[9.5,9.561],"ix":6},"t":1,"nm":"color","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[33,33,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":9,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":13,"s":[90,90,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"w":66,"h":66,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}
|
||||
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"
|
||||
}
|
||||
}
|
||||
]
|
||||
360
app/src/main/assets/privacy_policies.html
Normal file
360
app/src/main/assets/privacy_policies.html
Normal file
@ -0,0 +1,360 @@
|
||||
<html lang="en"><head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>隐私政策</title>
|
||||
<style>
|
||||
* {
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content-area">
|
||||
<p>
|
||||
<b>欢迎您使用光环game!</b>
|
||||
<br>
|
||||
</p>
|
||||
<p>更新日期:2020年11月20日</p>
|
||||
<p>生效日期:2020年11月30日</p>
|
||||
<p>
|
||||
当您使用或开启相关功能或使用服务时,为了实现功能、服务所必需,受制于手机系统限制,我们会申请您的设备信息权限;除非是为实现基本业务服务功能或根据法律法规要求所必需的必要信息,您均可以拒绝提供且不影响其他功能或服务。
|
||||
</p>
|
||||
<p>
|
||||
为了让您正常观看视频和记录浏览账户登录功能,我们会申请您的储存权限;
|
||||
</p>
|
||||
<p>以下为完整《隐私权限政策》</p>
|
||||
<p>
|
||||
光环game(简称“我们”)深知个人信息对您的重要性,我们将依据《中华人民共和国网络安全法》、《信息安全技术
|
||||
个人信息安全规范》(GB/T
|
||||
35273-2017)以及其他相关法律法规和技术规范收集和使用您的个人信息,以帮助我们向您提供更优质的产品和/或服务,
|
||||
保护您的个人信息及隐私安全。我们制定本“隐私指引”并特别提示:希望您在使用光环game及相关服务前仔细阅读并理解本隐私政策,以便做出适当的选择。
|
||||
</p>
|
||||
<p>
|
||||
下文将帮您详细了解我们如何收集、使用、存储、传输、共享、转让(如适用)与保护个人信息;帮您了解查询、访问、删除、更正、撤回授权个人信息的方式。其中,
|
||||
<b>
|
||||
有关您个人信息权益的条款重要内容我们已用加粗形式提示,请特别关注。
|
||||
</b>
|
||||
</p>
|
||||
<p><b>1.我们处理个人信息的法律依据</b></p>
|
||||
<p><b>2.我们如何共享、转让、公开披露个人信息</b></p>
|
||||
<p><b>3.我们如何收集和使用个人信息</b></p>
|
||||
<p><b>4.我们如何存储个人信息</b></p>
|
||||
<p><b>5.我们如何保护个人信息的安全</b></p>
|
||||
<p><b>6.管理您的个人信息</b></p>
|
||||
<p><b>7.未成年人使用条款</b></p>
|
||||
<p><b>8.隐私政策的修订和通知</b></p>
|
||||
<p><b>9.联系我们</b></p>
|
||||
<p><b>1.我们处理个人信息的法律依据</b></p>
|
||||
<p>
|
||||
如果您是中华人民共和国大陆地区的用户,我们将依据《中华人民共和国网络安全法》、《信息安全技术个人信息安全规范》(GB/T
|
||||
35273-2017)以及其他相关法律法规收集和使用您的个人信息,为您提供产品或服务。
|
||||
</p>
|
||||
<p>
|
||||
我们通常只会在征得您同意的情况下收集您的个人信息。在某些情况下,我们可能还会基于法律义务或者履行合同之必需向您收集个人信息,或者可能需要个人信息来保护您的重要利益或其他人的利益。
|
||||
</p>
|
||||
<p><b>2.我们如何共享、转让、公开披露个人信息</b></p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>1</b>
|
||||
<b>共享您的个人信息</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)我们不会与任何公司、组织和个人共享您的个人信息,但以下情况除外:
|
||||
</p>
|
||||
<p>
|
||||
(2)事先获得您的明确授权或同意:
|
||||
获得您的明确同意后,我们会与其他方共享您的个人信息;
|
||||
</p>
|
||||
<p>
|
||||
(3)在法定情形下的共享:
|
||||
根据适用的法律法规、法律程序、政府的强制命令或司法裁定而需共享您的个人信息;
|
||||
</p>
|
||||
<p>
|
||||
(4)在法律要求或允许的范围内,为了保护光环game及其用户或社会公众的利益、财产或安全免遭损害而有必要提供您的个人信息给第三方;
|
||||
</p>
|
||||
<p>
|
||||
(5)与我们的关联公司共享:
|
||||
您的个人信息可能会在我们的关联公司之间共享。我们会对共享的个人信息进行匿名化处理,且这种共享受本指引所声明目的的约束。关联公司如要改变个人信息的处理目的,将再次征求您的授权同意。
|
||||
</p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>2</b>
|
||||
<b>转让</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)我们不会转让您的个人信息给任何其他第三方,除非征得您的明确同意。
|
||||
</p>
|
||||
<p>
|
||||
(2)随着我们业务的持续发展,我们将有可能进行合并、收购、资产转让,您的个人信息有可能因此而被转移。在发生前述变更时,我们将按照法律法规及不低于本隐私政策所载明的安全标准要求继受方保护您的个人信息,否则我们将要求继受方重新征得您的授权同意。
|
||||
</p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>3</b>
|
||||
<b>披露</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)我们不会公开披露您的信息,除非遵循国家法律法规规定或者获得您的同意。我们公开披露您的个人信息会采用符合行业内标准的安全保护措施。
|
||||
</p>
|
||||
<p>
|
||||
(2)基于法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会向有权机关披露您的个人信息。但我们保证,在上述情况发生时,我们会要求披露请求方必须出具与之相应的有效法律文件,并对被披露的信息采取符合法律和业界标准的安全防护措施。
|
||||
</p>
|
||||
<p>(3)对违规账号、欺诈行为进行处罚公告时,我们会披露相关账号的信息。</p>
|
||||
<p>
|
||||
<b>2.</b>
|
||||
<b>4</b>
|
||||
<b>依法豁免征得同意共享、转让、公开披露的个人信息</b>
|
||||
</p>
|
||||
<p>
|
||||
请您理解,在下列情形中,根据法律法规及国家标准,我们共享、转让、公开披露您的个人信息无需征得您的授权同意:
|
||||
</p>
|
||||
<p>(1)与国家安全、国防安全直接相关的;</p>
|
||||
<p>(2)与公共安全、公共卫生、重大公共利益直接相关的;</p>
|
||||
<p>(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;</p>
|
||||
<p>
|
||||
(4)出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
|
||||
</p>
|
||||
<p>(5)您自行向社会公众公开的个人信息;</p>
|
||||
<p>
|
||||
(6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
|
||||
</p>
|
||||
<p><b>3.我们如何收集和使用个人信息</b></p>
|
||||
<p>
|
||||
我们会遵循正当、合法、必要的原则,出于本指引所述的以下目的,收集和使用您在使用服务过程中主动提供或因使用产品或服务而产生的个人信息。
|
||||
</p>
|
||||
<p>
|
||||
我们收集和使用的您的个人信息类型包括两种:第一种:我们产品或服务的核心业务功能所必需的信息:此类信息为产品或服务正常运行的必备信息,您须授权我们收集。如您拒绝提供,您将无法正常使用我们的功能,以"仅浏览(游客身份)"
|
||||
的状态体验;第二种:我们产品或服务的附加业务功能可能需要收集的信息:此信息为非核心业务功能所需的信息,您可以选择是否授权我们收集。如您拒绝提供,将导致附加业务功能无法实现或无法达到我们拟达到的效果,但不影响您对核心业务功能的正常使用。
|
||||
</p>
|
||||
<p>
|
||||
如果我们要将您的个人信息用于本指引未载明的其它用途,或基于特定目的将收集而来的信息用于其他目的,我们将以合理的方式向您告知,并在使用前再次征得您的同意。
|
||||
</p>
|
||||
<p><b>3.1实现产品或服务的基本功能</b></p>
|
||||
<p>
|
||||
(1)手机管理和内容资源下载功能。为实现手机管理及手机内容资源下载的基本功能,我们会通过手机系统的公用接口收集经过MD5算法加密的国际移动设备身份码(IMEI)和网络设备地址(MAC),以及手机型号、手机系统版本号、系统编号、系统ID号、屏幕分辨率、上网类型、手机中软件的名称、版本号、版本名、包名、软件使用时间和频率、软件崩溃信息、设备和软件相关的信息。这些信息是提供服务所必须收集的基础信息,如您拒绝提供上述权限将可能导致您无法使用我们的服务。
|
||||
</p>
|
||||
<p>
|
||||
(2)软件升级管理功能。为实现手机软件下载、安装、升级、卸载软件管理功能,在您使用产品时,我们会采集您手机中已安装软件的软件名称、版本号、版本名、软件包名信息并上传到我们的服务器进行软件版本比对。发现有更新的版本,我们会提示您升级相应的软件。上述软件信息为实现此功能所必需,不涉及您个人身份敏感信息。
|
||||
</p>
|
||||
<p>
|
||||
(3)过滤无法使用的软件功能。为了过滤您手机无法使用的软件,我们会收集您手机的手机型号、手机系统版本号、系统版本号、屏幕分辨率信息,并依据这些信息排除您手机无法使用的软件,以保证您在光环game下载的软件都可安装使用。
|
||||
</p>
|
||||
<p><b>3.2关于获取手机设备信息的说明</b></p>
|
||||
<p>
|
||||
(1)为方便区分每个用户的个人信息等,本软件需获取用户的手机设备信息。(2)为了保障软件与服务的安全运行,我们会收集您的硬件型号、操作系统版本号、国际移动设备识别码、唯一设备标识符、网络设备硬件地址、IP
|
||||
地址、WLAN接入点、蓝牙、基站、软件版本号、网络接入方式、类型、状态、网络质量数据、操作、使用、服务日志。
|
||||
</p>
|
||||
<p>
|
||||
(3)为了预防恶意程序及安全运营所必需,我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据、应用来源。
|
||||
</p>
|
||||
<p>
|
||||
(4)我们可能使用您的账户信息、设备信息、服务日志信息以及我们关联公司、合作方在获得您授权或依法可以共享的信息,用于判断账户安全、进行身份验证、检测及防范安全事件。
|
||||
</p>
|
||||
<p>(5)具体会发生获取手机设备信息场景如下说明:</p>
|
||||
<p>
|
||||
①首次启动光环game ②评论详情-发送评论功能 ③视频投稿-上传视频功能 ④视频详情-关注up主功能
|
||||
</p>
|
||||
<p><b>3.3帮助您成为我们的在线用户</b></p>
|
||||
<p>(1)注册账号/登录账号</p>
|
||||
<p>
|
||||
a.当您注册、登录我们相关服务时,您可以通过手机号创建账号,并且您可以完善相关的网络身份识别信息(头像、昵称、密码),收集这些信息是为了帮助您完成注册。您还可以根据自身需求选择填写性别、生日、地区及个人介绍来完善您的信息。
|
||||
</p>
|
||||
<p>(2)认证用户</p>
|
||||
<p>
|
||||
a.在您使用身份认证的功能或服务时,根据相关法律法规,您可能需要提供您的真实身份信息(真实姓名、身份证号码、电话号码)以完成实名验证。
|
||||
</p>
|
||||
<p>
|
||||
b.这些信息属于个人敏感信息,您可以拒绝提供,但您将可能无法获得相关服务,但不影响其他功能与服务的正常使用。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>4</b>
|
||||
<b>信息发布功能</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)注册成为光环game用户后,可在光环game平台上发布评论、视频,还可以对别人的视频评论作出回复、赞同、感谢。
|
||||
</p>
|
||||
<p>
|
||||
(2)上述功能基于相册(图片库/视频库)的图片/视频访问及上传的附加服务,我们会请求您授权相机、照片、麦克风权限,您可以使用该功能上传您的照片/图片/视频,以实现发布照片/图片/视频的功能、与其他用户进行照片/图片分享等功能。如您拒绝提供该权限和内容的,仅会使您无法使用该功能,但并不影响您正常使用产品与/或服务的其他功能。
|
||||
</p>
|
||||
<p>
|
||||
(3)您发布视频内容或回答时,我们将收集您发布的信息,并展示您的昵称、头像、发布内容。
|
||||
</p>
|
||||
<p>
|
||||
(4)用户因使用我们的产品或者服务而被我们收集的信息,例如其他用户发布的信息中可能含有您的部分信息(如:在评论、留言、发布图文、音视频中涉及到与您相关的信息)。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>5</b>
|
||||
<b>浏览、关注与收藏功能</b>
|
||||
</p>
|
||||
<p>(1)您可浏览的内容包括视频、评论。</p>
|
||||
<p>
|
||||
(2)在浏览的过程中,您还可以关注您感兴趣的用户、收藏,并收藏上述内容。
|
||||
</p>
|
||||
<p>
|
||||
(3)为此,
|
||||
我们可能会收集您使用时的设备信息,如设备型号、唯一设备标识符、操作系统、分辨率、电信运营商等软硬件信息。
|
||||
我们还可能收集您的浏览器类型,以此来为您提供信息展示的最优方案。
|
||||
</p>
|
||||
<p>
|
||||
(4)此外,在您使用浏览和收藏功能的过程中,我们会自动收集您使用的详细情况,并作为有关的
|
||||
网络日志保存。
|
||||
</p>
|
||||
<p>
|
||||
(5)您浏览和发布的内容及评论信息,您上传的视频作品、您使用的语言、访问的日期和时间、及您的操作系统、软件版本号、登录IP
|
||||
信息。
|
||||
</p>
|
||||
<p>
|
||||
(6)在此过程中,
|
||||
我们会收集您的浏览记录,浏览记录包括您浏览的视频、评论,您可以自主清楚浏览缓存。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>6</b>
|
||||
<b>互动交流</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)您主动关注您感兴趣的up主、视频并与之进行互动,进行浏览、评论、收藏、点赞或分享内容时,我们会收集您关注的账号,并向您展示您关注账号发布内容。
|
||||
</p>
|
||||
<p>
|
||||
(2)您使用推荐通讯录好友功能时,我们会请求通讯录权限,并将通讯录中的信息进行高强度加密算法处理后,用于向您推荐通信录中的好友。通讯录信息属于个人敏感信息,拒绝提供该信息仅会使您无法使用上述功能,但不影响您正常使用“光环game”及相关服务的其他功能。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>7</b>
|
||||
<b>收集、使用个人信息目的变更</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)请您了解,随着我们业务的发展,可能会对“光环game”的功能和提供的服务有所调整变化。
|
||||
</p>
|
||||
<p>
|
||||
(2)原则上,当新功能或服务与我们当前提供的功能或服务相关时,收集与使用的个人信息将与原处理目的具有直接或合理关联。
|
||||
</p>
|
||||
<p>
|
||||
(3)在与原处理目的无直接或合理关联的场景下,我们收集、使用您的个人信息,会再次进行告知,并征得您的同意。
|
||||
</p>
|
||||
<p>
|
||||
<b>3.</b>
|
||||
<b>8</b>
|
||||
<b>依法豁免征得同意收集和使用的个人信息</b>
|
||||
</p>
|
||||
<p>
|
||||
请您理解,在下列情形中,根据法律法规及相关国家标准,我们收集和使用您的个人信息无需征得您的授权同意:
|
||||
</p>
|
||||
<p>(1)与国家安全、国防安全直接相关的;</p>
|
||||
<p>(2)与公共安全、公共卫生、重大公共利益直接相关的;</p>
|
||||
<p>(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;</p>
|
||||
<p>
|
||||
(4)出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
|
||||
</p>
|
||||
<p>(5)所收集的您的个人信息是您自行向社会公众公开的;</p>
|
||||
<p>
|
||||
(6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
|
||||
</p>
|
||||
<p>(7)根据您的要求签订或履行合同所必需的;</p>
|
||||
<p>
|
||||
(8)用于维护软件及相关服务的安全稳定运行所必需的,例如发现、处置软件及相关服务的故障;
|
||||
</p>
|
||||
<p>(9)为合法的新闻报道所必需的;</p>
|
||||
<p>
|
||||
(10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的。
|
||||
</p>
|
||||
<p>(11)法律法规规定的其他情形。</p>
|
||||
<p>
|
||||
特别提示您注意,如信息无法单独或结合其他信息识别到您的个人身份,其不属于法律意义上您的个人信息;当您的信息可以单独或结合其他信息识别到您的个人身份时或我们将无法与任何特定个人信息建立联系的数据与其他您的个人信息结合使用时,这些信息在结合使用期间,将作为您的个人信息按照本隐私政策处理与保护。
|
||||
</p>
|
||||
<p><b>4.我们如何存储个人信息</b></p>
|
||||
<p><b>4.1 存储地点</b></p>
|
||||
<p>
|
||||
(1)我们依照法律法规的规定,将在境内运营过程中收集和产生的您的个人信息存储于中华人民共和国境内。
|
||||
</p>
|
||||
<p>
|
||||
(2)目前,我们不会将上述信息传输至境外,如果我们向境外传输,我们将会遵循相关国家规定或者征求您的同意。
|
||||
</p>
|
||||
<p><b>4.2存储期限</b></p>
|
||||
<p>
|
||||
(1)我们仅在为提供“光环game”及服务之目的所必需的期间内保留您的个人信息:您发布的视频、评论、点赞及相关信息,在您未撤回、删除或未注销账号期间,我们会保留相关信息。
|
||||
</p>
|
||||
<p>
|
||||
(2)超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
|
||||
</p>
|
||||
<p><b>5.我们如何保护个人信息的安全</b></p>
|
||||
<p>
|
||||
(1)我们非常重视您个人信息的安全,将努力采取合理的安全措施(包括技术方面和管理方面)来保护您的个人信息,防止您提供的个人信息被不当使用或未经授权的情况下被访问、公开披露、使用、修改、损坏、丢失或泄漏。
|
||||
</p>
|
||||
<p>
|
||||
(2)我们会使用不低于行业同行的加密技术、匿名化处理及相关合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
|
||||
</p>
|
||||
<p>
|
||||
(3)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
|
||||
</p>
|
||||
<p>
|
||||
(4)尽管已经采取了上述合理有效措施,并已经遵守了相关法律规定要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保您提供给我们的个人信息的安全性。
|
||||
</p>
|
||||
<p>
|
||||
(5)您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人。
|
||||
</p>
|
||||
<p>
|
||||
(6)我们会制定应急处理预案,并在发生用户信息安全事件时立即启动应急预案,努力阻止这些安全事件的影响和后果扩大。一旦发生用户信息安全事件(泄露、丢失)后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已经采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施。我们将及时将事件相关情况以推送通知、邮件、信函、短信及相关形式告知您,难以逐一告知时,我们会采取合理、有效的方式发布公告。同时,我们还将按照相关监管部门要求,上报用户信息安全事件的处置情况。
|
||||
</p>
|
||||
<p>
|
||||
(7)您一旦离开“光环game”及相关服务,浏览或使用其他网站、服务及内容资源,我们将没有能力和直接义务保护您在光环game及相关服务之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于“光环game”的链接或引导。
|
||||
</p>
|
||||
<p><b>6.管理您的个人信息</b></p>
|
||||
<p>
|
||||
我们非常重视您对个人信息的管理,并尽全力保护您的隐私,对于您个人信息的查询、访问、修改、删除、撤回同意授权、注销账号、投诉举报以及设置隐私功能的相关权利,以使您有能力保障您的隐私和信息安全。
|
||||
</p>
|
||||
<p><b>6.1 访问、删除、更正您的个人信息</b></p>
|
||||
<p>(1)访问个人账号信息</p>
|
||||
<p>a. 您可以查询、访问您的头像、用户名、简介、性别、生日、地区</p>
|
||||
<p>b.您可以在光环game的“个人主页”中进行查询、访问。</p>
|
||||
<p>(2)查询访问、更正、取消您关注账号、查询访问粉丝</p>
|
||||
<p>a.进入“关注”在关注列表中查询、访问、取消关注您关注的账号。</p>
|
||||
<p>b.您可以通过点击“设置”—点击“清理缓存”。</p>
|
||||
<p>(3)访问隐私政策</p>
|
||||
<p>
|
||||
a.您可以在注册页面,或者在登录个人账号“设置”—“关于”查看本隐私政策的全部内容
|
||||
</p>
|
||||
<p>
|
||||
b.请您了解,本隐私政策中所述的“光环game”及相关服务可能会根据您所使用的手机型号、系统版本、软件应用程序版本、移动客户端等因素而有所不同。最终的产品和服务以您所使用的“光环game”软件及相关服务为准。
|
||||
</p>
|
||||
<p>(6)停止运营向您告知</p>
|
||||
<p>
|
||||
a.如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理。
|
||||
</p>
|
||||
<p><b>7.未成年人条款</b></p>
|
||||
<p>
|
||||
a.若您是未满18周岁的未成年人,在使用“光环game”及相关服务前,应在您的父母或其他监护人监护、指导下共同阅读并同意本隐私政策。
|
||||
</p>
|
||||
<p>
|
||||
b.我们根据国家相关法律法规的规定保护未成年人的个人信息,只会在法律允许、父母或其他监护人明确同意或保护未成年人所必要的情况下收集、使用、储存、共享、转让或披露未成年人的个人信息;如果我们发现在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关信息。
|
||||
</p>
|
||||
<p>
|
||||
c.若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过公司本隐私政策公示的联系方式与我们联系。
|
||||
</p>
|
||||
<p><b>8.隐私政策的修订和通知</b></p>
|
||||
<p>
|
||||
(1)为了给您提供更好的服务,光环game及相关服务将不时更新与变化,我们会适时对本隐私政策进行修订,这些修订构成本隐私政策的一部分并具有等同于本隐私政策的效力,未经您明确同意,我们不会削减您依据当前生效的本隐私政策所应享受的权利。
|
||||
</p>
|
||||
<p>
|
||||
(2)本隐私政策更新后,我们会在光环game发出更新版本,并在更新后的条款生效前通过公告或其他适当的方式提醒您更新的内容,以便您及时了解本隐私政策的最新版本。
|
||||
</p>
|
||||
<p><b>9.联系我们</b></p>
|
||||
<p>
|
||||
如果您对我们的隐私政策及对您个人信息的处理有任何疑问、意见、建议、或投诉,请通过以下方式与我们联系
|
||||
</p>
|
||||
<p>
|
||||
广州市来特悦游信息科技有限公司注册地址:广州市天河区中山大道建工路13、15号3-6层5楼512房(仅限办公用途)
|
||||
</p>
|
||||
<p>在线客服QQ:3624425003</p>
|
||||
<p>信息保护事务联系电话:020-85526920</p>
|
||||
<p>在一般情况下,我们会在15个工作日内对您的请求予以答复</p>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB |
161
app/src/main/assets/user_regulation.html
Normal file
161
app/src/main/assets/user_regulation.html
Normal file
@ -0,0 +1,161 @@
|
||||
<html lang="en"><head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>光环助手软件许可及服务协议</title>
|
||||
<style>
|
||||
* {
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content-area">
|
||||
<p><b></b></p>
|
||||
<p>
|
||||
<b>光环</b>
|
||||
<b>game</b>
|
||||
<b>软件许可及服务协议</b>
|
||||
</p>
|
||||
<p><b>更新日期:2020年11月20日</b></p>
|
||||
<p><b>生效日期:2020年11月30日</b></p>
|
||||
<p><b>首部及导言</b></p>
|
||||
<p>欢迎使用光环game软件许可及服务</p>
|
||||
<p>
|
||||
各位用户在使用光环game前,请您务必审慎阅读、并充分理解本协议中的各项条款,
|
||||
<b>
|
||||
特别是免除或者限制责任的条款,以及开通或使用某项服务的单独协议,并选择接受或不接受。
|
||||
</b>
|
||||
除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本软件及相关服务。您的下载、安装、使用、登录等行为即视为您已阅读并同意上述协议的约束。
|
||||
</p>
|
||||
<p>如果您未满18周岁,请在法定监护人的陪同下阅读本协议及其他上述协议。</p>
|
||||
<p><b>一、权利声明</b></p>
|
||||
<p>
|
||||
“光环game”的一切知识产权,以及与“光环game”相关的所有信息内容,包括但不限于:文字表述及其组合、图标、图饰、图像、图表、色彩、界面设计、版面框架、有关数据、附加程序、印刷材料或电子文档等均为光环game所有,受著作权法和国际著作权条约以及其他知识产权法律法规的保护。
|
||||
</p>
|
||||
<p><b>二、软件使用规范</b></p>
|
||||
<p>
|
||||
2.1
|
||||
本软件是基于Android(安卓)系统手机、平板电脑(PAD)等设备开发的一款软件,提供注册登录、观看视频、视频投稿等功能
|
||||
</p>
|
||||
<p>2.2 软件的下载、安装和使用</p>
|
||||
<p>
|
||||
本软件为免费软件,用户可以非商业性、无限制数量地从光环game授权的渠道下载、安装及使用本软件。
|
||||
</p>
|
||||
<p>
|
||||
<b>如果您从未经光环</b>
|
||||
<b>game</b>
|
||||
<b>授权的第三方获取本软件或与本软件名称相同的安装程序,光环</b>
|
||||
<b>game</b>
|
||||
<b>无法保证该软件能够正常使用,并对因此给您造成的损失不予负责。</b>
|
||||
</p>
|
||||
<p>2.3 软件的复制、分发和传播</p>
|
||||
<p>
|
||||
本产品以研究交流为目的。用户可以非商业性、无限制数量地复制、分发和传播本软件产品。但必须保证每一份复制、分发和传播都是完整和真实的,
|
||||
包括所有有关本软件产品的软件、电子文档, 版权和商标,亦包括本协议。
|
||||
</p>
|
||||
<p>2.4 软件的更新</p>
|
||||
<p>
|
||||
为了改善用户体验、完善服务内容,光环game将不断努力开发新的服务,并为您不时提供软件更新(这些更新可能会采取软件替换、修改、功能强化、版本升级等形式)。为了保证本软件及服务的安全性和功能的一致性,光环game有权不经向您特别通知而对软件进行更新,或者对软件的部分功能效果进行改变或限制。本软件新版本发布后,旧版本的软件可能无法使用。光环game不保证旧版本软件继续可用及相应的客户服务,请您随时核对并下载最新版本。
|
||||
</p>
|
||||
<p><b>三、用户使用须知</b></p>
|
||||
<p>3.1 您理解并同意:</p>
|
||||
<p>
|
||||
为了向您提供有效的服务,本软件会利用您移动通讯终端的处理器和带宽等资源。本软件使用过程中可能产生数据流量的费用,用户需自行向运营商了解相关资费信息,并自行承担相关费用.
|
||||
</p>
|
||||
<p>3.2您理解并同意:</p>
|
||||
<p>
|
||||
<b>
|
||||
如果因您不正当使用本软件造成了不良影响,或因使用本软件造成的包括但不限于数据异常等问题,均由使用者自行承担,光环团队不对任意类型的使用结果承担责任;
|
||||
</b>
|
||||
</p>
|
||||
<p>3.3您理解并同意:</p>
|
||||
<p>
|
||||
本软件不含任何破坏用户移动通讯设备数据和获取用户隐私信息的恶意代码,不会泄露用户的个人信息和隐私;
|
||||
</p>
|
||||
<p>3.4您理解并同意:</p>
|
||||
<p>
|
||||
<b>
|
||||
对于包括但不限于互联网网络故障、计算机故障、手机故障或病毒、信息损坏或丢失、计算机系统问题,或其它任何基于不可抗力原因而产生的损失,光环团队不承担任何责任。
|
||||
</b>
|
||||
</p>
|
||||
<p>3.5您理解并同意:</p>
|
||||
<p>光环game发布、收录的视频均不代表光环立场。</p>
|
||||
<p>3.6您理解并同意:</p>
|
||||
<p>
|
||||
用户应在遵守法律及本协议的前提下使用本软件。用户无权实施包括但不限于下列行为:
|
||||
</p>
|
||||
<p>3.6.1 不得删除或者改变本软件上的所有权利管理电子信息</p>
|
||||
<p>
|
||||
3.6.2
|
||||
不得故意避开或者破坏著作权人为保护本软件著作权而采取的技术措施;
|
||||
</p>
|
||||
<p>3.6.3 用户不得利用本软件误导、欺骗他人; </p>
|
||||
<p>
|
||||
3.6.4
|
||||
违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行;
|
||||
</p>
|
||||
<p>3.6.5 未经允许,进入计算机信息网络或者使用计算机信息网络资源; </p>
|
||||
<p>3.6.6 未经允许,对计算机信息网络功能进行删除、修改或者增加; </p>
|
||||
<p>
|
||||
3.6.7
|
||||
未经允许,对计算机信息网络中存储、处理或者传输的数据和应用程序进行删除、修改或者增加;
|
||||
</p>
|
||||
<p>
|
||||
3.6.8
|
||||
破坏本软件系统或网站的正常运行,故意传播计算机病毒等破坏性程序;
|
||||
</p>
|
||||
<p>3.6.9 其他任何危害计算机信息网络安全的行为。 </p>
|
||||
<p>3.7 您理解并同意:</p>
|
||||
<p>
|
||||
本软件经过详细的测试,但不能保证与所有的软硬件系统完全兼容,不能保证本软件完全没有错误。如果出现不兼容及软件错误的情况,用户可通过各反馈途径将情况告知光环团队,获得技术支持。如果无法解决兼容性问题,用户可以删除本软件。
|
||||
</p>
|
||||
<p><b>四、争议解决处理</b></p>
|
||||
<p>
|
||||
本《协议》的解释、效力及纠纷的解决,适用于中华人民共和国法律。若用户和光环game之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户在此完全同意将纠纷或争议提交光环game所在地法院管辖
|
||||
</p>
|
||||
<p>
|
||||
<b>五</b>
|
||||
<b>、关于获取手机设备信息的说明</b>
|
||||
</p>
|
||||
<p>
|
||||
(1)为方便区分每个用户的个人信息等,本软件需获取用户的手机设备信息,用于用户登录、视频评论互动交流等用户相关的行为
|
||||
</p>
|
||||
<p>
|
||||
(2)为了保障软件与服务的安全运行,我们会收集您的硬件型号、操作系统版本号、国际移动设备识别码、唯一设备标识符、网络设备硬件地址、IP
|
||||
地址、WLAN接入点、蓝牙、基站、软件版本号、网络接入方式、类型、状态、网络质量数据、操作、使用、服务日志。
|
||||
</p>
|
||||
<p>
|
||||
(3)为了预防恶意程序及安全运营所必需,我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据、应用来源。
|
||||
</p>
|
||||
<p>
|
||||
(4)我们可能使用您的账户信息、设备信息、服务日志信息以及我们关联公司、合作方在获得您授权或依法可以共享的信息,用于判断账户安全、进行身份验证、检测及防范安全事件。
|
||||
</p>
|
||||
<p>(5)具体会发生获取手机设备信息场景如下说明:</p>
|
||||
<p>
|
||||
1) 首次启动光环game 2) 评论详情-发送评论功能 3)
|
||||
视频投稿-上传视频功能 4) 视频详情-关注up主功能
|
||||
</p>
|
||||
<p><b>七、其他</b></p>
|
||||
<p>
|
||||
7.1
|
||||
本协议所有条款的标题仅为阅读方便,本身并无实际涵义,不能作为本协议涵义解释的依据。
|
||||
</p>
|
||||
<p>
|
||||
7.2
|
||||
如果本协议中的任何条款无论因何种原因完全或部分无效或不具有执行力,或违反任何适用的法律,则该条款被视为删除,但本协议的其余条款仍应有效并且有约束力。
|
||||
</p>
|
||||
<p>
|
||||
7.3
|
||||
光环有权随时根据有关法律、法规的变化以及公司经营状况和经营策略的调整等修改本协议。修改后的协议会在软件设置内发布。
|
||||
当发生有关争议时,以最新的协议文本为准。如果不同意改动的内容,用户可以自行删除本软件。如果用户继续使用本软件,则视为您接受本协议的变动。
|
||||
</p>
|
||||
<p> 7.4 光环在法律允许的最大范围内对本协议拥有解释权与修改权。</p>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
||||
@ -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
@ -18,12 +18,19 @@ 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;
|
||||
@ -44,10 +51,6 @@ import org.json.JSONObject;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import butterknife.ButterKnife;
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
|
||||
@ -97,10 +100,13 @@ 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
|
||||
@ -168,14 +174,15 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
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.setBackground(ContextCompat.getDrawable(this, R.color.red));
|
||||
tv.measure(0, 0);
|
||||
tv.setAlpha(0.15F);
|
||||
int height = tv.getMeasuredHeight();
|
||||
@ -186,6 +193,13 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
|
||||
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);
|
||||
|
||||
@ -206,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())) {
|
||||
|
||||
@ -4,10 +4,6 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
@ -18,6 +14,9 @@ import com.lightgame.view.NoScrollableViewPager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import butterknife.BindView;
|
||||
|
||||
/**
|
||||
@ -73,10 +72,13 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getIntent() != null) mCheckedIndex = getIntent().getIntExtra(PAGE_INDEX, 0);
|
||||
mFragmentsList = new ArrayList<>();
|
||||
initFragmentList(mFragmentsList);
|
||||
mTabTitleList = new ArrayList<>();
|
||||
initTabTitleList(mTabTitleList);
|
||||
mFragmentsList = new ArrayList<>(restoreFragments());
|
||||
if (mFragmentsList.isEmpty() || mFragmentsList.size() != mTabTitleList.size()) {
|
||||
mFragmentsList.clear();
|
||||
initFragmentList(mFragmentsList);
|
||||
}
|
||||
|
||||
mViewPager.setOffscreenPageLimit(mFragmentsList.size());
|
||||
mViewPager.addOnPageChangeListener(this);
|
||||
@ -100,6 +102,20 @@ public abstract class BaseActivity_TabLayout extends ToolBarActivity implements
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex);
|
||||
}
|
||||
|
||||
private ArrayList<Fragment> restoreFragments() {
|
||||
String tag = "android:switcher:" + mViewPager.getId() + ":";
|
||||
ArrayList<Fragment> fragments = new ArrayList<>();
|
||||
int childCount = mTabTitleList.size();
|
||||
for (int index = 0; index < childCount; index++) {
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag + index);
|
||||
if (fragment != null) {
|
||||
fragments.add(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ abstract class BaseRichEditorActivity : ToolBarActivity() {
|
||||
|
||||
mDraftBtn.text = if (this is AnswerEditActivity) {
|
||||
"回答草稿"
|
||||
} else "文章草稿"
|
||||
} else "帖子草稿"
|
||||
}
|
||||
|
||||
@OnClick(R.id.editor_image, R.id.editor_font, R.id.editor_link, R.id.editor_paragraph,
|
||||
|
||||
@ -4,10 +4,10 @@ import android.app.Activity;
|
||||
import android.app.Application.ActivityLifecycleCallbacks;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.gh.common.im.ImManager;
|
||||
import com.gh.common.notifier.Notifier;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.AppManager;
|
||||
|
||||
/**
|
||||
@ -34,23 +34,27 @@ public class GHActivityLifecycleCallbacksImpl implements ActivityLifecycleCallba
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
|
||||
DataUtils.onResume(activity);
|
||||
CurrentActivityHolder.getActivitySet().add(activity);
|
||||
ImManager.updateFloatingWindow();
|
||||
//FIXME 这里应该只是部分Activity需要
|
||||
try {
|
||||
// 初始化gameMap
|
||||
DownloadManager.getInstance(activity).initGameMap();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
if (HaloApp.isUserAcceptPrivacyPolicy(activity)) {
|
||||
DataUtils.onResume(activity);
|
||||
//FIXME 这里应该只是部分Activity需要
|
||||
try {
|
||||
// 初始化gameMap
|
||||
DownloadManager.getInstance(activity).initGameMap();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
DataUtils.onPause(activity);
|
||||
CurrentActivityHolder.getActivitySet().remove(activity);
|
||||
|
||||
if (HaloApp.isUserAcceptPrivacyPolicy(activity)) {
|
||||
DataUtils.onPause(activity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,229 +1,229 @@
|
||||
package com.gh.base
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.text.htmlEncode
|
||||
import com.gh.common.notifier.Notifier
|
||||
import com.gh.common.util.*
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.PushEntity
|
||||
import com.gh.gamecenter.entity.PushMessageEntity
|
||||
import com.gh.gamecenter.entity.PushMessageUnreadEntity
|
||||
import com.gh.gamecenter.entity.PushNotificationEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_CLICK
|
||||
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_REMOVE
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.google.gson.Gson
|
||||
import com.umeng.message.UmengMessageService
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import org.android.agoo.common.AgooConstants
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import java.util.*
|
||||
|
||||
class GHUmengNotificationService : UmengMessageService() {
|
||||
|
||||
companion object {
|
||||
const val ACTION_UMENG = "com.gh.gamecenter.UMENG"
|
||||
const val MESSAGE_FROM_SYSTEM = "message_from_system"
|
||||
const val HALO_MESSAGE_DIALOG = "HALO_MESSAGE_DIALOG"
|
||||
const val HALO_MESSAGE_CENTER = "HALO_MESSAGE_CENTER"
|
||||
const val ANSWER = "answer"
|
||||
const val FOLLOW_QUESTION = "follow_question"
|
||||
const val NOTIFICATION_ID = 2015
|
||||
const val DISPLAY_TYPE_NOTIFICATION = "notification"
|
||||
const val DISPLAY_TYPE_CUSTOM = "custom"
|
||||
const val MESSAGE_ID = "message_id"
|
||||
const val NOTIFICATION_MESSAGE_ID = "notification_message_id" // 通知中心消息 ID
|
||||
const val PUSH_ID = "push_id"
|
||||
}
|
||||
|
||||
val notificationTags = arrayOf("GH_UMENG_TAG_1", "GH_UMENG_TAG_2", "GH_UMENG_TAG_3")
|
||||
val gson = Gson()
|
||||
|
||||
override fun onMessage(context: Context, intent: Intent) {
|
||||
val message = intent.getStringExtra(AgooConstants.MESSAGE_BODY)
|
||||
val isMessageFromSystem = intent.getBooleanExtra(MESSAGE_FROM_SYSTEM, false)
|
||||
|
||||
try {
|
||||
val pushData = message.toObject<PushEntity>()
|
||||
pushData?.let { handlePushData(context, it, message, isMessageFromSystem) }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePushData(context: Context, pushData: PushEntity, message: String, isMessageFromSystem: Boolean) {
|
||||
val notificationManager = context.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
if (pushData.displayType == DISPLAY_TYPE_NOTIFICATION) {
|
||||
// 其它类型的透传信息
|
||||
// 显示到通知栏
|
||||
val msg = message.toObject<PushNotificationEntity>()
|
||||
val data = msg?.extra?.data
|
||||
|
||||
// 系统推送(非自定义信息),直接处理跳转
|
||||
if (isMessageFromSystem) {
|
||||
val intent = Intent()
|
||||
intent.setClass(context, UmengMessageReceiver::class.java)
|
||||
intent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
intent.putExtra(EntranceUtils.KEY_TYPE, UmengMessageReceiver.DIRECT_ONLY)
|
||||
intent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
intent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
context.sendBroadcast(intent)
|
||||
return
|
||||
}
|
||||
|
||||
// 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
|
||||
if (data != null
|
||||
&& data.link?.link == "system"
|
||||
&& !UserManager.getInstance().isLoggedIn) {
|
||||
return
|
||||
}
|
||||
|
||||
val clickIntent = Intent()
|
||||
val removeIntent = Intent()
|
||||
|
||||
clickIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
clickIntent.putExtra(MESSAGE_ID, msg?.msgId)
|
||||
clickIntent.putExtra(PUSH_ID, data?.pushId)
|
||||
clickIntent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
|
||||
|
||||
removeIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
|
||||
removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
|
||||
val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
|
||||
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
|
||||
removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
val notification = NotificationCompat.Builder(context, "Halo_Push")
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setTicker(pushData.body?.ticker)
|
||||
.setContentTitle(pushData.body?.title)
|
||||
.setContentText(pushData.body?.text?.fromHtml())
|
||||
.setContentIntent(clickPendingIntent)
|
||||
.setDeleteIntent(deletePendingIntent)
|
||||
.build()
|
||||
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
|
||||
|
||||
notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
|
||||
} else {
|
||||
if (UserManager.getInstance().isLoggedIn &&
|
||||
HALO_MESSAGE_DIALOG == pushData.body?.custom &&
|
||||
MessageUnreadRepository.unreadLiveData.value != null) {
|
||||
// 回答了问题或者关注了问题的消息
|
||||
val msg = gson.fromJson(message, PushMessageEntity::class.java)
|
||||
val data = msg?.extra?.data
|
||||
|
||||
val type = if (ANSWER == data?.type) {
|
||||
"回答了你的问题"
|
||||
} else {
|
||||
"回答了你关注的问题"
|
||||
}
|
||||
|
||||
val userName = StringUtils.shrinkStringWithDot(data?.userEntity?.name, 8)
|
||||
val displayText = userName + type
|
||||
|
||||
if (Notifier.isActivityValid(CurrentActivityHolder.getCurrentActivity()) &&
|
||||
Notifier.shouldShowNotifier(data?.answer?.id + displayText)) {
|
||||
Notifier.create(CurrentActivityHolder.getCurrentActivity())
|
||||
.setText(displayText)
|
||||
.setDuration(5000)
|
||||
.setIcon(data?.userEntity?.icon)
|
||||
.setOnClickListener(View.OnClickListener {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(EntranceUtils.KEY_ANSWER_ID, data?.answer?.id)
|
||||
bundle.putString(EntranceUtils.KEY_ENTRANCE, EntranceUtils.ENTRANCE_UMENG)
|
||||
bundle.putString(EntranceUtils.KEY_TO, AnswerDetailActivity::class.java.name)
|
||||
EntranceUtils.jumpActivity(context, bundle)
|
||||
|
||||
MtaHelper.onEvent("消息弹窗", type, "Does not contains any parameter.")
|
||||
|
||||
// 标记已读
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("type", type)
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
|
||||
RetrofitManager.getInstance(application).api.postMessageRead(UserManager.getInstance().userId, data?.id, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<ResponseBody>() {
|
||||
override fun onResponse(response: ResponseBody?) {
|
||||
super.onResponse(response)
|
||||
MessageUnreadRepository.loadMessageUnreadData()
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
e?.printStackTrace()
|
||||
}
|
||||
})
|
||||
Notifier.hide()
|
||||
})
|
||||
.show(false)
|
||||
Notifier.tagNotifierAsShowed(data?.answer?.id + displayText)
|
||||
}
|
||||
} else if (HALO_MESSAGE_CENTER == pushData.body?.custom) {
|
||||
// 消息中心逻辑
|
||||
val msg = gson.fromJson(message, PushMessageUnreadEntity::class.java)
|
||||
val data = msg?.extra?.data
|
||||
data?.let { MessageUnreadRepository.loadMessageUnreadData() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 规则:最多三条消息,以旧换新
|
||||
*
|
||||
* @return NotificationTag
|
||||
*/
|
||||
private fun getNotificationTag(context: Context): String {
|
||||
val sp = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val edit = sp.edit()
|
||||
|
||||
val timeTagMap = HashMap<Long, String>()
|
||||
for (tag in notificationTags) {
|
||||
val time = sp.getLong(tag, 0)
|
||||
if (time == 0L) {
|
||||
edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
return tag
|
||||
} else {
|
||||
timeTagMap[time] = tag
|
||||
}
|
||||
}
|
||||
|
||||
val minTime = Collections.min(timeTagMap.keys)
|
||||
val tag = timeTagMap[minTime]
|
||||
edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
return if (TextUtils.isEmpty(tag)) notificationTags[0] else tag!!
|
||||
}
|
||||
}
|
||||
//package com.gh.base
|
||||
//
|
||||
//import android.app.Notification
|
||||
//import android.app.NotificationChannel
|
||||
//import android.app.NotificationManager
|
||||
//import android.app.PendingIntent
|
||||
//import android.content.Context
|
||||
//import android.content.Intent
|
||||
//import android.os.Build
|
||||
//import android.os.Bundle
|
||||
//import android.preference.PreferenceManager
|
||||
//import android.text.TextUtils
|
||||
//import android.view.View
|
||||
//import androidx.core.app.NotificationCompat
|
||||
//import androidx.core.text.htmlEncode
|
||||
//import com.gh.common.notifier.Notifier
|
||||
//import com.gh.common.util.*
|
||||
//import com.gh.gamecenter.R
|
||||
//import com.gh.gamecenter.entity.PushEntity
|
||||
//import com.gh.gamecenter.entity.PushMessageEntity
|
||||
//import com.gh.gamecenter.entity.PushMessageUnreadEntity
|
||||
//import com.gh.gamecenter.entity.PushNotificationEntity
|
||||
//import com.gh.gamecenter.manager.UserManager
|
||||
//import com.gh.gamecenter.message.MessageUnreadRepository
|
||||
//import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_CLICK
|
||||
//import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_REMOVE
|
||||
//import com.gh.gamecenter.retrofit.Response
|
||||
//import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
//import com.google.gson.Gson
|
||||
//import com.umeng.message.UmengMessageService
|
||||
//import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
//import io.reactivex.schedulers.Schedulers
|
||||
//import okhttp3.MediaType
|
||||
//import okhttp3.RequestBody
|
||||
//import okhttp3.ResponseBody
|
||||
//import org.android.agoo.common.AgooConstants
|
||||
//import org.json.JSONObject
|
||||
//import retrofit2.HttpException
|
||||
//import java.util.*
|
||||
//
|
||||
//class GHUmengNotificationService : UmengMessageService() {
|
||||
//
|
||||
// companion object {
|
||||
// const val ACTION_UMENG = "com.gh.gamecenter.UMENG"
|
||||
// const val MESSAGE_FROM_SYSTEM = "message_from_system"
|
||||
// const val HALO_MESSAGE_DIALOG = "HALO_MESSAGE_DIALOG"
|
||||
// const val HALO_MESSAGE_CENTER = "HALO_MESSAGE_CENTER"
|
||||
// const val ANSWER = "answer"
|
||||
// const val FOLLOW_QUESTION = "follow_question"
|
||||
// const val NOTIFICATION_ID = 2015
|
||||
// const val DISPLAY_TYPE_NOTIFICATION = "notification"
|
||||
// const val DISPLAY_TYPE_CUSTOM = "custom"
|
||||
// const val MESSAGE_ID = "message_id"
|
||||
// const val NOTIFICATION_MESSAGE_ID = "notification_message_id" // 通知中心消息 ID
|
||||
// const val PUSH_ID = "push_id"
|
||||
// }
|
||||
//
|
||||
// val notificationTags = arrayOf("GH_UMENG_TAG_1", "GH_UMENG_TAG_2", "GH_UMENG_TAG_3")
|
||||
// val gson = Gson()
|
||||
//
|
||||
// override fun onMessage(context: Context, intent: Intent) {
|
||||
// val message = intent.getStringExtra(AgooConstants.MESSAGE_BODY)
|
||||
// val isMessageFromSystem = intent.getBooleanExtra(MESSAGE_FROM_SYSTEM, false)
|
||||
//
|
||||
// try {
|
||||
// val pushData = message.toObject<PushEntity>()
|
||||
// pushData?.let { handlePushData(context, it, message, isMessageFromSystem) }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun handlePushData(context: Context, pushData: PushEntity, message: String, isMessageFromSystem: Boolean) {
|
||||
// val notificationManager = context.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
//
|
||||
// if (pushData.displayType == DISPLAY_TYPE_NOTIFICATION) {
|
||||
// // 其它类型的透传信息
|
||||
// // 显示到通知栏
|
||||
// val msg = message.toObject<PushNotificationEntity>()
|
||||
// val data = msg?.extra?.data
|
||||
//
|
||||
// // 系统推送(非自定义信息),直接处理跳转
|
||||
// if (isMessageFromSystem) {
|
||||
// val intent = Intent()
|
||||
// intent.setClass(context, UmengMessageReceiver::class.java)
|
||||
// intent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
// intent.putExtra(EntranceUtils.KEY_TYPE, UmengMessageReceiver.DIRECT_ONLY)
|
||||
// intent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
// intent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
// context.sendBroadcast(intent)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
|
||||
// if (data != null
|
||||
// && data.link?.link == "system"
|
||||
// && !UserManager.getInstance().isLoggedIn) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// val clickIntent = Intent()
|
||||
// val removeIntent = Intent()
|
||||
//
|
||||
// clickIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
// clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
||||
// clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
// clickIntent.putExtra(MESSAGE_ID, msg?.msgId)
|
||||
// clickIntent.putExtra(PUSH_ID, data?.pushId)
|
||||
// clickIntent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
||||
// clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
|
||||
//
|
||||
// removeIntent.setClass(context, UmengMessageReceiver::class.java)
|
||||
// removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
|
||||
// removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
||||
//
|
||||
// val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
|
||||
// clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
|
||||
// removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
//
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
// notificationManager.createNotificationChannel(channel)
|
||||
// }
|
||||
//
|
||||
// val notification = NotificationCompat.Builder(context, "Halo_Push")
|
||||
// .setSmallIcon(R.drawable.ic_notification)
|
||||
// .setTicker(pushData.body?.ticker)
|
||||
// .setContentTitle(pushData.body?.title)
|
||||
// .setContentText(pushData.body?.text?.fromHtml())
|
||||
// .setContentIntent(clickPendingIntent)
|
||||
// .setDeleteIntent(deletePendingIntent)
|
||||
// .build()
|
||||
// notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
|
||||
//
|
||||
// notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
|
||||
// } else {
|
||||
// if (UserManager.getInstance().isLoggedIn &&
|
||||
// HALO_MESSAGE_DIALOG == pushData.body?.custom &&
|
||||
// MessageUnreadRepository.unreadLiveData.value != null) {
|
||||
// // 回答了问题或者关注了问题的消息
|
||||
// val msg = gson.fromJson(message, PushMessageEntity::class.java)
|
||||
// val data = msg?.extra?.data
|
||||
//
|
||||
// val type = if (ANSWER == data?.type) {
|
||||
// "回答了你的问题"
|
||||
// } else {
|
||||
// "回答了你关注的问题"
|
||||
// }
|
||||
//
|
||||
// val userName = StringUtils.shrinkStringWithDot(data?.userEntity?.name, 8)
|
||||
// val displayText = userName + type
|
||||
//
|
||||
// if (Notifier.isActivityValid(CurrentActivityHolder.getCurrentActivity()) &&
|
||||
// Notifier.shouldShowNotifier(data?.answer?.id + displayText)) {
|
||||
// Notifier.create(CurrentActivityHolder.getCurrentActivity())
|
||||
// .setText(displayText)
|
||||
// .setDuration(5000)
|
||||
// .setIcon(data?.userEntity?.icon)
|
||||
// .setOnClickListener(View.OnClickListener {
|
||||
// val bundle = Bundle()
|
||||
// bundle.putString(EntranceUtils.KEY_ANSWER_ID, data?.answer?.id)
|
||||
// bundle.putString(EntranceUtils.KEY_ENTRANCE, EntranceUtils.ENTRANCE_UMENG)
|
||||
// bundle.putString(EntranceUtils.KEY_TO, AnswerDetailActivity::class.java.name)
|
||||
// EntranceUtils.jumpActivity(context, bundle)
|
||||
//
|
||||
// MtaHelper.onEvent("消息弹窗", type, "Does not contains any parameter.")
|
||||
//
|
||||
// // 标记已读
|
||||
// val jsonObject = JSONObject()
|
||||
// jsonObject.put("type", type)
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
//
|
||||
// RetrofitManager.getInstance(application).api.postMessageRead(UserManager.getInstance().userId, data?.id, body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .observeOn(AndroidSchedulers.mainThread())
|
||||
// .subscribe(object : Response<ResponseBody>() {
|
||||
// override fun onResponse(response: ResponseBody?) {
|
||||
// super.onResponse(response)
|
||||
// MessageUnreadRepository.loadMessageUnreadData()
|
||||
// }
|
||||
//
|
||||
// override fun onFailure(e: HttpException?) {
|
||||
// e?.printStackTrace()
|
||||
// }
|
||||
// })
|
||||
// Notifier.hide()
|
||||
// })
|
||||
// .show(false)
|
||||
// Notifier.tagNotifierAsShowed(data?.answer?.id + displayText)
|
||||
// }
|
||||
// } else if (HALO_MESSAGE_CENTER == pushData.body?.custom) {
|
||||
// // 消息中心逻辑
|
||||
// val msg = gson.fromJson(message, PushMessageUnreadEntity::class.java)
|
||||
// val data = msg?.extra?.data
|
||||
// data?.let { MessageUnreadRepository.loadMessageUnreadData() }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 规则:最多三条消息,以旧换新
|
||||
// *
|
||||
// * @return NotificationTag
|
||||
// */
|
||||
// private fun getNotificationTag(context: Context): String {
|
||||
// val sp = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
// val edit = sp.edit()
|
||||
//
|
||||
// val timeTagMap = HashMap<Long, String>()
|
||||
// for (tag in notificationTags) {
|
||||
// val time = sp.getLong(tag, 0)
|
||||
// if (time == 0L) {
|
||||
// edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
// return tag
|
||||
// } else {
|
||||
// timeTagMap[time] = tag
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// val minTime = Collections.min(timeTagMap.keys)
|
||||
// val tag = timeTagMap[minTime]
|
||||
// edit.putLong(tag, System.currentTimeMillis()).apply()
|
||||
// return if (TextUtils.isEmpty(tag)) notificationTags[0] else tag!!
|
||||
// }
|
||||
//}
|
||||
@ -14,6 +14,13 @@ import android.view.Window;
|
||||
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.download.DownloadManager;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
@ -31,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>
|
||||
@ -49,7 +49,7 @@ public abstract class ToolBarActivity extends BaseActivity implements ToolbarCon
|
||||
@Nullable
|
||||
private PackageViewModel mPackageViewModel;
|
||||
|
||||
protected RelativeLayout mToolbarContainer;
|
||||
protected View mToolbarContainer;
|
||||
|
||||
protected Toolbar mToolbar;
|
||||
|
||||
|
||||
@ -4,16 +4,20 @@ import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
import com.gh.common.util.ClickUtils;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.lightgame.utils.RuntimeUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
* @Date 17/05/2017
|
||||
@ -58,6 +62,18 @@ public class BaseDialogFragment extends DialogFragment {
|
||||
public boolean onBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(@NonNull FragmentManager manager, @Nullable String tag) {
|
||||
Fragment fragment = manager.findFragmentByTag(tag);
|
||||
if (fragment != null) {
|
||||
FragmentTransaction transaction = manager.beginTransaction();
|
||||
transaction.show(fragment);
|
||||
transaction.commit();
|
||||
} else {
|
||||
super.show(manager, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,15 +3,6 @@ package com.gh.base.fragment;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.CheckedTextView;
|
||||
@ -21,6 +12,7 @@ import com.gh.base.adapter.FragmentAdapter;
|
||||
import com.gh.common.view.TabIndicatorView;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.normal.NormalFragment;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.lightgame.view.NoScrollableViewPager;
|
||||
@ -28,6 +20,10 @@ import com.lightgame.view.NoScrollableViewPager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import butterknife.BindView;
|
||||
|
||||
/**
|
||||
@ -83,10 +79,27 @@ public abstract class BaseFragment_TabLayout extends NormalFragment implements V
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) mCheckedIndex = getArguments().getInt(PAGE_INDEX, 0);
|
||||
mFragmentsList = new ArrayList<>();
|
||||
initFragmentList(mFragmentsList);
|
||||
mTabTitleList = new ArrayList<>();
|
||||
initTabTitleList(mTabTitleList);
|
||||
mFragmentsList = new ArrayList<>(restoreFragments());
|
||||
if (mFragmentsList.isEmpty() || mFragmentsList.size() != mTabTitleList.size()) {
|
||||
mFragmentsList.clear();
|
||||
initFragmentList(mFragmentsList);
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<Fragment> restoreFragments() {
|
||||
String tag = "android:switcher:" + mViewPager.getId() + ":";
|
||||
ArrayList<Fragment> fragments = new ArrayList<>();
|
||||
int childCount = mTabTitleList.size();
|
||||
for (int index = 0; index < childCount; index++) {
|
||||
Fragment fragment = getChildFragmentManager().findFragmentByTag(tag + index);
|
||||
if (fragment != null) {
|
||||
fragments.add(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
package com.gh.base.fragment
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
@ -13,9 +11,8 @@ import com.gh.base.adapter.FragmentAdapter
|
||||
import com.gh.common.view.TabIndicatorView
|
||||
import com.gh.gamecenter.R
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import com.lightgame.utils.Utils
|
||||
import com.lightgame.view.NoScrollableViewPager
|
||||
import java.util.*
|
||||
|
||||
abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeListener {
|
||||
|
||||
@ -72,9 +69,15 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
|
||||
|
||||
override fun onFragmentFirstVisible() {
|
||||
super.onFragmentFirstVisible()
|
||||
mTabTitleList.clear()
|
||||
mFragmentsList.clear()
|
||||
|
||||
initFragmentList(mFragmentsList)
|
||||
initTabTitleList(mTabTitleList)
|
||||
mFragmentsList.addAll(restoreFragments())
|
||||
if (mFragmentsList.isEmpty() || mFragmentsList.size != mTabTitleList.size) {
|
||||
mFragmentsList.clear()
|
||||
initFragmentList(mFragmentsList)
|
||||
}
|
||||
|
||||
mViewPager.offscreenPageLimit = mFragmentsList.size
|
||||
mViewPager.addOnPageChangeListener(this)
|
||||
@ -95,6 +98,19 @@ abstract class BaseLazyTabFragment : BaseLazyFragment(), ViewPager.OnPageChangeL
|
||||
BaseFragment_TabLayout.initTabStyle(mTabLayout, mCheckedIndex)
|
||||
}
|
||||
|
||||
private fun restoreFragments(): ArrayList<Fragment> {
|
||||
val tag = "android:switcher:${mViewPager.id}:"
|
||||
val fragments = ArrayList<Fragment>()
|
||||
val childCount = mTabTitleList.size
|
||||
for (index in 0 until childCount) {
|
||||
val fragment = childFragmentManager.findFragmentByTag("$tag$index")
|
||||
if (fragment != null) {
|
||||
fragments.add(fragment)
|
||||
}
|
||||
}
|
||||
return fragments
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
|
||||
override fun onPageSelected(position: Int) {}
|
||||
|
||||
@ -5,6 +5,7 @@ import android.os.Looper
|
||||
import com.gh.common.AppExecutor.ioExecutor
|
||||
import com.gh.common.AppExecutor.lightWeightIoExecutor
|
||||
import com.gh.common.AppExecutor.uiExecutor
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@ -25,6 +26,8 @@ object AppExecutor {
|
||||
@JvmStatic
|
||||
val ioExecutor = Executors.newCachedThreadPool() // 用 by lazy 可能影响初始化速度
|
||||
|
||||
val cachedScheduler by lazy { Schedulers.from(ioExecutor) }
|
||||
|
||||
class MainThreadExecutor : Executor {
|
||||
private val mainThreadHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
|
||||
@ -1,22 +1,28 @@
|
||||
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.WebActivity
|
||||
import com.gh.gamecenter.entity.Badge
|
||||
import com.gh.gamecenter.entity.MtaEvent
|
||||
import com.gh.gamecenter.entity.NotificationUgc
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.room.AppDatabase
|
||||
import com.gh.gamecenter.security.BindPhoneActivity
|
||||
import com.gh.gamecenter.user.LoginTag
|
||||
import com.gh.gamecenter.user.UserRepository
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@ -24,6 +30,8 @@ import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import org.json.JSONObject
|
||||
import retrofit2.HttpException
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class DefaultJsApi(var context: Context) {
|
||||
|
||||
@ -46,7 +54,7 @@ class DefaultJsApi(var context: Context) {
|
||||
|
||||
@JavascriptInterface
|
||||
fun getUserInfo(msg: Any): String {
|
||||
return UserManager.getInstance().userInfoEntity.toJson()
|
||||
return UserManager.getInstance().userInfoEntity?.toJson() ?: ""
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -65,12 +73,11 @@ class DefaultJsApi(var context: Context) {
|
||||
val userInfoEntity = UserManager.getInstance().userInfoEntity
|
||||
if (msg.toString().isNotEmpty()) {
|
||||
val badge = msg.toString().toObject() ?: Badge()
|
||||
userInfoEntity.badge = badge
|
||||
userInfoEntity?.badge = badge
|
||||
} else {
|
||||
userInfoEntity.badge = null
|
||||
userInfoEntity?.badge = null
|
||||
}
|
||||
UserManager.getInstance().userInfoEntity = userInfoEntity
|
||||
AppDatabase.getInstance(context).userInfoDao().updateUserInfo(userInfoEntity)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -83,6 +90,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 +151,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,10 +174,88 @@ 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)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun shareBase64Image(event: Any) {
|
||||
val imageShareEvent = event.toString().toObject() ?: ImageShareEvent()
|
||||
val context = CurrentActivityHolder.getCurrentActivity()
|
||||
Base64ImageHolder.image = imageShareEvent.image.run {
|
||||
if (this.startsWith("data:image/png;base64")) this.split(",")[1] else this
|
||||
}
|
||||
MessageShareUtils.getInstance(context).shareFromWeb(context, imageShareEvent.type)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun bindPhone(msg: Any) {
|
||||
val intent = BindPhoneActivity.getNormalIntent(context, false)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun updateTitle(msg: Any) {
|
||||
if (context is WebActivity) {
|
||||
runOnUiThread { (context as WebActivity).setNavigationTitle(msg.toString()) }
|
||||
}
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun logoutExitWebViewAndRedirectToLogin() {
|
||||
UserRepository.getInstance(context).logout()
|
||||
if (context is Activity) {
|
||||
AppExecutor.uiExecutor.executeWithDelay(Runnable {
|
||||
context.ifLogin("内部网页")
|
||||
(context as Activity).finish()
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
|
||||
|
||||
@Keep
|
||||
internal data class ImageShareEvent(var image: String = "", var type: String = "")
|
||||
|
||||
}
|
||||
|
||||
@ -4,20 +4,25 @@ 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 android.util.Base64
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.DirectUtils.directToFeedback
|
||||
import com.gh.common.util.DirectUtils.directToGameDetailVideoStreaming
|
||||
import com.gh.common.util.DirectUtils.directToGameServerCalendar
|
||||
import com.gh.common.util.DirectUtils.directToGameVideo
|
||||
import com.gh.common.util.DirectUtils.directToLinkPage
|
||||
import com.gh.common.util.DirectUtils.directToQa
|
||||
import com.gh.common.util.DirectUtils.directToVideoDetail
|
||||
import com.gh.common.util.EntranceUtils
|
||||
import com.gh.gamecenter.*
|
||||
import com.gh.gamecenter.entity.CommunityEntity
|
||||
import com.gh.gamecenter.entity.SubjectRecommendEntity
|
||||
import com.gh.gamecenter.entity.VideoLinkEntity
|
||||
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 {
|
||||
|
||||
@ -37,7 +42,7 @@ object DefaultUrlHandler {
|
||||
when (host) {
|
||||
"article" -> context.startActivity(NewsDetailActivity.getIntentById(context, id, entrance))
|
||||
|
||||
"game" -> GameDetailActivity.startGameDetailActivity(context, id, "libao" == uri.getQueryParameter("to"), 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)
|
||||
|
||||
@ -50,7 +55,7 @@ object DefaultUrlHandler {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
"qqqun" -> {
|
||||
EntranceUtils.HOST_QQ_QUN -> {
|
||||
val key = uri.getQueryParameter("key")
|
||||
if (!DirectUtils.directToQqGroup(context, key)) {
|
||||
Utils.toast(context, "请检查是否已经安装手机QQ")
|
||||
@ -124,12 +129,14 @@ object DefaultUrlHandler {
|
||||
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)
|
||||
// }
|
||||
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, EntranceUtils.ENTRANCE_BROWSER, "")
|
||||
DirectUtils.directToVideoManager(context, linkEntity, simpleGameEntity, EntranceUtils.ENTRANCE_BROWSER, "")
|
||||
}
|
||||
}
|
||||
EntranceUtils.HOST_USERHOME -> {
|
||||
@ -140,8 +147,19 @@ object DefaultUrlHandler {
|
||||
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
|
||||
directToVideoDetail(context, id, loaction, false, "", entrance, "", referer, type, 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") ?: ""
|
||||
@ -191,7 +209,7 @@ object DefaultUrlHandler {
|
||||
val name = uri.getQueryParameter("name")
|
||||
?: ""
|
||||
val entity = SubjectRecommendEntity(link = id, name = name, text = name)
|
||||
DirectUtils.directToBlock(context, entity)
|
||||
DirectUtils.directToBlock(context, entity, entrance)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_SERVER_BLOCK -> {
|
||||
@ -215,14 +233,187 @@ object DefaultUrlHandler {
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_GAME_UPLOAD -> {
|
||||
DirectUtils.directGameUpload(context,entrance = entrance, path = "")
|
||||
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)
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_SUGGESTION -> {
|
||||
val platform = uri.getQueryParameter(EntranceUtils.KEY_PLATFORM)
|
||||
val platformName = PlatformUtils.getInstance(context).getPlatformName(platform)
|
||||
val gameId = uri.getQueryParameter(EntranceUtils.KEY_GAMEID)
|
||||
val packageMd5 = uri.getQueryParameter(EntranceUtils.KEY_PACKAGE_MD5)
|
||||
val content = if (TextUtils.isEmpty(gameId) || TextUtils.isEmpty(packageMd5)) String.format("%s-%s-V%s,",
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
if (TextUtils.isEmpty(platformName)) platform else platformName,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_VERSION)) else String.format("%s-%s-V%s\n游戏ID:%s\n游戏包MD5:%s\n",
|
||||
uri.getQueryParameter(EntranceUtils.KEY_GAME_NAME),
|
||||
if (TextUtils.isEmpty(platformName)) platform else platformName,
|
||||
uri.getQueryParameter(EntranceUtils.KEY_VERSION), gameId, packageMd5)
|
||||
val qaId = uri.getQueryParameter("qa_id") ?: ""
|
||||
val qaTitle = uri.getQueryParameter(EntranceUtils.KEY_QA_TITLE)
|
||||
if (!TextUtils.isEmpty(qaId)) {
|
||||
directToQa(context, qaTitle, qaId)
|
||||
} else {
|
||||
directToFeedback(context, content, EntranceUtils.ENTRANCE_BROWSER)
|
||||
}
|
||||
}
|
||||
|
||||
EntranceUtils.HOST_HELP_AND_FEEDBACK -> {
|
||||
val position = uri.getQueryParameter("position") ?: ""
|
||||
DirectUtils.directToHelpAndFeedback(context, position.toInt())
|
||||
}
|
||||
else -> DialogUtils.showLowVersionDialog(context)
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -4,22 +4,26 @@ 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 io.reactivex.schedulers.Schedulers
|
||||
import kotlin.concurrent.fixedRateTimer
|
||||
|
||||
object FixedRateJobHelper {
|
||||
private const val CHECKER_PERIOD: Long = 60 * 1000L
|
||||
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
|
||||
@ -31,7 +35,7 @@ object FixedRateJobHelper {
|
||||
// 时间校对,10分钟一次
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % TIME_PERIOD == 0L) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api.time
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribeOn(AppExecutor.cachedScheduler)
|
||||
.subscribe(object : Response<TimeEntity>() {
|
||||
override fun onResponse(response: TimeEntity?) {
|
||||
val serverTime = response?.time
|
||||
@ -45,6 +49,14 @@ object FixedRateJobHelper {
|
||||
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()
|
||||
@ -52,7 +64,9 @@ object FixedRateJobHelper {
|
||||
|
||||
// 更新游戏屏蔽信息
|
||||
if ((mExecuteCount * CHECKER_PERIOD) % REGION_SETTING_PERIOD == 0L) {
|
||||
RegionSettingHelper.getRegionSetting()
|
||||
if (HaloApp.getInstance().isRunningForeground) {
|
||||
RegionSettingHelper.getRegionSetting()
|
||||
}
|
||||
}
|
||||
|
||||
// 提交视频浏览记录数据
|
||||
|
||||
@ -1,39 +1,39 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.gh.common.im.ImManager
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.m7.imkfsdk.chat.ChatActivity
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* 可使用 [LocalBroadcastManager] 来进行简单的模块间消息通知
|
||||
*/
|
||||
|
||||
class LocalBroadcastReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
intent?.let {
|
||||
when (intent.action) {
|
||||
ChatActivity.ACTION_DISMISS_FLOATING_WINDOW -> {
|
||||
ImManager.dismissFloatingWindow()
|
||||
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api.postImEnding(UserManager.getInstance().userId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe()
|
||||
}
|
||||
|
||||
ChatActivity.ACTION_HIDE_UNREAD_DOT -> {
|
||||
ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
}
|
||||
|
||||
else -> return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//package com.gh.common
|
||||
//
|
||||
//import android.content.BroadcastReceiver
|
||||
//import android.content.Context
|
||||
//import android.content.Intent
|
||||
//import com.gh.common.im.ImManager
|
||||
//import com.gh.gamecenter.manager.UserManager
|
||||
//import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
//import com.halo.assistant.HaloApp
|
||||
//import com.m7.imkfsdk.chat.ChatActivity
|
||||
//import io.reactivex.schedulers.Schedulers
|
||||
//
|
||||
///**
|
||||
// * 可使用 [LocalBroadcastManager] 来进行简单的模块间消息通知
|
||||
// */
|
||||
//
|
||||
//class LocalBroadcastReceiver : BroadcastReceiver() {
|
||||
//
|
||||
// override fun onReceive(context: Context?, intent: Intent?) {
|
||||
// intent?.let {
|
||||
// when (intent.action) {
|
||||
// ChatActivity.ACTION_DISMISS_FLOATING_WINDOW -> {
|
||||
// ImManager.dismissFloatingWindow()
|
||||
//
|
||||
// RetrofitManager.getInstance(HaloApp.getInstance().application).api.postImEnding(UserManager.getInstance().userId)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .subscribe()
|
||||
// }
|
||||
//
|
||||
// ChatActivity.ACTION_HIDE_UNREAD_DOT -> {
|
||||
// ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
// }
|
||||
//
|
||||
// else -> return
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -1,29 +1,8 @@
|
||||
package com.gh.common
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.preference.PreferenceManager
|
||||
import com.gh.base.GHUmengNotificationService
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.util.edit
|
||||
import com.gh.common.util.toJson
|
||||
import com.gh.common.util.toObject
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.entity.AliasEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import com.umeng.commonsdk.UMConfigure
|
||||
import com.umeng.message.IUmengRegisterCallback
|
||||
import com.umeng.message.PushAgent
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import org.android.agoo.huawei.HuaWeiRegister
|
||||
import org.android.agoo.mezu.MeizuRegister
|
||||
import org.android.agoo.xiaomi.MiPushRegistar
|
||||
import org.json.JSONObject
|
||||
|
||||
object PushManager {
|
||||
|
||||
@ -36,102 +15,103 @@ object PushManager {
|
||||
|
||||
@JvmStatic
|
||||
fun init(channel: String) {
|
||||
tryWithDefaultCatch {
|
||||
//初始化友盟推送
|
||||
UMConfigure.init(mApplication, Config.UMENG_APPKEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Config.UMENG_MESSAGE_SECRET)
|
||||
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
runOnIoThread { registerDevice() }
|
||||
|
||||
// 注册小米、华为和魅族通道
|
||||
MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
|
||||
HuaWeiRegister.register(mApplication)
|
||||
MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
|
||||
|
||||
val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
|
||||
mPreviousAlias = aliasInSp?.toObject()
|
||||
|
||||
if (mPreviousAlias == null) {
|
||||
getAndSetAlias()
|
||||
}
|
||||
|
||||
// 完全自定义处理(透传)
|
||||
pushAgent.setPushIntentServiceClass(GHUmengNotificationService::class.java)
|
||||
}
|
||||
// tryWithDefaultCatch {
|
||||
// //初始化友盟推送
|
||||
// UMConfigure.init(mApplication, Config.UMENG_APPKEY, channel, UMConfigure.DEVICE_TYPE_PHONE, Config.UMENG_MESSAGE_SECRET)
|
||||
//
|
||||
// val pushAgent = PushAgent.getInstance(mApplication)
|
||||
//
|
||||
// runOnIoThread { registerDevice() }
|
||||
//
|
||||
// // 注册小米、华为和魅族通道
|
||||
// MiPushRegistar.register(mApplication, Config.MIPUSH_APPID, Config.MIPUSH_APPKEY)
|
||||
// HuaWeiRegister.register(mApplication)
|
||||
// MeizuRegister.register(mApplication, BuildConfig.MEIZUPUSH_APPID, BuildConfig.MEIZUPUSH_APPKEY)
|
||||
//
|
||||
// val aliasInSp = PreferenceManager.getDefaultSharedPreferences(mApplication).getString(SP_PUSH_ALIAS, "")
|
||||
// mPreviousAlias = aliasInSp?.toObject()
|
||||
//
|
||||
// if (mPreviousAlias == null) {
|
||||
// getAndSetAlias()
|
||||
// }
|
||||
//
|
||||
// // 完全自定义处理(透传)
|
||||
// pushAgent.setPushIntentServiceClass(GHUmengNotificationService::class.java)
|
||||
// }
|
||||
}
|
||||
|
||||
private fun registerDevice() {
|
||||
PushAgent.getInstance(mApplication).register(object : IUmengRegisterCallback {
|
||||
override fun onSuccess(dToken: String) {
|
||||
//注册成功会返回device token
|
||||
deviceToken = dToken
|
||||
getAndSetAlias()
|
||||
Utils.log("deviceToken::$dToken")
|
||||
}
|
||||
|
||||
override fun onFailure(s: String, s1: String) {
|
||||
Utils.log("deviceToken::" + "注册失败")
|
||||
}
|
||||
})
|
||||
// PushAgent.getInstance(mApplication).register(object : IUmengRegisterCallback {
|
||||
// override fun onSuccess(dToken: String) {
|
||||
// //注册成功会返回device token
|
||||
// deviceToken = dToken
|
||||
// getAndSetAlias()
|
||||
// Utils.log("deviceToken::$dToken")
|
||||
// }
|
||||
//
|
||||
// override fun onFailure(s: String, s1: String) {
|
||||
// Utils.log("deviceToken::" + "注册失败")
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getAndSetAlias() {
|
||||
if (deviceToken.isNullOrEmpty()) {
|
||||
registerDevice()
|
||||
return
|
||||
}
|
||||
|
||||
val meta = MetaUtil.getMeta()
|
||||
|
||||
val jsonObject = JSONObject()
|
||||
jsonObject.put("device_token", deviceToken)
|
||||
jsonObject.put("imei", meta.imei)
|
||||
jsonObject.put("android_id", meta.android_id)
|
||||
jsonObject.put("model", meta.model)
|
||||
jsonObject.put("manufacturer", meta.manufacturer)
|
||||
jsonObject.put("os", meta.os)
|
||||
jsonObject.put("os_version", meta.android_version)
|
||||
jsonObject.put("mac", meta.mac)
|
||||
|
||||
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
|
||||
RetrofitManager.getInstance(mApplication).api.getAlias(body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
{ setAlias(it) },
|
||||
{ it.printStackTrace() }
|
||||
)
|
||||
// if (deviceToken.isNullOrEmpty()) {
|
||||
// registerDevice()
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// val meta = MetaUtil.getMeta()
|
||||
//
|
||||
// val jsonObject = JSONObject()
|
||||
// jsonObject.put("device_token", deviceToken)
|
||||
// jsonObject.put("imei", meta.imei)
|
||||
// jsonObject.put("android_id", meta.android_id)
|
||||
// jsonObject.put("model", meta.model)
|
||||
// jsonObject.put("manufacturer", meta.manufacturer)
|
||||
// jsonObject.put("os", meta.os)
|
||||
// jsonObject.put("os_version", meta.android_version)
|
||||
// jsonObject.put("mac", meta.mac)
|
||||
// jsonObject.put("gid", meta.gid)
|
||||
//
|
||||
// val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
||||
//
|
||||
// RetrofitManager.getInstance(mApplication).api.getAlias(body)
|
||||
// .subscribeOn(Schedulers.io())
|
||||
// .subscribe(
|
||||
// { setAlias(it) },
|
||||
// { it.printStackTrace() }
|
||||
// )
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setAlias(alias: AliasEntity) {
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
mPreviousAlias = alias
|
||||
PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
putString(SP_PUSH_ALIAS, mPreviousAlias?.toJson())
|
||||
}
|
||||
|
||||
pushAgent.setAlias(alias.alias, alias.aliasType) { b, s ->
|
||||
Utils.log("注册别名 $b + $s")
|
||||
}
|
||||
// val pushAgent = PushAgent.getInstance(mApplication)
|
||||
//
|
||||
// mPreviousAlias = alias
|
||||
// PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
// putString(SP_PUSH_ALIAS, mPreviousAlias?.toJson())
|
||||
// }
|
||||
//
|
||||
// pushAgent.setAlias(alias.alias, alias.aliasType) { b, s ->
|
||||
// Utils.log("注册别名 $b + $s")
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteAlias() {
|
||||
val pushAgent = PushAgent.getInstance(mApplication)
|
||||
|
||||
mPreviousAlias?.let {
|
||||
pushAgent.deleteAlias(it.alias, it.aliasType) { b, s ->
|
||||
Utils.log("删除别名 $b + $s")
|
||||
}
|
||||
}
|
||||
PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
putString(SP_PUSH_ALIAS, "")
|
||||
}
|
||||
mPreviousAlias = null
|
||||
// val pushAgent = PushAgent.getInstance(mApplication)
|
||||
//
|
||||
// mPreviousAlias?.let {
|
||||
// pushAgent.deleteAlias(it.alias, it.aliasType) { b, s ->
|
||||
// Utils.log("删除别名 $b + $s")
|
||||
// }
|
||||
// }
|
||||
// PreferenceManager.getDefaultSharedPreferences(mApplication).edit {
|
||||
// putString(SP_PUSH_ALIAS, "")
|
||||
// }
|
||||
// mPreviousAlias = null
|
||||
}
|
||||
}
|
||||
3
app/src/main/java/com/gh/common/Typealias.kt
Normal file
3
app/src/main/java/com/gh/common/Typealias.kt
Normal file
@ -0,0 +1,3 @@
|
||||
package com.gh.common
|
||||
|
||||
typealias OnFastClickListener = (isSuccess: Boolean) -> Unit
|
||||
@ -5,8 +5,6 @@ import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.util.GsonUtils;
|
||||
import com.gh.common.util.PackageHelper;
|
||||
import com.gh.common.util.PackageUtils;
|
||||
@ -25,6 +23,7 @@ import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
@ -51,6 +50,8 @@ public class Config {
|
||||
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";
|
||||
@ -239,6 +240,9 @@ public class Config {
|
||||
public static boolean isGameDomeSwitchOpen() {
|
||||
return getSettings() != null && getSettings().getGameDomeSwitch().equals("on");
|
||||
}
|
||||
public static boolean isPermissionPopupSwitchOpen() {
|
||||
return getSettings() != null && getSettings().getPermissionPopupSwitch().equals("on");
|
||||
}
|
||||
|
||||
public static void fixHideFunction() {
|
||||
SharedPreferences preferences = PreferenceManager.
|
||||
|
||||
@ -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";
|
||||
@ -28,12 +30,12 @@ public class Constants {
|
||||
public static final String XPOSED_INSTALLER_PACKAGE_NAME = "de.robv.android.xposed.installer";
|
||||
|
||||
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";
|
||||
// 游戏详情进入时的自定义栏目标签是否已经显示过一次展开更多的浮窗提示
|
||||
@ -42,10 +44,24 @@ public class Constants {
|
||||
// 最近显示的弹窗信息
|
||||
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 SIMULATOR_DOWNLOAD = "下载模拟器";
|
||||
public static final String SIMULATOR_GAME = "simulator_game";
|
||||
public static final String SIMULATOR_DOWNLOAD_START_TIME = "simulator_download_start_time";
|
||||
public static final String LAST_GHZS_UPDATE_FILE_SIZE = "last_ghzs_update_file_size";
|
||||
|
||||
// 新用户首次启动光环的时间
|
||||
public static final String SP_INITIAL_USAGE_TIME = "initial_usage_time";
|
||||
|
||||
public static final String SP_IMEI = "imei";
|
||||
public static final String SP_ANDROID_ID = "android_id";
|
||||
|
||||
//引导设置 “通知管理” 引导弹窗
|
||||
public static final String SP_SHOWED_NOTIFICATION_LOGIN = "show_notification_login_hint";
|
||||
public static final String SP_SHOWED_NOTIFICATION_QUESTION = "show_notification_question_hint";
|
||||
@ -53,6 +69,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";
|
||||
// 今天是否已经触发了 “通知管理” 引导弹窗
|
||||
@ -91,6 +110,25 @@ public class Constants {
|
||||
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 SP_PRIVACY_CURRENT_MD5 = "sp_privacy_current_md5";
|
||||
public static final String SP_PRIVACY_MINE_MD5 = "sp_privacy_mine_md5";
|
||||
public static final String SP_PRIVACY_SETTING_MD5 = "sp_privacy_setting_md5";
|
||||
public static final String SP_PRIVACY_MD5 = "sp_privacy_md5";
|
||||
|
||||
public static final String SP_IS_USER_ACCEPTED_PRIVACY_STATEMENT = "has_user_accepted_privacy_statement";
|
||||
public static final String SP_BRAND_NEW_USER = "brand_new_user";
|
||||
|
||||
//手机号码匹配规则
|
||||
public static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
||||
@ -100,13 +138,39 @@ 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 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 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 = "https://static-web.ghzs.com/badge-dev/index.html#/";
|
||||
public static final String BADGE_ADDRESS = "https://static-web.ghzs.com/badge/index.html#/";
|
||||
|
||||
// 徽章详情
|
||||
public static final String BADGE_DETAIL_ADDRESS_DEV = "https://static-web.ghzs.com/badge-dev/index.html#/badgedetail";
|
||||
public static final String BADGE_DETAIL_ADDRESS = "https://static-web.ghzs.com/badge/index.html#/badgedetail";
|
||||
|
||||
// 分享个人主页地址
|
||||
public static final String SHARE_USER_HOME_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs-userhome-dev/index.html#/";
|
||||
public static final String SHARE_USER_HOME_ADDRESS = "https://static-web.ghzs.com/ghzs-userhome/index.html#/";
|
||||
|
||||
// 腾讯企点地址
|
||||
public static final String TENCENT_QIDIAN_ADDRESS = "https://admin.qidian.qq.com/template/blue/mp/menu/qr-code-jump.html?linkType=0&env=ol&kfuin=2355094296&fid=457&key=c76dcb2e3d582b6ffbfb5bb22cde85ff&cate=1&source=&isLBS=&isCustomEntry=&type=16&ftype=1&_type=wpa&qidian=true";
|
||||
|
||||
//版规声明
|
||||
public static final String FORUM_REGULATIONS_NEWS_ID = "5f4db9cc34d44d01b92fd670";
|
||||
|
||||
//帮助内容详情
|
||||
public static final String HELP_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content=";
|
||||
public static final String HELP_ADDRESS = "https://static-web.ghzs.com/ghzs_help/help.html?content=";
|
||||
|
||||
// 注销页面
|
||||
public static final String LOGOUT_ADDRESS_DEV = "https://static-web.ghzs.com/ghzs_help_dev/help.html?content=5f6b1f02786564003944a693";
|
||||
public static final String LOGOUT_ADDRESS = "https://static-web.ghzs.com/ghzs_help/help.html?content=5f534111b1f72909fc225672";
|
||||
|
||||
//最少需要多少数据才能上传
|
||||
public static final int DATA_AMOUNT = 20;
|
||||
|
||||
@ -32,6 +32,9 @@ public class ItemViewType {
|
||||
public static final int IMAGE_SLIDE_ITEM = 23;
|
||||
public static final int VERTICAL_SLIDE_ITEM = 24;
|
||||
public static final int COLUMN_COLLECTION = 25;
|
||||
public static final int GALLERY_SLIDE = 27; // 首页自动滚动画廊专题
|
||||
public static final int GALLERY = 28; // 首页倾斜画廊专题
|
||||
public static final int BLANK_DIVIDER = 29; // 空白补充区域
|
||||
|
||||
/**
|
||||
* 普通列表
|
||||
|
||||
@ -14,12 +14,6 @@ import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.base.OnViewClickListener;
|
||||
import com.gh.common.constant.Config;
|
||||
@ -28,6 +22,8 @@ import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorDownloadManager;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.util.CheckLoginUtils;
|
||||
import com.gh.common.util.DataUtils;
|
||||
import com.gh.common.util.DialogUtils;
|
||||
@ -40,12 +36,14 @@ 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.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;
|
||||
@ -70,11 +68,18 @@ import com.lightgame.utils.Utils;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.BindingAdapter;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
/**
|
||||
* Created by khy on 12/02/18.
|
||||
*/
|
||||
@ -313,6 +318,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);
|
||||
@ -427,15 +439,25 @@ public class BindingAdapters {
|
||||
case PLUGIN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
ApkEntity apk = gameEntity.getApk().get(0);
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk,
|
||||
() -> {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
});
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
|
||||
if (gameEntity.getSimulator() != null) {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(v.getContext(), gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(v.getContext(), gameEntity.getSimulator(),
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(), null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(v.getContext(), gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showOverseaDownloadDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.checkDownload(v.getContext(), apk.getSize(),
|
||||
isSubscribe -> download(progressBar, gameEntity, traceEvent, isSubscribe, entrance, location));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
CertificationDialog.showCertificationDialog(v.getContext(), gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(v.getContext(), gameEntity, () -> {
|
||||
@ -451,6 +473,20 @@ public class BindingAdapters {
|
||||
break;
|
||||
case LAUNCH_OR_OPEN:
|
||||
if (gameEntity.getApk().size() == 1) {
|
||||
//启动模拟器游戏
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(progressBar, gameEntity, traceEvent, false, entrance, location);
|
||||
return;
|
||||
}
|
||||
|
||||
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
DataUtils.onGameLaunchEvent(v.getContext(), gameEntity.getName(), gameEntity.getApk().get(0).getPlatform(), location);
|
||||
PackageUtils.launchApplicationByPackageName(v.getContext(), gameEntity.getApk().get(0).getPackageName());
|
||||
} else {
|
||||
@ -467,7 +503,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;
|
||||
@ -506,9 +542,12 @@ public class BindingAdapters {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay));
|
||||
Intent i = new Intent(WebActivity.getIntentForWebGame(progressBar.getContext(), linkEntity.getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton()));
|
||||
progressBar.getContext().startActivity(i);
|
||||
break;
|
||||
case UPDATING:
|
||||
Utils.toast(progressBar.getContext(), "正在加急更新版本,敬请后续留意");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@ -538,10 +577,14 @@ public class BindingAdapters {
|
||||
} else {
|
||||
if (offStatus != null && "dialog".equals(offStatus)) {
|
||||
progressBar.setText("查看");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
} else if ("updating".equals(offStatus)) {
|
||||
progressBar.setText("更新中");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.UPDATING);
|
||||
} else {
|
||||
progressBar.setText("暂无");
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
}
|
||||
progressBar.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -775,4 +818,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("-");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,21 +26,12 @@ import com.gh.gamecenter.UserInfoEditActivity
|
||||
import com.gh.gamecenter.WebActivity
|
||||
import com.gh.gamecenter.entity.AuthDialogEntity
|
||||
import com.gh.gamecenter.entity.AuthDialogLevel
|
||||
import com.gh.gamecenter.entity.DeviceDialogEntity
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.gh.gamecenter.user.UserViewModel
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.halo.assistant.fragment.user.UserInfoEditFragment
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class CertificationDialog(context: Context, private val authDialogEntity: AuthDialogEntity, val gameId: String, val listener: DialogUtils.ConfirmListener) :
|
||||
Dialog(context, R.style.GhAlertDialog) {
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.airbnb.lottie.LottieAnimationView
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.util.MtaHelper
|
||||
import com.gh.common.util.PermissionHelper
|
||||
import com.gh.common.util.PermissionHelper.INSTALL_PERMISS_CODE
|
||||
import com.gh.common.util.goneIf
|
||||
import com.gh.gamecenter.R
|
||||
import kotlin.random.Random
|
||||
|
||||
class InstallPermissionDialogFragment : BaseTrackableDialogFragment() {
|
||||
|
||||
lateinit var mView: View
|
||||
var mCallBack: (() -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
mView = inflater.inflate(R.layout.dialog_install_permission, null, false)
|
||||
return mView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val closeTv = mView.findViewById<TextView>(R.id.closeTv)
|
||||
val closeIv = mView.findViewById<ImageView>(R.id.closeIv)
|
||||
val activateTv = mView.findViewById<TextView>(R.id.activateTv)
|
||||
val switchLottie = mView.findViewById<LottieAnimationView>(R.id.switchLottie)
|
||||
|
||||
switchLottie.setAnimation("lottie/install_permission_switch.json")
|
||||
switchLottie.playAnimation()
|
||||
|
||||
val randomNumber = Random.nextInt(2)
|
||||
closeTv.goneIf(randomNumber == 0)
|
||||
closeIv.goneIf(randomNumber != 0)
|
||||
closeTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), "文案样式_点击以后再说")
|
||||
dismiss()
|
||||
}
|
||||
closeIv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), "图标样式_点击关闭")
|
||||
dismiss()
|
||||
}
|
||||
activateTv.setOnClickListener {
|
||||
MtaHelper.onEvent(getEvent(), getKey(), if (randomNumber == 0) "文案样式_点击立即开启" else "图标样式_点击立即开启")
|
||||
PermissionHelper.toInstallPermissionSetting(requireActivity())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == RESULT_OK && requestCode == INSTALL_PERMISS_CODE) {
|
||||
mCallBack?.invoke()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getEvent(): String = "安装引导弹窗"
|
||||
|
||||
override fun getKey(): String = "引导弹窗"
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(activity: AppCompatActivity, callBack: (() -> Unit)?) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
if (!Config.isPermissionPopupSwitchOpen()) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
}
|
||||
val haveInstallPermission = activity.packageManager.canRequestPackageInstalls();
|
||||
if (haveInstallPermission) {
|
||||
callBack?.invoke()
|
||||
return
|
||||
|
||||
}
|
||||
var installPermissionDialogFragment = activity.supportFragmentManager.findFragmentByTag(InstallPermissionDialogFragment::class.java.simpleName) as? InstallPermissionDialogFragment
|
||||
if (installPermissionDialogFragment != null) {
|
||||
installPermissionDialogFragment.mCallBack = callBack
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(installPermissionDialogFragment)
|
||||
transaction.commit()
|
||||
} else {
|
||||
installPermissionDialogFragment = InstallPermissionDialogFragment().apply {
|
||||
mCallBack = callBack
|
||||
}
|
||||
installPermissionDialogFragment.show(activity.supportFragmentManager, InstallPermissionDialogFragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,28 +2,33 @@ package com.gh.common.dialog
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
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 +39,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 +79,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 +98,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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
154
app/src/main/java/com/gh/common/dialog/PrivacyDialogFragment.kt
Normal file
154
app/src/main/java/com/gh/common/dialog/PrivacyDialogFragment.kt
Normal file
@ -0,0 +1,154 @@
|
||||
package com.gh.common.dialog
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import com.gh.base.fragment.BaseDialogFragment
|
||||
import com.gh.common.util.dip2px
|
||||
import com.gh.gamecenter.R
|
||||
|
||||
class PrivacyDialogFragment : BaseDialogFragment() {
|
||||
|
||||
private val mLocalPrivacyHtml = "file:///android_asset/privacy_policies.html"
|
||||
private val mLocalRegulationHtml = "file:///android_asset/user_regulation.html"
|
||||
|
||||
var containerView: View? = null
|
||||
var mCallBack: ((isSuccess: Boolean) -> Unit)? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
containerView = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_privacy_protocol, null, false)
|
||||
return containerView
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val mWebViewPrivacy = containerView?.findViewById<WebView>(R.id.webView)
|
||||
val mWebViewRegulation = containerView?.findViewById<WebView>(R.id.webView2)
|
||||
|
||||
mWebViewPrivacy?.isHorizontalScrollBarEnabled = false
|
||||
mWebViewRegulation?.isHorizontalScrollBarEnabled = false
|
||||
|
||||
val mTitlePrivacyTv = containerView?.findViewById<TextView>(R.id.privacyTitleTv)
|
||||
val mTitleRegulationTv = containerView?.findViewById<TextView>(R.id.userRegulationTitleTv)
|
||||
|
||||
val settingsArrayList = arrayListOf(mWebViewPrivacy?.settings, mWebViewRegulation?.settings)
|
||||
|
||||
for (settings in settingsArrayList) {
|
||||
settings?.javaScriptEnabled = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
settings?.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
|
||||
}
|
||||
// 避免提示网页有害信息不能访问
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
settings?.safeBrowsingEnabled = false
|
||||
}
|
||||
|
||||
// 适配大于屏幕宽度的页面
|
||||
settings?.useWideViewPort = true
|
||||
settings?.loadWithOverviewMode = true
|
||||
settings?.domStorageEnabled = true
|
||||
|
||||
// 自适应屏幕
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
settings?.layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||
}
|
||||
}
|
||||
|
||||
// if (NetworkUtils.isNetworkConnected(requireContext())) {
|
||||
// mWebViewPrivacy?.loadUrl(requireContext().getString(R.string.privacy_policy_url))
|
||||
// mWebViewRegulation?.loadUrl(requireContext().getString(R.string.user_regulation_url))
|
||||
// } else {
|
||||
mWebViewPrivacy?.loadUrl(mLocalPrivacyHtml)
|
||||
mWebViewRegulation?.loadUrl(mLocalRegulationHtml)
|
||||
// }
|
||||
|
||||
// val client = object : WebViewClient() {
|
||||
// override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
|
||||
// super.onReceivedError(view, request, error)
|
||||
// if (view == mWebViewPrivacy) {
|
||||
// view?.loadUrl(mLocalPrivacyHtml)
|
||||
// } else {
|
||||
// view?.loadUrl(mLocalRegulationHtml)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// mWebViewPrivacy?.webViewClient = client
|
||||
// mWebViewRegulation?.webViewClient = client
|
||||
|
||||
mTitlePrivacyTv?.setOnClickListener {
|
||||
mTitlePrivacyTv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
|
||||
mTitleRegulationTv?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_F5F5F5))
|
||||
|
||||
mWebViewPrivacy?.visibility = View.VISIBLE
|
||||
mWebViewRegulation?.visibility = View.GONE
|
||||
}
|
||||
|
||||
mTitleRegulationTv?.setOnClickListener {
|
||||
mTitlePrivacyTv?.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.text_F5F5F5))
|
||||
mTitleRegulationTv.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.white))
|
||||
|
||||
mWebViewPrivacy?.visibility = View.GONE
|
||||
mWebViewRegulation?.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
containerView?.findViewById<View>(R.id.refuseTv)?.setOnClickListener {
|
||||
mCallBack?.invoke(false)
|
||||
dismiss()
|
||||
}
|
||||
containerView?.findViewById<View>(R.id.agreeTv)?.setOnClickListener {
|
||||
mCallBack?.invoke(true)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val createDialog = super.onCreateDialog(savedInstanceState)
|
||||
createDialog.setCanceledOnTouchOutside(false)
|
||||
createDialog.setOnKeyListener(object : DialogInterface.OnKeyListener {
|
||||
override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
val window = createDialog.window
|
||||
window?.setGravity(Gravity.CENTER)
|
||||
return createDialog
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val width = requireContext().resources.displayMetrics.widthPixels - 60F.dip2px()
|
||||
val height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
dialog?.window?.setLayout(width, height)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun show(activity: AppCompatActivity, callBack: ((isSuccess: Boolean) -> Unit)?) {
|
||||
var privacyDialogFragment = activity.supportFragmentManager.findFragmentByTag(PrivacyDialogFragment::class.java.simpleName) as? PrivacyDialogFragment
|
||||
if (privacyDialogFragment != null) {
|
||||
privacyDialogFragment.mCallBack = callBack
|
||||
val transaction: FragmentTransaction = activity.supportFragmentManager.beginTransaction()
|
||||
transaction.show(privacyDialogFragment)
|
||||
transaction.commit()
|
||||
} else {
|
||||
privacyDialogFragment = PrivacyDialogFragment().apply {
|
||||
mCallBack = callBack
|
||||
}
|
||||
privacyDialogFragment.show(activity.supportFragmentManager, PrivacyDialogFragment::class.java.simpleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,51 +4,80 @@ 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
|
||||
: BaseDialogFragment() {
|
||||
: 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
|
||||
@ -57,10 +86,19 @@ class ReserveDialogFragment
|
||||
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? {
|
||||
@ -81,11 +119,14 @@ class ReserveDialogFragment
|
||||
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) {
|
||||
@ -94,6 +135,11 @@ class ReserveDialogFragment
|
||||
HistoryHelper.insertGameEntity(mGame!!)
|
||||
}
|
||||
}
|
||||
|
||||
mViewModel.reserveMobile.observe(viewLifecycleOwner, Observer {
|
||||
setMobileIndexHint(it)
|
||||
})
|
||||
|
||||
dialog?.setCanceledOnTouchOutside(true)
|
||||
}
|
||||
|
||||
@ -123,18 +169,57 @@ class ReserveDialogFragment
|
||||
}
|
||||
}
|
||||
|
||||
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("预约游戏", "预约功能操作", "点击无手机号预约")
|
||||
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, "手机号格式错误,请检查并重新输入")
|
||||
@ -148,7 +233,65 @@ class ReserveDialogFragment
|
||||
R.id.close_btn -> {
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,6 +313,12 @@ class ReserveDialogFragment
|
||||
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 = "") {
|
||||
|
||||
@ -201,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)
|
||||
}
|
||||
@ -15,5 +15,15 @@ data class ExposureEntity(
|
||||
val sequence: Int? = 0,
|
||||
val platform: String? = "",
|
||||
val downloadType: String? = "",
|
||||
val downloadCompleteType: String? = ""
|
||||
val downloadCompleteType: String? = "",
|
||||
|
||||
// 下载地址的 host 和 path
|
||||
var host: String? = "",
|
||||
var path: String? = "",
|
||||
|
||||
// 统计启动弹窗相关数据用的 (ugly)
|
||||
@SerializedName("dialog_id")
|
||||
var welcomeDialogId: String? = "",
|
||||
@SerializedName("link_title")
|
||||
var welcomeDialogLinkTitle: String? = ""
|
||||
) : Parcelable
|
||||
@ -26,6 +26,8 @@ data class ExposureEvent(
|
||||
@PrimaryKey
|
||||
val id: String = UUID.randomUUID().toString()) : Parcelable {
|
||||
companion object {
|
||||
|
||||
// TODO 建一个 exposureEvent 池规避反复生成对象
|
||||
@JvmStatic
|
||||
fun createEvent(gameEntity: GameEntity?, source: List<ExposureSource>, eTrace: List<ExposureEvent>? = null, event: ExposureType = ExposureType.EXPOSURE): ExposureEvent {
|
||||
if (gameEntity?.getApk()?.size == 1) {
|
||||
@ -39,7 +41,10 @@ data class ExposureEvent(
|
||||
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 }
|
||||
|
||||
@ -43,7 +43,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
if (layoutManager == null) layoutManager = recyclerView.layoutManager as LinearLayoutManager
|
||||
|
||||
layoutManager?.run {
|
||||
visibleState = ExposureThrottleBus.VisibleState(findFirstCompletelyVisibleItemPosition(), findLastCompletelyVisibleItemPosition())
|
||||
visibleState = ExposureThrottleBus.VisibleState(findFirstVisibleItemPosition(), findLastVisibleItemPosition())
|
||||
throttleBus?.postVisibleState(visibleState!!)
|
||||
}
|
||||
}
|
||||
@ -55,7 +55,7 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
|
||||
|
||||
val eventList = arrayListOf<ExposureEvent>()
|
||||
|
||||
for (pos in visibleState.firstCompletelyVisible..visibleState.lastCompletelyVisible) {
|
||||
for (pos in visibleState.firstVisiblePosition..visibleState.lastVisiblePosition) {
|
||||
try {
|
||||
exposable.getEventByPosition(pos)?.let { eventList.add(it) }
|
||||
exposable.getEventListByPosition(pos)?.let { eventList.addAll(it) }
|
||||
|
||||
@ -3,6 +3,7 @@ package com.gh.common.exposure
|
||||
import com.aliyun.sls.android.sdk.model.LogGroup
|
||||
import com.gh.common.exposure.time.TimeUtil
|
||||
import com.gh.common.util.toJson
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.loghub.LgLOG
|
||||
import com.gh.loghub.LoghubHelper
|
||||
@ -94,15 +95,18 @@ object ExposureManager {
|
||||
*/
|
||||
fun commitSavedExposureEvents(forced: Boolean = false) {
|
||||
exposureExecutor.execute {
|
||||
if (exposureSet.size < STORE_SIZE && !forced || exposureSet.size == 0) return@execute
|
||||
tryWithDefaultCatch {
|
||||
// TODO 初始化 loghubHelper 去掉这个 tryCatch 块
|
||||
if (exposureSet.size < STORE_SIZE && !forced || exposureSet.size == 0) return@execute
|
||||
|
||||
val exposureList = exposureSet.toList()
|
||||
// uploadLogGroup 是一个异步方法,LoghubHelper 里面实现了重传功能,所以这里交给它就好了
|
||||
loghubHelper.uploadLogGroup(buildLogGroup(exposureList))
|
||||
val exposureList = exposureSet.toList()
|
||||
// uploadLogGroup 是一个异步方法,LoghubHelper 里面实现了重传功能,所以这里交给它就好了
|
||||
loghubHelper.uploadLogGroup(buildLogGroup(exposureList))
|
||||
|
||||
Utils.log("Exposure", "提交了${exposureList.size}条曝光记录")
|
||||
exposureSet.removeAll(exposureList)
|
||||
exposureDao.deleteMany(exposureList)
|
||||
Utils.log("Exposure", "提交了${exposureList.size}条曝光记录")
|
||||
exposureSet.removeAll(exposureList)
|
||||
exposureDao.deleteMany(exposureList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,21 +38,21 @@ class ExposureThrottleBus(var onSuccess: Consumer<VisibleState>, var onError: Co
|
||||
mPublishSubject.onNext(visibleState)
|
||||
}
|
||||
|
||||
class VisibleState(val firstCompletelyVisible: Int, val lastCompletelyVisible: Int) {
|
||||
class VisibleState(val firstVisiblePosition: Int, val lastVisiblePosition: Int) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
||||
val that = other as VisibleState
|
||||
|
||||
if (firstCompletelyVisible != that.firstCompletelyVisible) return false
|
||||
if (firstVisiblePosition != that.firstVisiblePosition) return false
|
||||
|
||||
return lastCompletelyVisible == that.lastCompletelyVisible
|
||||
return lastVisiblePosition == that.lastVisiblePosition
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = firstCompletelyVisible
|
||||
result = 31 * result + lastCompletelyVisible
|
||||
var result = firstVisiblePosition
|
||||
result = 31 * result + lastVisiblePosition
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,8 @@ object ExposureUtils {
|
||||
fun logADownloadCompleteExposureEvent(entity: GameEntity,
|
||||
platform: String?,
|
||||
trace: String?,
|
||||
host: String? = "unknown",
|
||||
path: String? = "unknown",
|
||||
downloadType: DownloadType) {
|
||||
val gameEntity = entity.clone()
|
||||
gameEntity.platform = platform
|
||||
@ -47,6 +49,8 @@ object ExposureUtils {
|
||||
source = traceEvent?.source ?: ArrayList(),
|
||||
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
|
||||
event = ExposureType.DOWNLOAD_COMPLETE)
|
||||
exposureEvent.payload.host = host
|
||||
exposureEvent.payload.path = path
|
||||
ExposureManager.log(exposureEvent)
|
||||
ExposureManager.commitSavedExposureEvents(forced = true)
|
||||
}
|
||||
|
||||
@ -5,17 +5,17 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import android.telephony.TelephonyManager
|
||||
import android.text.TextUtils
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.leon.channel.helper.ChannelReaderUtil
|
||||
import com.walkud.rom.checker.RomIdentifier
|
||||
import java.io.File
|
||||
|
||||
object MetaUtil {
|
||||
|
||||
@ -23,9 +23,11 @@ object MetaUtil {
|
||||
private var channel = ""
|
||||
|
||||
private var m: Meta? = null
|
||||
private var imei: String? = null
|
||||
private var androidId: String? = null
|
||||
|
||||
fun refreshMeta() {
|
||||
m = Meta(mac = getMac(),
|
||||
m = Meta(mac = "",
|
||||
imei = getIMEI(),
|
||||
model = getModel(),
|
||||
manufacturer = getManufacturer(),
|
||||
@ -57,57 +59,48 @@ object MetaUtil {
|
||||
return channel
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MAC address
|
||||
* TODO check > 6.0 results
|
||||
*/
|
||||
fun getMac(): String? {
|
||||
|
||||
var mac: String = ""
|
||||
|
||||
//Plan A
|
||||
try {
|
||||
mac = File("/sys/class/net/wlan0/address").inputStream().bufferedReader().use { it.readText() }
|
||||
if (!TextUtils.isEmpty(mac)) return mac.trim()
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
// Plan B
|
||||
try {
|
||||
mac = File("/sys/class/net/eth0/address").inputStream().bufferedReader().use { it.readText() }
|
||||
if (!TextUtils.isEmpty(mac)) return mac.trim()
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
// Plan C
|
||||
val wifiManager = application.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
try {
|
||||
mac = wifiManager.connectionInfo.macAddress
|
||||
} catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
}
|
||||
|
||||
return mac.trim()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMEI
|
||||
*/
|
||||
fun getIMEI(): String? {
|
||||
@JvmStatic
|
||||
fun getIMEI(): String {
|
||||
|
||||
if (application.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED)
|
||||
if (!HaloApp.isUserAcceptPrivacyPolicy(HaloApp.getInstance().application)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (imei != null) {
|
||||
return imei ?: ""
|
||||
}
|
||||
|
||||
imei = SPUtils.getString(Constants.SP_IMEI)
|
||||
|
||||
if (!TextUtils.isEmpty(imei)) {
|
||||
return imei ?: ""
|
||||
}
|
||||
|
||||
if (application.checkCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
|
||||
return ""
|
||||
}
|
||||
|
||||
val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
return telephonyManager.imei
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
return "".apply {
|
||||
imei = this
|
||||
SPUtils.setString(Constants.SP_IMEI, this)
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= 26) {
|
||||
return (telephonyManager.imei ?: "").apply {
|
||||
imei = this
|
||||
SPUtils.setString(Constants.SP_IMEI, this)
|
||||
}
|
||||
}
|
||||
|
||||
return telephonyManager.getDeviceId()
|
||||
return (telephonyManager.getDeviceId() ?: "").apply {
|
||||
imei = this
|
||||
SPUtils.setString(Constants.SP_IMEI, this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -119,14 +112,35 @@ object MetaUtil {
|
||||
return Build.MANUFACTURER
|
||||
}
|
||||
|
||||
fun getAndroidId(): String? {
|
||||
var android_id: String = ""
|
||||
try {
|
||||
android_id = Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
@JvmStatic
|
||||
fun getAndroidId(): String {
|
||||
|
||||
if (!HaloApp.isUserAcceptPrivacyPolicy(HaloApp.getInstance().application)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (androidId != null) {
|
||||
return androidId ?: ""
|
||||
}
|
||||
|
||||
androidId = SPUtils.getString(Constants.SP_ANDROID_ID)
|
||||
|
||||
if (!TextUtils.isEmpty(androidId)) {
|
||||
return androidId ?: ""
|
||||
}
|
||||
|
||||
return try {
|
||||
Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID).apply {
|
||||
androidId = this
|
||||
SPUtils.setString(Constants.SP_ANDROID_ID, this)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
androidId = ""
|
||||
SPUtils.setString(Constants.SP_ANDROID_ID, "")
|
||||
""
|
||||
}
|
||||
return android_id
|
||||
|
||||
}
|
||||
|
||||
fun getAndroidSDK(): Int? {
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
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
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
object RegionSettingHelper {
|
||||
|
||||
@ -49,7 +51,7 @@ object RegionSettingHelper {
|
||||
list
|
||||
}
|
||||
|
||||
fun shouldGameOfThisCategoryUseMirrorInfo(category: String) : Boolean {
|
||||
fun shouldGameOfThisCategoryUseMirrorInfo(category: String): Boolean {
|
||||
return if (mChannelControl == null || mChannelControl?.effect == false || !isUserUsedLessThan24Hours()) {
|
||||
false
|
||||
} else {
|
||||
@ -60,23 +62,26 @@ object RegionSettingHelper {
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun getRegionSetting() {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.sensitiveApi
|
||||
.getRegionSetting(HaloApp.getInstance().channel)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.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)
|
||||
debounceActionWithInterval(R.string.app_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) {
|
||||
|
||||
@ -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 = 6, 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,
|
||||
@ -63,12 +63,19 @@ abstract class HistoryDatabase : RoomDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,8 @@ object HistoryHelper {
|
||||
historyGame.id = updateEntity.id
|
||||
historyGame.brief = updateEntity.brief
|
||||
historyGame.des = ""
|
||||
historyGame.icon = updateEntity.icon
|
||||
historyGame.icon = updateEntity.rawIcon ?: updateEntity.icon
|
||||
historyGame.iconSubscript = historyGame.iconSubscript
|
||||
historyGame.name = updateEntity.name
|
||||
historyGame.tagStyle = updateEntity.tagStyle
|
||||
historyGame.tag = updateEntity.tag
|
||||
@ -55,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
|
||||
}
|
||||
|
||||
@ -109,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
|
||||
|
||||
10
app/src/main/java/com/gh/common/iinterface/IOffsetable.kt
Normal file
10
app/src/main/java/com/gh/common/iinterface/IOffsetable.kt
Normal file
@ -0,0 +1,10 @@
|
||||
package com.gh.common.iinterface
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
interface IOffsetable {
|
||||
fun getOffset(position: Int): Int
|
||||
|
||||
fun updateOffset(position: Int, offset: Int)
|
||||
|
||||
fun resetOffset()
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.gh.common.iinterface
|
||||
|
||||
interface IScrollable {
|
||||
fun scrollToTop()
|
||||
}
|
||||
@ -1,67 +1,67 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.core.view.ViewCompat
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
||||
object ImHintHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun show(activity: Activity?) {
|
||||
activity?.let {
|
||||
var hintView = retrieveHintViewFromActivity(it)
|
||||
if (hintView == null) {
|
||||
hintView = ImHintView(it)
|
||||
hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
|
||||
val decorView = it.window.decorView as ViewGroup
|
||||
it.runOnUiThread {
|
||||
decorView.addView(hintView)
|
||||
}
|
||||
} else {
|
||||
hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun dismiss(activity: Activity?) {
|
||||
activity?.let {
|
||||
clearCurrent(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun retrieveHintViewFromActivity(activity: Activity?) : ImHintView? {
|
||||
(activity?.window?.decorView as? ViewGroup)?.let {
|
||||
for (i in 0..it.childCount) {
|
||||
val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
if (childView != null && childView.windowToken != null) {
|
||||
return childView
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun clearCurrent(activity: Activity?) {
|
||||
(activity?.window?.decorView as? ViewGroup)?.let {
|
||||
for (i in 0..it.childCount) {
|
||||
val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
if (childView != null && childView.windowToken != null) {
|
||||
ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRemoveViewRunnable(childView: View?): Runnable {
|
||||
return Runnable {
|
||||
childView?.let {
|
||||
(childView.parent as? ViewGroup)?.removeView(childView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//package com.gh.common.im
|
||||
//
|
||||
//import android.app.Activity
|
||||
//import androidx.core.view.ViewCompat
|
||||
//import android.view.View
|
||||
//import android.view.ViewGroup
|
||||
//
|
||||
//object ImHintHelper {
|
||||
//
|
||||
// @JvmStatic
|
||||
// fun show(activity: Activity?) {
|
||||
// activity?.let {
|
||||
// var hintView = retrieveHintViewFromActivity(it)
|
||||
// if (hintView == null) {
|
||||
// hintView = ImHintView(it)
|
||||
// hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
//
|
||||
// val decorView = it.window.decorView as ViewGroup
|
||||
// it.runOnUiThread {
|
||||
// decorView.addView(hintView)
|
||||
// }
|
||||
// } else {
|
||||
// hintView.showDot(ImManager.shouldShowFloatingWindowDot)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @JvmStatic
|
||||
// fun dismiss(activity: Activity?) {
|
||||
// activity?.let {
|
||||
// clearCurrent(it)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun retrieveHintViewFromActivity(activity: Activity?) : ImHintView? {
|
||||
// (activity?.window?.decorView as? ViewGroup)?.let {
|
||||
// for (i in 0..it.childCount) {
|
||||
// val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
// if (childView != null && childView.windowToken != null) {
|
||||
// return childView
|
||||
// }
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
// private fun clearCurrent(activity: Activity?) {
|
||||
// (activity?.window?.decorView as? ViewGroup)?.let {
|
||||
// for (i in 0..it.childCount) {
|
||||
// val childView = if (it.getChildAt(i) is ImHintView) it.getChildAt(i) as ImHintView else null
|
||||
// if (childView != null && childView.windowToken != null) {
|
||||
// ViewCompat.animate(childView).alpha(0f).withEndAction(getRemoveViewRunnable(childView))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun getRemoveViewRunnable(childView: View?): Runnable {
|
||||
// return Runnable {
|
||||
// childView?.let {
|
||||
// (childView.parent as? ViewGroup)?.removeView(childView)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@ -1,45 +1,45 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.gh.common.util.DisplayUtils
|
||||
import com.gh.gamecenter.R
|
||||
import kotlinx.android.synthetic.main.view_im_hint.view.*
|
||||
|
||||
class ImHintView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
: RelativeLayout(context, attrs, defStyle) {
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.view_im_hint, this)
|
||||
|
||||
ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat() - 1)
|
||||
|
||||
ivContainer.setOnClickListener {
|
||||
if (context is Activity) {
|
||||
ImManager.startChatActivity(context)
|
||||
ImManager.removeNotification()
|
||||
}
|
||||
}
|
||||
|
||||
val lp = ivContainer.layoutParams as RelativeLayout.LayoutParams
|
||||
|
||||
lp.setMargins(0, 0, dp2px(30f), dp2px(106f) + DisplayUtils.retrieveNavigationHeight(context))
|
||||
}
|
||||
|
||||
fun showDot(show: Boolean) {
|
||||
if (show) {
|
||||
unreadDot.visibility = View.VISIBLE
|
||||
} else {
|
||||
unreadDot.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
private fun dp2px(dp: Float): Int {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.applicationContext.resources.displayMetrics).toInt()
|
||||
}
|
||||
}
|
||||
//package com.gh.common.im
|
||||
//
|
||||
//import android.app.Activity
|
||||
//import android.content.Context
|
||||
//import android.util.AttributeSet
|
||||
//import android.util.TypedValue
|
||||
//import android.view.View
|
||||
//import android.widget.RelativeLayout
|
||||
//import androidx.core.view.ViewCompat
|
||||
//import com.gh.common.util.DisplayUtils
|
||||
//import com.gh.gamecenter.R
|
||||
//import kotlinx.android.synthetic.main.view_im_hint.view.*
|
||||
//
|
||||
//class ImHintView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
// : RelativeLayout(context, attrs, defStyle) {
|
||||
//
|
||||
// init {
|
||||
// inflate(context, R.layout.view_im_hint, this)
|
||||
//
|
||||
// ViewCompat.setTranslationZ(this, Integer.MAX_VALUE.toFloat() - 1)
|
||||
//
|
||||
// ivContainer.setOnClickListener {
|
||||
// if (context is Activity) {
|
||||
// ImManager.startChatActivity(context)
|
||||
// ImManager.removeNotification()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// val lp = ivContainer.layoutParams as RelativeLayout.LayoutParams
|
||||
//
|
||||
// lp.setMargins(0, 0, dp2px(30f), dp2px(106f) + DisplayUtils.retrieveNavigationHeight(context))
|
||||
// }
|
||||
//
|
||||
// fun showDot(show: Boolean) {
|
||||
// if (show) {
|
||||
// unreadDot.visibility = View.VISIBLE
|
||||
// } else {
|
||||
// unreadDot.visibility = View.GONE
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun dp2px(dp: Float): Int {
|
||||
// return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.applicationContext.resources.displayMetrics).toInt()
|
||||
// }
|
||||
//}
|
||||
@ -1,25 +1,9 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import com.gh.base.CurrentActivityHolder
|
||||
import com.gh.common.runOnIoThread
|
||||
import com.gh.common.util.SPUtils
|
||||
import com.gh.common.util.tryWithDefaultCatch
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.HelpAndFeedbackActivity
|
||||
import com.gh.gamecenter.MainActivity
|
||||
import com.gh.gamecenter.MessageActivity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.m7.imkfsdk.KfStartHelper
|
||||
import com.m7.imkfsdk.utils.Utils
|
||||
import com.moor.imkf.ChatListener
|
||||
import com.moor.imkf.IMChat
|
||||
import com.moor.imkf.IMChatManager
|
||||
import com.moor.imkf.IMMessage
|
||||
import com.moor.imkf.utils.MoorUtils
|
||||
|
||||
object ImManager {
|
||||
|
||||
@ -35,57 +19,57 @@ object ImManager {
|
||||
|
||||
@JvmStatic
|
||||
fun attachIm() {
|
||||
try {
|
||||
if (UserManager.getInstance().userInfoEntity != null &&
|
||||
currentUserId != UserManager.getInstance().userId) {
|
||||
currentUserId = UserManager.getInstance().userId
|
||||
MoorUtils.init(HaloApp.getInstance().application)
|
||||
Utils.init(HaloApp.getInstance().application)
|
||||
IMChatManager.getInstance().init(
|
||||
HaloApp.getInstance().application,
|
||||
ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
IM_KEY,
|
||||
UserManager.getInstance().userInfoEntity.name + "(" + UserManager.getInstance().userId + ")",
|
||||
UserManager.getInstance().userId)
|
||||
|
||||
shouldShowFloatingWindow = SPUtils.getBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId)
|
||||
shouldShowFloatingWindowDot = SPUtils.getBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId)
|
||||
updateFloatingWindow()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// if (UserManager.getInstance().userInfoEntity != null &&
|
||||
// currentUserId != UserManager.getInstance().userId) {
|
||||
// currentUserId = UserManager.getInstance().userId
|
||||
// MoorUtils.init(HaloApp.getInstance().application)
|
||||
// Utils.init(HaloApp.getInstance().application)
|
||||
// IMChatManager.getInstance().init(
|
||||
// HaloApp.getInstance().application,
|
||||
// ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
// IM_KEY,
|
||||
// UserManager.getInstance().userInfoEntity?.name + "(" + UserManager.getInstance().userId + ")",
|
||||
// UserManager.getInstance().userId)
|
||||
//
|
||||
// shouldShowFloatingWindow = SPUtils.getBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId)
|
||||
// shouldShowFloatingWindowDot = SPUtils.getBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId)
|
||||
// updateFloatingWindow()
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun detachIm() {
|
||||
try {
|
||||
IMChatManager.getInstance().quitSDk()
|
||||
shouldShowFloatingWindow = false
|
||||
updateFloatingWindow()
|
||||
removeNotification()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// IMChatManager.getInstance().quitSDk()
|
||||
// shouldShowFloatingWindow = false
|
||||
// updateFloatingWindow()
|
||||
// removeNotification()
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun startChatActivity(activity: Activity, inputContent: String? = "", requestCode: Int? = null) {
|
||||
if (!UserManager.getInstance().userId.isNullOrEmpty()) {
|
||||
try {
|
||||
SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, false)
|
||||
shouldShowFloatingWindowDot = false
|
||||
val chatHelper = KfStartHelper(activity, UserManager.getInstance().userInfoEntity.icon, inputContent, requestCode)
|
||||
chatHelper.initSdkChat(
|
||||
ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
IM_KEY,
|
||||
UserManager.getInstance().userInfoEntity.name + "(" + UserManager.getInstance().userId + ")"
|
||||
+ "[" + BuildConfig.VERSION_NAME + "]",
|
||||
UserManager.getInstance().userId)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
// if (!UserManager.getInstance().userId.isNullOrEmpty()) {
|
||||
// try {
|
||||
// SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, false)
|
||||
// shouldShowFloatingWindowDot = false
|
||||
// val chatHelper = KfStartHelper(activity, UserManager.getInstance().userInfoEntity?.icon, inputContent, requestCode)
|
||||
// chatHelper.initSdkChat(
|
||||
// ImReceiver.UNIQUE_BROADCAST_ACTION,
|
||||
// IM_KEY,
|
||||
// UserManager.getInstance().userInfoEntity?.name + "(" + UserManager.getInstance().userId + ")"
|
||||
// + "[" + BuildConfig.VERSION_NAME + "]",
|
||||
// UserManager.getInstance().userId)
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@ -104,50 +88,50 @@ object ImManager {
|
||||
|
||||
@JvmStatic
|
||||
fun removeNotification() {
|
||||
val notificationManager = HaloApp.getInstance().application?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.cancel(ImReceiver.NOTIFICATION_ID)
|
||||
// val notificationManager = HaloApp.getInstance().application?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// notificationManager.cancel(ImReceiver.NOTIFICATION_ID)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun updateFloatingWindow() {
|
||||
try {
|
||||
CurrentActivityHolder.getCurrentActivity()?.let {
|
||||
if (isActivityValid(it)) {
|
||||
if (shouldShowFloatingWindow) {
|
||||
ImHintHelper.show(it)
|
||||
} else {
|
||||
ImHintHelper.dismiss(it)
|
||||
removeNotification()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// CurrentActivityHolder.getCurrentActivity()?.let {
|
||||
// if (isActivityValid(it)) {
|
||||
// if (shouldShowFloatingWindow) {
|
||||
// ImHintHelper.show(it)
|
||||
// } else {
|
||||
// ImHintHelper.dismiss(it)
|
||||
// removeNotification()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun sendFeedbackMessage(message: String) {
|
||||
val fromToMessage = IMMessage.createTxtMessage(message)
|
||||
runOnIoThread {
|
||||
tryWithDefaultCatch {
|
||||
IMChat.getInstance().sendMessage(fromToMessage, object : ChatListener {
|
||||
override fun onProgress(p0: Int) {}
|
||||
override fun onSuccess() {}
|
||||
override fun onFailed() {}
|
||||
})
|
||||
}
|
||||
}
|
||||
// val fromToMessage = IMMessage.createTxtMessage(message)
|
||||
// runOnIoThread {
|
||||
// tryWithDefaultCatch {
|
||||
// IMChat.getInstance().sendMessage(fromToMessage, object : ChatListener {
|
||||
// override fun onProgress(p0: Int) {}
|
||||
// override fun onSuccess() {}
|
||||
// override fun onFailed() {}
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateShouldShowFloatingWindow(show: Boolean) {
|
||||
SPUtils.setBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId, show)
|
||||
shouldShowFloatingWindow = show
|
||||
// SPUtils.setBoolean(SP_FLOATING_WINDOW_KEY + UserManager.getInstance().userId, show)
|
||||
// shouldShowFloatingWindow = show
|
||||
}
|
||||
|
||||
fun updateShouldShowFloatingWindowDot(show: Boolean) {
|
||||
SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, show)
|
||||
shouldShowFloatingWindowDot = show
|
||||
// SPUtils.setBoolean(SP_FLOATING_WINDOW_DOT_KEY + UserManager.getInstance().userId, show)
|
||||
// shouldShowFloatingWindowDot = show
|
||||
}
|
||||
|
||||
private fun isActivityValid(activity: Activity): Boolean {
|
||||
|
||||
@ -1,20 +1,9 @@
|
||||
package com.gh.common.im
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.gh.base.CurrentActivityHolder
|
||||
import com.gh.common.util.doOnMainProcessOnly
|
||||
import com.gh.gamecenter.R
|
||||
import com.m7.imkfsdk.chat.ChatActivity
|
||||
import com.m7.imkfsdk.utils.Utils
|
||||
import com.moor.imkf.IMChatManager
|
||||
|
||||
class ImReceiver : BroadcastReceiver() {
|
||||
|
||||
@ -26,54 +15,54 @@ class ImReceiver : BroadcastReceiver() {
|
||||
var notificationManager: NotificationManager? = null
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
context?.doOnMainProcessOnly {
|
||||
intent?.let {
|
||||
if (intent.action == IMChatManager.NEW_MSG_ACTION) {
|
||||
notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// 判断 ImActivity 是否在最顶端
|
||||
if (CurrentActivityHolder.getCurrentActivity() is ChatActivity) {
|
||||
ImManager.showFloatingWindow()
|
||||
ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
} else {
|
||||
val contentIntent = Intent(Utils.getApp(), ChatActivity::class.java)
|
||||
|
||||
contentIntent.putExtra("PeerId", "")
|
||||
contentIntent.putExtra("type", "peedId")
|
||||
|
||||
contentIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
val resultPendingIntent = PendingIntent.getActivity(
|
||||
Utils.getApp(),
|
||||
0,
|
||||
contentIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
)
|
||||
|
||||
// 新的通知
|
||||
val builder = NotificationCompat.Builder(Utils.getApp(), "Halo_IM")
|
||||
val notification = builder.setTicker("您有新的消息")
|
||||
.setDefaults(Notification.DEFAULT_ALL)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setContentIntent(resultPendingIntent)
|
||||
.setContentTitle("光环助手客服回复")
|
||||
.setContentText("您有新的消息")
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val channel = NotificationChannel("Halo_IM", "Halo_IM", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
notificationManager?.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
if (notification != null) {
|
||||
notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||
ImManager.showFloatingWindow()
|
||||
}
|
||||
}
|
||||
} else if (intent.action == IMChatManager.FINISH_ACTION) {
|
||||
ImManager.dismissFloatingWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
// context?.doOnMainProcessOnly {
|
||||
// intent?.let {
|
||||
// if (intent.action == IMChatManager.NEW_MSG_ACTION) {
|
||||
// notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
// // 判断 ImActivity 是否在最顶端
|
||||
// if (CurrentActivityHolder.getCurrentActivity() is ChatActivity) {
|
||||
// ImManager.showFloatingWindow()
|
||||
// ImManager.updateShouldShowFloatingWindowDot(false)
|
||||
// } else {
|
||||
// val contentIntent = Intent(Utils.getApp(), ChatActivity::class.java)
|
||||
//
|
||||
// contentIntent.putExtra("PeerId", "")
|
||||
// contentIntent.putExtra("type", "peedId")
|
||||
//
|
||||
// contentIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
// val resultPendingIntent = PendingIntent.getActivity(
|
||||
// Utils.getApp(),
|
||||
// 0,
|
||||
// contentIntent,
|
||||
// PendingIntent.FLAG_UPDATE_CURRENT
|
||||
// )
|
||||
//
|
||||
// // 新的通知
|
||||
// val builder = NotificationCompat.Builder(Utils.getApp(), "Halo_IM")
|
||||
// val notification = builder.setTicker("您有新的消息")
|
||||
// .setDefaults(Notification.DEFAULT_ALL)
|
||||
// .setSmallIcon(R.drawable.ic_notification)
|
||||
// .setWhen(System.currentTimeMillis())
|
||||
// .setContentIntent(resultPendingIntent)
|
||||
// .setContentTitle("光环助手客服回复")
|
||||
// .setContentText("您有新的消息")
|
||||
// .setAutoCancel(true)
|
||||
// .build()
|
||||
//
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// val channel = NotificationChannel("Halo_IM", "Halo_IM", NotificationManager.IMPORTANCE_DEFAULT)
|
||||
// notificationManager?.createNotificationChannel(channel)
|
||||
// }
|
||||
//
|
||||
// if (notification != null) {
|
||||
// notificationManager?.notify(NOTIFICATION_ID, notification)
|
||||
// ImManager.showFloatingWindow()
|
||||
// }
|
||||
// }
|
||||
// } else if (intent.action == IMChatManager.FINISH_ACTION) {
|
||||
// ImManager.dismissFloatingWindow()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,12 @@
|
||||
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.common.util.tryWithDefaultCatch
|
||||
import com.gh.loghub.LoghubHelper
|
||||
import org.json.JSONObject
|
||||
import java.util.concurrent.Executors
|
||||
@ -43,19 +47,39 @@ 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)
|
||||
}
|
||||
|
||||
fun commitSavedLoghubEvents() {
|
||||
loghubEventExecutor.execute {
|
||||
if (loghubEventSet.isEmpty()) return@execute
|
||||
// TODO 初始化 loghubHelper 去掉这个 tryCatch 块
|
||||
tryWithDefaultCatch {
|
||||
if (loghubEventSet.isEmpty()) return@execute
|
||||
|
||||
val exposureList = loghubEventSet.toList()
|
||||
val exposureList = loghubEventSet.toList()
|
||||
|
||||
createLogGroupAndUpload()
|
||||
loghubEventSet.removeAll(exposureList)
|
||||
loghubEventDao.deleteMany(exposureList)
|
||||
createLogGroupAndUpload()
|
||||
loghubEventSet.removeAll(exposureList)
|
||||
loghubEventDao.deleteMany(exposureList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,4 +110,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)
|
||||
@ -5,7 +5,7 @@ import com.gh.common.util.ApkActiveUtils
|
||||
import com.gh.common.util.RandomUtils
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import com.halo.assistant.HaloApp
|
||||
import io.reactivex.Observable
|
||||
|
||||
// 热门卡牌的仓库
|
||||
@ -16,7 +16,7 @@ object RemenkapaiRepository {
|
||||
@JvmStatic
|
||||
fun getRemenkapai(size: Int): Observable<List<GameEntity>> {
|
||||
return if (remenkapaiList.isEmpty()) {
|
||||
RetrofitManager.getInstance(getApplication()).sensitiveApi.remenkapai
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).sensitiveApi.remenkapai
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map { gameList -> filterEntityWithoutApk(gameList) }
|
||||
.map { pickRandomSizeEntity(size) }
|
||||
|
||||
@ -0,0 +1,243 @@
|
||||
package com.gh.common.simulator
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.AppExecutor.uiExecutor
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.dialog.TrackableDialog
|
||||
import com.gh.common.util.*
|
||||
import com.gh.common.util.PackageInstaller.getDownloadPath
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.entity.ApkEntity
|
||||
import com.gh.gamecenter.entity.SimulatorEntity
|
||||
import com.gh.gamecenter.entity.TrackableEntity
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.*
|
||||
import com.lightgame.utils.Utils
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class SimulatorDownloadManager private constructor() {
|
||||
|
||||
private var app_pb_progress: ProgressBar? = null
|
||||
private var appProgressSize: TextView? = null
|
||||
private var appProgressRemain: TextView? = null
|
||||
private var appProgressPercent: TextView? = null
|
||||
private var appProgressFilling: View? = null
|
||||
private var appProgressAnchor: View? = null
|
||||
private var downloadDialog: Dialog? = null
|
||||
|
||||
private var simulatorLocation: SimulatorLocation? = null
|
||||
private var simulator: SimulatorEntity? = null
|
||||
private var gameId: String = ""
|
||||
private var gameName: String = ""
|
||||
private var downloadType: String = ""
|
||||
|
||||
private val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: DownloadEntity?) {
|
||||
if (downloadEntity?.isSimulatorDownload() == true) {
|
||||
val size = downloadEntity.progress.toFloat() / 1024 / 1024
|
||||
val df = DecimalFormat("0.00")
|
||||
appProgressSize!!.text = "${df.format(size.toDouble())}MB"
|
||||
appProgressRemain!!.text = String.format("剩余%s", SpeedUtils.getRemainSecondTime(downloadEntity.size,
|
||||
downloadEntity.progress, downloadEntity.speed * 1024))
|
||||
app_pb_progress!!.progress = (downloadEntity.percent * 10).toInt()
|
||||
|
||||
val width = app_pb_progress!!.width
|
||||
val marLeft = (downloadEntity.percent / 100 * width).toInt()
|
||||
val anchorLp = appProgressAnchor!!.layoutParams
|
||||
if (anchorLp is ConstraintLayout.LayoutParams) {
|
||||
anchorLp.leftMargin = marLeft
|
||||
appProgressAnchor!!.layoutParams = anchorLp
|
||||
}
|
||||
|
||||
val fillingLp = appProgressFilling!!.layoutParams
|
||||
fillingLp.width = marLeft + DisplayUtils.dip2px(5f)
|
||||
appProgressFilling!!.layoutParams = fillingLp
|
||||
|
||||
appProgressPercent?.text = if (downloadEntity.percent != 100.0) "${downloadEntity.percent}%" else "100%"
|
||||
when {
|
||||
DownloadStatus.done == downloadEntity.status -> {
|
||||
val locationStr = if (simulatorLocation == SimulatorLocation.LAUNCH) "${simulatorLocation?.value}《${gameName}》" else simulatorLocation?.value
|
||||
val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk")
|
||||
val startTime = downloadEntity.getMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME)
|
||||
LogUtils.uploadSimulatorDownload("simulator_download_complete", fileName, simulator?.id, downloadEntity.name, gameId, locationStr, downloadType, startTime)
|
||||
DownloadManager.getInstance(HaloApp.getInstance().application).cancel(downloadEntity.url, false, true)
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
DownloadStatus.neterror == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络不稳定,下载任务已暂停")
|
||||
}
|
||||
DownloadStatus.timeout == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络不稳定,下载任务已暂停")
|
||||
}
|
||||
DownloadStatus.notfound == downloadEntity.status -> {
|
||||
ToastUtils.showToast("下载链接异常,请稍后重试")
|
||||
}
|
||||
DownloadStatus.hijack == downloadEntity.status -> {
|
||||
ToastUtils.showToast("网络劫持,请稍后重试")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation) {
|
||||
showDownloadDialog(context, simulator, location, "", "", null)
|
||||
}
|
||||
|
||||
fun showDownloadDialog(context: Context, simulator: SimulatorEntity?, location: SimulatorLocation, gameId: String = "", gameName: String = "", cancelCallback: (() -> Unit)? = null) {
|
||||
this.simulatorLocation = location
|
||||
this.simulator = simulator
|
||||
this.gameId = gameId
|
||||
this.gameName = gameName
|
||||
//判断是否隐藏
|
||||
if (simulator?.active == false) {
|
||||
showNoneEmulatorDialog(context)
|
||||
return
|
||||
}
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(context, simulator?.apk?.packageName)
|
||||
val versionFromInstalledApp = PackageUtils.getVersionByPackage(simulator?.apk?.packageName)
|
||||
val shouldShowUpdate = Version(simulator?.apk?.version).isHigherThan(versionFromInstalledApp)
|
||||
val title = if (shouldShowUpdate && isInstalled) "更新模拟器" else "安装模拟器"
|
||||
val message = if (shouldShowUpdate && isInstalled) "检测到模拟器存在更高版本,是否前往更新" else "模拟器游戏需要先下载安装对应的模拟器,才可以运行"
|
||||
val positiveText = if (shouldShowUpdate && isInstalled) "更新(${simulator?.apk?.size})" else "下载(${simulator?.apk?.size})"
|
||||
val negativeText = if (shouldShowUpdate && isInstalled) "下次再说" else "取消"
|
||||
downloadType = if (shouldShowUpdate && isInstalled) "update" else "download"
|
||||
|
||||
val trackableEntity = TrackableEntity("模拟器下载",
|
||||
key = if (shouldShowUpdate && isInstalled) "更新弹窗" else "下载弹窗",
|
||||
logShowEvent = true
|
||||
)
|
||||
DialogUtils.showNewAlertDialog(context, title, message, negativeText, positiveText, trackableEntity, {
|
||||
if (shouldShowUpdate && isInstalled){
|
||||
cancelCallback?.invoke()
|
||||
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, "点击下次再说")
|
||||
}
|
||||
}, {
|
||||
showDownloadingDialog(context, simulator)
|
||||
MtaHelper.onEvent(trackableEntity.event, trackableEntity.key, if (shouldShowUpdate && isInstalled) "点击更新" else "点击下载")
|
||||
})
|
||||
}
|
||||
|
||||
private fun showDownloadingDialog(context: Context, simulator: SimulatorEntity?) {
|
||||
val msg = FileUtils.isCanDownload(context, simulator?.apk?.size)
|
||||
if (!msg.isNullOrEmpty()) {
|
||||
Utils.toast(context, msg)
|
||||
return
|
||||
}
|
||||
if (NetworkUtils.isMobileConnected(context)) {
|
||||
Utils.toast(context, "当前使用移动数据进行下载")
|
||||
}
|
||||
|
||||
downloadDialog = TrackableDialog(context, R.style.GhAlertDialog, "模拟器下载", "下载中弹窗")
|
||||
downloadDialog?.window?.setBackgroundDrawableResource(R.color.transparent)
|
||||
|
||||
val view = View.inflate(context, R.layout.download_simulator_dialog, null)
|
||||
|
||||
app_pb_progress = view.findViewById(R.id.progress)
|
||||
appProgressSize = view.findViewById(R.id.size)
|
||||
appProgressRemain = view.findViewById(R.id.remain)
|
||||
appProgressAnchor = view.findViewById(R.id.progress_anchor)
|
||||
appProgressPercent = view.findViewById(R.id.percent)
|
||||
appProgressFilling = view.findViewById(R.id.progress_filling)
|
||||
|
||||
view.findViewById<View>(R.id.app_tv_cancel).setOnClickListener {
|
||||
DownloadManager.getInstance(context).pause(simulator?.apk?.url)
|
||||
MtaHelper.onEvent("模拟器下载", "下载中弹窗", "点击关闭")
|
||||
downloadDialog?.dismiss()
|
||||
}
|
||||
|
||||
downloadDialog?.setOnDismissListener {
|
||||
DownloadManager.getInstance(context).removeObserver(dataWatcher)
|
||||
}
|
||||
|
||||
downloadDialog?.setCanceledOnTouchOutside(false)
|
||||
downloadDialog?.setCancelable(false)
|
||||
downloadDialog?.closeOptionsMenu()
|
||||
downloadDialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
||||
downloadDialog?.setContentView(view)
|
||||
val params = downloadDialog?.window?.attributes
|
||||
params?.width = context.resources.displayMetrics.widthPixels - DisplayUtils.dip2px(60f)
|
||||
downloadDialog?.window?.attributes = params
|
||||
|
||||
download(context, simulator)
|
||||
}
|
||||
|
||||
private fun showNoneEmulatorDialog(context: Context) {
|
||||
val dialog = DialogUtils.showNewAlertDialog(context, "安装模拟器", "模拟器游戏需要先下载安装对应的模拟器,才可以运行", "取消", "暂无下载", null, {
|
||||
ToastUtils.showToast("该模拟器暂未提供下载")
|
||||
})
|
||||
dialog?.window?.findViewById<TextView>(R.id.confirm)?.setTextColor(ContextCompat.getColor(context, R.color.text_cccccc))
|
||||
}
|
||||
|
||||
private fun download(context: Context, simulator: SimulatorEntity?) {
|
||||
val apkEntity = simulator?.apk ?: return
|
||||
DownloadManager.getInstance(context).pauseAll()
|
||||
|
||||
val entity = DownloadManager.getInstance(context).getDownloadEntityByUrl(apkEntity.url)
|
||||
if (entity != null) {
|
||||
when (entity.status) {
|
||||
DownloadStatus.pause, DownloadStatus.subscribe,
|
||||
DownloadStatus.neterror, DownloadStatus.timeout -> {
|
||||
DownloadManager.getInstance(context).addObserver(dataWatcher)
|
||||
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance(context).resume(entity, true) }, 200)
|
||||
downloadDialog?.show()
|
||||
}
|
||||
DownloadStatus.done -> DataChanger.notifyDataChanged(entity)
|
||||
|
||||
else -> createDownload(context, apkEntity, simulator)
|
||||
}
|
||||
} else {
|
||||
createDownload(context, apkEntity, simulator)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDownload(context: Context, apkEntity: ApkEntity, simulator: SimulatorEntity) {
|
||||
DownloadManager.getInstance(context).addObserver(dataWatcher)
|
||||
val downloadEntity = DownloadEntity()
|
||||
downloadEntity.url = apkEntity.url
|
||||
downloadEntity.name = simulator.name
|
||||
downloadEntity.path = getDownloadPath(simulator.name, apkEntity.format)
|
||||
downloadEntity.platform = apkEntity.getPlatform()
|
||||
downloadEntity.packageName = apkEntity.packageName
|
||||
downloadEntity.versionName = apkEntity.version
|
||||
|
||||
downloadEntity.addMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE, Constants.SIMULATOR_DOWNLOAD)
|
||||
downloadEntity.addMetaExtra(Constants.SIMULATOR_DOWNLOAD_START_TIME, (System.currentTimeMillis() / 1000).toString())
|
||||
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance(context).add(downloadEntity) }, 200)
|
||||
|
||||
val locationStr = if (simulatorLocation == SimulatorLocation.LAUNCH) "${simulatorLocation?.value}《${gameName}》" else simulatorLocation?.value
|
||||
val fileName = downloadEntity.path.substring(downloadEntity.path.lastIndexOf('/') + 1).removeSuffix(".apk")
|
||||
LogUtils.uploadSimulatorDownload("simulator_download", fileName, simulator.id, simulator.name, gameId, locationStr, downloadType, "")
|
||||
|
||||
downloadDialog?.show()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var instance: SimulatorDownloadManager? = null
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(): SimulatorDownloadManager {
|
||||
return instance ?: synchronized(this) {
|
||||
instance ?: SimulatorDownloadManager().also { instance = it }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum class SimulatorLocation(val value: String) {
|
||||
LAUNCH("启动"),
|
||||
SIMULATOR_GAME("模拟器游戏"),
|
||||
SIMULATOR_MANAGE("模拟器游戏-模拟器管理")
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,219 @@
|
||||
package com.gh.common.simulator
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import com.g00fy2.versioncompare.Version
|
||||
import com.gh.common.util.*
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.entity.GameEntity
|
||||
import com.gh.gamecenter.manager.UserManager
|
||||
import com.gh.gamecenter.retrofit.BiResponse
|
||||
import com.gh.gamecenter.retrofit.EmptyResponse
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.download.DownloadDao
|
||||
import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.AppManager
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
import java.io.File
|
||||
|
||||
|
||||
object SimulatorGameManager {
|
||||
|
||||
private val gamePath = FileUtils.getDownloadPath(HaloApp.getInstance().application, "emulator_game")
|
||||
|
||||
@JvmStatic
|
||||
fun getPathByType(type: String) = "${gamePath}/${type}"
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGames(names: List<String>) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
names.forEach { name ->
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
val file = File(downloadEntity.path)
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
DownloadDao.getInstance(HaloApp.getInstance().application).delete(downloadEntity.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteLocalGame(name: String) {
|
||||
val downloadEntityList = DownloadDao.getInstance(HaloApp.getInstance().application).all
|
||||
val downloadEntity = downloadEntityList.find { it.name == name }
|
||||
if (downloadEntity != null) {
|
||||
val file = File(downloadEntity.path)
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
DownloadDao.getInstance(HaloApp.getInstance().application).delete(downloadEntity.url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun findDownloadEntityByUrl(url: String?): DownloadEntity? {
|
||||
val downloadEntity = DownloadDao.getInstance(HaloApp.getInstance().application).get(url)
|
||||
if (downloadEntity != null) {
|
||||
val isFileCompleted = DownloadManager.getInstance(HaloApp.getInstance().application).isFileCompleted(url)
|
||||
if (downloadEntity.isSimulatorGame() && isFileCompleted) {
|
||||
return downloadEntity
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isSimulatorGame(gameEntity: GameEntity) = gameEntity.category == "simulator"
|
||||
|
||||
|
||||
@JvmStatic
|
||||
fun launchSimulatorGame(downloadEntity: DownloadEntity, gameEntity: GameEntity) {
|
||||
val versionFromInstalledApp = PackageUtils.getVersionByPackage(gameEntity.simulator?.apk?.packageName)
|
||||
val shouldShowUpdate = Version(gameEntity.simulator?.apk?.version).isHigherThan(versionFromInstalledApp)
|
||||
if (shouldShowUpdate) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(AppManager.getInstance().recentActiveActivity, gameEntity.simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
|
||||
?: "") {
|
||||
jumpToSimulator(downloadEntity, gameEntity)
|
||||
}
|
||||
} else {
|
||||
jumpToSimulator(downloadEntity, gameEntity)
|
||||
}
|
||||
}
|
||||
|
||||
private fun jumpToSimulator(downloadEntity: DownloadEntity, gameEntity: GameEntity) {
|
||||
val intent = Intent()
|
||||
intent.data = Uri.fromFile(File(downloadEntity.path))
|
||||
if (gameEntity.simulatorType == "FBA") {
|
||||
val apkEntity = gameEntity.getApk()[0]
|
||||
intent.putExtra("rom_name", apkEntity.packageName)
|
||||
}
|
||||
intent.putExtra("default_path", downloadEntity.path.substring(0, downloadEntity.path.lastIndexOf('/')))
|
||||
intent.putExtra("game_type", gameEntity.simulatorType)
|
||||
intent.putExtra("title", downloadEntity.name)
|
||||
intent.putExtra("icon", gameEntity.icon ?: "")
|
||||
intent.putExtra("meta", LogUtils.getMetaObject().toString())
|
||||
intent.putExtra("simulatorId", gameEntity.simulator?.id)
|
||||
intent.putExtra("simulatorName", gameEntity.simulator?.name)
|
||||
intent.putExtra("gameId", gameEntity.id)
|
||||
|
||||
val destActivity = "com.gh.emu.RequestPermissionActivity"
|
||||
intent.setClassName(gameEntity.simulator?.apk?.packageName ?: "", destActivity)
|
||||
try {
|
||||
AppManager.getInstance().recentActiveActivity.startActivity(intent)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
ToastUtils.showToast("模拟器安装错误")
|
||||
}
|
||||
|
||||
recordPlaySimulatorGames(gameEntity.id)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录设备下载的模拟器游戏
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun recordDownloadSimulatorGames(gameId: String) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_id"] = gameId
|
||||
requestMap["package"] = "-"
|
||||
val body = requestMap.createRequestBodyAny()
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.downloadSimulatorGames(HaloApp.getInstance().gid, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记已玩过
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun postPlayedGame(gameId: String, packageName: String) {
|
||||
if (!TextUtils.isEmpty(gameId) && UserManager.getInstance().isLoggedIn) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_id"] = gameId
|
||||
requestMap["package"] = packageName
|
||||
val body = requestMap.toRequestBody()
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.postPlayedGame(UserManager.getInstance().userId, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 记录启动设备上的模拟器游戏
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun recordPlaySimulatorGames(gameId: String) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_id"] = gameId
|
||||
requestMap["package"] = "-"
|
||||
val body = requestMap.createRequestBodyAny()
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.playedSimulatorGames(HaloApp.getInstance().gid, body)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteSimulatorGame(gameId: String, callback: () -> Unit) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.deleteSimulatorGame(HaloApp.getInstance().gid, gameId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
callback.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteSimulatorGames(gameIds: List<String>, callback: () -> Unit) {
|
||||
val requestMap = hashMapOf<String, Any>()
|
||||
requestMap["game_ids"] = gameIds
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.deleteSimulatorGames(HaloApp.getInstance().gid, requestMap.toRequestBody())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : BiResponse<ResponseBody>() {
|
||||
override fun onSuccess(data: ResponseBody) {
|
||||
callback.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除设备下载模拟器游戏的记录
|
||||
*/
|
||||
@JvmStatic
|
||||
@SuppressLint("CheckResult")
|
||||
fun deleteAllSimulatorGame() {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application).api
|
||||
.deleteAllSimulatorGame(HaloApp.getInstance().gid)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(EmptyResponse())
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.gh.common.structure
|
||||
|
||||
class FixedSizeLinkedHashSet<T>(var maxSize: Int) : LinkedHashSet<T>() {
|
||||
override fun add(element: T): Boolean {
|
||||
if (size == maxSize) {
|
||||
pop()
|
||||
}
|
||||
return super.add(element);
|
||||
}
|
||||
|
||||
private fun pop() {
|
||||
if (size > 0) {
|
||||
remove(iterator().next())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,14 +5,17 @@ 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"
|
||||
|
||||
@ -21,9 +21,7 @@ object ActivationHelper {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun sendActivationInfo() {
|
||||
// 能获取到 IMEI 并且之前没发送过激活信息才发
|
||||
if (!mHasSentActivatedInfo
|
||||
&& Util_System_Phone_State.canGetImei(HaloApp.getInstance().application)) {
|
||||
if (!mHasSentActivatedInfo) {
|
||||
RetrofitManager.getInstance(HaloApp.getInstance().application)
|
||||
.api.postActivationInfo()
|
||||
.subscribeOn(Schedulers.io())
|
||||
|
||||
@ -5,11 +5,12 @@ import com.gh.gamecenter.entity.SettingsEntity
|
||||
|
||||
object AdHelper {
|
||||
|
||||
// 搜索为空/求版本/意见反馈-功能收录/发现
|
||||
// 搜索为空/求版本/意见反馈-功能收录/发现/模拟器游戏
|
||||
const val LOCATION_SEARCH_EMPTY = "search_empty"
|
||||
const val LOCATION_GAME_REQUEST_VERSION = "game_request_version"
|
||||
const val LOCATION_SUGGESTION_FUNCTION = "suggestion_function"
|
||||
const val LOCATION_DISCOVER = "discover"
|
||||
const val LOCATION_SIMULATOR_GAME = "simulator_game"
|
||||
|
||||
fun getAd(location: String): SettingsEntity.AD? {
|
||||
val adList = Config.getSettings()?.adList ?: return null
|
||||
@ -34,4 +35,19 @@ object AdHelper {
|
||||
return discoverAdList
|
||||
}
|
||||
|
||||
fun getAdForLocation(location: String): SettingsEntity.AD? {
|
||||
val adList = Config.getSettings()?.adList ?: return null
|
||||
|
||||
var result: SettingsEntity.AD? = null
|
||||
run outside@ {
|
||||
for (ad in adList) {
|
||||
if (ad.location == location) {
|
||||
result = ad
|
||||
return@outside
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,10 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.alibaba.wireless.security.jaq.avmp.IJAQAVMPSignComponent
|
||||
import com.alibaba.wireless.security.open.SecurityGuardManager
|
||||
import com.halo.assistant.HaloApp
|
||||
|
||||
object AntiBotHelper {
|
||||
@JvmStatic
|
||||
val manager by lazy {
|
||||
SecurityGuardManager.getInstance(HaloApp.getInstance().application).getInterface(IJAQAVMPSignComponent::class.java).apply {
|
||||
this.initialize()
|
||||
}
|
||||
}
|
||||
// @JvmStatic
|
||||
// val manager by lazy {
|
||||
// SecurityGuardManager.getInstance(HaloApp.getInstance().application).getInterface(IJAQAVMPSignComponent::class.java).apply {
|
||||
// this.initialize()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
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)
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
@ -14,9 +15,17 @@ import com.halo.assistant.HaloApp;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.renderscript.Allocation;
|
||||
import androidx.renderscript.Element;
|
||||
import androidx.renderscript.RenderScript;
|
||||
import androidx.renderscript.ScriptIntrinsicBlur;
|
||||
|
||||
/**
|
||||
* Created by LGT on 2016/10/21.
|
||||
*/
|
||||
@ -114,6 +123,14 @@ public class BitmapUtils {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapByFile(String filepath, int w, int h) {
|
||||
return getBitmapByFile(filepath, w, h, Bitmap.Config.RGB_565);
|
||||
}
|
||||
|
||||
public static Bitmap getBitmapByFile(String filepath, Bitmap.Config config) {
|
||||
return getBitmapByFile(filepath, 0, 0, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件路径返回bitmap
|
||||
*
|
||||
@ -122,12 +139,12 @@ public class BitmapUtils {
|
||||
* @param h 高
|
||||
* @return bitmap
|
||||
*/
|
||||
public static Bitmap getBitmapByFile(String filepath, int w, int h) {
|
||||
public static Bitmap getBitmapByFile(String filepath, int w, int h, Bitmap.Config config) {
|
||||
try {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
// 设置为ture只获取图片大小
|
||||
options.inJustDecodeBounds = true;
|
||||
options.inPreferredConfig = Bitmap.Config.RGB_565;
|
||||
options.inPreferredConfig = config;
|
||||
// 返回为空
|
||||
BitmapFactory.decodeFile(filepath, options);
|
||||
int width = options.outWidth;
|
||||
@ -135,8 +152,8 @@ public class BitmapUtils {
|
||||
float scaleWidth = 0.f, scaleHeight = 0.f;
|
||||
if (width > w || height > h) {
|
||||
// 缩放
|
||||
scaleWidth = ((float) width) / w;
|
||||
scaleHeight = ((float) height) / h;
|
||||
if (w > 0) scaleWidth = ((float) width) / w;
|
||||
if (h > 0) scaleHeight = ((float) height) / h;
|
||||
}
|
||||
options.inJustDecodeBounds = false;
|
||||
int scale = (int) Math.ceil(Math.max(scaleWidth, scaleHeight));
|
||||
@ -189,6 +206,7 @@ public class BitmapUtils {
|
||||
|
||||
/**
|
||||
* Drawable转Bitmap
|
||||
*
|
||||
* @param isSquare 是否是正方形
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable, boolean isSquare) {
|
||||
@ -196,7 +214,7 @@ public class BitmapUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
int w,h;
|
||||
int w, h;
|
||||
|
||||
// 取 drawable 的长宽
|
||||
w = drawable.getIntrinsicWidth();
|
||||
@ -227,4 +245,108 @@ public class BitmapUtils {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改bitmap透明度
|
||||
*
|
||||
* @param sourceImg
|
||||
* @param config
|
||||
* @param number
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap getTransparentBitmap(Bitmap sourceImg, Bitmap.Config config, int number) {
|
||||
int[] argb = new int[sourceImg.getWidth() * sourceImg.getHeight()];
|
||||
sourceImg.getPixels(argb, 0, sourceImg.getWidth(), 0, 0, sourceImg
|
||||
.getWidth(), sourceImg.getHeight());// 获得图片的ARGB值
|
||||
number = number * 255 / 100;
|
||||
for (int i = 0; i < argb.length; i++) {
|
||||
argb[i] = (number << 24) | (argb[i] & 0x00FFFFFF);
|
||||
}
|
||||
sourceImg = Bitmap.createBitmap(argb, sourceImg.getWidth(), sourceImg
|
||||
.getHeight(), config);
|
||||
return sourceImg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 高斯模糊
|
||||
*
|
||||
* @param context
|
||||
* @param image
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
public static Bitmap getBlurBitmap(Context context, Bitmap image, @IntRange(from = 1, to = 25) int radius) {
|
||||
// 计算图片缩小后的长宽
|
||||
int width = Math.round(image.getWidth() * 0.8f);
|
||||
int height = Math.round(image.getHeight() * 0.8f);
|
||||
|
||||
// 将缩小后的图片做为预渲染的图片。
|
||||
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
|
||||
// 创建一张渲染后的输出图片。
|
||||
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
|
||||
// 创建RenderScript内核对象
|
||||
RenderScript rs = RenderScript.create(context);
|
||||
// 创建一个模糊效果的RenderScript的工具对象
|
||||
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
|
||||
|
||||
// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。
|
||||
// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。
|
||||
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
|
||||
Allocation tmpOut = Allocation.createTyped(rs, tmpIn.getType());
|
||||
// 设置渲染的模糊程度, 25f是最大模糊度
|
||||
blurScript.setRadius(radius);
|
||||
// 设置blurScript对象的输入内存
|
||||
blurScript.setInput(tmpIn);
|
||||
// 将输出数据保存到输出内存中
|
||||
blurScript.forEach(tmpOut);
|
||||
|
||||
// 将数据填充到Allocation中
|
||||
tmpOut.copyTo(outputBitmap);
|
||||
|
||||
return outputBitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存图片
|
||||
*
|
||||
* @param bitmap
|
||||
* @param path
|
||||
*/
|
||||
public static void saveBitmap(Bitmap bitmap, String path) {
|
||||
File file = new File(path);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
FileOutputStream out;
|
||||
try {
|
||||
out = new FileOutputStream(file);
|
||||
if (bitmap.compress(Bitmap.CompressFormat.PNG, 80, out)) {
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap compressBitmap(Bitmap bitmap) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
Matrix matrix = new Matrix();
|
||||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
result.compress(Bitmap.CompressFormat.WEBP, 100, bos);
|
||||
|
||||
while (bos.toByteArray().length > 400 * 1024) {
|
||||
System.out.println(bos.toByteArray().length);
|
||||
matrix.setScale(0.9f, 0.9f);
|
||||
result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true);
|
||||
bos.reset();
|
||||
result.compress(Bitmap.CompressFormat.WEBP, 100, bos);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,18 +1,23 @@
|
||||
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.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Utils
|
||||
import com.tencent.bugly.beta.tinker.TinkerManager.getApplication
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.ResponseBody
|
||||
@ -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,46 @@ 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>()
|
||||
dialogOptions.add("复制")
|
||||
dialogOptions.add("投诉")
|
||||
if (commentEntity.user.id != UserManager.getInstance().userId) {
|
||||
dialogOptions.add("投诉")
|
||||
}
|
||||
if (isVideoAuthor || (videoId != null && commentEntity.user.id == UserManager.getInstance().userId)) {
|
||||
dialogOptions.add("删除评论")
|
||||
} else if (articleId != null && (commentEntity.user.id == UserManager.getInstance().userId ||
|
||||
commentEntity.me?.isModerator == true || commentEntity.me?.isArticleOrAnswerAuthor == true)) {
|
||||
dialogOptions.add("删除评论")
|
||||
}
|
||||
|
||||
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 +110,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, !videoId.isNullOrEmpty()) { 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,
|
||||
@ -152,7 +194,7 @@ object CommentHelper {
|
||||
var canHighlightCommentDirectly = false
|
||||
var canHideCommentDirectly = false
|
||||
|
||||
if (me.moderatorPermissions.topAnswerComment > Permissions.GUEST
|
||||
if (me.isModerator || me.moderatorPermissions.topAnswerComment > Permissions.GUEST
|
||||
|| me.moderatorPermissions.topCommunityArticleComment > Permissions.GUEST) {
|
||||
dialogOptions.add(highlight)
|
||||
if (me.moderatorPermissions.topAnswerComment > Permissions.REPORTER
|
||||
@ -161,7 +203,7 @@ object CommentHelper {
|
||||
}
|
||||
}
|
||||
|
||||
if (me.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|
||||
if (me.isModerator || me.moderatorPermissions.hideAnswerComment > Permissions.GUEST
|
||||
|| me.moderatorPermissions.hideCommunityArticleComment > Permissions.GUEST) {
|
||||
dialogOptions.add(hide)
|
||||
if (me.moderatorPermissions.hideAnswerComment > Permissions.REPORTER
|
||||
@ -226,10 +268,10 @@ object CommentHelper {
|
||||
val errorJson = JSONObject(string)
|
||||
val errorCode = errorJson.getInt("code")
|
||||
if (errorCode == 403059) {
|
||||
Utils.toast(getApplication(), "权限错误,请刷新后重试")
|
||||
Utils.toast(HaloApp.getInstance().application, "权限错误,请刷新后重试")
|
||||
return
|
||||
} else {
|
||||
Utils.toast(getApplication(), e.message())
|
||||
Utils.toast(HaloApp.getInstance().application, e.message())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -275,10 +317,10 @@ object CommentHelper {
|
||||
val errorJson = JSONObject(string)
|
||||
val errorCode = errorJson.getInt("code")
|
||||
if (errorCode == 403059) {
|
||||
Utils.toast(getApplication(), "权限错误,请刷新后重试")
|
||||
Utils.toast(HaloApp.getInstance().application, "权限错误,请刷新后重试")
|
||||
return
|
||||
} else {
|
||||
Utils.toast(getApplication(), e.message())
|
||||
Utils.toast(HaloApp.getInstance().application, e.message())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,16 +351,22 @@ object CommentHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private fun showReportTypeDialog(context: Context, reportCallback: (reportType: String) -> Unit) {
|
||||
private fun showReportTypeDialog(context: Context, isVideoComment: Boolean, reportCallback: (reportType: String) -> Unit) {
|
||||
val reportTypes = arrayListOf("垃圾广告营销", "恶意攻击谩骂", "淫秽色情信息", "违法有害信息", "其它")
|
||||
|
||||
DialogUtils.showListDialog(context, reportTypes, null) { text ->
|
||||
val jsonObject = JSONObject()
|
||||
try {
|
||||
jsonObject.put("reason", text)
|
||||
reportCallback.invoke(jsonObject.toString())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
if (!isVideoComment) {
|
||||
DialogUtils.showListDialog(context, reportTypes, null) { text ->
|
||||
val jsonObject = JSONObject()
|
||||
try {
|
||||
jsonObject.put("reason", text)
|
||||
reportCallback.invoke(jsonObject.toString())
|
||||
} catch (e: JSONException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DialogUtils.showVideoComplaintDialog(context, reportTypes, null) { text ->
|
||||
reportCallback.invoke(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import com.gh.gamecenter.entity.MeEntity;
|
||||
import com.gh.gamecenter.entity.UserInfoEntity;
|
||||
import com.gh.gamecenter.manager.UserManager;
|
||||
import com.gh.gamecenter.retrofit.BiResponse;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -38,6 +39,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
@ -50,9 +52,13 @@ 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 = time * 1000;
|
||||
long day = timestamp * 1000;
|
||||
String year = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
|
||||
format.applyPattern("yyyy");
|
||||
String currentYear = format.format(day);
|
||||
@ -63,35 +69,34 @@ public class CommentUtils {
|
||||
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;
|
||||
textView.setText(String.format(Locale.getDefault(), "%d天前 ", days));
|
||||
return String.format(Locale.getDefault(), "%d天前 ", days);
|
||||
} else if (day < today - 86400 * 1000 * 7 && year.equals(currentYear)) {
|
||||
format.applyPattern("MM-dd");
|
||||
textView.setText(format.format(day));
|
||||
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,
|
||||
@ -275,6 +280,9 @@ public class CommentUtils {
|
||||
if (TextUtils.isEmpty(articleId)) {
|
||||
entrance = "社区文章详情-评论-点赞";
|
||||
}
|
||||
if (TextUtils.isEmpty(videoId)) {
|
||||
entrance = "视频流-评论-点赞";
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
if (commentLikeCountTv.getCurrentTextColor() == ContextCompat.getColor(context, R.color.theme_font)) {
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
@ -326,6 +334,97 @@ public class CommentUtils {
|
||||
});
|
||||
});
|
||||
}
|
||||
public static void voteVideoComment(final Context context,
|
||||
String answerId,
|
||||
String articleId,
|
||||
String articleCommunityId,
|
||||
String videoId,
|
||||
final CommentEntity commentEntity,
|
||||
final TextView commentLikeCountTv,
|
||||
final ImageView commentLikeIv,
|
||||
final OnVoteListener listener) {
|
||||
|
||||
String entrance = "视频流-评论-点赞";
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
|
||||
PostCommentUtils.likeComment(context, answerId, articleId, articleCommunityId, videoId, commentEntity.getId(),
|
||||
new PostCommentUtils.PostCommentListener() {
|
||||
@Override
|
||||
public void postSuccess(JSONObject response) {
|
||||
if (listener != null) {
|
||||
listener.onVote();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postFailed(Throwable e) {
|
||||
commentEntity.setVote(commentEntity.getVote() - 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.hint));
|
||||
commentLikeIv.setImageResource(R.drawable.comment_vote_unselect);
|
||||
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
|
||||
if (commentEntity.getVote() == 0) {
|
||||
commentLikeCountTv.setVisibility(View.GONE);
|
||||
} else {
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (e instanceof HttpException) {
|
||||
HttpException exception = (HttpException) e;
|
||||
if (exception.code() == 403) {
|
||||
try {
|
||||
String detail = new JSONObject(exception.response().errorBody().string()).getString("detail");
|
||||
if ("voted".equals(detail)) {
|
||||
ToastUtils.INSTANCE.showToast("已经点过赞啦!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
Utils.toast(context, "网络异常,点赞失败");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static void unVoteVideoComment(final Context context,
|
||||
String videoId,
|
||||
final CommentEntity commentEntity,
|
||||
final TextView commentLikeCountTv,
|
||||
final ImageView commentLikeIv) {
|
||||
String entrance = "视频流-评论-取消点赞";
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
RetrofitManager.getInstance(context).getApi()
|
||||
.unVoteVideoComment(videoId, commentEntity.getId())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Response<ResponseBody>() {
|
||||
@Override
|
||||
public void onResponse(@Nullable ResponseBody response) {
|
||||
super.onResponse(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@Nullable HttpException e) {
|
||||
super.onFailure(e);
|
||||
commentEntity.setVote(commentEntity.getVote() + 1);
|
||||
commentLikeCountTv.setTextColor(ContextCompat.getColor(context, R.color.theme_font));
|
||||
commentLikeIv.setImageResource(R.drawable.comment_vote_select);
|
||||
commentLikeCountTv.setText(NumberUtils.transSimpleCount(commentEntity.getVote()));
|
||||
commentLikeCountTv.setVisibility(View.VISIBLE);
|
||||
try {
|
||||
if (e != null && e.response().errorBody() != null) {
|
||||
ErrorHelper.handleError(context, e.response().errorBody().string(), false);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 设置评论item 用户相关的view(点赞/头像/用户名)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -2,10 +2,10 @@ package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.common.loghub.LoghubUtils;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import org.json.JSONObject;
|
||||
@ -20,12 +20,13 @@ import java.util.Map;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -52,10 +53,13 @@ public class DataLogUtils {
|
||||
String channel = HaloApp.getInstance().getChannel();
|
||||
map.put("version", version);
|
||||
map.put("user", user);
|
||||
map.put("device_id", Util_System_Phone_State.getDeviceId(context));
|
||||
map.put("device_id", MetaUtil.getIMEI());
|
||||
map.put("channel", channel);
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
if ("search-hot-tag".equals(topic) || "game".equals(topic) || "slide".equals(topic)) {
|
||||
params.put("meta", LogUtils.getMetaObject().toString());
|
||||
}
|
||||
params.put("topic", topic);
|
||||
params.put("source", "GH-ASSIST-Client");
|
||||
params.put("time", String.valueOf(Utils.getTime(context)));
|
||||
|
||||
@ -6,7 +6,6 @@ import android.content.Context;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.constant.Constants;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.gh.gid.GidCallback;
|
||||
@ -14,13 +13,6 @@ import com.gh.gid.GidHelper;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.config.CommonDebug;
|
||||
import com.lightgame.utils.Utils;
|
||||
import com.tencent.bugly.crashreport.CrashReport;
|
||||
import com.tencent.stat.MtaSDkException;
|
||||
import com.tencent.stat.StatConfig;
|
||||
import com.tencent.stat.StatCrashReporter;
|
||||
import com.tencent.stat.StatReportStrategy;
|
||||
import com.tencent.stat.StatService;
|
||||
import com.tendcloud.tenddata.TCAgent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -44,71 +36,71 @@ public class DataUtils {
|
||||
return;
|
||||
}
|
||||
//TalkingData
|
||||
try {
|
||||
TCAgent.LOG_ON = false;
|
||||
TCAgent.init(context, Config.TALKINGDATA_APPID, channel);
|
||||
/**
|
||||
*
|
||||
* 不要启用!!!!不要启用,全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
*/
|
||||
TCAgent.setReportUncaughtExceptions(false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// TCAgent.LOG_ON = false;
|
||||
// TCAgent.init(context, Config.TALKINGDATA_APPID, channel);
|
||||
// /**
|
||||
// *
|
||||
// * 不要启用!!!!不要启用,全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
// */
|
||||
// TCAgent.setReportUncaughtExceptions(false);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
//MTA
|
||||
try {
|
||||
/**
|
||||
*
|
||||
* 不要启用!!!!全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
*/
|
||||
StatConfig.setAutoExceptionCaught(false);
|
||||
|
||||
StatCrashReporter crashReporter = StatCrashReporter.getStatCrashReporter(context);
|
||||
crashReporter.setJavaCrashHandlerStatus(false);
|
||||
// crashReporter.setEnableInstantReporting(true);
|
||||
|
||||
StatConfig.setDebugEnable(false);
|
||||
|
||||
// 设置数据上报策略
|
||||
// 测试渠道的时候即时上传,方便查看日志
|
||||
if (Config.DEFAULT_CHANNEL.equals(HaloApp.getInstance().getChannel())) {
|
||||
StatConfig.setStatSendStrategy(StatReportStrategy.INSTANT);
|
||||
} else {
|
||||
StatConfig.setStatSendStrategy(StatReportStrategy.PERIOD);
|
||||
StatConfig.setSendPeriodMinutes(5);
|
||||
}
|
||||
|
||||
// 设置启用Tlink
|
||||
StatConfig.setTLinkStatus(true);
|
||||
|
||||
StatConfig.init(context);
|
||||
StatConfig.setInstallChannel(channel);
|
||||
StatConfig.setAntoActivityLifecycleStat(true);
|
||||
StatConfig.setAppVersion(PackageUtils.getVersionName());
|
||||
|
||||
// 开启收集服务
|
||||
StatService.startStatService(context, Config.MTA_APPKEY, com.tencent.stat.common.StatConstants.VERSION);
|
||||
StatService.registerActivityLifecycleCallbacks(context);
|
||||
} catch (MtaSDkException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// /**
|
||||
// *
|
||||
// * 不要启用!!!!全部由{@link com.gh.base.AppUncaughtHandler}处理
|
||||
// */
|
||||
// StatConfig.setAutoExceptionCaught(false);
|
||||
//
|
||||
// StatCrashReporter crashReporter = StatCrashReporter.getStatCrashReporter(context);
|
||||
// crashReporter.setJavaCrashHandlerStatus(false);
|
||||
//// crashReporter.setEnableInstantReporting(true);
|
||||
//
|
||||
// StatConfig.setDebugEnable(false);
|
||||
//
|
||||
// // 设置数据上报策略
|
||||
// // 测试渠道的时候即时上传,方便查看日志
|
||||
// if (Config.DEFAULT_CHANNEL.equals(HaloApp.getInstance().getChannel())) {
|
||||
// StatConfig.setStatSendStrategy(StatReportStrategy.INSTANT);
|
||||
// } else {
|
||||
// StatConfig.setStatSendStrategy(StatReportStrategy.PERIOD);
|
||||
// StatConfig.setSendPeriodMinutes(5);
|
||||
// }
|
||||
//
|
||||
// // 设置启用Tlink
|
||||
// StatConfig.setTLinkStatus(true);
|
||||
//
|
||||
// StatConfig.init(context);
|
||||
// StatConfig.setInstallChannel(channel);
|
||||
// StatConfig.setAntoActivityLifecycleStat(true);
|
||||
// StatConfig.setAppVersion(PackageUtils.getVersionName());
|
||||
//
|
||||
// // 开启收集服务
|
||||
// StatService.startStatService(context, Config.MTA_APPKEY, com.tencent.stat.common.StatConstants.VERSION);
|
||||
// StatService.registerActivityLifecycleCallbacks(context);
|
||||
// } catch (MtaSDkException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
// init bugly
|
||||
try {
|
||||
CrashReport.setIsDevelopmentDevice(context, Config.DEFAULT_CHANNEL.equals(channel));
|
||||
|
||||
CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
|
||||
strategy.setEnableANRCrashMonitor(false);
|
||||
strategy.setEnableNativeCrashMonitor(false);
|
||||
strategy.setAppChannel(channel);
|
||||
strategy.setAppVersion(PackageUtils.getVersionName());
|
||||
|
||||
CrashReport.initCrashReport(context, Config.BUGLY_APPID, false, strategy);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// try {
|
||||
// CrashReport.setIsDevelopmentDevice(context, Config.DEFAULT_CHANNEL.equals(channel));
|
||||
//
|
||||
// CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(context);
|
||||
// strategy.setEnableANRCrashMonitor(false);
|
||||
// strategy.setEnableNativeCrashMonitor(false);
|
||||
// strategy.setAppChannel(channel);
|
||||
// strategy.setAppVersion(PackageUtils.getVersionName());
|
||||
//
|
||||
// CrashReport.initCrashReport(context, Config.BUGLY_APPID, false, strategy);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -121,7 +113,7 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void getGid() {
|
||||
GidHelper.getInstance().registerDevice(new GidCallback() {
|
||||
GidHelper.getInstance().registerDevice(HaloApp.getInstance().getApplication(), new GidCallback() {
|
||||
@Override
|
||||
public void onSuccess(String gid) {
|
||||
Utils.log("Gid", gid);
|
||||
@ -141,26 +133,23 @@ public class DataUtils {
|
||||
|
||||
@Override
|
||||
public void onFailure(String s) {
|
||||
Utils.log(s);
|
||||
MtaHelper.onEventWithBasicDeviceInfo("开发辅助", "GID 获取异常", s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2) {
|
||||
TCAgent.onEvent(var0, var1, var2);
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty(var1, var2);
|
||||
StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
// StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
public static void onPause(Activity var0) {
|
||||
TCAgent.onPageEnd(var0, var0.getClass().getSimpleName());
|
||||
StatService.onPause(var0);
|
||||
// StatService.onPause(var0);
|
||||
}
|
||||
|
||||
public static void onResume(Activity var0) {
|
||||
TCAgent.onPageStart(var0, var0.getClass().getSimpleName());
|
||||
StatService.onResume(var0);
|
||||
// StatService.onResume(var0);
|
||||
}
|
||||
|
||||
// 游戏启动
|
||||
@ -172,13 +161,12 @@ public class DataUtils {
|
||||
}
|
||||
|
||||
public static void onEvent(Context var0, String var1, String var2, Map<String, Object> var3) {
|
||||
TCAgent.onEvent(var0, var1, var2, var3);
|
||||
Properties prop = new Properties();
|
||||
prop.setProperty("label", var2);
|
||||
for (String key : var3.keySet()) {
|
||||
prop.setProperty(key, var3.get(key) + "");
|
||||
}
|
||||
StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
// StatService.trackCustomKVEvent(var0, var1, prop);
|
||||
}
|
||||
|
||||
public static void trackTimeEvent(Context context, String eventId, int costTime, String... kv) {
|
||||
@ -196,7 +184,7 @@ public class DataUtils {
|
||||
|
||||
if (prop.size() == 0) return;
|
||||
|
||||
StatService.trackCustomKVTimeIntervalEvent(context, costTime, eventId, prop);
|
||||
// StatService.trackCustomKVTimeIntervalEvent(context, costTime, eventId, prop);
|
||||
}
|
||||
|
||||
// 游戏下载
|
||||
@ -244,13 +232,13 @@ public class DataUtils {
|
||||
public static void onError(Context context, Throwable throwable) {
|
||||
//bugly 作为默认处理异常的类库,已经上报了,此处不重复上报
|
||||
try {
|
||||
CrashReport.postCatchedException(throwable);
|
||||
// CrashReport.postCatchedException(throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
//talkingdata
|
||||
try {
|
||||
TCAgent.onError(context, throwable);
|
||||
// TCAgent.onError(context, throwable);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,10 @@ import android.view.View;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.view.DownloadProgressBar;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
|
||||
@ -13,7 +16,6 @@ import com.gh.gamecenter.entity.LinkEntity;
|
||||
import com.gh.gamecenter.entity.PluginLocation;
|
||||
import com.gh.gamecenter.manager.PackagesManager;
|
||||
import com.lightgame.download.DownloadEntity;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
/**
|
||||
* Created by khy on 27/06/17.
|
||||
@ -65,6 +67,9 @@ public class DetailDownloadUtils {
|
||||
if ("dialog".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "查看详情" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE_WITH_HINT);
|
||||
} else if ("updating".equals(viewHolder.gameEntity.getDownloadOffStatus())) {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "更新中" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.UPDATING);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setText(TextUtils.isEmpty(viewHolder.gameEntity.getDownloadOffText()) ? "暂无下载" : viewHolder.gameEntity.getDownloadOffText());
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.NONE);
|
||||
@ -112,8 +117,18 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
|
||||
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:
|
||||
@ -137,13 +152,25 @@ public class DetailDownloadUtils {
|
||||
}
|
||||
break;
|
||||
case done:
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
if (SimulatorGameManager.isSimulatorGame(viewHolder.gameEntity)){
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(viewHolder.context, viewHolder.gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (isInstalled){
|
||||
viewHolder.mDownloadPb.setText(R.string.launch);
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.LAUNCH_OR_OPEN);
|
||||
}else{
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
}
|
||||
}else{
|
||||
viewHolder.mDownloadPb.setText(R.string.install);
|
||||
if (downloadEntity.isPluggable()
|
||||
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_PLUGIN);
|
||||
} else {
|
||||
viewHolder.mDownloadPb.setDownloadType(DownloadProgressBar.DownloadType.INSTALL_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case cancel:
|
||||
case hijack:
|
||||
|
||||
@ -3,12 +3,12 @@ package com.gh.common.util
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import android.preference.PreferenceManager
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.entity.TimeEntity
|
||||
import com.gh.gamecenter.retrofit.Response
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Phone_State
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@ -60,7 +60,7 @@ object DeviceTokenUtils {
|
||||
lunchType = LunchType.FIRST
|
||||
}
|
||||
// 保存deviceId
|
||||
var deviceId = Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application)
|
||||
var deviceId = MetaUtil.getIMEI()
|
||||
if (deviceId.isNullOrEmpty()) {
|
||||
deviceId = Utils.getTime(HaloApp.getInstance().application).toString()
|
||||
}
|
||||
|
||||
@ -6,24 +6,21 @@ import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
import com.halo.assistant.HaloApp;
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.tencent.stat.StatConfig;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Reader;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
@ -44,14 +41,14 @@ public class DeviceUtils {
|
||||
context = context.getApplicationContext();
|
||||
JSONObject object = new JSONObject();
|
||||
object.put("os", "Android");
|
||||
object.put("imei", Util_System_Phone_State.getDeviceId(context));
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("mac", getMac(context));
|
||||
object.put("model", MODEL);
|
||||
object.put("manufacturer", MANUFACTURER);
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("android_sdk", Build.VERSION.SDK_INT);
|
||||
object.put("android_version", android.os.Build.VERSION.RELEASE);
|
||||
object.put("ip", getIPAddress(context));
|
||||
object.put("ip", "");
|
||||
object.put("network", getNetwork(context));
|
||||
return object;
|
||||
}
|
||||
@ -60,10 +57,10 @@ public class DeviceUtils {
|
||||
public static JSONObject getUserDevice(Context context) { // 判断新老用户device数据
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("IMEI", Util_System_Phone_State.getDeviceId(context));
|
||||
object.put("ANDROID_ID", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("IMEI", MetaUtil.getIMEI());
|
||||
object.put("ANDROID_ID", MetaUtil.getAndroidId());
|
||||
object.put("MAC", getMac(context));
|
||||
object.put("MTA_ID", StatConfig.getMid(context));
|
||||
// object.put("MTA_ID", StatConfig.getMid(context));
|
||||
object.put("MANUFACTURER", MANUFACTURER);
|
||||
object.put("MODEL", MODEL);
|
||||
object.put("ANDROID_SDK", Build.VERSION.SDK_INT);
|
||||
@ -76,39 +73,39 @@ public class DeviceUtils {
|
||||
}
|
||||
|
||||
public static String getMac(Context context) {
|
||||
String str = "";
|
||||
String macSerial = "";
|
||||
try {
|
||||
Process pp = Runtime.getRuntime().exec(
|
||||
"cat /sys/class/net/wlan0/address ");
|
||||
InputStreamReader ir = new InputStreamReader(pp.getInputStream());
|
||||
LineNumberReader input = new LineNumberReader(ir);
|
||||
|
||||
while (null != str) {
|
||||
str = input.readLine();
|
||||
if (str != null) {
|
||||
macSerial = str.trim();// 去空格
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if ("".equals(macSerial)) {
|
||||
try {
|
||||
return loadFileAsString("/sys/class/net/eth0/address")
|
||||
.toUpperCase().substring(0, 17);
|
||||
} catch (FileNotFoundException e) {
|
||||
// do nothing
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
if (TextUtils.isEmpty(macSerial)) { // 备用方案
|
||||
macSerial = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).getConnectionInfo().getMacAddress();
|
||||
}
|
||||
return macSerial;
|
||||
// String str = "";
|
||||
// String macSerial = "";
|
||||
// try {
|
||||
// Process pp = Runtime.getRuntime().exec(
|
||||
// "cat /sys/class/net/wlan0/address ");
|
||||
// InputStreamReader ir = new InputStreamReader(pp.getInputStream());
|
||||
// LineNumberReader input = new LineNumberReader(ir);
|
||||
//
|
||||
// while (null != str) {
|
||||
// str = input.readLine();
|
||||
// if (str != null) {
|
||||
// macSerial = str.trim();// 去空格
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception ex) {
|
||||
// ex.printStackTrace();
|
||||
// }
|
||||
// if ("".equals(macSerial)) {
|
||||
// try {
|
||||
// return loadFileAsString("/sys/class/net/eth0/address")
|
||||
// .toUpperCase().substring(0, 17);
|
||||
// } catch (FileNotFoundException e) {
|
||||
// // do nothing
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// if (TextUtils.isEmpty(macSerial)) { // 备用方案
|
||||
// macSerial = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).getConnectionInfo().getMacAddress();
|
||||
// }
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String loadFileAsString(String fileName) throws Exception {
|
||||
@ -222,8 +219,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 +235,11 @@ public class DeviceUtils {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getTelephonySubscriberId(Context context) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// ping domain
|
||||
public static String ping(String domain) {
|
||||
try {
|
||||
@ -266,7 +267,6 @@ public class DeviceUtils {
|
||||
return memInfo.totalMem / (1024 * 1024);
|
||||
}
|
||||
|
||||
|
||||
// 只能获取WiFi的IpAddress
|
||||
public static String getCurrentIpAddress() {
|
||||
String ipAddress = "0.0.0.0";
|
||||
|
||||
@ -8,8 +8,11 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.CountDownTimer;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
@ -24,12 +27,23 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchy;
|
||||
import com.facebook.drawee.view.SimpleDraweeView;
|
||||
import com.gh.common.AppExecutor;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.TrackableDialog;
|
||||
@ -39,31 +53,34 @@ 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.WebActivity;
|
||||
import com.gh.gamecenter.SuggestionActivity;
|
||||
import com.gh.gamecenter.adapter.viewholder.PrivacyPolicyItemViewHolder;
|
||||
import com.gh.gamecenter.databinding.DialogOverseaConfirmationBinding;
|
||||
import com.gh.gamecenter.databinding.ImprintContentItemBinding;
|
||||
import com.gh.gamecenter.databinding.PrivacyItemBinding;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
import com.gh.gamecenter.entity.Badge;
|
||||
import com.gh.gamecenter.entity.BadgeEntity;
|
||||
import com.gh.gamecenter.entity.GameEntity;
|
||||
import com.gh.gamecenter.entity.PrivacyPolicyEntity;
|
||||
import com.gh.gamecenter.entity.SettingsEntity;
|
||||
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 org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class DialogUtils {
|
||||
|
||||
public static Dialog showWaitDialog(Context context, String msg) {
|
||||
@ -80,7 +97,6 @@ public class DialogUtils {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
public static void showInstallHintDialog(Context context, final ConfirmListener cmListener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
@ -322,6 +338,82 @@ public class DialogUtils {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* ios 风格弹窗
|
||||
*
|
||||
* @param context
|
||||
* @param title 标题
|
||||
* @param message 内容
|
||||
* @param negative 取消按钮文本
|
||||
* @param positive 确认按钮文本
|
||||
* @param clListener 取消按钮监听
|
||||
* @param cmListener 确认按钮监听
|
||||
*/
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, TrackableEntity trackableEntity, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
context = checkDialogContext(context);
|
||||
final Dialog dialog;
|
||||
if (trackableEntity != null) {
|
||||
dialog = new TrackableDialog(context,
|
||||
R.style.GhAlertDialog,
|
||||
trackableEntity.getEvent(),
|
||||
trackableEntity.getKey(),
|
||||
trackableEntity.getValue(),
|
||||
trackableEntity.getCancelValue(),
|
||||
trackableEntity.getKeyBackValue(),
|
||||
trackableEntity.getLogShowEvent());
|
||||
} else {
|
||||
dialog = new Dialog(context, R.style.GhAlertDialog);
|
||||
}
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_new_alert, null);
|
||||
|
||||
TextView titleTv = contentView.findViewById(R.id.title);
|
||||
TextView contentTv = contentView.findViewById(R.id.content);
|
||||
TextView cancelBtn = contentView.findViewById(R.id.cancel);
|
||||
TextView confirmBtn = contentView.findViewById(R.id.confirm);
|
||||
View middleLine = contentView.findViewById(R.id.middle_line);
|
||||
|
||||
titleTv.setText(title);
|
||||
contentTv.setText(message);
|
||||
cancelBtn.setText(negative);
|
||||
confirmBtn.setText(positive);
|
||||
if (negative.isEmpty()) {
|
||||
cancelBtn.setVisibility(View.GONE);
|
||||
middleLine.setVisibility(View.GONE);
|
||||
confirmBtn.setTextColor(ContextCompat.getColor(context, R.color.text_333333));
|
||||
}
|
||||
if (positive.isEmpty()) {
|
||||
confirmBtn.setVisibility(View.GONE);
|
||||
middleLine.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
cancelBtn.setOnClickListener(v -> {
|
||||
if (clListener != null) clListener.onCancel();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
confirmBtn.setOnClickListener(v -> {
|
||||
if (cmListener != null) cmListener.onConfirm();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
}
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public static Dialog showNewAlertDialog(Context context, String title, CharSequence message
|
||||
, String negative, String positive, final CancelListener clListener, final ConfirmListener cmListener) {
|
||||
return showNewAlertDialog(context, title, message, negative, positive, null, clListener, cmListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Material Design 风格弹窗
|
||||
*
|
||||
@ -539,8 +631,6 @@ public class DialogUtils {
|
||||
clListener.onCancel();
|
||||
});
|
||||
dialog.show();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -584,7 +674,6 @@ public class DialogUtils {
|
||||
dialog.setContentView(contentView);
|
||||
dialog.setCancelable(false);
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -665,7 +754,6 @@ public class DialogUtils {
|
||||
TextPaint tp = mesage.getPaint();
|
||||
tp.setFakeBoldText(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void showSignDialog(Context context, String title, CharSequence message, CharSequence message2
|
||||
@ -899,7 +987,7 @@ public class DialogUtils {
|
||||
params.horizontalMargin = 0;
|
||||
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40);
|
||||
int height = context.getResources().getDisplayMetrics().heightPixels - DisplayUtils.dip2px(120);
|
||||
int maxHeight = DisplayUtils.dip2px(546);
|
||||
int maxHeight = DisplayUtils.dip2px(446);
|
||||
if (height > maxHeight) {
|
||||
params.height = maxHeight;
|
||||
} else {
|
||||
@ -935,8 +1023,10 @@ public class DialogUtils {
|
||||
if (hierarchy != null) {
|
||||
if (position == 0) {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_storage);
|
||||
} else {
|
||||
} else if (position == 1) {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_phone_state);
|
||||
} else {
|
||||
hierarchy.setPlaceholderImage(R.drawable.permission_sdk);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -959,9 +1049,8 @@ public class DialogUtils {
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击隐私政策");
|
||||
Intent intent = WebActivity.getPrivacyPolicyIntent(activityContext);
|
||||
activityContext.startActivity(intent);
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击隐私政策");
|
||||
DirectUtils.directToExternalBrowser(context, context.getString(R.string.privacy_policy_url));
|
||||
}
|
||||
}, skipText.length() - 9, skipText.length() - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
@ -975,11 +1064,26 @@ public class DialogUtils {
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击用户协议");
|
||||
activityContext.startActivity(WebActivity.getWebIntent(activityContext));
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击用户协议");
|
||||
DirectUtils.directToExternalBrowser(context, context.getString(R.string.disclaimer_url));
|
||||
}
|
||||
}, skipText.length() - 4, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
/*skipText.setSpan(new ClickableSpan() {
|
||||
@Override
|
||||
public void updateDrawState(@NonNull TextPaint ds) {
|
||||
super.updateDrawState(ds);
|
||||
ds.setColor(ContextCompat.getColor(activityContext, R.color.theme_font));
|
||||
ds.setUnderlineText(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击第三方SDK接入说明");
|
||||
activityContext.startActivity(WebActivity.getThirdPartySdkStatementIntent(activityContext));
|
||||
}
|
||||
}, skipText.length() - 10, skipText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);*/
|
||||
|
||||
title.setText(entity.getTitle());
|
||||
linkContent.setText(skipText);
|
||||
linkContent.setMovementMethod(new LinkMovementMethod());
|
||||
@ -989,30 +1093,30 @@ public class DialogUtils {
|
||||
allowButton.setOnClickListener(view -> {
|
||||
dialog.dismiss();
|
||||
callback.onCallback();
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击同意");
|
||||
});
|
||||
|
||||
disallowButton.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
showPrivacyPolicyDisallowDialog(activityContext, entity, callback);
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "不同意并退出App");
|
||||
});
|
||||
|
||||
dialog.setOnCancelListener(cd -> {
|
||||
if (isCanceledByClickOutsideOfDialog.get()) {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击空白");
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setOnKeyListener((dialog1, keyCode, event) -> {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
|
||||
isCanceledByClickOutsideOfDialog.set(false);
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "点击返回");
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
|
||||
// 用户未同意隐私策略不应该触发 MTA 事件
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "隐私政策弹窗", "出现弹窗");
|
||||
|
||||
try {
|
||||
dialog.setCancelable(false);
|
||||
@ -1033,14 +1137,16 @@ public class DialogUtils {
|
||||
View reviewButton = contentView.findViewById(R.id.review_button);
|
||||
|
||||
backButton.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "退出应用");
|
||||
// 用户未同意隐私策略不应该触发 MTA 事件
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "退出应用");
|
||||
dialog.dismiss();
|
||||
AppManager.getInstance().appExit(activityContext);
|
||||
});
|
||||
reviewButton.setOnClickListener(v -> {
|
||||
MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "再次查看");
|
||||
// MtaHelper.onEvent("隐私政策弹窗", "退出提示弹窗", "再次查看");
|
||||
callback.onCallback();
|
||||
dialog.dismiss();
|
||||
showPrivacyPolicyDialog(activityContext, entity, callback);
|
||||
//showPrivacyPolicyDialog(activityContext, entity, callback);
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
@ -1099,6 +1205,21 @@ 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,
|
||||
@ -1110,7 +1231,17 @@ public class DialogUtils {
|
||||
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);
|
||||
@ -1265,6 +1396,45 @@ public class DialogUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// 海外下载地址弹窗
|
||||
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);
|
||||
@ -1341,6 +1511,41 @@ public class DialogUtils {
|
||||
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);
|
||||
|
||||
@ -1368,6 +1573,335 @@ public class DialogUtils {
|
||||
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 showVideoComplaintDialog(Context context,
|
||||
List<String> options,
|
||||
List<String> disabledOptions,
|
||||
OptionCallback callback) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
Dialog dialog = new Dialog(context);
|
||||
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.dialog_video_complaint, null, false);
|
||||
LinearLayout complaintContainer = view.findViewById(R.id.complaintContainer);
|
||||
ConstraintLayout otherComplaintContainer = view.findViewById(R.id.otherComplaintContainer);
|
||||
EditText complaintCommentEt = view.findViewById(R.id.complaintCommentEt);
|
||||
TextView backTv = view.findViewById(R.id.backTv);
|
||||
TextView commitTv = view.findViewById(R.id.commitTv);
|
||||
Context finalContext = context;
|
||||
//添加透明阴影,实现类似 clipPadding=false 效果
|
||||
complaintCommentEt.setShadowLayer(complaintCommentEt.getExtendedPaddingBottom(), 0f, 0f, Color.TRANSPARENT);
|
||||
|
||||
ExtensionsKt.setTextChangedListener(complaintCommentEt, (s, start, before, count) -> {
|
||||
commitTv.setTextColor(ContextCompat.getColor(finalContext, s.toString().trim().isEmpty() ? R.color.text_999999 : R.color.theme_font));
|
||||
return null;
|
||||
});
|
||||
|
||||
for (String option : options) {
|
||||
TextView reportTv = new TextView(context);
|
||||
reportTv.setText(option);
|
||||
reportTv.setTextSize(16f);
|
||||
if (disabledOptions != null && disabledOptions.contains(option)) {
|
||||
reportTv.setTextColor(ContextCompat.getColor(context, R.color.btn_gray));
|
||||
} else {
|
||||
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
|
||||
reportTv.setBackgroundResource(R.drawable.textview_white_style);
|
||||
}
|
||||
reportTv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
reportTv.setPadding(DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 17f),
|
||||
DisplayUtils.dip2px(context, 20f), DisplayUtils.dip2px(context, 17f));
|
||||
if (option.equals("其它")) {
|
||||
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_complaint_arrow_right);
|
||||
drawable.setBounds(0, 0, DisplayUtils.dip2px(6f), DisplayUtils.dip2px(10f));
|
||||
reportTv.setCompoundDrawables(null, null, drawable, null);
|
||||
}
|
||||
complaintContainer.addView(reportTv);
|
||||
|
||||
reportTv.setOnClickListener(v -> {
|
||||
if (option.equals("其它")) {
|
||||
complaintContainer.setVisibility(View.GONE);
|
||||
otherComplaintContainer.setVisibility(View.VISIBLE);
|
||||
complaintCommentEt.requestFocus();
|
||||
Util_System_Keyboard.showSoftKeyboard(finalContext, complaintCommentEt);
|
||||
} else {
|
||||
dialog.cancel();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("reason", reportTv.getText().toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
callback.onClicked(jsonObject.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
backTv.setOnClickListener(v -> {
|
||||
Util_System_Keyboard.hideSoftKeyboard(finalContext, complaintCommentEt);
|
||||
complaintContainer.setVisibility(View.VISIBLE);
|
||||
otherComplaintContainer.setVisibility(View.GONE);
|
||||
});
|
||||
commitTv.setOnClickListener(v -> {
|
||||
if (complaintCommentEt.getText().toString().isEmpty()) {
|
||||
ToastUtils.INSTANCE.showToast("请先输入说明~");
|
||||
return;
|
||||
}
|
||||
dialog.cancel();
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("reason", "其它");
|
||||
jsonObject.put("description", complaintCommentEt.getText().toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
callback.onClicked(jsonObject.toString());
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(view);
|
||||
dialog.show();
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.width = context.getResources().getDisplayMetrics().widthPixels - DisplayUtils.dip2px(40f);
|
||||
window.setAttributes(params);
|
||||
}
|
||||
}
|
||||
|
||||
public static void showViewBadgeDialog(Context context, Badge badge, ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_view_badge, null);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
|
||||
ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);
|
||||
|
||||
ImageUtils.display(badgeView, badge.getIcon());
|
||||
titleTv.setText(badge.getName());
|
||||
|
||||
// 领取条件文本超过一行就不显示
|
||||
if (badge.getActions() == null || badge.getActions().isEmpty() || badge.getActions().size() > 1) {
|
||||
contentTv.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
contentTv.setText(badge.getActions().get(0).getText());
|
||||
contentTv.post(() -> {
|
||||
if (contentTv.getLineCount() > 1) contentTv.setVisibility(View.INVISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
Animation animation = AnimationUtils.loadAnimation(context, R.anim.anim_badge_light_bg);
|
||||
badgeLightBg.startAnimation(animation);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
badgeLightBg.clearAnimation();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showReceiveBadgeDialog(Context context, BadgeEntity badge, ConfirmListener listener) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_receive_badge, null);
|
||||
TextView titleTv = contentView.findViewById(R.id.dialog_title);
|
||||
TextView contentTv = contentView.findViewById(R.id.dialog_content);
|
||||
SimpleDraweeView badgeView = contentView.findViewById(R.id.dialog_badge);
|
||||
ImageView badgeLightBg = contentView.findViewById(R.id.dialog_badge_light_bg);
|
||||
TextView receiveTv = contentView.findViewById(R.id.dialog_ok);
|
||||
|
||||
ImageUtils.display(badgeView, badge.getIcon());
|
||||
titleTv.setText(badge.getName());
|
||||
|
||||
// 领取条件文本超过一行就不显示
|
||||
if (badge.getActions() == null || badge.getActions().isEmpty() || badge.getActions().size() > 1) {
|
||||
contentTv.setVisibility(View.INVISIBLE);
|
||||
} else {
|
||||
contentTv.setText(badge.getActions().get(0).getText());
|
||||
contentTv.post(() -> {
|
||||
if (contentTv.getLineCount() > 1) contentTv.setVisibility(View.INVISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
if ("self".equals(badge.getReceive().getType())) {
|
||||
receiveTv.setText(R.string.receive_badge);
|
||||
} else {
|
||||
receiveTv.setText(R.string.apply_badge);
|
||||
}
|
||||
|
||||
Animation animation = AnimationUtils.loadAnimation(context, R.anim.anim_badge_light_bg);
|
||||
badgeLightBg.startAnimation(animation);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
listener.onConfirm();
|
||||
badgeLightBg.clearAnimation();
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showPassRegulationDialog(Context context, String icon) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_pass_regulation, null);
|
||||
SimpleDraweeView userIcon = contentView.findViewById(R.id.dialog_icon);
|
||||
|
||||
ImageUtils.display(userIcon, icon);
|
||||
|
||||
contentView.findViewById(R.id.dialog_ok).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public static void showShortCutPermissionDialog(Context context) {
|
||||
context = checkDialogContext(context);
|
||||
|
||||
final Dialog dialog = new Dialog(context, R.style.DialogWindowTransparent);
|
||||
|
||||
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_shortcut_permission, null);
|
||||
|
||||
Context finalContext = context;
|
||||
contentView.findViewById(R.id.dialog_positive).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||
intent.setData(Uri.parse("package:" + finalContext.getPackageName()));
|
||||
finalContext.startActivity(intent);
|
||||
});
|
||||
|
||||
contentView.findViewById(R.id.dialog_negative).setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(contentView);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context may be is application context
|
||||
* @return activity context
|
||||
|
||||
@ -8,10 +8,12 @@ import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.base.BaseActivity_TabLayout
|
||||
import com.gh.base.ToolBarActivity
|
||||
import com.gh.base.fragment.BaseFragment_TabLayout
|
||||
import com.gh.common.AppExecutor
|
||||
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
|
||||
@ -25,10 +27,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
|
||||
@ -39,17 +45,27 @@ 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
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* 跳转用的方法
|
||||
@ -86,9 +102,6 @@ object DirectUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到特定页面,只支持App内部跳转
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToLinkPage(context: Context, linkEntity: LinkEntity, entrance: String, path: String) {
|
||||
directToLinkPage(context, linkEntity, entrance, path, null)
|
||||
@ -153,7 +166,10 @@ object DirectUtils {
|
||||
|
||||
"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", "社区文章" -> directToCommunityArticle(context, linkEntity.community!!, linkEntity.link!!, entrance, path)
|
||||
|
||||
@ -185,11 +201,14 @@ object DirectUtils {
|
||||
"category", "分类" -> directCategoryDirectory(context, linkEntity.link!!, linkEntity.text!!)
|
||||
|
||||
"block", "版块" -> {
|
||||
directToBlock(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)
|
||||
@ -224,6 +243,8 @@ object DirectUtils {
|
||||
|
||||
"game_upload", "游戏投稿" -> directGameUpload(context, entrance, path)
|
||||
|
||||
"bbs_detail" -> directForumDetail(context, linkEntity.link ?: "", entrance)
|
||||
|
||||
//"h5_game_center" -> directLetoGameCenter(context)
|
||||
|
||||
"" -> {
|
||||
@ -243,8 +264,8 @@ object DirectUtils {
|
||||
* 跳转至QA
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToQa(context: Context, text: String, id: String) {
|
||||
// context.startActivity(QaActivity.getIntent(context, navigationTitle = text, qaId = id))
|
||||
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)
|
||||
@ -257,7 +278,7 @@ object DirectUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToQaCollection(context: Context, text: String, id: String) {
|
||||
// context.startActivity(QaActivity.getIntent(context, navigationTitle = text, qaCollectionId = id))
|
||||
if (id.isEmpty()) return
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, QaActivity::class.java.simpleName)
|
||||
bundle.putString(KEY_NAVIGATION_TITLE, text)
|
||||
@ -270,13 +291,52 @@ object DirectUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToColumnCollection(context: Context, id: String, position: Int = -1, entrance: String, columnName: String = "") {
|
||||
// context.startActivity(ColumnCollectionDetailActivity.getIntent(context, id, position, entrance, columnName))
|
||||
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)
|
||||
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)
|
||||
}
|
||||
|
||||
@ -285,6 +345,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)
|
||||
@ -327,14 +388,19 @@ object DirectUtils {
|
||||
* 跳转到游戏详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToGameDetail(context: Context, id: String, entrance: String? = null, autoDownload: Boolean? = null, scrollToLibao: Boolean = false, traceEvent: ExposureEvent? = null) {
|
||||
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)
|
||||
@ -345,6 +411,19 @@ object DirectUtils {
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转视频流-游戏介绍进入
|
||||
*/
|
||||
@ -356,7 +435,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)
|
||||
}
|
||||
|
||||
@ -368,6 +456,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)
|
||||
@ -444,6 +533,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)
|
||||
@ -454,6 +544,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)
|
||||
@ -464,6 +555,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)
|
||||
@ -482,8 +574,9 @@ 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){
|
||||
if (context !is AppCompatActivity) {
|
||||
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(browserIntent)
|
||||
@ -507,7 +600,7 @@ object DirectUtils {
|
||||
}
|
||||
val str = "mqqwpa://im/chat?chat_type=$chatType&uin=$qq&version=1&src_type=web"
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(str))
|
||||
if (context !is AppCompatActivity){
|
||||
if (context !is AppCompatActivity) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
@ -521,12 +614,13 @@ object DirectUtils {
|
||||
// 跳转 QQ 群
|
||||
@JvmStatic
|
||||
fun directToQqGroup(context: Context, groupNumber: String? = null): Boolean {
|
||||
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){
|
||||
if (context !is AppCompatActivity) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
context.startActivity(intent)
|
||||
@ -534,7 +628,7 @@ object DirectUtils {
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
Utils.toast(context, "请安装QQ客户端")
|
||||
return false
|
||||
}
|
||||
@ -546,10 +640,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)
|
||||
}
|
||||
|
||||
@ -600,6 +696,7 @@ object DirectUtils {
|
||||
|
||||
@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)
|
||||
@ -614,6 +711,7 @@ object DirectUtils {
|
||||
*/
|
||||
@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)
|
||||
@ -627,7 +725,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)
|
||||
@ -640,6 +739,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)
|
||||
@ -670,27 +772,66 @@ object DirectUtils {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBadgeWall(context: Context, userId: String?, name: String?, icon: String?) {
|
||||
context.startActivity(WebActivity.getBadgeCenterIntent(context, userId, name, icon))
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.BADGE_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.BADGE_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s?user_id=%s&name=%s&icon=%s×tamp=%d", url, userId, name, URLEncoder.encode(icon), (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至徽章详情
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBadgeDetail(context: Context, userId: String?, badgeId: String?) {
|
||||
var url: String = if ("internal" == BuildConfig.FLAVOR) {
|
||||
Constants.BADGE_DETAIL_ADDRESS_DEV
|
||||
} else {
|
||||
Constants.BADGE_DETAIL_ADDRESS
|
||||
}
|
||||
|
||||
url = String.format(Locale.CHINA, "%s?user_id=%s&badge_id=%s×tamp=%d", url, userId, badgeId, (Date().time / 1000 / 1000.toFloat()).roundToInt())
|
||||
directToFullScreenWebPage(context, url, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至上传视频
|
||||
*/
|
||||
@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)
|
||||
@ -738,6 +879,7 @@ object DirectUtils {
|
||||
*/
|
||||
@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)
|
||||
@ -766,6 +908,7 @@ object DirectUtils {
|
||||
*/
|
||||
@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)
|
||||
@ -779,10 +922,11 @@ object DirectUtils {
|
||||
* 跳转到板块
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToBlock(context: Context, blockData: SubjectRecommendEntity) {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -814,6 +958,7 @@ object DirectUtils {
|
||||
*/
|
||||
@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)
|
||||
@ -821,4 +966,81 @@ object DirectUtils {
|
||||
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) })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转至使用帮助与反馈
|
||||
* @param position 使用帮助:[HelpAndFeedbackActivity.HELP_ITEM],意见反馈:[HelpAndFeedbackActivity.SUGGESTION_ITEM]
|
||||
*/
|
||||
@JvmStatic
|
||||
fun directToHelpAndFeedback(context: Context, position: Int = HelpAndFeedbackActivity.HELP_ITEM) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_TO, HelpAndFeedbackActivity::class.java.name)
|
||||
bundle.putInt(BaseActivity_TabLayout.PAGE_INDEX, position)
|
||||
jumpActivity(context, bundle)
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -272,13 +273,23 @@ public class DisplayUtils {
|
||||
}
|
||||
|
||||
public static int getToastOffset() {
|
||||
int i = Resources.getSystem().getIdentifier("toast_y_offset", "dimen", "android");
|
||||
return HaloApp.getInstance().getApplication().getResources().getDimensionPixelSize(i);
|
||||
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() {
|
||||
int i = Resources.getSystem().getIdentifier("config_toastDefaultGravity", "integer", "android");
|
||||
return HaloApp.getInstance().getApplication().getResources().getInteger(i);
|
||||
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) {
|
||||
|
||||
@ -8,12 +8,6 @@ import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.collection.ArrayMap;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.dialog.CertificationDialog;
|
||||
import com.gh.common.dialog.DeviceRemindDialog;
|
||||
@ -21,6 +15,10 @@ import com.gh.common.dialog.ReserveDialogFragment;
|
||||
import com.gh.common.exposure.ExposureEvent;
|
||||
import com.gh.common.history.HistoryHelper;
|
||||
import com.gh.common.repository.ReservationRepository;
|
||||
import com.gh.common.simulator.SimulatorDownloadManager;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.common.xapk.XapkInstaller;
|
||||
import com.gh.common.xapk.XapkUnzipStatus;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.download.dialog.DownloadDialog;
|
||||
import com.gh.gamecenter.DownloadManagerActivity;
|
||||
@ -38,8 +36,15 @@ import com.lightgame.download.DownloadStatus;
|
||||
import com.lightgame.download.FileUtils;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.collection.ArrayMap;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* todo 下载判断不能以按钮文案为判断条件,否则按钮文案修改时又要修改判断逻辑
|
||||
*/
|
||||
@ -193,6 +198,10 @@ public class DownloadItemUtils {
|
||||
holder.gameDownloadBtn.setText("查看");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.game_item_btn_download_style);
|
||||
} else if ("updating".equals(offStatus)) {
|
||||
holder.gameDownloadBtn.setText("更新中");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.white));
|
||||
holder.gameDownloadBtn.setBackgroundResource(R.drawable.download_button_updating_style);
|
||||
} else {
|
||||
holder.gameDownloadBtn.setText("暂无");
|
||||
holder.gameDownloadBtn.setTextColor(ContextCompat.getColor(context, R.color.button_gray));
|
||||
@ -221,9 +230,18 @@ public class DownloadItemUtils {
|
||||
if (entryMap != null && !entryMap.isEmpty()) {
|
||||
DownloadEntity downloadEntity = entryMap.get(apkEntity.getPlatform());
|
||||
if (downloadEntity != null) {
|
||||
// 更改进度条和提示文本的状态
|
||||
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
|
||||
return;
|
||||
if (ExtensionsKt.isSimulatorGame(downloadEntity)) {
|
||||
if (downloadEntity.getStatus() != DownloadStatus.done) {
|
||||
// 更改进度条和提示文本的状态
|
||||
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// 更改进度条和提示文本的状态
|
||||
changeStatus(context, holder, downloadEntity, isShowPlatform, true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +279,7 @@ public class DownloadItemUtils {
|
||||
boolean isShowPlatform, boolean isNormal) {
|
||||
|
||||
updateItemViewStatus(holder, true, null);
|
||||
holder.gameProgressbar.setProgressDrawable(context.getResources().getDrawable(R.drawable.progressbar_bg_style));
|
||||
|
||||
String platform = PlatformUtils.getInstance(context).getPlatformName(downloadEntity.getPlatform());
|
||||
|
||||
@ -321,6 +340,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));
|
||||
@ -454,7 +484,7 @@ public class DownloadItemUtils {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay);
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton());
|
||||
context.startActivity(i);
|
||||
});
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
@ -492,7 +522,115 @@ public class DownloadItemUtils {
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clickCallback 供那些需要知道点击回调的地方使用,只要触发了点击事件就响应回调(未登录状态下点击预约也要响应回调)
|
||||
*/
|
||||
public static void setOnClickListenerWithInvokeCallbackForAllState(final Context context,
|
||||
final TextView downloadBtn,
|
||||
final GameEntity gameEntity,
|
||||
final int position,
|
||||
final RecyclerView.Adapter<? extends RecyclerView.ViewHolder> adapter,
|
||||
final String entrance,
|
||||
final String location,
|
||||
final ExposureEvent traceEvent,
|
||||
@Nullable final EmptyCallback clickCallback) {
|
||||
|
||||
if (gameEntity.isReservable()) {
|
||||
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.getId())) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
CheckLoginUtils.checkLogin(context, entrance, () -> {
|
||||
PermissionHelper.checkReadPhoneStatePermissionBeforeAction(context, () -> {
|
||||
ReserveDialogFragment dialogFragment = ReserveDialogFragment.getInstance(
|
||||
gameEntity,
|
||||
() -> {
|
||||
LogUtils.logReservation(gameEntity, traceEvent);
|
||||
adapter.notifyItemChanged(position);
|
||||
}
|
||||
);
|
||||
dialogFragment.show(((AppCompatActivity) context).getSupportFragmentManager(), "reserve");
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
if ("download".equals(gameEntity.getReserveStatus())) {
|
||||
ReservationHelper.showDeleteReservationDialog(context, () -> {
|
||||
ReservationHelper.deleteReservation(gameEntity, () -> {
|
||||
adapter.notifyItemChanged(position);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ReservationHelper.showCancelReservationDialog(context, () -> {
|
||||
ReservationHelper.cancelReservation(gameEntity, () -> {
|
||||
adapter.notifyItemChanged(position);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (gameEntity.getApk().size() == 0 && gameEntity.getH5Link() != null) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.getName());
|
||||
|
||||
LinkEntity linkEntity = gameEntity.getH5Link();
|
||||
|
||||
boolean isPlay = "play".equals(linkEntity.getType()); // 是否为开始玩
|
||||
if (isPlay) {
|
||||
HistoryHelper.insertGameEntity(gameEntity);
|
||||
}
|
||||
|
||||
Intent i = WebActivity.getIntentForWebGame(context, gameEntity.getH5Link().getLink(), gameEntity.getName(), isPlay, linkEntity.getCloseButton());
|
||||
context.startActivity(i);
|
||||
});
|
||||
} else if (gameEntity.getApk().size() == 1) {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
EmptyCallback clickRunnable = () -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
onNormalClick(context, downloadBtn, gameEntity, position, adapter, entrance, location, traceEvent);
|
||||
};
|
||||
|
||||
// 启动不需要请求存储权限
|
||||
if (downloadBtn.getText().toString().equals(context.getString(R.string.launch))) {
|
||||
clickRunnable.onCallback();
|
||||
} else {
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(context, clickRunnable);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
downloadBtn.setOnClickListener(v -> {
|
||||
if (clickCallback != null) {
|
||||
clickCallback.onCallback();
|
||||
}
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(context, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DownloadDialog.showDownloadDialog(
|
||||
v.getContext(),
|
||||
gameEntity,
|
||||
traceEvent,
|
||||
entrance,
|
||||
location);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void onNormalClick(final Context context,
|
||||
@ -520,18 +658,23 @@ public class DownloadItemUtils {
|
||||
// 先弹下载弹窗(如果需要的话)
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
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.attempt))) {
|
||||
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, () -> {
|
||||
CertificationDialog.showCertificationDialog(context, gameEntity, () -> {
|
||||
DialogUtils.showVersionNumberDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
DialogUtils.showOverseaDownloadDialog(context, gameEntity, () -> {
|
||||
DialogUtils.checkDownload(context, apk.getSize(),
|
||||
isSubscribe -> download(context, gameEntity, downloadBtn, entrance, location, isSubscribe, traceEvent));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -552,17 +695,35 @@ public class DownloadItemUtils {
|
||||
});
|
||||
}
|
||||
} else if (str.equals(context.getString(R.string.install))) {
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apk.getUrl());
|
||||
if (gameEntity.getSimulator() != null) {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (downloadEntity != null && SimulatorGameManager.isSimulatorGame(gameEntity) && !isInstalled) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(context, gameEntity.getSimulator(),
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.getId(), gameEntity.getName(),null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
install(context, gameEntity, position, adapter);
|
||||
} else if (str.equals(context.getString(R.string.launch))) {
|
||||
//启动模拟器游戏
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
|
||||
if (downloadEntity != null) {
|
||||
File file = new File(downloadEntity.getPath());
|
||||
if (!file.exists()) {
|
||||
download(context, gameEntity, downloadBtn, entrance, location, false, traceEvent);
|
||||
return;
|
||||
}
|
||||
SimulatorGameManager.launchSimulatorGame(downloadEntity, gameEntity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (entrance.contains("我的游戏")) {
|
||||
MtaHelper.onEvent("我的游戏_启动", "启动", gameEntity.getName());
|
||||
}
|
||||
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());
|
||||
@ -571,6 +732,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] + ")"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,9 +795,9 @@ public class DownloadItemUtils {
|
||||
}
|
||||
adapter.notifyItemChanged(position);
|
||||
} else if (PackageUtils.isCanPluggable(apkEntity)) {
|
||||
DialogUtils.showPluginDialog(context, () -> context.startActivity(PackageUtils.getUninstallIntent(context, path)));
|
||||
DialogUtils.showPluginDialog(context, () -> PackageInstaller.uninstall(context, path));
|
||||
} else {
|
||||
PackageUtils.launchSetup(context, downloadEntity);
|
||||
PackageInstaller.install(context, downloadEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,10 +10,13 @@ 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
|
||||
import com.lightgame.download.DownloadStatus
|
||||
import com.walkud.rom.checker.RomIdentifier
|
||||
|
||||
object DownloadNotificationHelper {
|
||||
|
||||
@ -27,6 +30,7 @@ object DownloadNotificationHelper {
|
||||
const val ACTION_DOWNLOAD = "com.gh.gamecenter.DOWNLOAD"
|
||||
|
||||
private val mNotifyMap: MutableMap<String, Long> = mutableMapOf()
|
||||
private val mShouldUseAlternativeNotificationIcon by lazy { RomIdentifier.getRom().versionName == null }
|
||||
|
||||
private fun getNotificationManager(): NotificationManager {
|
||||
return HaloApp.getInstance().application.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
@ -38,9 +42,13 @@ 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
|
||||
if (entity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) == Constants.SIMULATOR_DOWNLOAD) 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 +61,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)
|
||||
}
|
||||
@ -61,22 +68,26 @@ object DownloadNotificationHelper {
|
||||
val whenTime = 1000 * 60 * (System.currentTimeMillis() / 1000 / 60)
|
||||
val builder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
|
||||
.setContentTitle(entity.name)
|
||||
.setSmallIcon(R.mipmap.logo)
|
||||
.setSmallIcon(getNotificationIcon())
|
||||
.setContentIntent(pendingIntent)
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setWhen(whenTime)
|
||||
.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 {
|
||||
@ -91,6 +102,11 @@ object DownloadNotificationHelper {
|
||||
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 {
|
||||
notification.flags = notification.flags or Notification.FLAG_NO_CLEAR
|
||||
}
|
||||
|
||||
if (entity.status == DownloadStatus.delete
|
||||
|| entity.status == DownloadStatus.cancel
|
||||
@ -98,7 +114,9 @@ object DownloadNotificationHelper {
|
||||
|| entity.status == DownloadStatus.notfound
|
||||
|| entity.status == DownloadStatus.overflow
|
||||
|| (entity.status == DownloadStatus.done // 触发安装事件以后也 cancel 掉通知
|
||||
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty())) {
|
||||
&& !entity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION].isNullOrEmpty()
|
||||
&& xapkStatus != XapkUnzipStatus.FAILURE.name)
|
||||
||entity.status == DownloadStatus.done && entity.isSimulatorGame()) {//模拟器游戏下载完需要cancel掉通知
|
||||
requireUpdateNotificationGroupDelay = true
|
||||
notificationManager.cancel(entity.path, DOWNLOAD_NOTIFICATION_ID)
|
||||
} else {
|
||||
@ -125,32 +143,35 @@ object DownloadNotificationHelper {
|
||||
}
|
||||
|
||||
private fun updateNotificationGroup() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val notificationManager = getNotificationManager()
|
||||
val activeNotifications = notificationManager.activeNotifications
|
||||
var downloadNotificationSize = 0
|
||||
var downloadGroupNotificationSize = 0
|
||||
for (activeNotification in activeNotifications) {
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_ID) {
|
||||
downloadNotificationSize++
|
||||
// 部分华为设备调用 getActiveNotifications() 方法时会触发方法内的空指针,这里整体包裹处理了
|
||||
tryCatchInRelease {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
val notificationManager = getNotificationManager()
|
||||
val activeNotifications = notificationManager.activeNotifications
|
||||
var downloadNotificationSize = 0
|
||||
var downloadGroupNotificationSize = 0
|
||||
for (activeNotification in activeNotifications) {
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_ID) {
|
||||
downloadNotificationSize++
|
||||
}
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_FOLD_ID) {
|
||||
downloadGroupNotificationSize++
|
||||
}
|
||||
}
|
||||
if (activeNotification.id == DOWNLOAD_NOTIFICATION_FOLD_ID) {
|
||||
downloadGroupNotificationSize++
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadNotificationSize == 0 && downloadGroupNotificationSize != 0) {
|
||||
// 删除组可能会把组内所有通知一并删除
|
||||
notificationManager.cancel(DOWNLOAD_NOTIFICATION_FOLD_ID)
|
||||
} else if (downloadNotificationSize != 0 && downloadGroupNotificationSize == 0) {
|
||||
val groupBuilder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
|
||||
.setSmallIcon(R.mipmap.logo)
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setGroupSummary(true)
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText("下载任务"))
|
||||
val groupNotification = groupBuilder.build()
|
||||
groupNotification.flags = groupNotification.flags or Notification.FLAG_NO_CLEAR
|
||||
notificationManager.notify(DOWNLOAD_NOTIFICATION_FOLD_ID, groupNotification)
|
||||
if (downloadNotificationSize == 0 && downloadGroupNotificationSize != 0) {
|
||||
// 删除组可能会把组内所有通知一并删除
|
||||
notificationManager.cancel(DOWNLOAD_NOTIFICATION_FOLD_ID)
|
||||
} else if (downloadNotificationSize != 0 && downloadGroupNotificationSize == 0) {
|
||||
val groupBuilder = NotificationCompat.Builder(HaloApp.getInstance().application, DOWNLOAD_CHANNEL_ID)
|
||||
.setSmallIcon(getNotificationIcon())
|
||||
.setGroup(DOWNLOAD_GROUP_KEY)
|
||||
.setGroupSummary(true)
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText("下载任务"))
|
||||
val groupNotification = groupBuilder.build()
|
||||
groupNotification.flags = groupNotification.flags or Notification.FLAG_NO_CLEAR
|
||||
notificationManager.notify(DOWNLOAD_NOTIFICATION_FOLD_ID, groupNotification)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,4 +182,8 @@ object DownloadNotificationHelper {
|
||||
addOrUpdateDownloadNotification(downloadTask)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNotificationIcon(): Int {
|
||||
return if (mShouldUseAlternativeNotificationIcon) R.drawable.ic_notification else R.mipmap.logo
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,11 @@ import android.preference.PreferenceManager
|
||||
import com.gh.base.BaseActivity
|
||||
import com.gh.common.constant.Constants
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.simulator.SimulatorDownloadManager
|
||||
import com.gh.common.simulator.SimulatorGameManager
|
||||
import com.gh.common.exposure.meta.MetaUtil
|
||||
import com.gh.common.xapk.XapkInstaller
|
||||
import com.gh.download.DownloadDataHelper
|
||||
import com.gh.download.DownloadManager
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.gh.gamecenter.R
|
||||
@ -24,7 +29,6 @@ import com.lightgame.download.DownloadEntity
|
||||
import com.lightgame.download.DownloadStatus
|
||||
import com.lightgame.download.FileUtils
|
||||
import com.lightgame.utils.AppManager
|
||||
import com.lightgame.utils.Util_System_Phone_State
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
@ -43,18 +47,22 @@ object DownloadObserver {
|
||||
fun initObserver() {
|
||||
val dataWatcher = object : DataWatcher() {
|
||||
override fun onDataChanged(downloadEntity: 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)
|
||||
|
||||
if (downloadEntity.status != DownloadStatus.downloading) {
|
||||
LogUtils.uploadDownloadEvent(downloadEntity)
|
||||
tryCatchInRelease {
|
||||
DownloadDataHelper.uploadDownloadEvent(downloadEntity)
|
||||
}
|
||||
|
||||
if (DownloadStatus.hijack == downloadEntity.status) {
|
||||
// 链接被劫持
|
||||
processHijack(downloadEntity)
|
||||
val nameAndPlatform = (downloadEntity.name + ":"
|
||||
+ PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
// val nameAndPlatform = (downloadEntity.name + ":"
|
||||
// + PlatformUtils.getInstance(mApplication).getPlatformName(downloadEntity.platform))
|
||||
// MtaHelper.onEvent("下载劫持",
|
||||
// "游戏名字", nameAndPlatform,
|
||||
// "网络状态", DeviceUtils.getNetwork(mApplication))
|
||||
@ -97,15 +105,20 @@ object DownloadObserver {
|
||||
Utils.log("DownloadObserver", "下载自动暂停->" + downloadEntity.toJson())
|
||||
}
|
||||
}
|
||||
} else if (DownloadStatus.redirected == downloadEntity.status) {
|
||||
debugOnly { Utils.log("重定向完毕") }
|
||||
DownloadDataHelper.uploadRedirectEvent(downloadEntity)
|
||||
}
|
||||
if (DownloadStatus.done == downloadEntity.status) {
|
||||
if (downloadEntity.name.contains(mApplication.getString(R.string.app_name))) {
|
||||
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)
|
||||
|
||||
@ -122,20 +135,36 @@ object DownloadObserver {
|
||||
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
|
||||
}
|
||||
if (!downloadEntity.isPluggable) {
|
||||
// 是否是自动安装
|
||||
if (PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)) {
|
||||
if (FileUtils.isEmptyFile(downloadEntity.path)) {
|
||||
Utils.toast(mApplication, R.string.install_failure_hint)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else {
|
||||
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
tryWithDefaultCatch {
|
||||
mApplication.startActivity(PackageUtils.getInstallIntent(mApplication, downloadEntity.path))
|
||||
}
|
||||
if (downloadEntity.isSimulatorGame()) {
|
||||
val gameEntity = HaloApp.get(GameEntity::class.java.simpleName, true) as? GameEntity
|
||||
if (gameEntity?.simulator != null) {
|
||||
val isInstalled = PackageUtils.isInstalledFromAllPackage(HaloApp.getInstance().application, gameEntity.simulator!!.apk!!.packageName)
|
||||
if (!isInstalled) {
|
||||
SimulatorDownloadManager.getInstance().showDownloadDialog(AppManager.getInstance().currentActivity(), gameEntity.simulator,
|
||||
SimulatorDownloadManager.SimulatorLocation.LAUNCH, gameEntity.id, gameEntity.name
|
||||
?: "", null)
|
||||
}
|
||||
SimulatorGameManager.recordDownloadSimulatorGames(gameEntity.id)
|
||||
SimulatorGameManager.postPlayedGame(gameEntity.id, downloadEntity.packageName)
|
||||
}
|
||||
} else {
|
||||
val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
// 是否是自动安装
|
||||
val isAutoInstall = PreferenceManager.getDefaultSharedPreferences(mApplication).getBoolean(SettingsFragment.AUTO_INSTALL_SP_KEY, true)
|
||||
if (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall) {
|
||||
if (FileUtils.isEmptyFile(downloadEntity.path)) {
|
||||
Utils.toast(mApplication, R.string.install_failure_hint)
|
||||
downloadManager.cancel(downloadEntity.url)
|
||||
} else {
|
||||
// 弹出卸载提示框
|
||||
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
|
||||
if (PackageUtils.isCanLaunchSetup(mApplication, downloadEntity.path)) {
|
||||
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
|
||||
tryWithDefaultCatch {
|
||||
PackageInstaller.install(mApplication, downloadEntity, false)
|
||||
}
|
||||
} else {
|
||||
// 弹出卸载提示框
|
||||
EventBus.getDefault().post(EBShowDialog(BaseActivity.PLUGGABLE, downloadEntity.path))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,7 +215,7 @@ object DownloadObserver {
|
||||
kv1["版本"] = platform
|
||||
kv1["状态"] = "下载完成"
|
||||
kv1["用户机型"] = Build.MODEL
|
||||
kv1["设备IMEI"] = Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application)
|
||||
kv1["设备IMEI"] = MetaUtil.getIMEI()
|
||||
kv1["网络状态"] = DeviceUtils.getNetwork(HaloApp.getInstance().application)
|
||||
kv1["光环助手版本"] = BuildConfig.VERSION_NAME
|
||||
if (downloadEntity.isUpdate) {
|
||||
@ -229,6 +258,8 @@ object DownloadObserver {
|
||||
gameVersion = downloadEntity.versionName ?: ""),
|
||||
downloadEntity.platform,
|
||||
downloadEntity.exposureTrace,
|
||||
downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown",
|
||||
downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown",
|
||||
type)
|
||||
|
||||
DataCollectionUtils.uploadDownload(mApplication, downloadEntity, "完成")
|
||||
|
||||
@ -1,17 +1,31 @@
|
||||
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 androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.gh.common.avoidcallback.AvoidOnResultManager;
|
||||
import com.gh.common.avoidcallback.Callback;
|
||||
import com.gh.gamecenter.BuildConfig;
|
||||
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.appcompat.app.AppCompatActivity;
|
||||
|
||||
/**
|
||||
* @author CsHeng
|
||||
@ -25,8 +39,10 @@ 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";
|
||||
@ -38,6 +54,7 @@ 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";//问题标签详情
|
||||
@ -45,25 +62,35 @@ public class EntranceUtils {
|
||||
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 HOST_HELP_AND_FEEDBACK = "help_and_feedback";
|
||||
public static final String HOST_LAUNCH_SIMULATOR_GAME = "launch_simulator_game";
|
||||
public static final String KEY_DATA = "data";
|
||||
public static final String KEY_MESSAGE = "message";
|
||||
public static final String KEY_MESSAGE_ID = "message_id";
|
||||
@ -81,6 +108,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";
|
||||
@ -91,8 +119,10 @@ 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_LOCAL_PATH = "local_path";
|
||||
public static final String KEY_OUTER_INFO = "outerInfo";
|
||||
public static final String KEY_OLDERUSER = "isOldUser";
|
||||
public static final String KEY_SEARCHKEY = "searchKey";
|
||||
@ -140,6 +170,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";
|
||||
@ -161,14 +192,29 @@ 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_CONTENT_ID = "qaContentId";
|
||||
public static final String KEY_QA_CATEGORY_NAME = "qaCategoryName";
|
||||
public static final String KEY_QA_TITLE = "qa_title";
|
||||
public static final String KEY_QA_COLLECTION_ID = "qaCollectionId";
|
||||
public static final String KEY_SHOW_EDIT_DRAFT = "showEditDraft";
|
||||
public static final String KEY_ARTICLE_OPEN_IN_NEW_PAGE = "openArticleInNewPage";
|
||||
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 final String KEY_DIAGNOSIS = "diagnosis";
|
||||
public static final String KEY_SIMULATOR = "simulator";
|
||||
|
||||
public static void jumpActivity(Context context, Bundle bundle) {
|
||||
bundle.putBoolean(KEY_REQUIRE_REDIRECT, true);
|
||||
@ -224,4 +270,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,6 +3,7 @@ package com.gh.common.util
|
||||
import android.animation.Animator
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
import android.text.*
|
||||
import android.text.style.ClickableSpan
|
||||
@ -11,7 +12,10 @@ 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.SeekBar
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.core.content.ContextCompat
|
||||
@ -19,6 +23,7 @@ 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
|
||||
@ -32,8 +37,10 @@ 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
|
||||
@ -41,6 +48,7 @@ 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
|
||||
@ -61,6 +69,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
|
||||
*/
|
||||
@ -159,6 +175,21 @@ 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() } }
|
||||
}
|
||||
|
||||
fun isPublishEnv(): Boolean {
|
||||
return BuildConfig.FLAVOR != "internal"
|
||||
}
|
||||
|
||||
/**
|
||||
* LiveData Extensions
|
||||
*/
|
||||
@ -220,6 +251,29 @@ fun String.containHtmlTag(): Boolean {
|
||||
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
|
||||
*/
|
||||
@ -275,6 +329,15 @@ fun throwExceptionInDebug(message: String = "", predicate: Boolean = true) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动抛出异常
|
||||
*/
|
||||
fun throwException(message: String = "", predicate: Boolean = true) {
|
||||
if (predicate) {
|
||||
throw RuntimeException(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* String related
|
||||
*/
|
||||
@ -314,6 +377,10 @@ 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]
|
||||
@ -364,6 +431,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 自动适配方向
|
||||
* 弹出与锚点右对齐
|
||||
@ -444,6 +516,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.
|
||||
*/
|
||||
@ -566,6 +647,29 @@ 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)
|
||||
}
|
||||
|
||||
fun DownloadEntity.isSimulatorDownload(): Boolean {
|
||||
return Constants.SIMULATOR_DOWNLOAD == getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
|
||||
}
|
||||
|
||||
fun DownloadEntity.isSimulatorGame(): Boolean {
|
||||
return getMetaExtra(Constants.SIMULATOR_GAME).isNotEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Process related
|
||||
*/
|
||||
@ -682,6 +786,17 @@ 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:不同
|
||||
@ -706,4 +821,32 @@ fun List<String>?.checkSameFromStringArray(check2: List<String>?): Boolean {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
fun SeekBar.doOnSeekBarChangeListener(progressChange: ((progress: Int) -> Unit)? = null, onStopTrackingTouch: (() -> Unit)? = null) {
|
||||
this.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
progressChange?.invoke(progress)
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||
onStopTrackingTouch?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
23
app/src/main/java/com/gh/common/util/FastClickUtils.kt
Normal file
23
app/src/main/java/com/gh/common/util/FastClickUtils.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import com.gh.common.OnFastClickListener
|
||||
import io.reactivex.disposables.Disposable
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
object FastClickUtils {
|
||||
|
||||
private var disposable: Disposable? = null
|
||||
private var ref: WeakReference<OnFastClickListener>? = null
|
||||
|
||||
fun click(duration: Int = 500, onClick: OnFastClickListener) {
|
||||
ref = WeakReference(onClick)
|
||||
disposable?.dispose()
|
||||
ref?.get()?.invoke(false)
|
||||
disposable = rxTimer(1) {
|
||||
if (it >= duration) {
|
||||
ref?.get()?.invoke(true)
|
||||
disposable?.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@ import android.text.TextUtils;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.common.simulator.SimulatorGameManager;
|
||||
import com.gh.download.DownloadManager;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.gh.gamecenter.entity.ApkEntity;
|
||||
@ -24,7 +25,6 @@ import java.util.List;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
||||
public class GameUtils {
|
||||
|
||||
/**
|
||||
@ -117,16 +117,27 @@ public class GameUtils {
|
||||
installCount++;
|
||||
}
|
||||
}
|
||||
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
DownloadEntity simulatorDownloadEntity = SimulatorGameManager.findDownloadEntityByUrl(apkEntity.getUrl());
|
||||
if (simulatorDownloadEntity != null && gameEntity.getSimulator() != null) {
|
||||
boolean isInstalled = PackageUtils.isInstalledFromAllPackage(context, gameEntity.getSimulator().getApk().getPackageName());
|
||||
if (isInstalled) {
|
||||
installCount++;
|
||||
} else {
|
||||
doneCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} else if (pluginCount != 0) {
|
||||
return context.getString(R.string.pluggable);
|
||||
} else if (updateCount != 0) {
|
||||
return context.getString(R.string.update);
|
||||
} else if (installCount != 0) {
|
||||
if (installCount != 0) {
|
||||
return context.getString(R.string.launch);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen()) {
|
||||
} else if (pluginCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.pluggable);
|
||||
} else if (updateCount != 0 && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.update);
|
||||
} else if (doneCount != 0) {
|
||||
return context.getString(R.string.install);
|
||||
} else if (gameEntity.getVersionNumber().contains("无版号") && Config.isGameDomeSwitchOpen() && !SimulatorGameManager.isSimulatorGame(gameEntity)) {
|
||||
return context.getString(R.string.attempt);
|
||||
} else {
|
||||
return context.getString(R.string.download);
|
||||
@ -183,6 +194,8 @@ public class GameUtils {
|
||||
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());
|
||||
@ -199,6 +212,7 @@ public class GameUtils {
|
||||
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) {
|
||||
@ -236,7 +250,7 @@ public class GameUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
collectionEntity.setSaveApkEntity(saveApkEntity);
|
||||
return collectionEntity;
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.app.Application
|
||||
import android.text.TextUtils
|
||||
import com.lightgame.utils.Utils
|
||||
import com.qq.gdt.action.GDTAction
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 广点通辅助类 [https://gitlab.ghzhushou.com/pm/halo-app-issues/issues/403]
|
||||
@ -22,32 +18,38 @@ object GdtHelper {
|
||||
const val SCORE = "SCORE"
|
||||
const val PLATFORM = "PLATFORM"
|
||||
|
||||
fun init(application: Application) {
|
||||
GDTAction.init(application, "1110071928", "7fe03caa04ed382e9dce401312b1d0ae")
|
||||
fun init(application: Application, channel: String) {
|
||||
// if (channel == "GH_728") {
|
||||
// GDTAction.init(application, "1111012969", "9d3d9da5b0948a317c03d08f14d445dc")
|
||||
// } else if (channel == "GH_729") {
|
||||
// GDTAction.init(application, "1111013063", "f53dabf458a356b101d99fc4069eb7f1")
|
||||
// } else {
|
||||
// GDTAction.init(application, "1110680399", "f5ddaafbf520d7d7385499232a408d0a")
|
||||
// }
|
||||
}
|
||||
|
||||
fun logAction(type: String) {
|
||||
GDTAction.logAction(type)
|
||||
Utils.log("GDT", type)
|
||||
// GDTAction.logAction(type)
|
||||
// Utils.log("GDT", type)
|
||||
}
|
||||
|
||||
fun logAction(type: String, vararg kv: String?) {
|
||||
try {
|
||||
val actionParam = JSONObject()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
actionParam.put(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
|
||||
GDTAction.logAction(type, actionParam)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
// try {
|
||||
// val actionParam = JSONObject()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// actionParam.put(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Utils.log("GDT", "$type + [${kv.joinToString(" , ")}]")
|
||||
// GDTAction.logAction(type, actionParam)
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -9,7 +10,10 @@ import org.json.JSONArray
|
||||
* Created by khy on 11/10/17.
|
||||
*/
|
||||
object GsonUtils {
|
||||
|
||||
@JvmStatic
|
||||
val gson: Gson = Gson()
|
||||
val gsonThatIgnoreNull: Gson = GsonBuilder().serializeNulls().create()
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJson(json: String, t: Class<T>): T {
|
||||
@ -18,18 +22,31 @@ object GsonUtils {
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJsonList(json: JSONArray): List<T> {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json.toString(), type)
|
||||
return try {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json.toString(), type)
|
||||
} catch (e: Exception) {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun <T> fromJsonList(json: String): List<T> {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
return gson.fromJson(json, type)
|
||||
return try {
|
||||
val type = object : TypeToken<List<T>>() {}.type
|
||||
gson.fromJson(json, type)
|
||||
} catch (e: Exception) {
|
||||
listOf()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun toJson(any: Any?): String {
|
||||
return gson.toJson(any)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun toJsonIgnoreNull(any: Any?): String {
|
||||
return gsonThatIgnoreNull.toJson(any)
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -10,27 +11,39 @@ import android.os.Build
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.facebook.common.executors.CallerThreadExecutor
|
||||
import com.facebook.common.references.CloseableReference
|
||||
import com.facebook.datasource.DataSource
|
||||
import com.facebook.drawee.backends.pipeline.Fresco
|
||||
import com.facebook.drawee.controller.BaseControllerListener
|
||||
import com.facebook.drawee.controller.ControllerListener
|
||||
import com.facebook.drawee.drawable.ScalingUtils
|
||||
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
|
||||
import com.facebook.drawee.view.SimpleDraweeView
|
||||
import com.facebook.imagepipeline.core.ImagePipeline
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber
|
||||
import com.facebook.imagepipeline.image.CloseableImage
|
||||
import com.facebook.imagepipeline.image.ImageInfo
|
||||
import com.facebook.imagepipeline.request.ImageRequest
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.common.structure.FixedSizeLinkedHashSet
|
||||
import com.gh.gamecenter.R
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.squareup.picasso.Picasso
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
|
||||
object ImageUtils {
|
||||
|
||||
private const val PIC_MAX_FILE_SIZE: Long = 10 * 1024 * 1024
|
||||
|
||||
private val TINY_GIF_SIZE = 30F.dip2px()
|
||||
private val LARGE_GIF_SIZE = 80F.dip2px()
|
||||
private val STANDARD_GIF_SIZE = 60F.dip2px()
|
||||
|
||||
private val mImageUrlCacheSet by lazy { FixedSizeLinkedHashSet<String>(maxSize = 200) }
|
||||
|
||||
@JvmStatic
|
||||
fun getUploadFileMaxSize(): Long {
|
||||
val uploadLimitSize = Config.getSettings()?.image?.uploadLimitSize
|
||||
@ -216,17 +229,54 @@ object ImageUtils {
|
||||
.build()
|
||||
}
|
||||
|
||||
// 获取bitmap
|
||||
/**
|
||||
* 获取bitmap (使用 fresco 获取 gif 的 bitmap 会为空,https://github.com/facebook/fresco/issues/241)
|
||||
* 所以当 url 以 .gif 结尾时换用 picasso 获取
|
||||
* 优先使用 fresco 是因为可能已经有了缓存
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
@JvmStatic
|
||||
fun display(context: Context?, url: String?, dataSubscriber: BaseBitmapDataSubscriber) {
|
||||
fun getBitmap(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
if (url.endsWith(".gif")) {
|
||||
getBitmapWithPicasso(url, callback)
|
||||
} else {
|
||||
getBitmapWithFresco(url, callback)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBitmapWithFresco(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
val imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(Uri.parse(url))
|
||||
.setProgressiveRenderingEnabled(true)
|
||||
.build()
|
||||
|
||||
Fresco.getImagePipeline()
|
||||
.fetchDecodedImage(imageRequest, context)
|
||||
.subscribe(dataSubscriber, CallerThreadExecutor.getInstance())
|
||||
.fetchDecodedImage(imageRequest, HaloApp.getInstance().application)
|
||||
.subscribe(object : BaseBitmapDataSubscriber() {
|
||||
override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
|
||||
callback.onSecond(true)
|
||||
}
|
||||
|
||||
override fun onNewResultImpl(bitmap: Bitmap?) {
|
||||
if (bitmap != null) {
|
||||
callback.onFirst(bitmap)
|
||||
} else {
|
||||
callback.onSecond(true)
|
||||
}
|
||||
}
|
||||
}, CallerThreadExecutor.getInstance())
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun getBitmapWithPicasso(url: String, callback: BiCallback<Bitmap, Boolean>) {
|
||||
Single.just(url)
|
||||
.map { Picasso.with(HaloApp.getInstance().application).load(url).priority(Picasso.Priority.HIGH).get() }
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
callback.onFirst(it)
|
||||
}, {
|
||||
callback.onSecond(true)
|
||||
it.printStackTrace()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,23 +287,56 @@ object ImageUtils {
|
||||
@JvmStatic
|
||||
fun display(view: SimpleDraweeView?, url: String?) {
|
||||
url?.let {
|
||||
// 图片是以 gif 结尾的就
|
||||
if (it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false) {
|
||||
if (view?.tag == url) return@let
|
||||
val width = view?.layoutParams?.width
|
||||
val height = view?.layoutParams?.height
|
||||
|
||||
val controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(url)
|
||||
.setAutoPlayAnimations(true)
|
||||
var lowResUrl = ""
|
||||
var highResUrl = ""
|
||||
|
||||
// 找同一图片地址已加载过的图片作为低质量预览图
|
||||
// TODO 根据实际请求大小(w_width)来避免小图用大图作为低质量图片
|
||||
for (cachedImageUrl in mImageUrlCacheSet) {
|
||||
if (cachedImageUrl.contains(url)) {
|
||||
lowResUrl = cachedImageUrl
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
val loadImageClosure: (autoPlay: Boolean, highResUrl: String, lowResUrl: String) -> Unit = { autoPlay, hUrl, lUrl ->
|
||||
view?.controller = Fresco.newDraweeControllerBuilder()
|
||||
.setImageRequest(ImageRequest.fromUri(hUrl))
|
||||
.apply {
|
||||
if (lUrl.isNotEmpty()
|
||||
&& lUrl != hUrl
|
||||
&& hUrl != view?.getTag(R.string.highResImageTag)) {
|
||||
lowResImageRequest = ImageRequest.fromUri(lUrl)
|
||||
}
|
||||
autoPlayAnimations = autoPlay
|
||||
}
|
||||
.build()
|
||||
view?.controller = controller
|
||||
} else {
|
||||
val width = view?.layoutParams?.width
|
||||
if (width != null && width > 0) {
|
||||
view.setImageURI(getTransformLimitUrl(url, width, view.context))
|
||||
|
||||
view?.setTag(R.string.highResImageTag, highResUrl)
|
||||
}
|
||||
|
||||
val shouldLoadAsGif = it.endsWith(".gif") && view?.getTag(R.id.tag_show_gif) != false
|
||||
|
||||
if (shouldLoadAsGif && view?.tag == url) return
|
||||
|
||||
if (width != null && width > 0) {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, width, height ?: 0)
|
||||
} else {
|
||||
view?.post {
|
||||
view.setImageURI(getTransformLimitUrl(url, view.width, view.context))
|
||||
getTransformLimitUrl(url, width, view.context) ?: ""
|
||||
}
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
} else {
|
||||
view?.post {
|
||||
highResUrl = if (shouldLoadAsGif) {
|
||||
resizeGif(url, view.width, height ?: 0)
|
||||
} else {
|
||||
getTransformLimitUrl(url, view.width, view.context) ?: ""
|
||||
}
|
||||
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
|
||||
}
|
||||
}
|
||||
view?.tag = url
|
||||
@ -265,12 +348,13 @@ object ImageUtils {
|
||||
fun getTransformLimitUrl(url: String?, width: Int?, context: Context?): String? {
|
||||
var transformUrl: String? = url
|
||||
if (width != null && width > 0) {
|
||||
// 加载大小是实际 ImageView 大小两倍的图片真的有意义吗?
|
||||
val transformUrlX2 = addLimitWidth(url, width * 2)
|
||||
val transformUrlX1 = addLimitWidth(url, width)
|
||||
// 当网络为 WIFI 或 4G, 且系统版本大于 5.0 && 手机内存大于 1G 才用高清图片
|
||||
if (NetworkUtils.isWifiOr4GConnected(context)
|
||||
&& Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP
|
||||
&& DeviceUtils.getTotalRamSizeOfDevice(context) > 1000) {
|
||||
&& HaloApp.getInstance().deviceRamSize > 1024) {
|
||||
transformUrl = transformUrlX2
|
||||
} else {
|
||||
// 检查X2大图是否被缓存
|
||||
@ -282,7 +366,7 @@ object ImageUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Utils.log("displayPost::viewWidth->$width----transformUrl->$transformUrl")
|
||||
addCachedUrl(transformUrl ?: "")
|
||||
return transformUrl
|
||||
}
|
||||
|
||||
@ -292,15 +376,19 @@ object ImageUtils {
|
||||
val width = view?.layoutParams?.width
|
||||
if (width != null && width > 0) {
|
||||
view.setImageURI(addLimitWidth(url, width * 2))
|
||||
// Utils.log("displayIcon::viewWidth->" + view.width + "---transformUrl->" + transformUrl)
|
||||
} else {
|
||||
view?.post {
|
||||
view.setImageURI(addLimitWidth(url, view.width * 2))
|
||||
// Utils.log("displayIcon::viewWidth->" + view.width + "---transformUrl->" + transformUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCachedUrl(url: String) {
|
||||
if (url.startsWith("http")) {
|
||||
mImageUrlCacheSet.add(url)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun bmpToByteArray(bmp: Bitmap, needRecycle: Boolean): ByteArray {
|
||||
val output = ByteArrayOutputStream()
|
||||
@ -327,14 +415,34 @@ object ImageUtils {
|
||||
|
||||
//预加载图片
|
||||
@JvmStatic
|
||||
fun prefetchToDiskCache(url: String){
|
||||
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".also { addCachedUrl(it) }
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
package com.gh.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.lightgame.utils.Util_System_Phone_State;
|
||||
import com.gh.common.exposure.meta.MetaUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -19,11 +18,11 @@ public class Installation {
|
||||
private static String sID = null;
|
||||
|
||||
public synchronized static String getUUID(Context context) {
|
||||
String imei = Util_System_Phone_State.getDeviceId(context);
|
||||
String imei = MetaUtil.getIMEI();
|
||||
if (!TextUtils.isEmpty(imei)) {
|
||||
return imei;
|
||||
}
|
||||
String android_id = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
String android_id = MetaUtil.getAndroidId();
|
||||
if (!TextUtils.isEmpty(android_id)) {
|
||||
return android_id;
|
||||
}
|
||||
|
||||
@ -18,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;
|
||||
@ -455,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,26 +1,29 @@
|
||||
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 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;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -30,6 +33,9 @@ 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 +59,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 {
|
||||
@ -297,14 +254,13 @@ public class LogUtils {
|
||||
try {
|
||||
object.put("version", PackageUtils.getVersionName());
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("time", Utils.getTime(context));
|
||||
object.put("network", DeviceUtils.getNetwork(context));
|
||||
object.put("user_id", UserManager.getInstance().getUserId());
|
||||
object.put("device_system", android.os.Build.VERSION.RELEASE);
|
||||
object.put("device_model", android.os.Build.MODEL);
|
||||
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance()
|
||||
.getApplication()));
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("G_ID", UserManager.getInstance().getDeviceId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -322,14 +278,13 @@ public class LogUtils {
|
||||
try {
|
||||
object.put("version", PackageUtils.getVersionName());
|
||||
object.put("channel", HaloApp.getInstance().getChannel());
|
||||
object.put("android_id", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
|
||||
object.put("android_id", MetaUtil.getAndroidId());
|
||||
object.put("time", Utils.getTime(context));
|
||||
object.put("network", DeviceUtils.getNetwork(context));
|
||||
object.put("user_id", UserManager.getInstance().getUserId());
|
||||
object.put("device_system", android.os.Build.VERSION.RELEASE);
|
||||
object.put("device_model", android.os.Build.MODEL);
|
||||
object.put("imei", Util_System_Phone_State.getImei(HaloApp.getInstance()
|
||||
.getApplication()));
|
||||
object.put("imei", MetaUtil.getIMEI());
|
||||
object.put("G_ID", UserManager.getInstance().getDeviceId());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
@ -420,6 +375,55 @@ 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();
|
||||
@ -486,6 +490,7 @@ public class LogUtils {
|
||||
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();
|
||||
@ -503,5 +508,133 @@ public class LogUtils {
|
||||
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<>());
|
||||
}
|
||||
|
||||
public static JSONObject getMetaObject() {
|
||||
Meta meta = MetaUtil.INSTANCE.getMeta();
|
||||
JSONObject metaObject = new JSONObject();
|
||||
try {
|
||||
metaObject.put("android_id", meta.getAndroid_id());
|
||||
metaObject.put("android_sdk", meta.getAndroid_sdk());
|
||||
metaObject.put("android_version", meta.getAndroid_version());
|
||||
metaObject.put("appVersion", meta.getAppVersion());
|
||||
metaObject.put("channel", meta.getChannel());
|
||||
metaObject.put("gid", meta.getGid());
|
||||
metaObject.put("imei", meta.getImei());
|
||||
metaObject.put("mac", meta.getMac());
|
||||
metaObject.put("manufacturer", meta.getManufacturer());
|
||||
metaObject.put("model", meta.getModel());
|
||||
metaObject.put("network", meta.getNetwork());
|
||||
metaObject.put("os", meta.getOs());
|
||||
metaObject.put("userId", meta.getUserId());
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return metaObject;
|
||||
}
|
||||
|
||||
private static void uploadCommunity(JSONObject object) {
|
||||
try {
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "community", false);
|
||||
}
|
||||
|
||||
public static void uploadAccessToBbs(String bbsId, String location) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
payload.put("location", location);//关注板块/文章外所属论坛/游戏详情/文章内所属论坛
|
||||
payload.put("bbs_id", bbsId);
|
||||
|
||||
object.put("event", "access_to_bbs");
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
uploadCommunity(object);
|
||||
}
|
||||
|
||||
public static void uploadAccessBbsTab() {
|
||||
JSONObject object = new JSONObject();
|
||||
try {
|
||||
object.put("event", "main_tab[bbs]");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
uploadCommunity(object);
|
||||
}
|
||||
|
||||
|
||||
public static void uploadSimulatorDownload(String event, String fileName, String simulatorId, String simulatorName, String gameId, String location, String downloadType, String startTime) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
object.put("event", event);// 取值有[开始, 完成] [simulator_download, simulator_download_complete]
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
|
||||
payload.put("filename", fileName);// 下载模拟器文件名,每次新创建的下载任务文件名都不同,可以用来关联同一次的下载开始与完成
|
||||
payload.put("simulator_id", simulatorId);
|
||||
payload.put("simulator_name", simulatorName);
|
||||
payload.put("location", location);//启动《具体的游戏名称》/模拟器游戏/模拟器游戏-模拟器管理
|
||||
payload.put("game_id", gameId);//如果是 启动《游戏名称》 这种方式, 记录这个游戏具体的游戏ID
|
||||
payload.put("download_type", downloadType);// update/download 下载类型(更新/下载)
|
||||
if (!TextUtils.isEmpty(startTime) && event.equals("simulator_download_complete")) {
|
||||
payload.put("simulator_download_timestamp", startTime);// 对应的下载开始时间
|
||||
}
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
|
||||
public static void uploadSearchGame(String event, String location, String key, String searchType) {
|
||||
uploadSearchClick(event, location, key, searchType, "", "");
|
||||
}
|
||||
|
||||
public static void uploadSearchClick(String event, String location, String key, String searchType, String gameId, String gameName) {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject payload = new JSONObject();
|
||||
try {
|
||||
object.put("event", event);
|
||||
object.put("location", location);
|
||||
object.put("meta", getMetaObject());
|
||||
object.put("timestamp", System.currentTimeMillis() / 1000);
|
||||
|
||||
payload.put("key", key); //搜索关键词
|
||||
payload.put("search_type", searchType); //搜索类型, 有四种取值 默认搜索/历史搜索/自动搜索/主动搜索
|
||||
payload.put("game_id", gameId); //event为search_click才取值
|
||||
payload.put("game_name", gameName); //event为search_click才取值
|
||||
object.put("payload", payload);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Utils.log("LogUtils->" + object.toString());
|
||||
}
|
||||
LoghubUtils.log(object, "event", false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package com.gh.common.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import com.gh.common.constant.Config
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.user.LoginTag
|
||||
@ -87,7 +86,9 @@ object LoginHelper {
|
||||
}
|
||||
}
|
||||
|
||||
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
|
||||
|
||||
|
||||
// DouYinOpenApiFactory.init(DouYinOpenConfig(Config.DOUYIN_CLIENTKEY))
|
||||
|
||||
Utils.log("LoginHelper initialization")
|
||||
}
|
||||
@ -107,6 +108,16 @@ object LoginHelper {
|
||||
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?.get()?.authorizeCallBack(requestCode, resultCode, data)
|
||||
@ -149,6 +160,8 @@ object LoginHelper {
|
||||
// 微博登录
|
||||
@JvmStatic
|
||||
fun loginWithWeibo(loginCallback: LoginCallback, context: Activity) {
|
||||
WbSdk.install(context, AuthInfo(context, Config.WEIBO_APPKEY, "http://www.sina.com", WEIBO_SCOPE))
|
||||
|
||||
mLoginCallback = WeakReference(loginCallback)
|
||||
mSsoHandler = WeakReference(SsoHandler(context))
|
||||
mSsoHandler?.get()?.authorizeClientSso(object : WbAuthListener {
|
||||
@ -187,6 +200,19 @@ object LoginHelper {
|
||||
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;
|
||||
|
||||
@ -3,9 +3,8 @@ package com.gh.common.util;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.net.Uri;
|
||||
@ -16,6 +15,7 @@ import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
@ -26,6 +26,7 @@ import android.widget.PopupWindow;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.gh.common.Base64ImageHolder;
|
||||
import com.gh.common.constant.Config;
|
||||
import com.gh.gamecenter.R;
|
||||
import com.lightgame.utils.Utils;
|
||||
@ -205,6 +206,48 @@ public class MessageShareUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public void shareFromWeb(Activity activity, String type) {
|
||||
// base64转bitmap
|
||||
byte[] decode = Base64.decode(Base64ImageHolder.INSTANCE.getImage(), Base64.DEFAULT);
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
|
||||
// 转完后重新置位
|
||||
Base64ImageHolder.INSTANCE.setImage("");
|
||||
|
||||
this.picName = "shareImgPic.jpg";
|
||||
this.mActivity = new WeakReference<>(activity);
|
||||
this.shareBm = bitmap;
|
||||
|
||||
// 保存图片
|
||||
File file = new File(activity.getExternalCacheDir().getPath() + "/ShareImg");
|
||||
if (!file.isDirectory()) {
|
||||
file.delete();
|
||||
file.mkdirs();
|
||||
}
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
writeBitmap(file.getPath(), picName, bitmap, false);
|
||||
|
||||
// 分享
|
||||
switch (type) {
|
||||
case "qq" :
|
||||
qqSahre();
|
||||
break;
|
||||
case "qq_zone" :
|
||||
qZoneSahre();
|
||||
break;
|
||||
case "wechat" :
|
||||
wechatSahre();
|
||||
break;
|
||||
case "wechat_moments" :
|
||||
wechatMomentsSahre();
|
||||
case "save" :
|
||||
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/";
|
||||
writeBitmap(savePath, "gh-" + new Date().getTime() + ".jpg", shareBm, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//QQ分享
|
||||
private void qqSahre() {
|
||||
Utils.toast(mContext, "分享跳转中...");
|
||||
|
||||
@ -1,61 +1,52 @@
|
||||
package com.gh.common.util
|
||||
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.BuildConfig
|
||||
import com.halo.assistant.HaloApp
|
||||
import com.lightgame.utils.Util_System_Phone_State
|
||||
import com.lightgame.utils.Utils
|
||||
import com.tencent.stat.StatService
|
||||
import java.util.*
|
||||
|
||||
object MtaHelper {
|
||||
|
||||
@JvmStatic
|
||||
fun onEvent(eventId: String, vararg kv: String?) {
|
||||
val prop = Properties()
|
||||
|
||||
if (kv.size == 1) {
|
||||
prop.setProperty(kv[0], kv[0])
|
||||
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
return
|
||||
}
|
||||
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// val prop = Properties()
|
||||
//
|
||||
// if (kv.size == 1) {
|
||||
// prop.setProperty(kv[0], kv[0])
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onEventWithTime(eventId: String, time: Int, vararg kv: String?) {
|
||||
val prop = Properties()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0 || i != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop.size == 0 && kv.size == 1) {
|
||||
prop.setProperty(kv[0], kv[0])
|
||||
}
|
||||
|
||||
if (prop.size == 0) return
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
|
||||
StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
|
||||
// val prop = Properties()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0 || i != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (prop.size == 0 && kv.size == 1) {
|
||||
// prop.setProperty(kv[0], kv[0])
|
||||
// }
|
||||
//
|
||||
// if (prop.size == 0) return
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}] + last $time seconds")
|
||||
// StatService.trackCustomKVTimeIntervalEvent(HaloApp.getInstance().application, time, eventId, prop)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,29 +54,29 @@ object MtaHelper {
|
||||
*/
|
||||
@JvmStatic
|
||||
fun onEventWithBasicDeviceInfo(eventId: String, vararg kv: String) {
|
||||
val prop = Properties()
|
||||
for (i in kv.indices) {
|
||||
if (i % 2 != 0) {
|
||||
val key = kv[i - 1]
|
||||
val value = kv[i]
|
||||
if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
prop.setProperty(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prop.setProperty("光环版本", BuildConfig.VERSION_NAME)
|
||||
prop.setProperty("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
prop.setProperty("IMEI", Util_System_Phone_State.getDeviceId(HaloApp.getInstance().application))
|
||||
prop.setProperty("机型", Build.MODEL)
|
||||
prop.setProperty("厂商", Build.MANUFACTURER)
|
||||
prop.setProperty("Android版本", Build.VERSION.RELEASE)
|
||||
if (!TextUtils.isEmpty(HaloApp.getInstance().gid)) {
|
||||
prop.setProperty("GID", HaloApp.getInstance().gid)
|
||||
}
|
||||
|
||||
Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
// val prop = Properties()
|
||||
// for (i in kv.indices) {
|
||||
// if (i % 2 != 0) {
|
||||
// val key = kv[i - 1]
|
||||
// val value = kv[i]
|
||||
// if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
|
||||
// prop.setProperty(key, value)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// prop.setProperty("光环版本", BuildConfig.VERSION_NAME)
|
||||
// prop.setProperty("网络状态", DeviceUtils.getNetwork(HaloApp.getInstance().application))
|
||||
// prop.setProperty("IMEI", MetaUtil.getIMEI())
|
||||
// prop.setProperty("机型", Build.MODEL)
|
||||
// prop.setProperty("厂商", Build.MANUFACTURER)
|
||||
// prop.setProperty("Android版本", Build.VERSION.RELEASE)
|
||||
// if (!TextUtils.isEmpty(HaloApp.getInstance().gid)) {
|
||||
// prop.setProperty("GID", HaloApp.getInstance().gid)
|
||||
// }
|
||||
//
|
||||
// Utils.log("MTA","$eventId + [${kv.joinToString(" , ")}]")
|
||||
// StatService.trackCustomKVEvent(HaloApp.getInstance().application, eventId, prop)
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user